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 "HDFAttributes.h"
00039 #include <stdexcept>
00040 #include <string>
00041 #include <string.h>
00042 #include <ClearSilver/util/neo_hdf.h>
00043 #include "ClearSilverError.h"
00044 #include "ClearSilverException.h"
00045
00046 #if HAVE_BROKEN_HDF_SET_ATTR
00047 static NEOERR* XXX_hdf_set_attr (HDF *hdf, const char *name,
00048 const char *key, const char *value);
00049 #endif // HAVE_BROKEN_HDF_SET_ATTR
00050
00051 namespace ClearSilver
00052 {
00053
00054
00055 HDFAttributes::HDFAttributes ()
00056 : path_(), head_(0) {}
00057
00058 HDFAttributes::HDFAttributes (const Nodes& path, _attr* head)
00059 : path_(path), head_(head) {}
00060
00061 HDFAttributes::HDFAttributes (const HDFAttributes& a)
00062 : path_(a.path_), head_(a.head_) {}
00063
00064 HDFAttributes::~HDFAttributes () throw() {}
00065
00066
00067 HDFAttributes&
00068 HDFAttributes::operator = (const HDFAttributes& a)
00069 {
00070 HDFAttributes a_(a);
00071 swap (a_);
00072 return *this;
00073 }
00074
00075
00076 void
00077 HDFAttributes::swap (HDFAttributes& a) throw()
00078 {
00079 std::swap (path_, a.path_);
00080 std::swap (head_, a.head_);
00081 }
00082
00083 HDFAttributes::size_type
00084 HDFAttributes::size () const
00085 {
00086 HDF_ATTR* node = head_;
00087 size_type n = 0;
00088 while (node != 0)
00089 {
00090 ++n;
00091 node = node->next;
00092 }
00093 return n;
00094 }
00095
00096
00097 bool
00098 HDFAttributes::empty () const
00099 {
00100 return head_ == 0;
00101 }
00102
00103 HDFAttributes::size_type
00104 HDFAttributes::count (const key_type& key)
00105 {
00106 HDF_ATTR* node = head_;
00107 size_type n = 0;
00108 while (node != 0)
00109 {
00110 if (strcmp (key, node->key) == 0)
00111 ++n;
00112 node = node->next;
00113 }
00114 return n;
00115 }
00116
00117 HDFAttributes::iterator
00118 HDFAttributes::find (const key_type& key)
00119 {
00120 HDF_ATTR* node = head_;
00121 while (node != 0)
00122 {
00123 if (strcmp (key, node->key) == 0)
00124 return iterator (node);
00125 node = node->next;
00126 }
00127 return iterator();
00128 }
00129
00130 HDFAttributes::const_iterator
00131 HDFAttributes::find (const key_type& key) const
00132 {
00133 HDF_ATTR* node = head_;
00134 while (node != 0)
00135 {
00136 if (strcmp (key, node->key) == 0)
00137 return const_iterator (node);
00138 node = node->next;
00139 }
00140 return const_iterator();
00141 }
00142
00143 HDFAttributes::mapped_type
00144 HDFAttributes::operator [] (const key_type& key)
00145 {
00146 iterator i = find (key);
00147 if (i)
00148 return i.value_->second;
00149
00150 ClearSilverError error (hdf_set_attr (path_.top().top().get(),
00151 path_.path().c_str(), key, ""));
00152 if (error)
00153 {
00154 std::string message;
00155 message += "ClearSilver::HDFAttributes::operator[](const key_type&): ";
00156 ClearSilverException e (message);
00157 e += error;
00158 throw e;
00159 }
00160 i = find (key);
00161 return i.value_->second;
00162 }
00163
00164 HDFAttributes::iterator
00165 HDFAttributes::begin ()
00166 {
00167 return iterator (head_);
00168 }
00169
00170 HDFAttributes::iterator
00171 HDFAttributes::end ()
00172 {
00173 return iterator();
00174 }
00175
00176 HDFAttributes::const_iterator
00177 HDFAttributes::begin () const
00178 {
00179 return const_iterator (head_);
00180 }
00181
00182 HDFAttributes::const_iterator
00183 HDFAttributes::end () const
00184 {
00185 return const_iterator();
00186 }
00187
00188 std::pair<HDFAttributes::iterator,bool>
00189 HDFAttributes::insert (const value_type& value)
00190 {
00191 iterator i = find (value.first);
00192 if (i)
00193 return std::pair<HDFAttributes::iterator,bool>(i, false);
00194 #if HAVE_BROKEN_HDF_SET_ATTR
00195 ClearSilverError error (XXX_hdf_set_attr (path_.top().get(), 0,
00196 value.first, value.second));
00197 #else // HAVE_BROKEN_HDF_SET_ATTR
00198 ClearSilverError error (hdf_set_attr (path_.top().top().get(),
00199 path_.path().c_str(),
00200 value.first, value.second));
00201 #endif // HAVE_BROKEN_HDF_SET_ATTR
00202 if (error)
00203 {
00204 std::string message;
00205 message += "ClearSilver::HDFAttributes::insert(const value_type&): ";
00206 ClearSilverException e (message);
00207 e += error;
00208 throw e;
00209 }
00210 i = find (value.first);
00211 return std::pair<HDFAttributes::iterator,bool>(i, true);
00212 }
00213
00214
00215 HDFAttributes::iterator
00216 HDFAttributes::insert (iterator, const value_type& value)
00217 {
00218 return insert (value).first;
00219 }
00220
00221 HDFAttributes::size_type
00222 HDFAttributes::erase (const key_type& key) throw()
00223 {
00224 iterator i = find (key);
00225 if (i)
00226 {
00227 erase (i);
00228 return 1;
00229 }
00230 else
00231 return 0;
00232 }
00233
00234 void
00235 HDFAttributes::erase (iterator i)
00236 {
00237 if (i == begin())
00238 head_ = head_->next;
00239
00240 #if HAVE_BROKEN_HDF_SET_ATTR
00241 ClearSilverError error (XXX_hdf_set_attr (path_.top().get(), 0,
00242 i.value_->first, 0));
00243 #else // HAVE_BROKEN_HDF_SET_ATTR
00244 ClearSilverError error (hdf_set_attr (path_.top().top().get(),
00245 path_.path().c_str(),
00246 i.value_->first, 0));
00247 #endif // HAVE_BROKEN_HDF_SET_ATTR
00248 if (error)
00249 {
00250 std::string message;
00251 message += "ClearSilver::HDFAttributes::erase(iterator): ";
00252 ClearSilverException e (message);
00253 e += error;
00254 throw e;
00255 }
00256 }
00257
00258 void
00259 HDFAttributes::erase (iterator begin, iterator end)
00260 {
00261 while (begin != end)
00262 {
00263 iterator i = begin++;
00264 erase (i);
00265 }
00266 }
00267
00268 void
00269 HDFAttributes::clear () throw()
00270 {
00271 erase (begin(), end());
00272 }
00273
00274 bool
00275 operator == (const HDFAttributes& a1, const HDFAttributes& a2)
00276 {
00277 return a1.head_ == a2.head_;
00278 }
00279
00280 bool&
00281 HDFAttributes::debug ()
00282 {
00283 static bool debug_ = false;
00284 return debug_;
00285 }
00286
00287
00288 HDFAttributes::mapped_type::mapped_type ()
00289 : value_(0), valuep_(&value_) {}
00290 HDFAttributes::mapped_type::mapped_type (const char* v)
00291 : value_(strdup(v)), valuep_(&value_) {}
00292 HDFAttributes::mapped_type::mapped_type (std::string v)
00293 : value_(strdup(v.c_str())), valuep_(&value_) {}
00294 HDFAttributes::mapped_type::mapped_type (char** v)
00295 : value_(0), valuep_(v)
00296 {
00297 if (!valuep_ || !*valuep_)
00298 {
00299 std::string message;
00300 message += "ClearSilver::HDFAttributes::mapped_type::mapped_type ";
00301 message += "(char**): ";
00302 message += "nil pointer argument";
00303 throw std::invalid_argument (message);
00304 }
00305 }
00306 HDFAttributes::mapped_type::mapped_type (const mapped_type& v)
00307 : value_(0), valuep_(&value_)
00308 {
00309 if (*v.valuep_ == v.value_)
00310 value_ = strdup(v.value_);
00311 else
00312 valuep_ = v.valuep_;
00313 }
00314 HDFAttributes::mapped_type::~mapped_type () throw()
00315 {
00316 if (value_)
00317 free(value_);
00318 }
00319 HDFAttributes::mapped_type&
00320 HDFAttributes::mapped_type::operator = (const mapped_type& v)
00321 {
00322 mapped_type v_(v);
00323 swap(v_);
00324 return *this;
00325 }
00326 HDFAttributes::mapped_type&
00327 HDFAttributes::mapped_type::operator = (const char* v)
00328 {
00329 if (!v)
00330 {
00331 std::string message;
00332 message += "ClearSilver::HDFAttributes::mapped_type::operator = ";
00333 message += "(const char*): ";
00334 message += "nil pointer argument";
00335 throw std::invalid_argument (message);
00336 }
00337
00338 char* v_ = strdup(v);
00339 free (*valuep_);
00340 *valuep_ = v_;
00341 return *this;
00342 }
00343 void
00344 HDFAttributes::mapped_type::swap (mapped_type& v) throw()
00345 {
00346 std::swap (value_, v.value_);
00347 std::swap (valuep_, v.valuep_);
00348 }
00349 HDFAttributes::mapped_type::operator char* ()
00350 {
00351 return *valuep_;
00352 }
00353 HDFAttributes::mapped_type::operator const char* () const
00354 { return *valuep_; }
00355
00356
00357 HDFAttributes::iterator::iterator () : node_(0), value_() {}
00358
00359 HDFAttributes::iterator::iterator (_attr* node)
00360 : node_(node), value_()
00361 {
00362 if (node_)
00363 value_ =
00364 boost::shared_ptr<value_type>
00365 (new value_type(node_->key, &node_->value));
00366 }
00367
00368 HDFAttributes::iterator::iterator (const iterator& i)
00369 : node_(i.node_), value_(i.value_) {}
00370
00371 HDFAttributes::iterator::~iterator () throw() {}
00372
00373 HDFAttributes::iterator::iterator&
00374 HDFAttributes::iterator::operator = (const iterator& i)
00375 {
00376 HDFAttributes::iterator i_(i);
00377 swap(i_);
00378 return *this;
00379 }
00380
00381 void
00382 HDFAttributes::iterator::swap (iterator& i) throw ()
00383 {
00384 std::swap (node_, i.node_);
00385 std::swap (value_, i.value_);
00386 }
00387
00388 HDFAttributes::iterator::operator bool () const
00389 {
00390 return node_ != 0;
00391 }
00392
00393 HDFAttributes::value_type
00394 HDFAttributes::iterator::operator * ()
00395 {
00396 return *value_;
00397 }
00398
00399 HDFAttributes::value_type*
00400 HDFAttributes::iterator::operator -> ()
00401 {
00402 return value_.get();
00403 }
00404
00405 HDFAttributes::iterator&
00406 HDFAttributes::iterator:: operator ++ ()
00407 {
00408 if (node_)
00409 {
00410 if (node_->next)
00411 {
00412 HDFAttributes::iterator i (node_->next);
00413 swap (i);
00414 }
00415 else
00416 {
00417 HDFAttributes::iterator i;
00418 swap (i);
00419 }
00420 }
00421 return *this;
00422 }
00423
00424 HDFAttributes::iterator
00425 HDFAttributes::iterator::operator ++ (int)
00426 {
00427 HDFAttributes::iterator i (*this);
00428 operator ++();
00429 return i;
00430 }
00431
00432 bool
00433 operator == (const HDFAttributes::iterator& i1,
00434 const HDFAttributes::iterator& i2)
00435 {
00436 return i1.node_ == i2.node_;
00437 }
00438
00439
00440 HDFAttributes::const_iterator::const_iterator () : node_(0), value_() {}
00441
00442 HDFAttributes::const_iterator::const_iterator (_attr* node)
00443 : node_(node), value_()
00444 {
00445 if (node_)
00446 value_ =
00447 boost::shared_ptr<value_type>
00448 (new value_type(node_->key, &node_->value));
00449 }
00450
00451 HDFAttributes::const_iterator::const_iterator (const const_iterator& i)
00452 : node_(i.node_), value_(i.value_) {}
00453
00454 HDFAttributes::const_iterator::~const_iterator () throw() {}
00455
00456 HDFAttributes::const_iterator::const_iterator&
00457 HDFAttributes::const_iterator::operator = (const const_iterator& i)
00458 {
00459 HDFAttributes::const_iterator i_(i);
00460 swap(i_);
00461 return *this;
00462 }
00463
00464 void
00465 HDFAttributes::const_iterator::swap (const_iterator& i) throw ()
00466 {
00467 std::swap (node_, i.node_);
00468 std::swap (value_, i.value_);
00469 }
00470
00471 HDFAttributes::const_iterator::operator bool () const
00472 {
00473 return node_ != 0;
00474 }
00475
00476 HDFAttributes::value_type
00477 HDFAttributes::const_iterator::operator * ()
00478 {
00479 return *value_;
00480 }
00481
00482 HDFAttributes::value_type*
00483 HDFAttributes::const_iterator::operator -> ()
00484 {
00485 return value_.get();
00486 }
00487
00488 HDFAttributes::const_iterator&
00489 HDFAttributes::const_iterator:: operator ++ ()
00490 {
00491 if (node_)
00492 {
00493 if (node_->next)
00494 {
00495 HDFAttributes::const_iterator i (node_->next);
00496 swap (i);
00497 }
00498 else
00499 {
00500 HDFAttributes::const_iterator i;
00501 swap (i);
00502 }
00503 }
00504 return *this;
00505 }
00506
00507 HDFAttributes::const_iterator
00508 HDFAttributes::const_iterator::operator ++ (int)
00509 {
00510 HDFAttributes::const_iterator i (*this);
00511 operator ++();
00512 return i;
00513 }
00514
00515 bool
00516 operator == (const HDFAttributes::const_iterator& i1,
00517 const HDFAttributes::const_iterator& i2)
00518 {
00519 return i1.node_ == i2.node_;
00520 }
00521
00522 };
00523
00524 #if HAVE_BROKEN_HDF_SET_ATTR
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 NEOERR* XXX_hdf_set_attr (HDF *hdf, const char *name, const char *key, const char *value)
00542 {
00543 HDF *obj = hdf;
00544 HDF_ATTR *attr, *last;
00545
00546
00547 if (obj == NULL)
00548 return nerr_raise(NERR_ASSERT, "Unable to set attribute on none existant node");
00549
00550 if (obj->attr != NULL)
00551 {
00552 attr = obj->attr;
00553 last = attr;
00554 while (attr != NULL)
00555 {
00556 if (!strcmp(attr->key, key))
00557 {
00558 if (attr->value) free(attr->value);
00559
00560 if (value == NULL)
00561 {
00562 if (attr == obj->attr)
00563 obj->attr = attr->next;
00564 else
00565 last->next = attr->next;
00566 free(attr->key);
00567 free(attr);
00568 return STATUS_OK;
00569 }
00570 attr->value = strdup(value);
00571 if (attr->value == NULL)
00572 return nerr_raise(NERR_NOMEM, "Unable to set attr %s to %s", key, value);
00573 return STATUS_OK;
00574 }
00575 last = attr;
00576 attr = attr->next;
00577 }
00578 last->next = (HDF_ATTR *) calloc(1, sizeof(HDF_ATTR));
00579 if (last->next == NULL)
00580 return nerr_raise(NERR_NOMEM, "Unable to set attr %s to %s", key, value);
00581 attr = last->next;
00582 }
00583 else
00584 {
00585 if (value == NULL) return STATUS_OK;
00586 obj->attr = (HDF_ATTR *) calloc(1, sizeof(HDF_ATTR));
00587 if (obj->attr == NULL)
00588 return nerr_raise(NERR_NOMEM, "Unable to set attr %s to %s", key, value);
00589 attr = obj->attr;
00590 }
00591 attr->key = strdup(key);
00592 attr->value = strdup(value);
00593 if (attr->key == NULL || attr->value == NULL)
00594 return nerr_raise(NERR_NOMEM, "Unable to set attr %s to %s", key, value);
00595
00596 return STATUS_OK;
00597 }
00598 #endif // HAVE_BROKEN_HDF_SET_ATTR