1 /*****************************************************************************/ 2 /* XDMF */ 3 /* eXtensible Data Model and Format */ 4 /* */ 5 /* Id : XdmfItem.hpp */ 6 /* */ 7 /* Author: */ 8 /* Kenneth Leiter */ 9 /* kenneth.leiter@arl.army.mil */ 10 /* US Army Research Laboratory */ 11 /* Aberdeen Proving Ground, MD */ 12 /* */ 13 /* Copyright @ 2011 US Army Research Laboratory */ 14 /* All Rights Reserved */ 15 /* See Copyright.txt for details */ 16 /* */ 17 /* This software is distributed WITHOUT ANY WARRANTY; without */ 18 /* even the implied warranty of MERCHANTABILITY or FITNESS */ 19 /* FOR A PARTICULAR PURPOSE. See the above copyright notice */ 20 /* for more information. */ 21 /* */ 22 /*****************************************************************************/ 23 24 #ifndef XDMFITEM_HPP_ 25 #define XDMFITEM_HPP_ 26 27 // C Compatible Includes 28 #include "XdmfCore.hpp" 29 #include "XdmfVisitor.hpp" 30 31 #ifdef __cplusplus 32 33 // Forward Declarations 34 class XdmfCoreReader; 35 class XdmfInformation; 36 class XdmfVisitor; 37 38 // Includes 39 #include <loki/Visitor.h> 40 #define vtk_libxml2_reference reference // Reversing VTK name mangling 41 #include <libxml/xmlexports.h> 42 #include <libxml/tree.h> 43 #include <libxml/uri.h> 44 #include <libxml/xpointer.h> 45 #include <libxml/xmlreader.h> 46 #include <map> 47 #include <set> 48 #include <string> 49 #include <vector> 50 #include "XdmfSharedPtr.hpp" 51 52 53 // Macro that allows children XdmfItems to be attached to a parent XdmfItem. 54 // -- For Header File 55 #define XDMF_CHILDREN(ParentClass, ChildClass, ChildName, SearchName) \ 56 \ 57 public: \ 58 \ 59 /** Get a ChildClass attached to this item by index.<br> 60 Example of use:<br> 61 C++<br> 62 //Assume that exampleItem is a shared pointer to the ParentClass object<br> 63 //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 64 unsigned int getIndex = 0;<br> 65 shared_ptr<XdmfInformation> exampleChild = exampleItem->getInformation(getIndex);<br> 66 Python<br> 67 '''<br> 68 Assume that exampleItem is a shared pointer to the ParentClass object<br> 69 Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 70 '''<br> 71 getIndex = 0<br> 72 exampleChild = exampleItem.getInformation(getIndex)<br> 73 @return requested ChildClass. If no ChildClass##s exist at the index, 74 a NULL pointer is returned. 75 */ \ 76 virtual shared_ptr<ChildClass> \ 77 get##ChildName(const unsigned int index); \ 78 \ 79 /** Get a ChildClass attached to this item by index (const version).<br> 80 Example of use:<br> 81 C++<br> 82 //Assume that exampleItem is a shared pointer to the ParentClass object<br> 83 //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 84 unsigned int getIndex = 0;<br> 85 shared_ptr<const XdmfInformation> exampleChildConst = exampleItem->getInformation(getIndex);<br> 86 Python: does not support a constant version of this function 87 @param index of the ChildClass to retrieve. 88 @return requested ChildClass. If no ChildClass##s exist at the index, a 89 NULL pointer is returned. 90 */ \ 91 virtual shared_ptr<const ChildClass> \ 92 get##ChildName(const unsigned int index) const; \ 93 \ 94 /** Get a ChildClass attached to this item by SearchName.<br> 95 Example of use:<br> 96 C++<br> 97 //Assume that exampleItem is a shared pointer to the ParentClass object<br> 98 //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 99 std::string findingInfo = "Find this";<br> 100 shared_ptr<XdmfInformation> exampleStringChild = exampleItem->getInformation(findingInfo);<br> 101 Python<br> 102 '''<br> 103 Assume that exampleItem is a shared pointer to the ParentClass object<br> 104 Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 105 '''<br> 106 findingInfo = "Find this"<br> 107 exampleStringChild = exampleItem.getInformation(findingInfo)<br> 108 @param SearchName of the ChildClass to retrieve. 109 @return requested ChildClass. If no ChildClass##s are found with the 110 correct SearchName, a NULL pointer is returned. 111 */ \ 112 virtual shared_ptr<ChildClass> \ 113 get##ChildName(const std::string & SearchName); \ 114 \ 115 /** Get a ChildClass attached to this item by SearchName (const version).<br> 116 Example of use:<br> 117 C++<br> 118 //Assume that exampleItem is a shared pointer to the ParentClass object<br> 119 //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 120 std::string findingInfo = "Find this";<br> 121 shared_ptr<const XdmfInformation> exampleStringChildConst = exampleItem->getInformation(findingInfo);<br> 122 Python: does not support a constant version of this function 123 @param SearchName of the ChildClass to retrieve. 124 @return requested ChildClass If no ChildClass##s are found with the 125 correct SearchName, a NULL pointer is returned. 126 */ \ 127 virtual shared_ptr<const ChildClass> \ 128 get##ChildName(const std::string & SearchName) const; \ 129 \ 130 /** Get the number of ChildClass##s attached to this item.<br> 131 Example of use:<br> 132 C++<br> 133 //Assume that exampleItem is a shared pointer to the ParentClass object<br> 134 //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 135 unsigned int exampleSize = exampleItem->getNumberInformations();<br> 136 Python<br> 137 '''<br> 138 Assume that exampleItem is a shared pointer to the ParentClass object<br> 139 Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 140 '''<br> 141 exampleSize = exampleItem.getNumberInformations()<br> 142 @return number of ChildClass##s attached to this item. 143 */ \ 144 virtual unsigned int getNumber##ChildName##s() const; \ 145 \ 146 /** Insert a ChildClass into to this item.<br> 147 Example of use:<br> 148 C++<br> 149 shared_ptr<XdmfInformation> exampleItem = XdmfInformation::New("Parent", "This is a parent information");<br> 150 shared_ptr<XdmfInformation> addChild = XdmfInformation::New("Child", "This is a child information");<br> 151 exampleItem->insert(addChild);<br> 152 Python<br> 153 exampleItem = XdmfInformation.New("Parent", "This is a parent information")<br> 154 addChild = XdmfInformation.New("Child", "This is a child information")<br> 155 exampleItem.insert(addChild)<br> 156 @param ChildName to attach to this item. 157 */ \ 158 virtual void insert(const shared_ptr<ChildClass> ChildName); \ 159 \ 160 /** Remove a ChildClass from this item by index. If no object exists 161 at the index, nothing is removed.<br> 162 Example of use:<br> 163 C++<br> 164 //Assume that exampleItem is a shared pointer to the ParentClass object<br> 165 //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 166 unsigned int removeIndex = 0;<br> 167 exampleItem->removeInformation(removeIndex);<br> 168 Python<br> 169 '''<br> 170 Assume that exampleItem is a shared pointer to the ParentClass object<br> 171 Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 172 '''<br> 173 removeIndex = 0<br> 174 exampleItem.removeInformation(removeIndex) 175 @param index of the ChildClass to remove. 176 */ \ 177 virtual void remove##ChildName(const unsigned int index); \ 178 \ 179 /** Remove a ChildClass from this item by SearchName. If no ChildClass##s 180 have the correct SearchName, nothing is removed.<br> 181 Example of use:<br> 182 C++<br> 183 //Assume that exampleItem is a shared pointer to the ParentClass object<br> 184 //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 185 std::string removeInfo = "Remove this";<br> 186 exampleItem->removeInformation(removeInfo);<br> 187 Python<br> 188 '''<br> 189 Assume that exampleItem is a shared pointer to the ParentClass object<br> 190 Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br> 191 '''<br> 192 removeInfo = "Remove this"<br> 193 exampleItem.removeInformation(removeInfo)<br> 194 @param SearchName of the ChildClass to remove. 195 */ \ 196 virtual void remove##ChildName(const std::string & SearchName); \ 197 \ 198 protected : \ 199 \ 200 std::vector<shared_ptr<ChildClass> > m##ChildName##s; \ 201 \ 202 public : 203 204 // Macro that allows children XdmfItems to be attached to a parent XdmfItem. 205 // -- For Implementation File 206 #define XDMF_CHILDREN_IMPLEMENTATION(ParentClass, \ 207 ChildClass, \ 208 ChildName, \ 209 SearchName) \ 210 \ 211 shared_ptr<ChildClass> \ 212 ParentClass::get##ChildName(const unsigned int index) \ 213 { \ 214 return boost::const_pointer_cast<ChildClass> \ 215 (static_cast<const ParentClass &>(*this).get##ChildName(index)); \ 216 } \ 217 \ 218 shared_ptr<const ChildClass> \ 219 ParentClass::get##ChildName(const unsigned int index) const \ 220 { \ 221 if(index < m##ChildName##s.size()) { \ 222 return m##ChildName##s[index]; \ 223 } \ 224 return shared_ptr<ChildClass>(); \ 225 } \ 226 \ 227 shared_ptr<ChildClass> \ 228 ParentClass::get##ChildName(const std::string & SearchName) \ 229 { \ 230 return boost::const_pointer_cast<ChildClass> \ 231 (static_cast<const ParentClass &>(*this).get##ChildName(SearchName)); \ 232 } \ 233 \ 234 shared_ptr<const ChildClass> \ 235 ParentClass::get##ChildName(const std::string & SearchName) const \ 236 { \ 237 for(std::vector<shared_ptr<ChildClass> >::const_iterator iter = \ 238 m##ChildName##s.begin(); \ 239 iter != m##ChildName##s.end(); \ 240 ++iter) { \ 241 if((*iter)->get##SearchName().compare(SearchName) == 0) { \ 242 return *iter; \ 243 } \ 244 } \ 245 return shared_ptr<ChildClass>(); \ 246 } \ 247 \ 248 unsigned int \ 249 ParentClass::getNumber##ChildName##s() const \ 250 { \ 251 return m##ChildName##s.size(); \ 252 } \ 253 \ 254 void \ 255 ParentClass::insert(const shared_ptr<ChildClass> ChildName) \ 256 { \ 257 m##ChildName##s.push_back(ChildName); \ 258 this->setIsChanged(true); \ 259 } \ 260 \ 261 void \ 262 ParentClass::remove##ChildName(const unsigned int index) \ 263 { \ 264 if(index < m##ChildName##s.size()) { \ 265 m##ChildName##s.erase(m##ChildName##s.begin() + index); \ 266 } \ 267 this->setIsChanged(true); \ 268 } \ 269 \ 270 void \ 271 ParentClass::remove##ChildName(const std::string & SearchName) \ 272 { \ 273 for(std::vector<shared_ptr<ChildClass> >::iterator iter = \ 274 m##ChildName##s.begin(); \ 275 iter != m##ChildName##s.end(); \ 276 ++iter) { \ 277 if((*iter)->get##SearchName().compare(SearchName) == 0) { \ 278 m##ChildName##s.erase(iter); \ 279 return; \ 280 } \ 281 } \ 282 this->setIsChanged(true); \ 283 } 284 285 /** 286 * @brief Base class of any object that is able to be added to an Xdmf 287 * structure. 288 * 289 * XdmfItem is an abstract base class. An XdmfItem is a structure that 290 * can be visited and traversed by an XdmfVisitor and have its 291 * contents written to an Xdmf file. 292 */ 293 294 class XDMFCORE_EXPORT XdmfItem : public Loki::BaseVisitable<void> { 295 296 public: 297 298 virtual ~XdmfItem() = 0; 299 300 LOKI_DEFINE_VISITABLE_BASE() 301 XDMF_CHILDREN(XdmfItem, XdmfInformation, Information, Key) 302 friend class XdmfCoreReader; 303 friend class XdmfWriter; 304 friend class XdmfHeavyDataWriter; 305 friend class XdmfHDF5Writer; 306 307 /** 308 * Get the tag for this item. This is equivalent to tags in XML 309 * parlance. 310 * 311 * Example of use: 312 * 313 * C++ 314 * 315 * @dontinclude ExampleXdmfItem.cpp 316 * @skipline //#initialization 317 * @until //#initialization 318 * @skipline //#getItemTag 319 * @until //#getItemTag 320 * 321 * Python 322 * 323 * @dontinclude XdmfExampleItem.py 324 * @skipline #//initialization 325 * @until #//initialization 326 * @skipline #//getItemTag 327 * @until #//getItemTag 328 * 329 * @return The tag for this XdmfItem. 330 */ 331 virtual std::string getItemTag() const = 0; 332 333 /** 334 * Get the key/value property pairs for this item. These are 335 * equivalent to attributes in XML parlance. 336 * 337 * Example of use: 338 * 339 * C++ 340 * 341 * @dontinclude ExampleXdmfItem.cpp 342 * @skipline //#initialization 343 * @until //#initialization 344 * @skipline //#getItemProperties 345 * @until //#getItemProperties 346 * 347 * Python 348 * 349 * @dontinclude XdmfExampleItem.py 350 * @skipline #//initialization 351 * @until #//initialization 352 * @skipline #//getItemProperties 353 * @until #//getItemProperties 354 * 355 * @return A map of key/value properties associated with this XdmfItem. 356 */ 357 virtual std::map<std::string, std::string> getItemProperties() const = 0; 358 359 /** 360 * Traverse this item by passing the visitor to child items. 361 * 362 * Example of use: 363 * 364 * C++ 365 * 366 * @dontinclude ExampleXdmfItem.cpp 367 * @skipline //#initialization 368 * @until //#initialization 369 * @skipline //#traverse 370 * @until //#traverse 371 * 372 * Python 373 * 374 * @dontinclude XdmfExampleItem.py 375 * @skipline #//initialization 376 * @until #//initialization 377 * @skipline #//traverse 378 * @until #//traverse 379 * 380 * @param visitor The visitor to pass to child items. 381 */ 382 virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor); 383 384 XdmfItem(const XdmfItem &); 385 386 protected: 387 388 XdmfItem(); 389 390 /** 391 * Populates an item using a map of key/value property pairs and a 392 * vector of its child items. This is used to support generic 393 * reading of XdmfItems from disk. 394 * 395 * @param itemProperties a map of key/value properties associated with 396 * this item. 397 * @param childItems a vector of child items to be added to this item. 398 * @param reader the current XdmfCoreReader being used to populate Xdmf 399 * structures. 400 */ 401 virtual void 402 populateItem(const std::map<std::string, std::string> & itemProperties, 403 const std::vector<shared_ptr<XdmfItem > > & childItems, 404 const XdmfCoreReader * const reader); 405 406 bool 407 getIsChanged(); 408 409 void 410 setIsChanged(bool status); 411 412 std::set<XdmfItem *> mParents; 413 414 bool mIsChanged; 415 416 private: 417 418 // XdmfItem(const XdmfItem &); // It is implemented for C wrappers. 419 void operator=(const XdmfItem &); // Not implemented. 420 421 }; 422 423 #endif 424 425 #ifdef __cplusplus 426 extern "C" { 427 #endif 428 429 // C wrappers go here 430 431 struct XDMFITEM; // Simply as a typedef to ensure correct typing 432 typedef struct XDMFITEM XDMFITEM; 433 434 #ifndef XDMFINFORMATIONCDEFINE 435 #define XDMFINFORMATIONCDEFINE 436 struct XDMFINFORMATION; // Simply as a typedef to ensure correct typing 437 typedef struct XDMFINFORMATION XDMFINFORMATION; 438 #endif 439 440 XDMFCORE_EXPORT void XdmfItemAccept(XDMFITEM * item, XDMFVISITOR * visitor, int * status); 441 442 XDMFCORE_EXPORT void XdmfItemFree(void * item); 443 444 XDMFCORE_EXPORT XDMFINFORMATION * XdmfItemGetInformation(XDMFITEM * item, unsigned int index); 445 446 XDMFCORE_EXPORT XDMFINFORMATION * XdmfItemGetInformationByKey(XDMFITEM * item, char * key); 447 448 XDMFCORE_EXPORT unsigned int XdmfItemGetNumberInformations(XDMFITEM * item); 449 450 XDMFCORE_EXPORT void XdmfItemInsertInformation(XDMFITEM * item, XDMFINFORMATION * information, int passControl); 451 452 XDMFCORE_EXPORT void XdmfItemRemoveInformation(XDMFITEM * item, unsigned int index); 453 454 XDMFCORE_EXPORT void XdmfItemRemoveInformationByKey(XDMFITEM * item, char * key); 455 456 XDMFCORE_EXPORT char * XdmfItemGetItemTag(XDMFITEM * item); 457 458 #define XDMF_ITEM_C_CHILD_DECLARE(ClassName, CClassName, Level) \ 459 \ 460 Level##_EXPORT void ClassName##Accept ( CClassName * item, XDMFVISITOR * visitor, int * status); \ 461 Level##_EXPORT CClassName * ClassName##Cast ( XDMFITEM * item); \ 462 Level##_EXPORT void ClassName##Free(void * item); \ 463 Level##_EXPORT XDMFINFORMATION * ClassName##GetInformation( CClassName * item, unsigned int index); \ 464 Level##_EXPORT XDMFINFORMATION * ClassName##GetInformationByKey( CClassName * item, char * key); \ 465 Level##_EXPORT unsigned int ClassName##GetNumberInformations( CClassName * item); \ 466 Level##_EXPORT void ClassName##InsertInformation( CClassName * item, XDMFINFORMATION * information, int passControl); \ 467 Level##_EXPORT void ClassName##RemoveInformation( CClassName * item, unsigned int index); \ 468 Level##_EXPORT void ClassName##RemoveInformationByKey( CClassName * item, char * key); \ 469 Level##_EXPORT char * ClassName##GetItemTag( CClassName * item); 470 471 472 #define XDMF_ITEM_C_CHILD_WRAPPER(ClassName, CClassName) \ 473 void ClassName##Accept( CClassName * item, XDMFVISITOR * visitor, int * status) \ 474 { \ 475 XdmfItemAccept(((XDMFITEM *)item), visitor, status); \ 476 } \ 477 \ 478 void ClassName##Free(void * item) \ 479 { \ 480 XdmfItemFree(item); \ 481 } \ 482 \ 483 XDMFINFORMATION * ClassName##GetInformation( CClassName * item, unsigned int index) \ 484 { \ 485 return XdmfItemGetInformation(((XDMFITEM *)item), index); \ 486 } \ 487 \ 488 XDMFINFORMATION * ClassName##GetInformationByKey( CClassName * item, char * key) \ 489 { \ 490 return XdmfItemGetInformationByKey(((XDMFITEM *)item), key); \ 491 } \ 492 \ 493 unsigned int ClassName##GetNumberInformations( CClassName * item) \ 494 { \ 495 return XdmfItemGetNumberInformations(((XDMFITEM *)item)); \ 496 } \ 497 \ 498 void ClassName##InsertInformation( CClassName * item, XDMFINFORMATION * information, int passControl) \ 499 { \ 500 XdmfItemInsertInformation(((XDMFITEM *)item), information, passControl); \ 501 } \ 502 \ 503 void ClassName##RemoveInformation( CClassName * item, unsigned int index) \ 504 { \ 505 XdmfItemRemoveInformation(((XDMFITEM *)item), index); \ 506 } \ 507 \ 508 void ClassName##RemoveInformationByKey( CClassName * item, char * key) \ 509 { \ 510 XdmfItemRemoveInformationByKey(((XDMFITEM *)item), key); \ 511 } \ 512 \ 513 char * ClassName##GetItemTag( CClassName * item) \ 514 { \ 515 return XdmfItemGetItemTag(((XDMFITEM *)item)); \ 516 } 517 518 #ifdef __cplusplus 519 } 520 #endif 521 522 #endif /* XDMFITEM_HPP_ */ 523