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 "ClearSilverNode.h"
00039
00040 #include <algorithm>
00041 #include <stdexcept>
00042 #include <string.h>
00043 #include <syslog.h>
00044 #include <boost/lexical_cast.hpp>
00045 #include <ClearSilver/util/neo_misc.h>
00046 #include <ClearSilver/util/neo_hdf.h>
00047 #include "ClearSilverError.h"
00048 #include "ClearSilverException.h"
00049 #include "ClearSilverNodeComparator.h"
00050 #include "ConstHDF.h"
00051 #include "RootNode.h"
00052
00053 using namespace std;
00054
00055
00056 static int sort_nodes (const void*, const void*);
00057
00058 ClearSilver::ClearSilverNodeComparator::Ptr comparator;
00059
00060
00061
00062 ClearSilver::ClearSilverNode::ClearSilverNode ()
00063 : node_(0) {}
00064
00065 ClearSilver::ClearSilverNode::ClearSilverNode (HDF* node)
00066 : node_(node) {}
00067
00068 ClearSilver::ClearSilverNode::ClearSilverNode (const ClearSilverNode& n)
00069 : node_(n.node_) {}
00070
00071 ClearSilver::ClearSilverNode::~ClearSilverNode () throw()
00072 {}
00073
00074
00075 ClearSilver::ClearSilverNode&
00076 ClearSilver::ClearSilverNode::operator = (const ClearSilverNode& n)
00077 {
00078 ClearSilverNode n0 (n);
00079 swap (n0);
00080 return *this;
00081 }
00082
00083 ClearSilver::ClearSilverNode&
00084 ClearSilver::ClearSilverNode::operator = (const char* value)
00085 {
00086 return operator = (std::string(value));
00087 }
00088
00089
00090
00091
00092
00093
00094 ClearSilver::ClearSilverNode&
00095 ClearSilver::ClearSilverNode::operator = (const string& value)
00096 {
00097 if (!node_)
00098 {
00099 string message;
00100 message += "ClearSilverNode::operator = (const std::string&): ";
00101 message += "cannot assign to null node";
00102 throw logic_error (message);
00103 }
00104 if (debug())
00105 {
00106 string message;
00107 message
00108 += "ClearSilver::ClearSilverNode::operator = (const string&): ";
00109 if (node_->name)
00110 message += string("name=") + node_->name + ", ";
00111 message += "value=" + value;
00112 syslog (LOG_DEBUG, "%s", message.c_str());
00113 }
00114 if (node_->value)
00115 free (node_->value);
00116 node_->value = strdup(value.c_str());
00117 return *this;
00118 }
00119
00120 ClearSilver::ClearSilverNode&
00121 ClearSilver::ClearSilverNode::operator = (int value)
00122 {
00123 if (debug())
00124 {
00125 string message;
00126 message += "ClearSilver::ClearSilverNode::operator = (int): ";
00127 if (node_ && node_->name)
00128 message += string("name=") + node_->name + ", ";
00129 message += "value=" + value;
00130 syslog (LOG_DEBUG, "%s", message.c_str());
00131 }
00132 return operator = (boost::lexical_cast<string>(value));
00133 }
00134
00135 ClearSilver::ClearSilverNode&
00136 ClearSilver::ClearSilverNode::operator = (bool value)
00137 {
00138 return operator = (std::string(value?True():False()));
00139 }
00140
00141
00142
00143
00144 bool
00145 ClearSilver::ClearSilverNode::empty () const
00146 {
00147 return node_ == 0;
00148 }
00149
00150
00151
00152 ClearSilver::ClearSilverNode::operator bool () const
00153 {
00154 return !empty();
00155 }
00156
00157
00158 string
00159 ClearSilver::ClearSilverNode::name () const
00160 {
00161 if (debug())
00162 syslog (LOG_DEBUG, "%s", "ClearSilver::ClearSilverNode::name () const");
00163 if (!node_)
00164 {
00165 string message;
00166 message += "ClearSilverNode::name () const: ";
00167 message += "null node";
00168 throw logic_error (message);
00169 }
00170 return string(hdf_obj_name(node_));
00171 }
00172
00173 string
00174 ClearSilver::ClearSilverNode::value () const
00175 {
00176 if (!node_)
00177 {
00178 string message;
00179 message += "ClearSilverNode::value () const: ";
00180 message += "null node";
00181 throw logic_error (message);
00182 }
00183 if (debug())
00184 {
00185 string message;
00186 message += string("ClearSilver::ClearSilverNode::value () const: ");
00187 if (node_->name)
00188 message += string("name=") + node_->name + ", ";
00189 if (node_->value)
00190 message += string("value=") + node_->value;
00191 syslog (LOG_DEBUG, "%s", message.c_str());
00192 }
00193 char * value = hdf_obj_value(node_);
00194 return value? string (value) : string();
00195 }
00196
00197
00198
00199
00200 ClearSilver::ClearSilverNode::HDF*
00201 ClearSilver::ClearSilverNode::get () const
00202 {
00203 return node_;
00204 }
00205
00206 ClearSilver::ClearSilverNode
00207 ClearSilver::ClearSilverNode::top () const
00208 {
00209 if (debug())
00210 syslog (LOG_DEBUG, "%s", "ClearSilverNode::top () const");
00211 return ClearSilverNode (hdf_obj_top (node_));
00212 }
00213
00214 ClearSilver::ClearSilverNode
00215 ClearSilver::ClearSilverNode::next () const
00216 {
00217 if (debug())
00218 syslog (LOG_DEBUG, "%s", "ClearSilverNode::next () const");
00219 return ClearSilverNode (hdf_obj_next (node_));
00220 }
00221
00222 ClearSilver::ClearSilverNode
00223 ClearSilver::ClearSilverNode::child () const
00224 {
00225 if (debug())
00226 syslog (LOG_DEBUG, "%s", "ClearSilverNode::child () const");
00227 return ClearSilverNode (hdf_obj_child (node_));
00228 }
00229
00230 ClearSilver::ClearSilverNode::HDF_ATTR*
00231 ClearSilver::ClearSilverNode::attr () const
00232 {
00233 if (debug())
00234 syslog (LOG_DEBUG, "%s", "ClearSilverNode::attr () const");
00235 return node_->attr;
00236 }
00237
00238
00239 string
00240 ClearSilver::ClearSilverNode::get_value
00241 (const string& key, const string& default_value) const
00242 {
00243 if (key.empty())
00244 {
00245 string message;
00246 message += "ClearSilver::ClearSilverNode::get_value ";
00247 message += "(const string&, const string&) const: ";
00248 message += "empty key";
00249 throw invalid_argument (message);
00250 }
00251 if (debug())
00252 {
00253 string message;
00254 message += "ClearSilver::ClearSilverNode::get_value";
00255 message += "(const string& key, const string& default_value) const: ";
00256 message += "key=" + key + ", ";
00257 message += "default_value=" + default_value;
00258 syslog (LOG_DEBUG, "%s", message.c_str());
00259 }
00260 return string(hdf_get_value (node_, key.c_str(), default_value.c_str()));
00261 }
00262
00263 void
00264 ClearSilver::ClearSilverNode::set_value
00265 (const std::string& key, const string& value)
00266 {
00267 if (key.empty())
00268 {
00269 string message;
00270 message += "ClearSilver::ClearSilverNode::set_value ";
00271 message += "(const string&, int): ";
00272 message += "empty key";
00273 throw invalid_argument (message);
00274 }
00275 if (debug())
00276 {
00277 string message;
00278 message += string("ClearSilverNode::set_value ")
00279 + "(const string& key, const string& value): ";
00280 message += "key=" + key + ", ";
00281 message += "value=" + value;
00282 syslog (LOG_DEBUG, "%s", message.c_str());
00283 }
00284 ClearSilverError error (hdf_set_value(node_,key.c_str(),value.c_str()));
00285 if (error)
00286 {
00287 string message;
00288 message += "ClearSilver::ClearSilverNode::set_value ";
00289 message += "(const std::string&, const std::string&):";
00290 ClearSilverException e (message);
00291 e += error;
00292 throw e;
00293 }
00294 }
00295
00296 void
00297 ClearSilver::ClearSilverNode::set_value
00298 (const std::string& key, int value)
00299 {
00300 if (key.empty())
00301 {
00302 string message;
00303 message += "ClearSilver::ClearSilverNode::set_value ";
00304 message += "(const string&, int): ";
00305 message += "empty key";
00306 throw invalid_argument (message);
00307 }
00308 if (debug())
00309 {
00310 string message;
00311 message += string("ClearSilverNode::set_value ")
00312 + "(const string& key, int value): ";
00313 message += "key=" + key + ", ";
00314 message += "value=" + boost::lexical_cast<string>(value);
00315 syslog (LOG_DEBUG, "%s", message.c_str());
00316 }
00317 ClearSilverError error (hdf_set_int_value (node_, key.c_str(), value));
00318 if (error)
00319 {
00320 string message;
00321 message += "ClearSilver::ClearSilverNode::set_value ";
00322 message += "(const string&, int):";
00323 ClearSilverException e (message);
00324 e += error;
00325 throw e;
00326 }
00327 }
00328
00329 void
00330 ClearSilver::ClearSilverNode::set_value
00331 (const std::string& key, unsigned int value)
00332 {
00333 if (key.empty())
00334 {
00335 string message;
00336 message += "ClearSilver::ClearSilverNode::set_value ";
00337 message += "(const string&, unsigned int): ";
00338 message += "empty key";
00339 throw invalid_argument (message);
00340 }
00341 if (debug())
00342 {
00343 string message;
00344 message += string("ClearSilverNode::set_value ")
00345 + "(const string& key, unsigned int value): ";
00346 message += "key=" + key + ", ";
00347 message += "value=" + boost::lexical_cast<string>(value);
00348 syslog (LOG_DEBUG, "%s", message.c_str());
00349 }
00350 ClearSilverError error (hdf_set_int_value (node_, key.c_str(),
00351 static_cast<int>(value)));
00352 if (error)
00353 {
00354 string message;
00355 message += "ClearSilver::ClearSilverNode::set_value ";
00356 message += "(const string&, unsigned int):";
00357 ClearSilverException e (message);
00358 e += error;
00359 throw e;
00360 }
00361 }
00362
00363 void
00364 ClearSilver::ClearSilverNode::set_value
00365 (const std::string& key, bool value)
00366 {
00367 if (debug())
00368 {
00369 string message;
00370 message += string("ClearSilverNode::set_value ")
00371 + "(const string& key, bool value): ";
00372 message += "key=" + key + ", ";
00373 message += string("value=") + (value?"true":"false");
00374 syslog (LOG_DEBUG, "%s", message.c_str());
00375 }
00376 set_value (key, string(value? True() : False()));
00377 }
00378
00379 ClearSilver::ClearSilverNode
00380 ClearSilver::ClearSilverNode::get_node
00381 (const string& key)
00382 {
00383 if (key.empty())
00384 {
00385 string message;
00386 message += "ClearSilver::ClearSilverNode::get_node ";
00387 message += "(const string&) const: ";
00388 message += "empty key";
00389 throw invalid_argument (message);
00390 }
00391 if (debug())
00392 {
00393 string message;
00394 message += string("ClearSilverNode::get_node (const string& key): ");
00395 message += "key=" + key;
00396 syslog (LOG_DEBUG, "%s", message.c_str());
00397 }
00398 HDF* node;
00399 ClearSilverError error (hdf_get_node (node_, key.c_str(), &node));
00400 if (error)
00401 {
00402 string message;
00403 message += "ClearSilver::ClearSilverNode::get_node ";
00404 message += "(const string& key): ";
00405 message += "key=" + key;
00406 ClearSilverException e (message);
00407 e += error;
00408 throw e;
00409 }
00410 if (!node)
00411 {
00412 string message;
00413 message += "ClearSilver::ClearSilverNode::get_node ";
00414 message += "(const string&) const: ";
00415 message += "impossible error: ";
00416 message += "cannot create intermediate nodes";
00417 throw logic_error (message);
00418 }
00419 return ClearSilverNode(node);
00420 }
00421
00422 ClearSilver::ClearSilverNode
00423 ClearSilver::ClearSilverNode::get_obj
00424 (const string& key) const
00425 {
00426 if (key.empty())
00427 {
00428 string message;
00429 message += "ClearSilver::ClearSilverNode::get_obj ";
00430 message += "(const string&) const: ";
00431 message += "empty key";
00432 throw invalid_argument (message);
00433 }
00434 if (debug())
00435 {
00436 string message;
00437 message += string("ClearSilverNode::get_obj (const string& key): ");
00438 message += "key=" + key;
00439 syslog (LOG_DEBUG, "%s", message.c_str());
00440 }
00441 return ClearSilverNode (hdf_get_obj (node_, key.c_str()));
00442 }
00443
00444 ClearSilver::ClearSilverNode
00445 ClearSilver::ClearSilverNode::get_child
00446 (const string& key) const
00447 {
00448 if (key.empty())
00449 {
00450 string message;
00451 message += "ClearSilver::ClearSilverNode::get_child ";
00452 message += "(const string&) const: ";
00453 message += "empty key";
00454 throw invalid_argument (message);
00455 }
00456 if (debug())
00457 {
00458 string message;
00459 message += string("ClearSilverNode::get_child(const string& key): ");
00460 message += "key=" + key;
00461 syslog (LOG_DEBUG, "%s", message.c_str());
00462 }
00463 return ClearSilverNode (hdf_get_child (node_, key.c_str()));
00464 }
00465
00466 void
00467 ClearSilver::ClearSilverNode::remove_tree ()
00468 {
00469 hdf_destroy (&node_);
00470 if (node_ != 0)
00471 {
00472 string message;
00473 message += "ClearSilver::ClearSilverNode::remove_tree(): ";
00474 message += "node_ not empty";
00475 throw logic_error(message);
00476 }
00477 }
00478
00479 void
00480 ClearSilver::ClearSilverNode::remove_tree
00481 (const std::string& key)
00482 {
00483 ClearSilverError error (hdf_remove_tree (node_, key.c_str()));
00484 if (error)
00485 {
00486 string message;
00487 message += "ClearSilver::ClearSilverNode::remove_tree ";
00488 message += "(const string& key): ";
00489 message += "key=" + key;
00490 ClearSilverException e (message);
00491 e += error;
00492 throw e;
00493 }
00494 }
00495
00496 void
00497 ClearSilver::ClearSilverNode::read_file
00498 (const std::string& path)
00499 {
00500 if (path.empty())
00501 {
00502 string message;
00503 message += "ClearSilver::ClearSilverNode::read_file ";
00504 message += "(const string&): ";
00505 message += "empty path";
00506 throw invalid_argument (message);
00507 }
00508 ClearSilverError error (hdf_read_file (node_, path.c_str()));
00509 if (error)
00510 {
00511 string message;
00512 message += "ClearSilver::ClearSilverNode::read_file ";
00513 message += "(const string& path): ";
00514 message += "path=" + path;
00515 ClearSilverException e (message);
00516 e += error;
00517 throw e;
00518 }
00519 }
00520
00521 void
00522 ClearSilver::ClearSilverNode::write_file
00523 (const std::string& path) const
00524 {
00525 if (path.empty())
00526 {
00527 string message;
00528 message += "ClearSilver::ClearSilverNode::write_file ";
00529 message += "(const string&): ";
00530 message += "empty path";
00531 throw invalid_argument (message);
00532 }
00533 ClearSilverError error (hdf_write_file_atomic (node_, path.c_str()));
00534 if (error)
00535 {
00536 string message;
00537 message += "ClearSilver::ClearSilverNode::write_file ";
00538 message += "(const string& path): ";
00539 message += "path=" + path;
00540 ClearSilverException e (message);
00541 e += error;
00542 throw e;
00543 }
00544 }
00545
00546 void
00547 ClearSilver::ClearSilverNode::dump
00548 (const std::string& prefix) const
00549 {
00550 ClearSilverError error (hdf_dump (node_, prefix.c_str()));
00551 if (error)
00552 {
00553 string message;
00554 message += "ClearSilver::ClearSilverNode::dump ";
00555 message += "(const string& prefix): ";
00556 message += "prefix=" + prefix;
00557 ClearSilverException e (message);
00558 e += error;
00559 throw e;
00560 }
00561 }
00562
00563 void
00564 ClearSilver::ClearSilverNode::copy (const string& key,
00565 const ClearSilverNode& src)
00566 {
00567 ClearSilverError error (hdf_copy (node_, key.c_str(), src.node_));
00568 if (error)
00569 {
00570 string message;
00571 message += "ClearSilver::ClearSilverNode::copy ";
00572 message += "(const string&, const ClearSilverNode&): ";
00573 ClearSilverException e (message);
00574 e += error;
00575 throw e;
00576 }
00577 }
00578
00579
00580 bool&
00581 ClearSilver::ClearSilverNode::debug ()
00582 {
00583 static bool debug_ = false;
00584 return debug_;
00585 }
00586
00587
00588 std::string
00589 ClearSilver::ClearSilverNode::Boolean (bool b)
00590 {
00591 return b? True() : False();
00592 }
00593
00594 std::string
00595 ClearSilver::ClearSilverNode::True ()
00596 {
00597 return std::string("1");
00598 }
00599
00600 std::string
00601 ClearSilver::ClearSilverNode::False ()
00602 {
00603 return std::string("0");
00604 }
00605
00606
00607 void
00608 ClearSilver::ClearSilverNode::swap (ClearSilverNode& n) throw()
00609 {
00610 std::swap (node_, n.node_);
00611 }
00612
00613
00614
00615 void
00616 ClearSilver::ClearSilverNode::sort (ClearSilverNodeComparator::Ptr c)
00617 {
00618 comparator = c;
00619 ClearSilverError error (hdf_sort_obj (node_, sort_nodes));
00620 if (error)
00621 {
00622 string message;
00623 message += "ClearSilver::ClearSilverNode::sort ";
00624 message += "(const ClearSilverNodeComparator::Ptr): ";
00625 ClearSilverException e (message);
00626 e += error;
00627 throw e;
00628 }
00629 }
00630
00631 int
00632 sort_nodes (const void* lhs, const void* rhs)
00633 {
00634 ClearSilver::ConstHDF n1
00635 (ClearSilver::RootNode(*(ClearSilver::ClearSilverNode::HDF**) lhs, false));
00636 ClearSilver::ConstHDF n2
00637 (ClearSilver::RootNode(*(ClearSilver::ClearSilverNode::HDF**) rhs, false));
00638 return (*comparator) (n1, n2);
00639 }
00640
00641 namespace ClearSilver
00642 {
00643
00644 bool
00645 operator == (const ClearSilverNode& n1, const ClearSilverNode& n2)
00646 {
00647 return n1.node_ == n2.node_;
00648 }
00649 };