HDF.cc

00001 /*
00002  * $Id: HDF.cc,v 1.42 2006/04/03 15:11:18 brook Exp $
00003  */
00004 
00005 /*
00006  * ClearSilver++ Software License.
00007  *
00008  * Copyright (c) 2005,2006 Brook Milligan <brook@nmsu.edu>
00009  * All rights reserved.
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above
00018  *    copyright notice, this list of conditions and the following
00019  *    disclaimer in the documentation and/or other materials provided
00020  *    with the distribution.
00021  * 3. The name of the author may not be used to endorse or promote
00022  *    products derived from this software without specific prior
00023  *    written permission.
00024  * 
00025  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00026  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00027  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00029  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00031  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00033  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036  */
00037 
00038 #include "HDF.h"
00039 
00040 #include <stdexcept>
00041 #include <string.h>
00042 #include <syslog.h>
00043 #include <boost/lexical_cast.hpp>
00044 #include <ClearSilver/util/neo_misc.h> // must precede neo_hdf.h
00045 #include <ClearSilver/util/neo_hdf.h>
00046 #include "ClearSilverError.h"
00047 #include "ClearSilverException.h"
00048 
00049 using namespace std;
00050 
00051                                 // constructors
00052 ClearSilver::HDF::HDF ()
00053   : TraceObject(debug(), "HDF"), ConstHDFNode(), HDFNode(), root_(), nodes_()
00054 {}
00055 ClearSilver::HDF::HDF (const char* path)
00056   : TraceObject(debug(), "HDF", "const char*"),
00057     ConstHDFNode(), HDFNode(), root_(), nodes_()
00058 {
00059   if (path && *path)
00060     root_().read_file(path);
00061 }
00062 ClearSilver::HDF::HDF (const string& path)
00063   : TraceObject(debug(), "HDF", "const string&"),
00064     ConstHDFNode(), HDFNode(), root_(), nodes_()
00065 {
00066   if (!path.empty())
00067     root_().read_file(path);
00068 }
00069 ClearSilver::HDF::HDF (const RootNode& root)
00070   : TraceObject(debug(), "HDF", "const RootNode&"),
00071     HDFNode(), root_(root), nodes_()
00072 {}
00073 ClearSilver::HDF::HDF (const HDF& hdf)
00074   : TraceObject(hdf), ConstHDFNode(hdf), HDFNode(hdf),
00075     root_(hdf.root_), nodes_(hdf.nodes_)
00076 {}
00077 ClearSilver::HDF::~HDF () throw()
00078 {}
00079 
00080                                 // assignment
00081 ClearSilver::HDF&
00082 ClearSilver::HDF::operator = (const HDF& hdf)
00083 {
00084   TraceObject::operator = (hdf);
00085   if (debug())
00086     {
00087       string message;
00088       message += string("ClearSilver::HDF::operator = (const HDF&): ");
00089       if (this->is_dataset())
00090         message += "dataset=";
00091       else if (this->is_reference())
00092         message += "reference=";
00093       else if (this->is_iterator())
00094         message += "iterator=";
00095       else
00096         message += "???";
00097       if (hdf.is_dataset())
00098         message += "dataset";
00099       else if (hdf.is_reference())
00100         message += "reference";
00101       else if (hdf.is_iterator())
00102         message += "iterator";
00103       else
00104         message += "???";
00105       syslog (LOG_DEBUG, "%s", message.c_str());
00106     }
00107   if (this->is_dataset() && hdf.is_dataset()
00108       || this->is_iterator() && hdf.is_iterator())
00109     {
00110       HDF hdf0 (hdf);
00111       swap (hdf0);
00112     }
00113   else if (this->is_reference() && hdf.is_reference())
00114     set_value (hdf.get_value());
00115   else
00116     {
00117       string message;
00118       message += "ClearSilver::HDF::operator = (const HDF&): ";
00119       message += "mismatched argument types";
00120       throw invalid_argument(message);
00121     }
00122   return *this;
00123 }
00124 
00125 ClearSilver::HDF::HDF&
00126 ClearSilver::HDF::operator = (const char* value)
00127 {
00128   return operator = (std::string(value));
00129 }
00130 
00131 ClearSilver::HDF::HDF&
00132 ClearSilver::HDF::operator = (const std::string& value)
00133 {
00134   set_value (value);
00135   return *this;
00136 }
00137 
00138 ClearSilver::HDF::HDF&
00139 ClearSilver::HDF::operator = (int value)
00140 {
00141   set_value (value);
00142   return *this;
00143 }
00144 
00145 ClearSilver::HDF::HDF&
00146 ClearSilver::HDF::operator = (bool value)
00147 {
00148   set_value (value);
00149   return *this;
00150 }
00151 
00152 ClearSilver::HDF::HDF&
00153 ClearSilver::HDF::operator = (const SymlinkTarget& target)
00154 {
00155   ClearSilverError error (hdf_set_symlink (root_().get(), path().c_str(),
00156                                            target().c_str()));
00157   if (error)
00158     {
00159       string message;
00160       message += "ClearSilver::HDF::operator = (const SymlinkTarget&): ";
00161       ClearSilverException e (message);
00162       e += error;
00163       throw e;
00164     }
00165 }
00166 
00167                                 // inspectors
00168                                 // depth of current node
00169 ClearSilver::HDF::size_type
00170 ClearSilver::HDF::depth () const
00171 {
00172   return nodes_.depth();
00173 }
00174 
00175                                 // path to the current node
00176 std::string
00177 ClearSilver::HDF::path () const
00178 {
00179   return nodes_.path();
00180 }
00181 
00182                                 // associative array-like interface
00183 ClearSilver::HDF::const_reference
00184 ClearSilver::HDF::operator [] (const char* key) const
00185 {
00186   return operator [] (std::string(key));
00187 }
00188 
00189 ClearSilver::HDF::const_reference
00190 ClearSilver::HDF::operator [] (const string& key) const
00191 {
00192   return *find(key);
00193 }
00194 
00195 ClearSilver::HDF::reference
00196 ClearSilver::HDF::operator [] (const char* key)
00197 {
00198   return operator [] (std::string(key));
00199 }
00200 
00201 ClearSilver::HDF::reference
00202 ClearSilver::HDF::operator [] (const string& key)
00203 {
00204   if (key.empty())
00205     {
00206       string message;
00207       message += "ClearSilver::HDF::operator [] (const string&): ";
00208       message += "empty key";
00209       throw invalid_argument(message);
00210     }
00211   if (debug())
00212     {
00213       string message;
00214       message += string("HDF::operator [] (const string& key): key=") + key;
00215       syslog (LOG_DEBUG, "%s", message.c_str());
00216     }
00217 
00218   iterator i (*this);
00219   ClearSilverNode node (i->node().get_node(key));
00220   if (!node)
00221     {
00222       string message;
00223       message += "ClearSilver::HDF::operator [] (const string&): ";
00224       message += "impossible error: ";
00225       message += "'" + key + "' ";
00226       message += "does not refer to any node";
00227       throw invalid_argument (message);
00228     }
00229   return *find (key);
00230 }
00231 
00232                                 // STL iterators
00233 ClearSilver::HDF::const_iterator
00234 ClearSilver::HDF::begin () const
00235 {
00236   if (empty())                  // XXX
00237     return end();
00238 
00239   const_iterator i (*this);
00240   i.is_iterator() = true;
00241   ClearSilverNode child (i->node().child());
00242   string name;
00243   if (child)
00244     name = child.name();
00245   i->push(name, child);
00246   return i;
00247 }
00248 
00249 ClearSilver::HDF::const_iterator
00250 ClearSilver::HDF::end () const
00251 {
00252   const_iterator i (*this);
00253   i.is_iterator() = true;
00254   i->push (string(), ClearSilverNode());
00255   return i;
00256 }
00257 
00258 ClearSilver::HDF::iterator
00259 ClearSilver::HDF::begin ()
00260 {
00261   if (empty())                  // XXX
00262     return end();
00263 
00264   iterator i (*this);
00265   i.is_iterator() = true;
00266   ClearSilverNode child (i->node().child());
00267   string name;
00268   if (child)
00269     name = child.name();
00270   i->push(name, child);
00271   return i;
00272 }
00273 
00274 ClearSilver::HDF::iterator
00275 ClearSilver::HDF::end ()
00276 {
00277   iterator i (*this);
00278   i.is_iterator() = true;
00279   i->push (string(), ClearSilverNode());
00280   return i;
00281 }
00282 
00283 ClearSilver::HDF::const_iterator
00284 ClearSilver::HDF::find (const char* key) const
00285 {
00286   return find(std::string(key));
00287 }
00288 
00289 ClearSilver::HDF::const_iterator
00290 ClearSilver::HDF::find (const string& key) const
00291 {
00292   if (debug())
00293     {
00294       string message;
00295       message += string("HDF::find (const string& key) const: ");
00296       message += "key=" + key;
00297       syslog (LOG_DEBUG, "%s", message.c_str());
00298     }
00299   Nodes nodes (find_node (key));
00300   const_iterator i (*this);
00301   i.is_iterator() = true;
00302   i->nodes() = nodes;
00303   if (debug())
00304     i->nodes().print();
00305   if (debug())
00306     syslog (LOG_DEBUG, "%s", "HDF::find (const string& key) const: done");
00307   return i;
00308 }
00309 
00310 ClearSilver::HDF::iterator
00311 ClearSilver::HDF::find (const char* key)
00312 {
00313   return find (std::string(key));
00314 }
00315 
00316 ClearSilver::HDF::iterator
00317 ClearSilver::HDF::find (const string& key)
00318 {
00319   if (debug())
00320     {
00321       string message;
00322       message += string("HDF::find (const string& key): key=") + key;
00323       syslog (LOG_DEBUG, "%s", message.c_str());
00324       nodes().print();
00325     }
00326   Nodes nodes (find_node (key));
00327   iterator i (*this);
00328   i.is_iterator() = true;
00329   i->nodes() = nodes;
00330   if (debug())
00331     {
00332       syslog (LOG_DEBUG, "%s", "HDF::find (const string& key): done");
00333       i->nodes().print();
00334     }
00335   return i;
00336 }
00337 
00338                                 // iterator methods
00339 ClearSilver::HDF::iterator&
00340 ClearSilver::HDF::operator ++ ()
00341 {
00342   ClearSilverNode node (this->node().next());
00343   string name;
00344   if (node)
00345     name = node.name();
00346   pop();
00347   push(name, node);
00348   return *this;
00349 }
00350 
00351 ClearSilver::HDF::iterator
00352 ClearSilver::HDF::operator ++ (int)
00353 {
00354   iterator i (*this);
00355   operator++();
00356   return i;
00357 }
00358 
00359                                 // XXX - no longer an iterator
00360 ClearSilver::HDF::value_type
00361 ClearSilver::HDF::operator * ()
00362 {
00363   value_type v(*this);
00364   v.is_iterator() = false;
00365   return v;
00366 }
00367 
00368 ClearSilver::HDF::pointer
00369 ClearSilver::HDF::operator -> ()
00370 {
00371   return this;
00372  }
00373 
00374                                 // deep copy methods
00375 ClearSilver::HDF&
00376 ClearSilver::HDF::copy (const HDF& dataset)
00377 {
00378   return copy("", dataset);
00379 }
00380 
00381 ClearSilver::HDF&
00382 ClearSilver::HDF::copy (const char* key, const HDF& dataset)
00383 {
00384   return copy(std::string(key), dataset);
00385 }
00386 
00387 ClearSilver::HDF&
00388 ClearSilver::HDF::copy (const std::string& key, const HDF& dataset)
00389 {
00390   node().copy (key, dataset.node());
00391   return *this;
00392 }
00393 
00394 ClearSilver::Nodes
00395 ClearSilver::HDF::nodes () const
00396 {
00397   return nodes_;
00398 }
00399 
00400 ClearSilver::Nodes&
00401 ClearSilver::HDF::nodes ()
00402 {
00403   return nodes_;
00404 }
00405 
00406 ClearSilver::ClearSilverNode
00407 ClearSilver::HDF::node () const
00408 {
00409   if (nodes_.empty())
00410     return root_();
00411   return nodes_.top();
00412 }
00413 
00414                                 // access the root node
00415 ClearSilver::ClearSilverNode
00416 ClearSilver::HDF::root () const
00417 {
00418   return root_();
00419 }
00420 
00421                                 // access the node attributes.
00422 ClearSilver::HDFAttributes
00423 ClearSilver::HDF::attributes ()
00424 {
00425   return HDFAttributes (nodes_, node().attr());
00426 }
00427 
00428 void
00429 ClearSilver::HDF::swap (HDF& hdf) throw()
00430 {
00431   TraceObject::swap (hdf);
00432   ConstHDFNode::swap (hdf);
00433   HDFNode::swap (hdf);
00434   root_.swap (hdf.root_);
00435   nodes_.swap (hdf.nodes_);
00436 }
00437 
00438 void
00439 ClearSilver::HDF::push (const ConstHDFNode::Name& name,
00440                         const ClearSilverNode& node)
00441 {
00442   nodes_.push(name, node);
00443 }
00444 
00445 void
00446 ClearSilver::HDF::pop ()
00447 {
00448   if (nodes_.empty())
00449     {
00450       string message;
00451       message += "ClearSilver::HDF::pop (): ";
00452       message += "empty stack";
00453       throw invalid_argument (message);
00454     }
00455   nodes_.pop();
00456 }
00457 
00458 ClearSilver::ClearSilverNode
00459 ClearSilver::HDF::top () const
00460 {
00461   if (nodes_.empty())
00462     return ClearSilverNode();
00463   return nodes_.top();
00464 }
00465 
00466                                 // debug flag
00467 bool&
00468 ClearSilver::HDF::debug ()
00469 {
00470   static bool debug_ = false;
00471   return debug_;
00472 }
00473 
00474 
00475 namespace ClearSilver
00476 {
00477                                 // logical comparison operators
00478   bool
00479   operator == (const HDF::reference& r1, const HDF::reference& r2)
00480   {
00481     return r1.root_() == r2.root_() && r1.nodes_ == r2.nodes_;
00482   }
00483 };                              // namespace ClearSilver

Generated on Tue May 16 14:50:52 2006 for ClearSilver C++ Library by  doxygen 1.4.5