|
1 /** |
|
2 * @file testscripts.h Defines classes for reading a configuration file |
|
3 * |
|
4 * @note Configuration File Format: |
|
5 * |
|
6 * [Defaults] |
|
7 * defaults= another_config_file.txt |
|
8 * |
|
9 * [SectionName] |
|
10 * variable= value |
|
11 * variable2= value2 |
|
12 * variable= value3 |
|
13 * |
|
14 * [SectionName2] |
|
15 * variable= value |
|
16 * |
|
17 * endscript |
|
18 * |
|
19 * |
|
20 * @note Explanation: |
|
21 * |
|
22 * A configuration file is made up of a number of "sections", each of which can contain a number of "items" (name, value combination). |
|
23 * |
|
24 * "Sections" must have a name and be surrounded by square backets, e.g.: |
|
25 * |
|
26 * [SectionName] |
|
27 * |
|
28 * |
|
29 * Each "item" consists of consists of a name, followed by an equals sign, followed by blank space, followed by the value to assign to that variable. |
|
30 * |
|
31 * The value can be of any length, contain whitespace and span multiple lines. The value ends when the next item or section is found. E.g: |
|
32 * |
|
33 * Simple Item: |
|
34 * |
|
35 * variable= value |
|
36 * |
|
37 * Two items on one line: |
|
38 * |
|
39 * variable= value variable2= value2 |
|
40 * |
|
41 * Multi-line item: |
|
42 * |
|
43 * variable= This variable |
|
44 * spans multiple |
|
45 * lines |
|
46 * |
|
47 * |
|
48 * @note Parsing stops at End-Of-File or if the tag "endscript" (without the quotes) appears in the file. |
|
49 * |
|
50 * @note A section may take some default values from another section or config file |
|
51 * |
|
52 * To specify default values for all sections, add a section at the start of the config file called [Defaults], e.g.: |
|
53 * |
|
54 * [Defaults] |
|
55 * sc= +447785016005 |
|
56 * |
|
57 * To read default values from another config file, add an item with name "defaults" and value is the name of the file. E.g.: |
|
58 * |
|
59 * defaults= another_config_file.txt |
|
60 |
|
61 */ |
|
62 |
|
63 |
|
64 #ifndef __TEST_CONFIG_FILE_PARSER_H__ |
|
65 #define __TEST_CONFIG_FILE_PARSER_H__ |
|
66 |
|
67 #include <e32std.h> |
|
68 #include <e32base.h> |
|
69 |
|
70 class CTestConfigSection; |
|
71 class CTestConfigItem; |
|
72 class RFs; |
|
73 class TParse; |
|
74 class RFile; |
|
75 |
|
76 _LIT(KScriptPanic, "TEST-SCRIPT"); |
|
77 _LIT(KScriptPathSep,"\\"); |
|
78 _LIT8(KScriptSectionStart, "["); |
|
79 _LIT8(KScriptSectionEnd, "]"); |
|
80 _LIT8(KScriptCRLF, "\r\n"); |
|
81 _LIT8(KScriptCRLF8, "\r\n"); |
|
82 _LIT8(KScriptLF, "\n"); |
|
83 _LIT8(KScriptCR, "\r"); |
|
84 _LIT8(KScriptItemEnd, "="); |
|
85 _LIT8(KScriptItemEnd8, "="); |
|
86 _LIT8(KScriptSpace8, " "); |
|
87 _LIT8(KScriptDefaults, "Defaults"); |
|
88 _LIT8(KScriptDefault1, "Def"); |
|
89 _LIT8(KScriptDefault2, "Default"); |
|
90 _LIT8(KScriptCommentStart, "#"); |
|
91 const TInt KScriptLFChar = '\n'; |
|
92 const TInt KScriptCRChar = '\r'; |
|
93 |
|
94 class CTestConfig : public CBase |
|
95 /** |
|
96 * @internalComponent |
|
97 * @deprecated |
|
98 */ |
|
99 { |
|
100 public: |
|
101 IMPORT_C static CTestConfig* NewLC(RFs& aFs, const TDesC& aComponent, const TDesC& aScriptFile); |
|
102 IMPORT_C static CTestConfig* NewLC(RFs& aFs, const TDesC& aComponent); |
|
103 IMPORT_C ~CTestConfig(); |
|
104 |
|
105 IMPORT_C const TDesC8& ItemValue(const TDesC8& aSection, const TDesC8& aItem, const TDesC8& aDefault) const; |
|
106 IMPORT_C TInt ItemValue(const TDesC8& aSection, const TDesC8& aItem, const TInt aDefault) const; |
|
107 |
|
108 IMPORT_C void ReadScriptL(const TDesC& aScript); |
|
109 |
|
110 inline const RPointerArray<CTestConfigSection>& Sections() const; |
|
111 inline RPointerArray<CTestConfigSection>& Sections(); |
|
112 |
|
113 IMPORT_C const CTestConfigSection* Section(const TDesC8& aSectionName) const; //return NULL if section not found |
|
114 IMPORT_C CTestConfigSection* Section(const TDesC8& aSectionName); //return NULL if section not found |
|
115 inline const CTestConfigSection& operator[](TInt aIndex) const {return *iSections[aIndex];} |
|
116 inline CTestConfigSection& operator[](TInt aIndex) {return *iSections[aIndex];} |
|
117 |
|
118 IMPORT_C static TInt CountElements(const TDesC8& aInput, TChar aDelimiter); |
|
119 IMPORT_C static TInt GetElement(const TDesC8& aInput, TChar aDelimiter, TInt aIndex, TInt& aOutput); |
|
120 IMPORT_C static TInt GetElement(const TDesC8& aInput, TChar aDelimiter, TInt aIndex, TPtrC8& aOutput, TBool aTrimOutput = ETrue); |
|
121 IMPORT_C static TPtrC8 Trim(const TDesC8& aInput); |
|
122 IMPORT_C static TPtrC8 TrimLeft(const TDesC8& aInput); |
|
123 IMPORT_C static TPtrC8 TrimRight(const TDesC8& aInput); |
|
124 |
|
125 IMPORT_C static HBufC8* ReplaceLC(const TDesC8& aOld, const TDesC8& aNew, const TDesC8& aOldString); |
|
126 IMPORT_C static TInt ResolveFile(RFs& aFs, const TDesC& aComponent, const TDesC& aFileName, TParse& aParseOut); |
|
127 |
|
128 IMPORT_C void WriteFileL(const TDesC& aFileName); |
|
129 IMPORT_C TBool operator==(const CTestConfig& aFile) const; |
|
130 |
|
131 IMPORT_C void AddSectionL(CTestConfigSection& aSection); |
|
132 |
|
133 protected: |
|
134 |
|
135 CTestConfig(RFs& aFs); |
|
136 void ConstructL(const TDesC& aComponent); |
|
137 |
|
138 TPtrC8 ParseValue(const TDesC8& aText, const TLex8& aInput, TInt aCurrentItemStart) const; |
|
139 void ParseAndSetItemValueL(const TDesC8& aText, const TLex8& aInput, TInt aCurrentItemStart, CTestConfigItem*& arCurrentItem); |
|
140 void CopyInDefaultsL(CTestConfigSection& aSection, const TDesC& aDefaultFile); |
|
141 |
|
142 HBufC8* ReadFileL(const TDesC& aFile) const; |
|
143 |
|
144 TBool IsDefaultSection(const TDesC8& aSectionName) const; |
|
145 static TInt GetNextElement(TLex8& aInput, TChar aDelimiter, TPtrC8& aOutput); |
|
146 TBool IsNewSection(const TDesC8& aSource, const TLex8& aInput) const; |
|
147 TBool IsNewItem(const TDesC8& aSource, const TLex8& aLex, TPtrC8& aItem, TInt& aStartOfValue) const; |
|
148 TBool IsNewComment(const TDesC8& aSource, const TLex8& aLex) const; |
|
149 TBool IsAtStartOfNewLine(const TDesC8& aSource, const TLex8& aLex, TBool aIgnoreSpaces) const; |
|
150 void SkipToNextLine(TLex8& aInput) const; |
|
151 |
|
152 |
|
153 protected: |
|
154 |
|
155 RFs& iFs; |
|
156 HBufC* iComponent; |
|
157 RPointerArray<CTestConfigSection> iSections; |
|
158 }; |
|
159 |
|
160 class CTestConfigSection : public CBase |
|
161 /** |
|
162 * @internalComponent |
|
163 * @deprecated |
|
164 */ |
|
165 { |
|
166 friend class CTestConfig; |
|
167 |
|
168 public: |
|
169 IMPORT_C static CTestConfigSection* NewLC(const TDesC8& aSectionName); |
|
170 IMPORT_C static CTestConfigSection* NewLC(const TDesC8& aSectionName, CTestConfigSection& aDefaults); |
|
171 IMPORT_C ~CTestConfigSection(); |
|
172 |
|
173 inline const TDesC8& SectionName() const; |
|
174 |
|
175 IMPORT_C const CTestConfigItem* Item(const TDesC8& aItemTag) const; //return NULL if the item does not exist |
|
176 IMPORT_C CTestConfigItem* Item(const TDesC8& aItemTag); //return NULL if the item does not exist |
|
177 IMPORT_C const CTestConfigItem* Item(const TDesC8& aItemTag,TInt aIndex) const; //return NULL if the item does not exist |
|
178 IMPORT_C CTestConfigItem* Item(const TDesC8& aItemTag,TInt aIndex); //return NULL if the item does not exist |
|
179 |
|
180 IMPORT_C const TDesC8& ItemValue(const TDesC8& aItemTag, const TDesC8& aDefault) const; |
|
181 IMPORT_C TInt ItemValue(const TDesC8& aItemTag, TInt aDefault) const; |
|
182 |
|
183 IMPORT_C CTestConfigItem& AddItemL(const TDesC8& aItemTag, const TDesC8& aValue); |
|
184 IMPORT_C void DeleteItemsL(const TDesC8& aItem); |
|
185 |
|
186 inline const RPointerArray<CTestConfigItem>& Items() const {return iItems;} |
|
187 inline RPointerArray<CTestConfigItem>& Items() {return iItems;} |
|
188 |
|
189 IMPORT_C TInt ItemCount(const TDesC8& aItemTag) const; |
|
190 IMPORT_C void ItemsL(RPointerArray<CTestConfigItem>& aArray, const TDesC8& aItemTag); |
|
191 IMPORT_C void ItemsL(RPointerArray<const CTestConfigItem>& aArray, const TDesC8& aItemTag) const; |
|
192 |
|
193 inline const CTestConfigItem& operator[](TInt aIndex) const {return *iItems[aIndex];} |
|
194 |
|
195 inline void SetDefaultsL(const CTestConfigSection& aDefaults); |
|
196 inline CTestConfigSection* Defaults() const {return iDefaults;} |
|
197 |
|
198 IMPORT_C CTestConfigSection* CopyLC() const; |
|
199 |
|
200 void WriteL(RFile& aFile) const; |
|
201 TBool operator==(const CTestConfigSection& aFile) const; |
|
202 |
|
203 private: |
|
204 void ConstructL(const TDesC8& aSectionName); |
|
205 CTestConfigSection(); |
|
206 RPointerArray<CTestConfigItem> iItems; |
|
207 HBufC8* iSectionName; |
|
208 CTestConfigSection* iDefaults; |
|
209 }; |
|
210 |
|
211 class CTestConfigItem : public CBase |
|
212 /** |
|
213 * @internalComponent |
|
214 * @deprecated |
|
215 */ |
|
216 { |
|
217 friend class CTestConfigSection; |
|
218 friend class CTestConfig; |
|
219 |
|
220 public: |
|
221 IMPORT_C static CTestConfigItem* NewLC(CTestConfigSection& aParent, const TDesC8& aItem, const TDesC8& aValue); |
|
222 inline CTestConfigItem* CopyLC() const; |
|
223 |
|
224 IMPORT_C ~CTestConfigItem(); |
|
225 inline const TDesC8& Item() const; |
|
226 inline const TDesC8& Value() const; |
|
227 |
|
228 void WriteL(RFile& aFile) const; |
|
229 TBool operator==(const CTestConfigItem& aItem) const {return Item() == aItem.Item() && Value() == aItem.Value();} |
|
230 |
|
231 public: |
|
232 |
|
233 CTestConfigSection& iParent; |
|
234 |
|
235 private: |
|
236 CTestConfigItem(CTestConfigSection& aParent); |
|
237 void ConstructL(const TDesC8& aItem, const TDesC8& aValue); |
|
238 HBufC8* iItem; |
|
239 HBufC8* iValue; |
|
240 }; |
|
241 |
|
242 #include "testconfigfileparser.inl" |
|
243 |
|
244 #endif |