BALL 1.5.0
Loading...
Searching...
No Matches
resourceFile.h
Go to the documentation of this file.
1// -*- Mode: C++; tab-width: 2; -*-
2// vi: set ts=2:
3//
4
5#ifndef BALL_FORMAT_RESOURCEFILE_H
6#define BALL_FORMAT_RESOURCEFILE_H
7
8#ifndef BALL_COMMON_H
9# include <BALL/common.h>
10#endif
11
12#ifndef BALL_CONCEPT_FORWARDITERATOR_H
14#endif
15
16#ifndef BALL_CONCEPT_VISITOR_H
17# include <BALL/CONCEPT/visitor.h>
18#endif
19
20#ifndef BALL_CONCEPT_AUTODELETABLE_H
22#endif
23
24#ifndef BALL_CONCEPT_PROCESSOR_H
26#endif
27
28#ifndef BALL_SYSTEM_FILE_H
29# include <BALL/SYSTEM/file.h>
30#endif
31
32namespace BALL
33{
42 : public AutoDeletable
43 {
44 public:
45
47
48
51
52
55
61 ResourceEntry(const ResourceEntry& entry, bool deep = true);
62
72 ResourceEntry(const String& key, const String& value, ResourceEntry* parent = 0);
73
76 virtual ~ResourceEntry();
77
80 void clear();
81
84 void destroy();
85
87
91
96 void set(const ResourceEntry& entry, bool deep = true);
97
101 const ResourceEntry& operator = (const ResourceEntry &entry);
102
107 void get(ResourceEntry& entry, bool deep = true) const;
109
110
114
117 bool operator == (const ResourceEntry& entry) const;
118
121 bool operator != (const ResourceEntry& entry) const;
122
125 ResourceEntry& getRoot();
126
129 const ResourceEntry& getRoot() const;
130
133 ResourceEntry* getParent();
134
137 const ResourceEntry* getParent() const;
138
142 ResourceEntry* getChild(Position index);
143
147 const ResourceEntry* getChild(Position index) const;
148
153 ResourceEntry* getEntry(const String& key_path);
154
159 const ResourceEntry* getEntry(const String& key_path) const;
160
163 const String& getKey() const;
164
167 void setValue(const String& value);
168
171 String& getValue();
172
175 const String& getValue() const;
176
179 String getPath() const;
180
183 Size countChildren() const;
184
187 Size countDescendants() const;
188
191 Size getSize() const;
192
195 Size getDepth() const;
196
200 ResourceEntry* insertChild(const String& key, const String& value, bool replace_value = true);
201
204 ResourceEntry* insertSibling(const String& key, const String& value, bool replace_value = true);
205
209 ResourceEntry* insertChild(ResourceEntry& entry, bool replace_value = true);
210
213 ResourceEntry* insert(const String& key_path, const String& name);
214
217 bool mergeChildrenOf(ResourceEntry& entry, bool replace_value = true);
218
221 bool removeChild(const String& key, ResourceEntry** removed = 0);
222
225 bool removeKey(const String& key_path);
226
229 ResourceEntry* findChild(const String& key);
230
233 const ResourceEntry* findChild(const String& key) const;
234
237 ResourceEntry* findDescendant(const String& key);
238
241 const ResourceEntry* findDescendant(const String& key) const;
242
245 ResourceEntry* findEntry(const String& key);
246
249 const ResourceEntry* findEntry(const String& key) const;
251
255
258 bool hasChild(const String& key) const;
259
262 bool isEmpty() const;
263
266 bool isParentOf(const ResourceEntry& entry) const;
267
270 bool isChildOf(const ResourceEntry& entry) const;
271
274 bool isAncestorOf(const ResourceEntry& entry) const;
275
278 bool isDescendantOf(const ResourceEntry& entry) const;
279
282 bool isRelatedWith(const ResourceEntry& entry) const;
283
286 bool isRoot() const;
287
289
295 bool isValid() const;
298 void dump(std::ostream& s = std::cout, Size depth = 0) const;
300
301
305
308 void host(Visitor<ResourceEntry>& visitor);
309
312 bool apply(UnaryProcessor<ResourceEntry>& processor);
313
316 bool applyChildren(UnaryProcessor<ResourceEntry>& processor);
318
320
322 {
323 public:
324
326
328 : bound_(0),
329 position_(0),
330 stack_index_(new Index[1]),
331 stack_capacity_(1),
332 stack_size_(0)
333 {
334 }
335
337 : bound_((ResourceEntry *)&entry),
338 position_(0),
339 stack_index_(new Index[1]),
340 stack_capacity_(1),
341 stack_size_(0)
342 {
343 }
344
345 IteratorTraits_(const IteratorTraits_& traits, bool /* deep */ = true)
346 : bound_(traits.bound_),
347 position_(traits.position_),
348 stack_index_(new Index[traits.stack_capacity_]),
349 stack_capacity_(traits.stack_capacity_),
350 stack_size_(traits.stack_size_)
351 {
352 for (Index index = 0; index < (Index)stack_capacity_; ++index)
353 stack_index_[index] = traits.stack_index_[index];
354 }
355
357 {
358 delete[] stack_index_;
359 }
360
361 const IteratorTraits_& operator = (const IteratorTraits_ &traits)
362 {
363 bound_ = traits.bound_;
364 position_ = traits.position_;
365 delete[] stack_index_;
366 stack_index_ = new Index[traits.stack_capacity_];
367 stack_capacity_ = traits.stack_capacity_;
368 stack_size_ = traits.stack_size_;
369
370 for (Index index = 0; index < (Index)stack_capacity_; ++index)
371 {
372 stack_index_[index] = traits.stack_index_[index];
373 }
374
375 return *this;
376 }
377
379 {
380 return bound_;
381 }
382
384 {
385 return bound_;
386 }
387
388 bool isSingular() const
389 {
390 return (bound_ == 0);
391 }
392
394 {
395 return position_;
396 }
397
399 {
400 return position_;
401 }
402
403 bool operator == (const IteratorTraits_& traits) const
404 {
405 return (position_ == traits.position_);
406 }
407
408 bool operator != (const IteratorTraits_& traits) const
409 {
410 return (position_ != traits.position_);
411 }
412
413 bool isValid() const
414 {
415 return (bound_ != 0 && position_ != 0
416 && stack_index_ != 0
417 && stack_size_ <= stack_capacity_
418 && stack_capacity_ > 0);
419 }
420
422 {
423 bound_ = 0;
424 position_ = 0;
425 stack_size_ = 0;
426 }
427
428 void toBegin()
429 {
430 stack_size_ = 0;
431 position_ = bound_;
432 }
433
434 bool isBegin() const
435 {
436 return (position_ == bound_);
437 }
438
439 void toEnd()
440 {
441 position_ = 0;
442 }
443
444 bool isEnd() const
445 {
446 return (position_ == 0);
447 }
448
450 {
451 return *position_;
452 }
453
454 const ResourceEntry& getData() const
455 {
456 return *position_;
457 }
458
459 void forward()
460 {
461 if (position_->number_children_ > 0)
462 {
463 position_ = position_->child_[0];
464 push(0);
465
466 }
467 else
468 {
469 Index next_child = INVALID_Index;
470
471 do
472 {
473 next_child = pop();
474 if (next_child == INVALID_Index)
475 {
476 position_ = 0;
477 return;
478 }
479 else
480 {
481 position_ = position_->parent_;
482 }
483
484 } while(++next_child >= (Index)position_->number_children_);
485
486 push(next_child);
487 position_ = position_->child_[next_child];
488 }
489 }
490
491 // traits-specific:
493 {
494 return stack_size_;
495 }
496
497 private:
498
499 void push(Index next_child)
500 {
501 if (stack_size_ >= stack_capacity_)
502 {
503 Index *new_stack_index = new Index[stack_capacity_ << 1];
504
505 for (Index index = 0; index < (Index)stack_capacity_; ++index)
506 {
507 new_stack_index[index] = stack_index_[index];
508 }
509
510 delete[] stack_index_;
511 stack_index_ = new_stack_index;
512 stack_capacity_ <<= 1;
513 }
514
515 stack_index_[stack_size_] = next_child;
516 ++stack_size_;
517
518 }
519
520 Index pop()
521 {
522 if (stack_size_ == 0)
523 {
524 return INVALID_Index;
525 }
526 else
527 {
528 return stack_index_[--stack_size_];
529 }
530 }
531
532 ResourceEntry* bound_;
533 IteratorPosition position_;
534 Index* stack_index_;
535 Size stack_capacity_;
536 Size stack_size_;
537 };
538
539 friend class IteratorTraits_;
540
543
544 Iterator begin() { return Iterator::begin(*this); }
545 Iterator end() { return Iterator::end(*this); }
546
547
548 ConstIterator begin() const { return ConstIterator::begin(*this); }
549 ConstIterator end() const { return ConstIterator::end(*this); }
550
551 protected:
552
554 (const String& key, const String& value, ResourceEntry* parent = 0) const;
555
556 virtual ResourceEntry** newEntryArray(Size size) const;
557
558 virtual void deleteEntry(ResourceEntry* entry) const;
559
560 virtual void deleteEntryArray(ResourceEntry** entry_array) const;
561
563
564
565 private:
566
567 ResourceEntry* clone_(ResourceEntry* parent) const;
568 bool findGreaterOrEqual_(const String& key, Index& found) const;
569
570 String key_;
571 String value_;
572 ResourceEntry* parent_;
573 ResourceEntry** child_;
574 Size number_children_;
575 };
576
577
582 : public File
583 {
584 public:
585
589
592 static char ENTRY_BEGIN;
593
596 static char ENTRY_END;
597
600 static char SEPARATOR;
602
606
611
615
619
623 ResourceFile(const String& name);
624
627 virtual ~ResourceFile();
628
631 void destroy();
632
635 virtual void clear();
636
638
639
643
644 /*
645 */
646 bool open(const String& name);
647
648 /*
649 */
650 void close();
651
652 /*
653 */
654 static void saveAs(const Entry& entry, const String& name);
655
656 /*
657 */
658 void saveAs(const String& name);
659
660 /*
661 */
662 void save(const Entry& entry);
663
664 /*
665 */
666 void save();
668
669
673 /*
674 */
675 Size getSize() const;
676
677 /*
678 */
680
681 /*
682 */
683 const Entry& getRoot() const;
684
685 /*
686 */
687 Entry* getEntry(const String& key_path);
688
689 /*
690 */
691 const Entry* getEntry(const String& key_path) const;
692
693 /*
694 */
695 String* getValue(const String& key_path);
696
697 /*
698 */
699 const String* getValue(const String& key_path) const;
700
701 /*
702 */
703 Entry* insert(const String& key_path, const String& name);
704
705 /*
706 */
707 bool removeKey(const String& key_path);
708
710
714
717 bool operator == (const ResourceFile& entry) const;
718
721 bool operator != (const ResourceFile& entry) const;
722
723 /* Return true if the key exists somewhere in the tree.
724 */
725 bool hasKey(const String& key_path) const;
726
727 /* Return true if the entry has no children.
728 */
729 bool isEmpty() const;
731
732
736
739 bool isValid() const;
740
743 void dump(std::ostream& s = std::cout, Size depth = 0) const;
745
746
750
753 friend std::istream& operator >> (std::istream& s, ResourceFile& resource_file);
755
759
763
766 bool apply(UnaryProcessor<Entry>& processor);
767
770 static bool applyChildren(Entry& entry, UnaryProcessor<Entry>& processor);
772
774
776 {
777 return Iterator::begin(root_);
778 }
779
781 {
782 return Iterator::end(root_);
783 }
784
785
787
789 {
790 return ConstIterator::begin(root_);
791 }
792
794 {
795 return ConstIterator::end(root_);
796 }
797
798
799 private:
800
801 const ResourceFile& operator = (const ResourceFile& file);
802
803 static void save_(File& file, const Entry* entry, Size& depth);
804
805 bool validateSyntax_();
806
807 void skipWhitespaces_();
808
809 Entry root_;
810 };
811
812# ifndef BALL_NO_INLINE_FUNCTIONS
813# include <BALL/FORMAT/resourceFile.iC>
814# endif
815} // namespace BALL
816
817#endif // BALL_FORMAT_RESOURCEFILE_H
#define BALL_CREATE_DEEP(name)
Definition create.h:26
STL namespace.
BALL_SIZE_TYPE Size
BALL_INDEX_TYPE Index
virtual ResourceEntry * newEntry(const String &key, const String &value, ResourceEntry *parent=0) const
ForwardIterator< ResourceEntry, ResourceEntry, ResourceEntry *, IteratorTraits_ > Iterator
virtual void deleteEntry(ResourceEntry *entry) const
bool applyNostart_(UnaryProcessor< ResourceEntry > &processor)
ConstForwardIterator< ResourceEntry, ResourceEntry, ResourceEntry *, IteratorTraits_ > ConstIterator
virtual void deleteEntryArray(ResourceEntry **entry_array) const
ConstIterator begin() const
ConstIterator end() const
virtual ResourceEntry ** newEntryArray(Size size) const
IteratorTraits_(const ResourceEntry &entry)
const ResourceEntry * getContainer() const
IteratorTraits_(const IteratorTraits_ &traits, bool=true)
const IteratorPosition & getPosition() const
const ResourceEntry & getData() const
void dump(std::ostream &s=std::cout, Size depth=0) const
bool hasKey(const String &key_path) const
void save(const Entry &entry)
const Entry & getRoot() const
bool isValid() const
static void saveAs(const Entry &entry, const String &name)
ConstIterator begin() const
static char ENTRY_BEGIN
bool apply(UnaryProcessor< Entry > &processor)
ResourceEntry Entry
const String * getValue(const String &key_path) const
void saveAs(const String &name)
static char ENTRY_END
virtual ~ResourceFile()
bool open(const String &name)
String * getValue(const String &key_path)
void host(Visitor< ResourceFile > &visitor)
static bool applyChildren(Entry &entry, UnaryProcessor< Entry > &processor)
Entry::ConstIterator ConstIterator
virtual void clear()
static char SEPARATOR
ConstIterator end() const
Size getSize() const
Entry * getEntry(const String &key_path)
bool removeKey(const String &key_path)
const Entry * getEntry(const String &key_path) const
ResourceFile(const String &name)
bool isEmpty() const
Entry * insert(const String &key_path, const String &name)
Entry::Iterator Iterator
#define BALL_EXPORT