BALL  1.4.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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
25 # include <BALL/CONCEPT/processor.h>
26 #endif
27 
28 #ifndef BALL_SYSTEM_FILE_H
29 # include <BALL/SYSTEM/file.h>
30 #endif
31 
32 namespace BALL
33 {
42  : public AutoDeletable
43  {
44  public:
45 
47 
48 
51 
54  ResourceEntry();
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 
356  virtual ~IteratorTraits_()
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 
378  ResourceEntry* getContainer()
379  {
380  return bound_;
381  }
382 
383  const ResourceEntry* getContainer() const
384  {
385  return bound_;
386  }
387 
388  bool isSingular() const
389  {
390  return (bound_ == 0);
391  }
392 
393  IteratorPosition& getPosition()
394  {
395  return position_;
396  }
397 
398  const IteratorPosition& getPosition() const
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 
421  void invalidate()
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 
449  ResourceEntry& getData()
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:
492  Size getDepth() const
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 
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 
553  virtual ResourceEntry* newEntry
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 
562  bool applyNostart_(UnaryProcessor<ResourceEntry>& processor);
563 
564 
565  private:
566 
567  ResourceEntry* clone_(ResourceEntry* parent) const;
568  bool findGreaterOrEqual_(const String& key, Index& found) const;
569 
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 
618  ResourceFile();
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  */
679  Entry& getRoot();
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 
762  void host(Visitor<ResourceFile>& visitor);
763 
766  bool apply(UnaryProcessor<Entry>& processor);
767 
770  static bool applyChildren(Entry& entry, UnaryProcessor<Entry>& processor);
772 
774 
775  Iterator begin()
776  {
777  return Iterator::begin(root_);
778  }
779 
780  Iterator end()
781  {
782  return Iterator::end(root_);
783  }
784 
785 
787 
788  ConstIterator begin() const
789  {
790  return ConstIterator::begin(root_);
791  }
792 
793  ConstIterator end() const
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 
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