1 //============================================================================= 2 // 3 // Adventure Game Studio (AGS) 4 // 5 // Copyright (C) 1999-2011 Chris Jones and 2011-20xx others 6 // The full list of copyright holders can be found in the Copyright.txt 7 // file, which is part of this source code distribution. 8 // 9 // The AGS source code is provided under the Artistic License 2.0. 10 // A copy of this license can be found in the file License.txt and at 11 // http://www.opensource.org/licenses/artistic-license-2.0.php 12 // 13 //============================================================================= 14 // 15 // IniFile class defines contents of the configuration file. 16 // It serves as a INI parser and plain enumerator of all the sections and items 17 // found in file, or, oppositely, as INI file constructor. 18 // But is not much suitable for regular key/value lookup. It is suggested to 19 // create a proper map to store items, from IniFile contents. 20 // 21 //============================================================================= 22 #ifndef __AGS_CN_UTIL__INIFILE_H 23 #define __AGS_CN_UTIL__INIFILE_H 24 25 #include <list> 26 #include "util/string.h" 27 28 namespace AGS 29 { 30 namespace Common 31 { 32 33 class IniFile 34 { 35 public: 36 // Position of a string in the line of text: 37 // is defined by a pair of first and next-after-last character indices 38 typedef std::pair<int, int> StrPos; 39 // Location of section in the array of text lines: 40 // is defined by a pair of first and next-after-last line indices 41 typedef std::pair<int, int> SectionPos; 42 43 // Item definition 44 // Valid key indicates a key-value line; no key means unparsed 45 // line of text, e.g. comment or incorrectly formatted item. 46 class ItemDef 47 { 48 public: 49 ItemDef(const String &key, const String &value); 50 ItemDef(const String &line, const StrPos &key, const StrPos &value, int sep_at); GetLine()51 String GetLine() const { return Line; } GetKey()52 String GetKey() const { return SubString(Line, Key); } GetValue()53 String GetValue() const { return SubString(Line, Value); } IsKeyValue()54 bool IsKeyValue() const { return Key.second - Key.first > 0; } 55 void SetKey(const String &key); 56 void SetValue(const String &value); 57 58 private: 59 String Line; // actual text 60 StrPos Key; // position of item key 61 int SepAt; // position of the separator (assignment) symbol 62 StrPos Value; // position of item value 63 }; 64 // Linked list of items 65 typedef std::list<ItemDef> LItems; 66 typedef LItems::iterator ItemIterator; 67 typedef LItems::const_iterator ConstItemIterator; 68 69 // Section definition 70 class SectionDef 71 { 72 public: 73 SectionDef(const String &name); 74 SectionDef(const String &line, const StrPos &name); GetLine()75 String GetLine() const { return Header; } GetName()76 String GetName() const { return SubString(Header, Name); } GetItemCount()77 size_t GetItemCount() const { return Items.size(); } IsGlobal()78 bool IsGlobal() const { return Name.second - Name.first <= 0; } Begin()79 ItemIterator Begin() { return Items.begin(); } End()80 ItemIterator End() { return Items.end(); } CBegin()81 ConstItemIterator CBegin() const { return Items.begin(); } CEnd()82 ConstItemIterator CEnd() const { return Items.end(); } 83 void SetName(const String &sec_name); 84 void Clear(); 85 ItemIterator InsertItem(ItemIterator item, const ItemDef &itemdef); 86 void EraseItem(ItemIterator item); 87 88 private: 89 String Header;// section's heading line 90 StrPos Name; // location of section name in the header line 91 LItems Items; // linked list of items belonging to the section 92 }; 93 // Linked list of sections 94 typedef std::list<SectionDef> LSections; 95 typedef LSections::iterator SectionIterator; 96 typedef LSections::const_iterator ConstSectionIterator; 97 98 private: SubString(const String & line,const StrPos & pos)99 inline static String SubString(const String &line, const StrPos &pos) 100 { 101 return line.Mid(pos.first, pos.second - pos.first); 102 } 103 104 public: 105 IniFile(); 106 Begin()107 SectionIterator Begin() { return _sections.begin(); } End()108 SectionIterator End() { return _sections.end(); } CBegin()109 ConstSectionIterator CBegin() const { return _sections.begin(); } CEnd()110 ConstSectionIterator CEnd() const { return _sections.end(); } 111 112 void Read(Stream *in); 113 void Write(Stream *out) const; 114 115 // Return number of sections GetSectionCount()116 size_t GetSectionCount() const { return _sections.size(); } 117 // Insert new item *before* existing item 118 ItemIterator InsertItem(SectionIterator sec, ItemIterator item, const String &key, const String &value); 119 // Insert new section *before* existing section 120 SectionIterator InsertSection(SectionIterator sec, const String &name); 121 // Remove a single item 122 void RemoveItem(SectionIterator sec, ItemIterator item); 123 // Completely remove whole section; this removes all lines between section 124 // header and the last item found in that section (inclusive). 125 void RemoveSection(SectionIterator sec); 126 127 private: 128 void MakeItemDef(const String &key, const String &value, ItemDef &itemdef); 129 130 LSections _sections; 131 }; 132 133 } // namespace Common 134 } // namespace AGS 135 136 #endif // __AGS_CN_UTIL__INIFILE_H 137