DCL 3.7.4
Loading...
Searching...
No Matches
IniFile.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#ifdef __WINNT__
4#include <windows.h> // dcl/Thread.h
5#endif
6
7#include <stdlib.h> // ListT.h malloc, free, realloc
8#include <string.h> // ListT.h memset, memmove
9
10#include <dcl/Object.h>
11
12#if __DCL_HAVE_ALLOC_DEBUG
13#undef __DCL_ALLOC_LEVEL
14#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
15#endif
16
17#include <dcl/Numeric.h>
18#include <dcl/File.h>
19#include <dcl/FileInputStream.h>
22#include <dcl/BufferedReader.h>
24#include <dcl/ListT.h>
25#include <dcl/IniFile.h>
26
27#if __DCL_HAVE_THIS_FILE__
28#undef __THIS_FILE__
29static const char_t __THIS_FILE__[] = __T("dcl/IniFile.cpp");
30#endif
31
32__DCL_BEGIN_NAMESPACE
33
40
41struct IniLine
42{
44 String __name;
45 String __strValue;
46
48 {
49 }
50
51 IniLine(IniLineType type, const String& str)
52 {
53 __type = type;
54 __name = str;
55 }
56 IniLine(const String& strKey, const String& strValue)
57 {
59 __name = strKey;
60 __strValue = strValue;
61 }
62 String toString() const
63 {
64 String str;
65 switch (__type) {
66 case ltSectionName :
67 str = L"[" + __name + L"]";
68 break;
69 case ltEntry :
70 str = __name + L"=" + __strValue;
71 break;
72 default :
73 str = __name;
74 }
75 return str;
76 }
77};
78
80
82
83String IniFile::toString() const
84{
85 return __name;
86}
87
88#ifdef __DCL_DEBUG
89void IniFile::dump(Writer& out) const
90{
91 Object::dump(out);
92 out << L"fileName: " << __name << L"\n";
93 if (__handle) {
94 const IniLineList* lines = (const IniLineList*)__handle;
95 for(IniLineList::ConstIterator it = lines->begin();
96 it != lines->end(); it++
97 ) {
98 out << (*it).toString() << L"\n";
99 }
100 }
101}
102
103#endif
104
106{
107 __handle = NULL;
108 __modified = false;
109}
110
111IniFile::IniFile(const String& strFileName)
113{
114 __handle = NULL;
115 __modified = false;
116
117 __DCL_ASSERT(!strFileName.isEmpty());
118
119 IniLineList* lines = new IniLineList;
120 __handle = lines;
121
124 new FileInputStream(strFileName)
125 )
126 );
127 String s;
128 while(in.readLine(s)) {
129 s = s.trim();
130
131 if (s.isEmpty())
132 lines->addTail(IniLine(ltComment, String()));
133 else if (s[(size_t)0] == L';' || s[(size_t)0] == L'#') {
134 lines->addTail(IniLine(ltComment, s));
135 }
136 else if (s[(size_t)0] == L'[') {
137 // section name
138 s = s.trim(L"[]\t ");
139 lines->addTail(IniLine(ltSectionName, s));
140 }
141 else {
142 // key=value
143 size_t pos = s.indexOf(L'=');
144 if (pos != (size_t)-1) {
145 String name = s.left(pos).trim();
146 String value = s.right(s.length() - pos - 1).trim();
147 lines->addTail(IniLine(name, value));
148 }
149 else {
150 // invalid line value. ignore
151 }
152 }
153 }
154}
155
156IniFile::~IniFile()
157{
158 if (__handle) {
159 try {
160 close();
161 }
162 catch (IOException* e) {
163 __DCL_TRACE1(L"%ls\n", e->toString().data());
164 e->destroy();
165 }
166 }
167}
168
169void IniFile::close()
171{
173
174 if (__handle != NULL) {
176 __handle = NULL;
177 Exception* e = NULL;
178 if (__modified) {
179 __modified = false;
180 try {
181 OutputStreamWriter out(
182 new FileOutputStream(__name, true)
183 );
184 for (IniLineList::Iterator it = lines->begin();
185 it != lines->end(); it++) {
186 out << (*it).toString() << endl;
187 }
188 }
189 catch (Exception* _e) {
190 e = _e;
191 }
192 }
193 delete lines;
194 if (e) {
195 throw e;
196 }
197 }
198}
199
200/*
201#ifdef __DCL_DEBUG
202void IniFile::dump(FILE* fp)
203{
204 if (__handle) {
205 IniLineList* lines = (IniLineList*)__handle;
206 for(IniLineList::Iterator it = lines->begin();
207 it != lines->end(); it++
208 ) {
209 fprintf(fp, "%s\n", (*it).line().cstr());
210 }
211 }
212}
213#endif
214*/
215
216String IniFile::getString(
217 const String& strSection,
218 const String& strEntry,
219 const wchar_t* pszDefault // = NULL
221{
222 __DCL_ASSERT(!strSection.isEmpty());
223 __DCL_ASSERT(!strEntry.isEmpty());
224
225 String strResult = __getValue(strSection, strEntry);
226 if (strResult.isEmpty() && pszDefault != NULL)
227 strResult = pszDefault;
228
229 return strResult;
230}
231
232int IniFile::getInteger(
233 const String& strSection,
234 const String& strEntry,
235 int nDefault
237{
238 __DCL_ASSERT(!strSection.isEmpty());
239 __DCL_ASSERT(!strEntry.isEmpty());
240
241 String strResult = __getValue(strSection, strEntry);
242 if (!strResult.isEmpty()) {
243 try {
244 nDefault = Integer::parse(strResult, 10);
245 }
246 catch (NumericConvertException* e) {
247 throw (new IOException(__name, e));
248 }
249 }
250 return nDefault;
251}
252
253void IniFile::setValue(
254 const String& strSection,
255 const String& strEntry,
256 const String& strValue
258{
259 __DCL_ASSERT(!strSection.isEmpty());
260 __DCL_ASSERT(!strEntry.isEmpty());
261
262 __setValue(strSection, strEntry, strValue);
263}
264
265void IniFile::setValue(
266 const String& strSection,
267 const String& strEntry,
268 int nValue
270{
271 __DCL_ASSERT(!strSection.isEmpty());
272 __DCL_ASSERT(!strEntry.isEmpty());
273
274 __setValue(strSection, strEntry, Integer::toString(nValue, 10));
275}
276
277String IniFile::__getValue(
278 const String& strSection,
279 const String& strEntry
280)
281{
283
284 String strResult;
285 if (__handle) {
287 IniLineList::Iterator it = lines->begin();
288 for(; it != lines->end(); it++) {
289 if (((*it).__type == ltSectionName)
290 && ((*it).__name.compareNoCase(strSection) == 0)
291 ) {
292 // found section
293 it++;
294 for( ; (it != lines->end()) && ((*it).__type != ltSectionName);
295 it++
296 ) {
297 if (((*it).__type == ltEntry)
298 && ((*it).__name.compareNoCase(strEntry) == 0)
299 ) {
300 strResult = (*it).__strValue;
301 break;
302 }
303 }
304 break;
305 }
306 }
307 }
308
309 return strResult;
310}
311
312void IniFile::__setValue(
313 const String& strSection,
314 const String& strEntry,
315 const String& strValue
316)
317{
319 __modified = true;
320
322 for(IniLineList::Iterator it = lines->begin();
323 it != lines->end(); it++
324 ) {
325 if (((*it).__type == ltSectionName)
326 && ((*it).__name.compareNoCase(strSection) == 0)
327 ) {
328 // found!
329 it++;
330 for( ; (it != lines->end()) && ((*it).__type != ltSectionName);
331 it++
332 ) {
333 if (((*it).__type == ltEntry)
334 && ((*it).__name.compareNoCase(strEntry) == 0)
335 ) {
336 // strEntry 가 있다. 값을 교체한다.
337 (*it).__strValue = strValue;
338 return;
339 }
340 }
341 lines->insert(it, IniLine(strEntry, strValue));
342 }
343 else {
344 // 해당하는 섹션이 없다.
345 // 섹션을 추가하고 엔트리를 추가한다.
346 lines->addTail(IniLine(ltSectionName, strSection));
347 lines->addTail(IniLine(strEntry, strValue));
348 }
349 }
350}
351
352#ifdef __WINNT__
353
354IMPLEMENT_CLASSINFO(RegIniFile, IniFile)
355
356RegIniFile::RegIniFile(HKEY hParentKey, const String& strKey)
358 : __reg(hParentKey)
359{
360 __DCL_ASSERT(!strKey.isEmpty());
361
362 __reg.create(strKey, KEY_ALL_ACCESS);
363 __handle = &__reg;
364 IniFile::__name = strKey;
365}
366
367void RegIniFile::close()
369{
370 __handle = NULL;
371 __reg.close();
372}
373
374String RegIniFile::getString(
375 const String& strSection,
376 const String& strEntry,
377 const wchar_t* pszDefault // = NULL
379{
380 __DCL_ASSERT(!strSection.isEmpty());
381 __DCL_ASSERT(!strEntry.isEmpty());
382
383 String strResult;
384 try {
385 Registry section(__reg.key(), strSection, KEY_READ);
386 strResult = section.getString(strEntry);
387 }
388 catch (IOException* e) {
389 __DCL_TRACE1(L"%ls\n", e->toString().data());
390 e->destroy();
391
392 if (pszDefault)
393 strResult = pszDefault;
394 }
395
396 return strResult;
397}
398
399int RegIniFile::getInteger(
400 const String& strSection,
401 const String& strEntry,
402 int nDefault
404{
405 __DCL_ASSERT(!strSection.isEmpty());
406 __DCL_ASSERT(!strEntry.isEmpty());
407
408 int nResult;
409 try {
410 Registry section(__reg.key(), strSection, KEY_READ);
411 nResult = section.getInteger(strEntry);
412 }
413 catch (IOException* e) {
414 __DCL_TRACE1(L"%ls\n", e->toString().data());
415 e->destroy();
416 nResult = nDefault;
417 }
418
419 return nResult;
420}
421
422void RegIniFile::setValue(
423 const String& strSection,
424 const String& strEntry,
425 const String& strValue
427{
428 __DCL_ASSERT(!strSection.isEmpty());
429 __DCL_ASSERT(!strEntry.isEmpty());
430
431 Registry section(__reg.key());
432 section.create(strSection);
433 section.setValue(strEntry, strValue);
434}
435
436void RegIniFile::setValue(
437 const String& strSection,
438 const String& strEntry,
439 int nValue
441{
442 __DCL_ASSERT(!strSection.isEmpty());
443 __DCL_ASSERT(!strEntry.isEmpty());
444
445 Registry section(__reg.key());
446 section.create(strSection);
447 section.setValue(strEntry, nValue);
448}
449
450#endif // __WINNT__
451
452__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
IniLineType
Definition IniFile.cpp:35
@ ltComment
Definition IniFile.cpp:37
@ ltEntry
Definition IniFile.cpp:38
@ ltSectionName
Definition IniFile.cpp:36
List< IniLine > IniLineList
Definition IniFile.cpp:79
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
DCLCVAR const struct __endl endl
virtual void destroy()
Definition Exception.cpp:74
virtual String toString() const
bool __modified
Definition IniFile.h:75
String __name
Definition IniFile.h:74
Object * __handle
Definition IniFile.h:73
String toString(unsigned _base=10) const
Definition Numeric.inl:21
static int parse(const wchar_t *_number, unsigned _base=10) __DCL_THROWS1(NumericConvertException *)
Definition Numeric.inl:36
ConstIterator end() const
Iterator insert(Iterator _pos, const ELEMENT &_element)
ConstIterator begin() const
List< ELEMENT > & addTail(const ELEMENT &_element)
virtual String toString() const
Definition Object.cpp:187
IniLine(const String &strKey, const String &strValue)
Definition IniFile.cpp:56
IniLine()
Definition IniFile.cpp:47
String __name
Definition IniFile.cpp:44
IniLine(IniLineType type, const String &str)
Definition IniFile.cpp:51
String __strValue
Definition IniFile.cpp:45
IniLineType __type
Definition IniFile.cpp:43
String toString() const
Definition IniFile.cpp:62