00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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>
00045 #include <ClearSilver/util/neo_hdf.h>
00046 #include "ClearSilverError.h"
00047 #include "ClearSilverException.h"
00048
00049 using namespace std;
00050
00051
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
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
00168
00169 ClearSilver::HDF::size_type
00170 ClearSilver::HDF::depth () const
00171 {
00172 return nodes_.depth();
00173 }
00174
00175
00176 std::string
00177 ClearSilver::HDF::path () const
00178 {
00179 return nodes_.path();
00180 }
00181
00182
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
00233 ClearSilver::HDF::const_iterator
00234 ClearSilver::HDF::begin () const
00235 {
00236 if (empty())
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())
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
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
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
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
00415 ClearSilver::ClearSilverNode
00416 ClearSilver::HDF::root () const
00417 {
00418 return root_();
00419 }
00420
00421
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
00467 bool&
00468 ClearSilver::HDF::debug ()
00469 {
00470 static bool debug_ = false;
00471 return debug_;
00472 }
00473
00474
00475 namespace ClearSilver
00476 {
00477
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 };