OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
configfl.cpp
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1998 by Yura Bidus
4//
5/// \file
6/// This source file implements TConfigFile,TIniConfigFile,TRegConfigFile and
7/// TConfigFileSection.
8//------------------------------------------------------------------------------
9#include <owl/pch.h>
10//#pragma hdrstop
11
12#include <owl/configfl.h>
13#include <owl/file.h>
14#include <owl/date.h>
15#include <owl/time.h>
16#include <owl/template.h>
17#include <owl/pointer.h>
18#include <owl/wsyscls.h>
19#include <owl/color.h>
21#include <algorithm>
22
23#if defined WINELIB
24//#include <wine/msvcrt/stdlib.h> //for _ltoa, _itoa
25#endif
26
27using namespace std;
28
29namespace owl {
30
31static const tchar szNO[] = _T("no");
32static const tchar szOFF[] = _T("off");
33static const tchar szZERO[] = _T("0");
34static const tchar szFALSE[] = _T("false");
35static const tchar szYES[] = _T("yes");
36static const tchar szON[] = _T("on");
37static const tchar szONE[] = _T("1");
38static const tchar szTRUE[] = _T("true");
39//static const tchar szDef[] = _T("!)@(#*$&%^");
40static const tchar szSep[] = _T("\\");
41
43
44////////////////////////////////////////////////////////////////////////////
45// This static method is used for parsing strings.
46//
47static LPTSTR skip_ws(LPTSTR sz)
48{
50 while (*sz == _T(' ') || *sz == _T('\t'))
51 ++sz;
52
53 return sz;
54}
55
56////////////////////////////////////////////////////////////////////////////
57/// This static method is used for parsing strings.
58//
59static LPTSTR skipPrefix (LPTSTR sz, tchar ch)
60{
62 sz = skip_ws(sz);
63
64 if (_totupper(*sz) == ch){
65 ++sz;
66 sz = skip_ws(sz);
67 if (*sz == _T('='))
68 sz = skip_ws(sz+1);
69 }
70 return sz;
71}
72
73//
74/// This static method converts a string to a bool, accepting most common
75/// boolean keywords: yes, on, true and 1.
76//
78{
80 if ((_tcsicmp(str,szNO)==0) ||
81 (_tcsicmp(str,szOFF)==0) ||
82 (_tcsicmp(str,szZERO)==0) ||
83 (_tcsicmp(str,szFALSE)==0)
84 ){
85 *pVal = false;
86 return true;
87 }
88 if ((_tcsicmp(str,szYES)==0) ||
89 (_tcsicmp(str,szON)==0) ||
90 (_tcsicmp(str,szONE)==0) ||
91 (_tcsicmp(str,szTRUE)==0)
92 ){
93 *pVal = true;
94 return true;
95 }
96 return false;
97}
98
99////////////////////////////////////////////////////////////////////////////
100/// This static method returns yes or no given a boolean value.
101//
103{
104 return tstring(b ? szYES : szNO);
105}
106//
107/// where string is integer????
109{
110 return _istdigit(c)||(_T('a')<=c && c<=_T('f'))||(_T('A')<=c && c<=_T('F'));
111}
112//
113// check if all string is digits
114//
116{
118 tchar* p = text;
119 tchar* ep;
120
121 // skip leading wa=hite spaces
122 p = skip_ws(p);
123 ep= p + ::_tcslen(p) - 1;
124 // skip trailing whitespaces
125 while(*ep && (*ep == _T('\t') || *ep == _T(' ')))
126 *ep-- = _T('\0');
127
128 while(*p && *p != _T('\n')){
129 if(!is_digit(*p))
130 return false;
131 p++;
132 }
133 return true;
134}
135//
136static LPTSTR next_name(LPTSTR p)
137{
138 PRECONDITION(p);
139 while(*p != _T('\0'))
140 p++;
141 return ++p;
142}
143//
145{
147
150
151 int sect_size = 4096;
152 int size;
153 do{
155 size = file.ReadSections(sections, sect_size);
156 sect_size += 1024;
157 }
158 while(size >= (sect_size-2));
159
160 // while sections not '\0'
161 while(*sections){
162 sect_size = 4096;
163 do{
165 size = file.ReadSection(sections, entries, sect_size);
166 sect_size += 1024;
167 }
168 while(size >= (sect_size-2));
169
170 //2. Read all values
171 while(*entries){
172 //?? where difference between int and text entries????
173 int size = file.ReadString(sections,entries,text,MAX_PATH,_T(""));
174 // if size ==0 or strlen == 0 -> error
175 if(!size || !::_tcslen(text) || is_integer(text)){
176 size = file.ReadInteger(sections,entries, INT_MAX);
177 if(size < INT_MAX)
179 }
180 else
182
183 //get next entry name
184 entries = next_name(entries);
185 }
186 //get next section
187 sections = next_name(sections);
188 }
189}
190//
191/// This method reads binary data.
192//
194{
198
199 if (!ReadString(section, entry, text, bufSize * 3 + 1, _T("")))
200 return false;
201
202 if(!::_tcslen(text))
203 return false;
204
205 uint8* data = (uint8*)buffer;
206 for (uint i = 0; i < bufSize; i++) {
207 int n; // string in form 'XX '
208 if(_stscanf(text, _T("%2x"), &n) == EOF)
209 return true;
210 *data++ = (uint8)n;
211
212 text += 3;
213 }
214 return true;
215}
216//
217/// This method writes binary data.
218//
220{
223
225 uint8* data = (uint8*)buffer;
226
227 for (uint i = 0; i < bufSize; i++) {
228 _stprintf(text, _T("%02X "), (int)*data++);
229 text += 3;
230 }
232}
233//
234/// This method reads an integer.
235//
237{
239
240 tchar text [20];
241 LPTSTR end;
242
243 if (!ReadString(section, entry, text, COUNTOF(text), _T("")))
244 return defval;
245
246 int retval = (int)_tcstol(text, &end, 10);
247
248 if (*end)
249 return retval;
250
251 return retval;
252}
253
254//
255/// This method writes an integer. We format it as a string.
256//
258{
260 tchar text [20];
261
262#if defined __GNUC__
263 #if defined UNICODE
264 snwprintf(text, 20, _T("%d"), value);
265 #else
266 snprintf(text, 20, "%d", value);
267 #endif
268#else
269 _ltot (value, text, 10);
270#endif
271
272
273
274 return WriteString(section, entry, text);
275}
276
277//
278//
279//
281{
284 int sect_size = 4096;
285 int size;
286
287 do{
289 size = ReadSection(section.c_str(),sections, sect_size);
290 sect_size += 1024;
291 }
292 while(size >= (sect_size-2));
294 return size;
295}
296//
297//
298//
300{
303 int sect_size = 4096;
304 int size;
305
306 do{
309 sect_size += 1024;
310 }
311 while(size >= (sect_size-2));
313 return size;
314}
315//
316/// String-aware overload.
317//
319{
320 auto result = tstring(MAX_PATH, _T('\0')); // String length; space for an additional null-terminator is guarantied (since C++11).
321 const auto resultSize = static_cast<uint>(result.size() + 1); // Size in character count, including null-terminator.
322 const auto p = const_cast<LPTSTR>(result.data()); // Workaround for pre-C++17 compilers.
323 const auto n = ReadString(section.c_str(), entry.c_str(), p, resultSize, defstr);
324 result.resize(n);
325 result.shrink_to_fit();
326 swap(buffer, result);
327 return n;
328}
329
330//
331//
332//
334{
336 double retval = defval;
337 tchar* end;
338 tchar text[80];
339
341
342 if (::_tcslen(text)){
343 retval = _tcstod(text, &end);
344
345 if(*end)
346 retval = defval;
347 }
348 return retval;
349}
350
351//
352/// This method writes an integer.
353//
355{
357 tchar text [80];
358
359 //
360 // We request a formatted number with a LOT of significant digits:
361 //
362 if(DefaultPrecision < 0)
363 _stprintf(text, _T("%1.20Lg"), (long double)val);
364 else{
365 if(DefaultPrecision==0)
366 _stprintf(text, _T("%Lg"), (long double)val);
367 else{
368 tstring format = _T("%1.");
369#if defined __GNUC__
370 #if defined UNICODE
371 snwprintf(text, 10, _T("%d"), DefaultPrecision);
372 #else
373 snprintf(text, 10, "%d", DefaultPrecision);
374 #endif
375 format += text;
376#else
378#endif
379 format += _T("Lg");
380 _stprintf(text, format.c_str(), (long double)val);
381 }
382 }
383 return WriteString(section, entry, text);
384}
385//
386/// This method reads a boolean value.
387//
389{
391 tchar text[20];
393
394 bool bVal;
395
396 if (::_tcslen(text)){
397 bool b = StringToBool(text, &bVal);
398
399 if (b)
400 return bVal;
401 }
402
403 return defval;
404}
405//
406/// This method writes a bool.
407//
413//
414//
415//
417{
421 if(text.length() > 0)
422 {
424 value = TDate((const tistream&)strtemp);
425 return true;
426 }
427 return false;
428}
429//
430//
431//
441//
442//
443//
445{
447 tchar text[80];
449 if(::_tcslen(text)){
450 SYSTEMTIME dt;
451 _stscanf(text,_T("%hu,%hu,%hu,%hu,%hu,%hu,%hu,%hu"),&dt.wYear,&dt.wMonth,&dt.wDayOfWeek,
452 &dt.wDay,&dt.wHour,&dt.wMinute,&dt.wSecond,&dt.wMilliseconds);
453 val = TSystemTime(dt);
454 return true;
455 }
456 return false;
457}
458//
459//
460//
462{
464 tchar text[80];
465 wsprintf(text,_T("%hu,%hu,%hu,%hu,%hu,%hu,%hu,%hu"),dt.wYear,dt.wMonth,dt.wDayOfWeek,
466 dt.wDay,dt.wHour,dt.wMinute,dt.wSecond,dt.wMilliseconds);
467 return WriteString(section, entry, text);
468}
469//
470//
471//
473{
475 tchar text[80];
477 if(::_tcslen(text)){
478 int h,m,s;
479 _stscanf(text,_T("h=%d m=%d s=%d"), &h, &m, &s);
480 val = TTime(h,m,s);
481 return true;
482 }
483 return false;
484}
485//
486//
487//
489{
491 tchar text[80];
492 wsprintf(text,_T("h=%d m=%d s=%d"),val.Hour(),val.Minute(),val.Second());
493 return WriteString(section, entry, text);
494}
495//
496//
497/// This method will take a profile string of the form:
498/// \code
499/// +---------------- lfHeight
500/// | +------------- lfWidth
501/// | | /lfWeight
502/// | | +------- / lfItalic
503/// | | | \ lfUnderline
504/// | | | \lfStrikeOut
505/// | | | +----- lfEscapement
506/// | | | | +-- lfOrientation
507/// | | | | |
508/// v v v v v
509/// 10, 8, BIU, 0, 0, 0, 0, 0, 0, 0, Times New Roman
510/// ^ ^ ^ ^ ^ ^
511/// | | | | | |
512/// lfCharSet -+ | | | | |
513/// lfOutPrecision ----+ | | | |
514/// lfClipPrecision -------+ | | |
515/// lfQuality ----------+ | |
516/// lfPitchAndFamily -------------+ |
517/// lfFaceName ----------------+
518/// \endcode
519/// and fills in a logfont structure.
520//
522{
526
527 if(!::_tcslen(text))
528 return false;
529
530 LPCTSTR szSep = _T(", \t");
531 bool b;
532 tchar* sz;
533 LOGFONT lf;
534 int i, n;
535
536 _tcscat(text,_T("\n"));
537 sz = _tcstok(text, szSep);
538 n = 0;
539 while (sz){
540 i = _ttoi(sz); // not needed all the time, but oh wel...
541
542 switch (n++){
543 // int lfHeight;
544 case 0:
545 lf.lfHeight = i;
546 break;
547
548 // int lfWidth;
549 case 1:
550 lf.lfWidth = i;
551 break;
552
553 // int lfWeight;
554 // BYTE lfItalic;
555 // BYTE lfUnderline;
556 // BYTE lfStrikeOut;
557 case 2:
558 lf.lfWeight = FW_NORMAL;
559 lf.lfItalic = FALSE;
560 lf.lfUnderline = FALSE;
561 lf.lfStrikeOut = FALSE;
562
563 if (_tcschr(sz, _T('B')))
564 lf.lfWeight = FW_BOLD;
565 if (_tcschr(sz, _T('I')))
566 lf.lfItalic = TRUE;
567 if (_tcschr(sz, _T('U')))
568 lf.lfUnderline = TRUE;
569 if (_tcschr(sz, _T('S')))
570 lf.lfStrikeOut = TRUE;
571 break;
572
573 // int lfEscapement;
574 case 3:
575 lf.lfEscapement = i;
576 break;
577
578 // int lfOrientation;
579 case 4:
580 lf.lfOrientation = i;
581 break;
582
583 // BYTE lfCharSet;
584 case 5:
585 lf.lfCharSet = uint8(i);
586 break;
587
588 // BYTE lfOutPrecision;
589 case 6:
590 lf.lfOutPrecision = uint8(i);
591 break;
592
593 // BYTE lfClipPrecision;
594 case 7:
595 lf.lfClipPrecision = uint8(i);
596 break;
597
598 // BYTE lfQuality;
599 case 8:
600 lf.lfQuality = uint8(i);
601 break;
602
603 // BYTE lfPitchAndFamily;
604 case 9:
605 lf.lfPitchAndFamily = uint8(i);
606 break;
607
608 // BYTE lfFaceName[LF_FACESIZE];
609 case 10:
610 ::_tcscpy(lf.lfFaceName, sz);
611 break;
612 }
613
614 if (n==10)
615 sz = _tcstok(0, _T("\n"));
616 else
617 sz = _tcstok(0, szSep);
618 }
619 b = (n == 11);
620
621 if(b)
622 pFont = lf;
623
624 return b;
625}
626
627//
628//
629/// This method writes a font description in the following format:
630/// \code
631/// +---------------- lfHeight
632/// | +------------- lfWidth
633/// | | /lfWeight
634/// | | +------- / lfItalic
635/// | | | \ lfUnderline
636/// | | | \lfStrikeOut
637/// | | | +----- lfEscapement
638/// | | | | +-- lfOrientation
639/// | | | | |
640/// v v v v v
641/// 10, 8, BIU, 0, 0, 0, 0, 0, 0, 0, Times New Roman
642/// ^ ^ ^ ^ ^ ^
643/// | | | | | |
644/// lfCharSet -+ | | | | |
645/// lfOutPrecision ----+ | | | |
646/// lfClipPrecision -------+ | | |
647/// lfQuality ----------+ | |
648/// lfPitchAndFamily -------------+ |
649/// lfFaceName ----------------+
650/// \endcode
652{
654 tstring s;
655 tchar ach [40];
656 int i;
657 tchar comma[] = _T(",");
658
659#if defined __GNUC__
660 _tprintf(ach, _T("%d"), logFont.lfHeight);
661 s = ach;
662#else
663 s = _itot(logFont.lfHeight, ach, 10);
664#endif
665 s += comma;
666#if defined __GNUC__
667 _tprintf(ach, _T("%d"), logFont.lfWidth);
668 s += ach;
669#else
670 s += _itot(logFont.lfWidth, ach, 10);
671#endif
672 s += comma;
673
674 i = 0;
675 ach[i++] = (logFont.lfWeight < FW_BOLD) ? _T('N') : _T('B');
676 if (logFont.lfItalic)
677 ach[i++] = _T('I');
678 if (logFont.lfUnderline)
679 ach[i++] = _T('U');
680 if (logFont.lfStrikeOut)
681 ach[i++] = _T('S');
682 ach[i] = 0;
683 s += ach;
684 s += comma;
685
686#if defined __GNUC__
687 _tprintf(ach, _T("%d"), logFont.lfEscapement);
688 s += ach;
689#else
690 s += _itot(logFont.lfEscapement, ach, 10);
691#endif
692 s += comma;
693#if defined __GNUC__
694 _tprintf(ach, _T("%d"), logFont.lfOrientation);
695 s += ach;
696#else
697 s += _itot(logFont.lfOrientation, ach, 10);
698#endif
699 s += comma;
700#if defined __GNUC__
701 _tprintf(ach, _T("%d"), logFont.lfCharSet);
702 s += ach;
703#else
704 s += _itot(logFont.lfCharSet, ach, 10);
705#endif
706 s += comma;
707#if defined __GNUC__
708 _tprintf(ach, _T("%d"), logFont.lfOutPrecision);
709 s += ach;
710#else
711 s += _itot(logFont.lfOutPrecision, ach, 10);
712#endif
713 s += comma;
714#if defined __GNUC__
715 _tprintf(ach, _T("%d"), logFont.lfClipPrecision);
716 s += ach;
717#else
718 s += _itot(logFont.lfClipPrecision, ach, 10);
719#endif
720 s += comma;
721#if defined __GNUC__
722 _tprintf(ach, _T("%d"), logFont.lfQuality);
723 s += ach;
724#else
725 s += _itot(logFont.lfQuality, ach, 10);
726#endif
727 s += comma;
728#if defined __GNUC__
729 _tprintf(ach, _T("%d"), logFont.lfPitchAndFamily);
730 s += ach;
731#else
732 s += _itot(logFont.lfPitchAndFamily, ach, 10);
733#endif
734 s += comma;
735 s += logFont.lfFaceName;
736
737 return WriteString(section, entry, s.c_str());
738}
739//
740/// This method reads an RGB color.
741//
743{
745 tchar text[40];
747
748 if(!::_tcslen(text))
749 return false;
750
751 TColor clr;
752 tchar* sz[3];
753 bool b;
754
755 b = false;
756
757 sz[0] = text;
758 sz[1] = _tcschr(sz[0], _T(','));
759 if(sz[1]){
760 *(sz[1]++) = 0;
761 sz[2] = _tcschr(sz[1], _T(','));
762 if (sz[2]){
763 *(sz[2]++) = 0;
764
765 int R = _ttoi(skipPrefix(sz[0], _T('R')));
766 int G = _ttoi(skipPrefix(sz[1], _T('G')));
767 int B = _ttoi(skipPrefix(sz[2], _T('B')));
768
769 if (R >= 0 && R < 256 &&
770 G >= 0 && G < 256 &&
771 B >= 0 && B < 256){
772 clr = RGB(R,G,B);
773 b = true;
774 }
775 }
776 }
777 if(b)
778 color = clr;
779 return b;
780}
781//
782/// This method writes an RGB color
783//
785{
787 tchar ach[40];
788
789 wsprintf (ach, _T("R=%d,G=%d,B=%d"), clr.Red(), clr.Green(), clr.Blue());
790
791 return WriteString(section, entry, ach);
792}
793//
794/// This method reads a TPoint.
795//
797{
801 int x, y;
802 const auto r = _stscanf_s(text.c_str(), _T("X=%d,Y=%d"), &x, &y);
803 if (r != 2) return false;
804 point = {x, y};
805 return true;
806}
807//
808/// This method writes a TPoint.
809//
811{
813 tchar buf[20];
814
815 wsprintf(buf, _T("X=%d,Y=%d"), point.x, point.y);
816
817 return WriteString(section, entry, buf);
818}
819//
820/// This method reads a TRect.
821//
823{
827 int l, t, w, h;
828 const auto r = _stscanf_s(text.c_str(), _T("L=%d,T=%d,W=%d,H=%d"), &l, &t, &w, &h);
829 if (r != 4) return false;
830 rect = {{l, t}, TSize{w, h}};
831 return true;
832}
833//
834/// This method writes a TRect.
835//
837{
839 tchar buf[40];
840
841 wsprintf(buf, _T("L=%d,T=%d,W=%d,H=%d"), r.left, r.top, r.Width(), r.Height());
842
843 return WriteString(section, entry, buf);
844}
845//
846/// This method reads a TSize.
847//
849{
853 int w, h;
854 const auto r = _stscanf_s(text.c_str(), _T("W=%d,H=%d"), &w, &h);
855 if (r != 2) return false;
856 size = {w, h};
857 return true;
858}
859//
860/// This method writes a TSize.
861//
863{
865 tchar buf[80];
866
867 wsprintf(buf, _T("W=%d,H=%d"), size.cx, size.cy);
868
869 return WriteString(section, entry, buf);
870}
871//
873{
875 tchar buff[3];
876 return ReadSection(section, buff, 3) != 0;
877}
878///////////////////////////////////////////////////////////////////////////////////////
879//
880// class TIniConfigFile
881// ~~~~~ ~~~~~~~~~~~~~~
882//
888//
894//
895/// This method deletes the specified section.
896//
898{
900 return ::WritePrivateProfileString(section, 0, 0, FileName.c_str()) != 0;
901}
902//
903//
904//
905/// This method deletes the specified entry.
906//
908{
910 return ::WritePrivateProfileString (section, entry, 0, FileName.c_str()) != 0;
911}
912//
913//
914//
919//
920/// This method is the base method for reading strings.
921///
922/// \return The number of characters written to the output buffer (excluding the null-terminator, which is also written).
923///
924/// \note If the buffer is too small to hold the whole string, the string is truncated to (bufSize - 1) characters and
925/// null-terminated.
926//
929{
931 return ::GetPrivateProfileString (section, entry, def?def:_T(""), buffer, bufSize, FileName.c_str());
932}
933//
934/// This method is the low-level method for writing strings.
935//
937{
939 return ::WritePrivateProfileString (section, entry, value, FileName.c_str()) != 0;
940}
941//
942/// This method reads binary data.
943//
945{
947 return ::GetPrivateProfileStruct(section, entry, buffer, bufSize, FileName.c_str()) != 0;
948}
949//
950/// This method writes binary data.
951//
953{
955 return ::WritePrivateProfileStruct(section, entry, buffer, bufSize, FileName.c_str()) != 0;
956}
957//////////////////////////////////////////////////////////////////////////////////////////////////
958//
959/// Container support
960//
961class TStringMapNode: public TMapNode<tstring,tstring> {
962public:
963 TStringMapNode(const tstring& str, const tstring& val)
964 : TMapNode<tstring,tstring>() {Name = str; Value = val;}
965
966 TStringMapNode(const tstring& str)
967 : TMapNode<tstring,tstring>() {Name = str;}
968};
969//
971//
972class TStringNode: public TMapNode<tstring,TStringMap> {
973 public:
974 TStringNode(const tstring& str)
976};
977//
978class TMemConfigFileSections: public TIPtrArray<TStringNode*> {
979 public:
980 TMemConfigFileSections(){}
981 ~TMemConfigFileSections(){}
982
983 bool DestroyItem(TStringNode* item);
984 bool Destroy(int loc);
985 int Add(TStringNode* item);
986 bool HasMember(TStringNode* item) const;
987 int Find(TStringNode* item) const;
988};
989//
990bool TMemConfigFileSections::HasMember(TStringNode* item) const
991{
992 return Find(item) != NPOS;
993}
994//
995bool TMemConfigFileSections::DestroyItem(TStringNode* item)
996{
997 const auto index = Find(item);
998 if (index != NPOS)
999 {
1000 TStringNode* item = Data[index];
1001 Remove(index);
1002 delete item;// using global delete because we didn't allocate it
1003 return true;
1004 }
1005 return false;
1006}
1007//
1008bool TMemConfigFileSections::Destroy(int loc)
1009{
1010 if(loc < (int)Size()){
1011 TStringNode* item = Data[loc];
1012 Remove(loc);
1013 delete item;// using global delete because we didn't allocate it
1014 return true;
1015 }
1016 return false;
1017}
1018//
1019int TMemConfigFileSections::Add(TStringNode* item)
1020{
1021 if(ItemCnt>=Reserved)
1022 Resize(ItemCnt+1); // on error -> throw xalloc
1023 unsigned loc = ItemCnt++;
1024 while( loc > 0 && *item < *Data[loc-1]) {
1025 Data[loc] = Data[loc-1];
1026 loc--;
1027 }
1028 Data[loc] = item;
1029 return loc;
1030}
1031//
1032int TMemConfigFileSections::Find(TStringNode* item) const
1033{
1034 auto lower = 0;
1035 auto upper = static_cast<int>(Size()) - 1;
1036 while (lower <= upper)
1037 {
1038 const auto middle = (lower + upper) / 2;
1039 if (*Data[middle] == *item)
1040 return middle;
1041 if (*Data[middle] < *item)
1042 lower = middle + 1;
1043 else
1044 upper = middle - 1;
1045 }
1046 return NPOS;
1047}
1048///////////////////////////////////////////////////////////////////////
1049//
1050// class TMemConfigFile
1051// ~~~~~ ~~~~~~~~~~~~~~
1053:
1055{
1056 Sections = new TMemConfigFileSections();
1057}
1058//
1060{
1061 Flush();
1062 delete Sections;
1063}
1064//
1066{
1067 Sections->Flush();
1068}
1069//
1075//
1076int TMemConfigFile::AddSection(const tstring& section)
1077{
1078 return Sections->Add(new TStringNode(section));
1079}
1080//
1082{
1084 TStringNode sn(section);
1085 const auto index = Sections->Find(&sn);
1086 if (index != Sections->NPOS)
1087 {
1088 return (*Sections)[index]->Value.DestroyItem(TStringMapNode(entry));
1089 }
1090 return false;
1091}
1092//
1094{
1096 TStringNode sn(section);
1097 return Sections->DestroyItem(&sn);
1098}
1099
1100//
1101/// Copies all value names of the given section to the specified buffer.
1102/// Each string is null-terminated, and the buffer is then terminated with a trailing null.
1103/// Returns the number of characters written, excluding the trailing null-terminators.
1104/// If the buffer is too small, the last string copied to the buffer may be truncated.
1105//
1107{
1109 tchar* p = buffer;
1110 *p = _T('\0'); // Ensure the buffer is terminated, if we exit early.
1111 TStringNode sn(section);
1112 const auto k = Sections->Find(&sn);
1113 if (k == Sections->NPOS) return 0;
1114 const TStringMap& map = (*Sections)[k]->Value;
1115 if (map.Empty()) return 0;
1116 for (uint i = 0; i != map.Size(); ++i)
1117 {
1118 const tstring& s = map[i].Name;
1119 size_t m = static_cast<size_t>(buffer + bufSize - 1 - p); // space left
1120 if (m == 0) break; // We've run out of space.
1121 size_t n = min(s.size(), m - 1);
1122 ::_tcsncpy(p, s.c_str(), n);
1123 p += n;
1124 *p++ = _T('\0');
1125 }
1126
1127 // Add buffer terminator.
1128 //
1129 *p++ = _T('\0');
1130 return static_cast<uint>(p - buffer) - 2; // Exclude trailing nulls in the count.
1131}
1132
1133//
1134/// Copies all section names to the specified buffer.
1135/// Each string is null-terminated, and the buffer is then terminated with a trailing null.
1136/// Returns the number of characters written, excluding the trailing null-terminators.
1137/// If the buffer is too small, the last string copied to the buffer may be truncated.
1138//
1140{
1141 PRECONDITION(buffer && bufSize > 1);
1142 tchar* p = buffer;
1143 *p = _T('\0'); // Ensure the buffer is terminated, if we exit early.
1144 if (Sections->Empty()) return 0;
1145 for (uint i = 0; i != Sections->Size(); ++i)
1146 {
1147 const tstring& s = (*Sections)[i]->Name;
1148 size_t m = static_cast<size_t>(buffer + bufSize - 1 - p); // space left
1149 if (m == 0) break; // We've run out of space.
1150 size_t n = min(s.size(), m - 1);
1151 ::_tcsncpy(p, s.c_str(), n);
1152 p += n;
1153 *p++ = _T('\0');
1154 }
1155
1156 // Add buffer terminator.
1157 //
1158 *p++ = _T('\0');
1159 return static_cast<uint>(p - buffer) - 2; // Exclude trailing nulls in the count.
1160}
1161
1162//
1163/// Looks up the value of the given entry of the given section, and if found, copies it to the given buffer.
1164/// If not found, the given default value `defstr` is copied to the buffer, unless `defstr` is null, in which
1165/// case an empty string is copied to the buffer.
1166///
1167/// \return The number of characters written to the output buffer (excluding the null-terminator, which is also written).
1168///
1169/// \note If the buffer is too small to hold the whole string, the string is truncated to (bufSize - 1) characters and
1170/// null-terminated.
1171//
1173{
1174 PRECONDITION(section && entry && buffer && bufSize > 0);
1175 struct TLocal
1176 {
1177 static LPCTSTR Lookup(const TMemConfigFile& f, LPCTSTR section, LPCTSTR entry, LPCTSTR def)
1178 {
1179 TStringNode sn(section);
1180 const auto i = f.Sections->Find(&sn);
1181 if (i == f.Sections->NPOS) return def;
1182 const TStringMap& map = (*f.Sections)[i]->Value;
1183 const auto j = map.Find(TStringMapNode{entry});
1184 if (j == map.NPOS) return def;
1185 return map[j].Value.c_str();
1186 }
1187 };
1188 LPCTSTR s = TLocal::Lookup(*this, section, entry, defstr ? defstr : _T(""));
1189 size_t n = min(::_tcslen(s), static_cast<size_t>(bufSize - 1));
1190 ::_tcsncpy(buffer, s, n);
1191 buffer[n] = _T('\0');
1192 return static_cast<uint>(n); // Exclude null-terminator in the count.
1193}
1194
1195//
1197{
1199 TStringNode sn(section);
1200 auto index = Sections->Find(&sn);
1201 if (index == Sections->NPOS)
1202 index = AddSection(section);
1203 TStringMap& map = (*Sections)[index]->Value;
1204 index = map.Find(TStringMapNode(entry));
1205 if (index != map.NPOS)
1206 map[index].Value = tstring(value);
1207 else
1208 index = map.Add(TStringMapNode(entry,value));
1209 return index != map.NPOS;
1210}
1211//
1213{
1215 if(!file.IsOpen())
1216 return;
1217
1219 for(uint section = 0; section < Sections->Size(); section++){
1220 // Section name
1221 file << _T("[") << (*Sections)[section]->Name.c_str() << _T("]") << _T("\r\n");
1222
1223 TStringMap& map = (*Sections)[section]->Value;
1224 for(uint value = 0; value < map.Size(); value++)
1225 file << map[value].Name.c_str() << _T("=") << map[value].Value.c_str() << _T("\r\n");
1226 }
1227}
1228//
1229//
1230//
1231static LPTSTR getName(tstring& name,LPTSTR p)
1232{
1233 PRECONDITION(p);
1234 while(!_istalpha(*p))
1235 p++;
1236 tchar* p1 = p++;
1237 while(_istalpha(*p))
1238 p++;
1239
1240 tchar c = *p;
1241 *p = _T('\0');
1242
1243 name = p1;
1244 *p = c;
1245 return p;
1246}
1247//
1248static void getValue(tstring& name,LPTSTR p)
1249{
1250 PRECONDITION(p);
1251 while(*p && (*p==_T(' ') || *p ==_T('\t')) && *p != _T('='))
1252 p++;
1253 name = ++p;
1254}
1255//
1256//
1257//
1259{
1260 TTextFile file(FileName.c_str());
1261 if(!file.IsOpen())
1262 return;
1263
1264 Sections->Flush();
1266 int sec_index = -1;
1268
1269 while(fitr){
1270 LPTSTR p = skip_ws((LPTSTR)(LPCTSTR)fitr);
1271 if(::_tcslen(p) && *p != _T(';')){
1272 // read section
1273 if(*p == _T('[')){
1274 getName(tmp_name1,p);
1275 sec_index = AddSection(tmp_name1.c_str());
1276 }
1277 // else read value
1278 else if(sec_index >= 0){
1279 p = getName(tmp_name1,p);
1280 getValue(tmp_name2,p);
1281 (*Sections)[sec_index]->Value.Add(TStringMapNode(tmp_name1,tmp_name2));
1282 }
1283 }
1284 ++fitr;
1285 }
1286}
1287//
1288
1289//
1290/// \class TRegConfigFile
1291// ~~~~~ ~~~~~~~~~~~~~~
1292/// This source file implements TRegConfigFile. This class is derived from
1293/// TConfigFile and overrides the low-level storage methods to vector them
1294/// to the registry.
1295//
1296/// TRegConfigFile is not intended to handle all of an app's registry needs,
1297/// but rather to be used for a convenient wrapper for app preference
1298/// settings. All data is stored in HKEY_CURRENT_USER, using FileName like
1299/// so:
1300/// \code
1301/// HKEY_CURRENT_USER\Software\"FileName"\...
1302/// \endcode
1303/// FileName should contain the company name and product name to adhere to
1304/// standard registry practices. Eg:
1305/// \code
1306/// FileName = "My Company\\Product"
1307/// HKEY_CURRENT_USER\Software\My Company\Product\...
1308/// \endcode
1309/// A version number can also be used to allow multiple versions of the
1310/// same product to live together:
1311/// \code
1312/// mFile = "My Company\\Product\\V1.0"
1313/// HKEY_CURRENT_USER\Software\My Company\Product\V1.0\...
1314/// \endcode
1315/// \note FileName must not end with a backslash!
1316///
1317/// All sections are created under the subtree as described above. Eg,
1318/// \code
1319/// Section = "Options"
1320/// HKEY_CURRENT_USER\Software\My Company\Product\V1.0\Options
1321/// \endcode
1322/// Entries are stored under sections as REG_SZ values (for numbers it is REG_DWORD). Eg,
1323/// \code
1324/// entry = "Tile"
1325/// HKEY_CURRENT_USER\Software\My Company\Product\V1.0\Options\Tile
1326/// \endcode
1327//
1329 : TConfigFile{_T("Software\\") + name}, Root{root}
1330{}
1331
1332//
1336//
1338{
1340 return Root.HasSubkey(FileName + szSep + section);
1341}
1342
1343//
1344/// Copies all value names of the given section to the specified buffer.
1345/// Each string is null-terminated, and the buffer is then terminated with a trailing null.
1346/// Returns the number of characters written, excluding the trailing null-terminators.
1347/// If the buffer is too small, the last string copied to the buffer may be truncated.
1348//
1350{
1352 tchar* p = buffer;
1353 *p = _T('\0'); // Ensure the buffer is terminated, if we exit early.
1354 TRegKey root(Root, FileName + szSep + section);
1356 if (!i) return 0;
1357 for (; i; ++i)
1358 {
1359 TRegValue v(i);
1360 LPCTSTR s = v.GetName();
1361 size_t m = static_cast<size_t>(buffer + bufSize - 1 - p); // space left
1362 if (m == 0) break; // We've run out of space.
1363 size_t n = min(::_tcslen(s), m - 1);
1364 ::_tcsncpy(p, s, n);
1365 p += n;
1366 *p++ = _T('\0');
1367 }
1368
1369 // Add buffer terminator.
1370 //
1371 *p++ = _T('\0');
1372 return static_cast<uint>(p - buffer) - 2; // Exclude trailing nulls in the count.
1373}
1374
1375//
1376/// Copies all section names to the specified buffer.
1377/// Each string is null-terminated, and the buffer is then terminated with a trailing null.
1378/// Returns the number of characters written, excluding the trailing null-terminators.
1379/// If the buffer is too small, the last string copied to the buffer may be truncated.
1380//
1382{
1383 PRECONDITION(buffer && bufSize > 1);
1384 tchar* p = buffer;
1385 *p = _T('\0'); // Ensure the buffer is terminated, if we exit early.
1388 if (!i) return 0;
1389 for (; i; ++i)
1390 {
1391 TRegKey k(i);
1392 LPCTSTR s = k.GetName();
1393 size_t m = static_cast<size_t>(buffer + bufSize - 1 - p); // space left
1394 if (m == 0) break; // We've run out of space.
1395 size_t n = min(::_tcslen(s), m - 1);
1396 ::_tcsncpy(p, s, n);
1397 p += n;
1398 *p++ = _T('\0');
1399 }
1400
1401 // Add buffer terminator.
1402 //
1403 *p++ = _T('\0');
1404 return static_cast<uint>(p - buffer) - 2; // Exclude trailing nulls in the count.
1405}
1406
1407//
1413//
1415{
1417 return TRegKey{Root, FileName + szSep + section}.DeleteValue(entry) == ERROR_SUCCESS;
1418}
1419//
1421{
1422 // don't need this currently
1423}
1424//
1426{
1428 const auto k = Root.GetSubkey(FileName + szSep + section);
1429 return k ? static_cast<int>(k->GetValueOrDefault<uint32>(entry, defint)) : defint;
1430}
1431//
1433{
1435 const auto k = TRegKey{Root, FileName + szSep + section};
1436 return k.SetValue(entry, static_cast<uint32>(value)) == ERROR_SUCCESS;
1437}
1438
1439//
1440/// Looks up the value of the given entry of the given section, and if found, copies it to the given buffer.
1441/// If not found, the given default value `defstr` is copied to the buffer, unless `defstr` is null, in which case an empty
1442/// string is copied to the buffer.
1443///
1444/// \return The number of characters written to the output buffer (excluding the null-terminator, which is also written).
1445/// If an error occurs, e.g. registry access is denied, a TXRegistry exception is thrown.
1446///
1447/// \note If the buffer is too small to hold the whole string, the string is truncated to (bufSize - 1) characters and
1448/// null-terminated.
1449//
1451{
1452 PRECONDITION(section && entry && buffer && bufSize > 0);
1453 const auto k = Root.GetSubkey(FileName + szSep + section);
1454 const auto d = defstr ? defstr : tstring{};
1455 const auto s = k ? k->GetValueOrDefault(entry, d) : d;
1456 const auto n = min(static_cast<uint>(s.size()), bufSize - 1);
1457 const auto e = copy_n(s.begin(), n, buffer);
1458 *e = _T('\0');
1459 return n;
1460}
1461
1462//
1464{
1466 const auto k = TRegKey{Root, FileName + szSep + section};
1467 return k.SetValue(entry, value) == ERROR_SUCCESS;
1468}
1469
1470//
1471/// This method reads binary data.
1472//
1474{
1475 PRECONDITION(section && entry && buffer && bufSize > 0);
1476 const auto k = Root.GetSubkey(FileName + szSep + section);
1477 if (!k) return false;
1478 auto size = uint32{bufSize};
1479 auto type = uint32{};
1480 return k->QueryValue(entry, &type, reinterpret_cast<uint8*>(buffer), &size) == ERROR_SUCCESS;
1481}
1482//
1483/// This method writes binary data.
1484//
1486{
1488 const auto k = TRegKey{Root, FileName + szSep + section};
1489 return k.SetValue(entry, REG_BINARY, reinterpret_cast<const uint8*>(buffer), bufSize) == ERROR_SUCCESS;
1490}
1491//
1492} // OWL namespace
1493//============================================================================================
#define PRECONDITION(condition)
Definition checks.h:227
uint Size() const
Definition template.h:672
bool Empty() const
Definition template.h:674
static const int NPOS
Definition template.h:682
Class wrapper for management of color values.
Definition color.h:245
Save/Load configuration parameters Base abstract class.
Definition configfl.h:48
virtual bool WriteData(LPCTSTR section, LPCTSTR entry, void *buffer, uint size)
This method writes binary data.
Definition configfl.cpp:219
static int DefaultPrecision
Definition configfl.h:154
bool ReadTime(LPCTSTR section, LPCTSTR entry, TTime &val) const
Definition configfl.cpp:472
bool ReadColor(LPCTSTR section, LPCTSTR entry, TColor &color) const
This method reads an RGB color.
Definition configfl.cpp:742
double ReadDouble(LPCTSTR section, LPCTSTR entry, double defval=0.0) const
Definition configfl.cpp:333
virtual bool WriteInteger(LPCTSTR section, LPCTSTR entry, int value)
This method writes an integer. We format it as a string.
Definition configfl.cpp:257
bool WriteRect(LPCTSTR section, LPCTSTR entry, const TRect &rc)
This method writes a TRect.
Definition configfl.cpp:836
bool ReadDate(LPCTSTR section, LPCTSTR entry, TDate &value) const
Definition configfl.cpp:416
virtual bool SectionExists(LPCTSTR section) const
Definition configfl.cpp:872
bool WriteFont(LPCTSTR section, LPCTSTR entry, const LOGFONT &font)
This method writes a font description in the following format:
Definition configfl.cpp:651
bool WriteColor(LPCTSTR section, LPCTSTR entry, const TColor &clr)
This method writes an RGB color.
Definition configfl.cpp:784
bool ReadPoint(LPCTSTR section, LPCTSTR entry, TPoint &val) const
This method reads a TPoint.
Definition configfl.cpp:796
bool WriteDouble(LPCTSTR section, LPCTSTR entry, double value)
This method writes an integer.
Definition configfl.cpp:354
virtual void LoadValues(const TConfigFile &file)
Definition configfl.cpp:144
virtual uint ReadSections(TCHAR *sections, uint bufSize) const =0
bool WriteTime(LPCTSTR section, LPCTSTR entry, TTime &val)
Definition configfl.cpp:488
bool WriteDate(LPCTSTR section, LPCTSTR entry, const TDate &val)
Definition configfl.cpp:432
bool WriteSystemTime(LPCTSTR section, LPCTSTR entry, const TSystemTime &val)
Definition configfl.cpp:461
bool ReadSize(LPCTSTR section, LPCTSTR entry, TSize &sz) const
This method reads a TSize.
Definition configfl.cpp:848
bool ReadBool(LPCTSTR section, LPCTSTR entry, bool defval=false) const
This method reads a boolean value.
Definition configfl.cpp:388
bool ReadRect(LPCTSTR section, LPCTSTR entry, TRect &val) const
This method reads a TRect.
Definition configfl.cpp:822
tstring FileName
Definition configfl.h:153
bool WritePoint(LPCTSTR section, LPCTSTR entry, const TPoint &point)
This method writes a TPoint.
Definition configfl.cpp:810
virtual uint ReadSection(LPCTSTR section, TCHAR *buffer, uint bufSize) const =0
virtual int ReadInteger(LPCTSTR section, LPCTSTR entry, int defint=0) const
This method reads an integer.
Definition configfl.cpp:236
static tstring BoolToString(bool val)
This static method returns yes or no given a boolean value.
Definition configfl.cpp:102
bool WriteSize(LPCTSTR section, LPCTSTR entry, const TSize &size)
This method writes a TSize.
Definition configfl.cpp:862
bool ReadFont(LPCTSTR section, LPCTSTR entry, LOGFONT &font) const
This method will take a profile string of the form:
Definition configfl.cpp:521
virtual bool ReadData(LPCTSTR section, LPCTSTR entry, void *buffer, uint size) const
This method reads binary data.
Definition configfl.cpp:193
bool WriteBool(LPCTSTR section, LPCTSTR entry, bool val)
This method writes a bool.
Definition configfl.cpp:408
bool ReadSystemTime(LPCTSTR section, LPCTSTR entry, TSystemTime &val) const
Definition configfl.cpp:444
static bool StringToBool(LPCTSTR str, bool *val)
This static method converts a string to a bool, accepting most common boolean keywords: yes,...
Definition configfl.cpp:77
virtual bool WriteString(LPCTSTR section, LPCTSTR entry, LPCTSTR value)=0
virtual uint ReadString(LPCTSTR section, LPCTSTR entry, TCHAR *buffer, uint bufSize, LPCTSTR defstr=0) const =0
The TDate class represents a date.
Definition date.h:48
static HowToPrint SetPrintOption(HowToPrint h)
Sets the print option for all TDate objects and returns the old setting.
Definition dateio.cpp:39
HowToPrint
Lists different print formats.
Definition date.h:52
@ Numbers
Definition date.h:55
@ WriteOnly
Definition file.h:131
@ CreateAlways
Creates a new file. The function overwrites the file if it exists.
Definition file.h:148
The TFileLineIterator class is used to iterate through a TTextFile file.
Definition file.h:472
void Flush(bool del=true)
Definition template.h:1874
virtual bool ReadData(LPCTSTR section, LPCTSTR entry, void *buffer, uint size) const
This method reads binary data.
Definition configfl.cpp:944
virtual uint ReadSections(TCHAR *buffer, uint bufSize) const
Definition configfl.cpp:889
virtual uint ReadSection(LPCTSTR section, TCHAR *buffer, uint bufSize) const
Definition configfl.cpp:883
virtual bool WriteString(LPCTSTR section, LPCTSTR entry, LPCTSTR value)
This method is the low-level method for writing strings.
Definition configfl.cpp:936
virtual void UpdateFile()
Definition configfl.cpp:915
virtual bool EraseEntry(LPCTSTR section, LPCTSTR entry)
This method deletes the specified entry.
Definition configfl.cpp:907
virtual uint ReadString(LPCTSTR section, LPCTSTR entry, TCHAR *buffer, uint bufSize, LPCTSTR defstr=0) const
This method is the base method for reading strings.
Definition configfl.cpp:927
virtual bool WriteData(LPCTSTR section, LPCTSTR entry, void *buffer, uint size)
This method writes binary data.
Definition configfl.cpp:952
virtual bool EraseSection(LPCTSTR section)
This method deletes the specified section.
Definition configfl.cpp:897
Map node.
Definition template.h:632
virtual uint ReadString(LPCTSTR section, LPCTSTR entry, TCHAR *buffer, uint bufSize, LPCTSTR defstr=0) const
Looks up the value of the given entry of the given section, and if found, copies it to the given buff...
virtual uint ReadSections(TCHAR *buffer, uint bufSize) const
Copies all section names to the specified buffer.
virtual ~TMemConfigFile()
virtual uint ReadSection(LPCTSTR section, TCHAR *buffer, uint bufSize) const
Copies all value names of the given section to the specified buffer.
virtual bool EraseSection(LPCTSTR section)
TMemConfigFile(const tstring &name)
virtual void UpdateFile()
virtual bool WriteString(LPCTSTR section, LPCTSTR entry, LPCTSTR value)
virtual void LoadValues(const TConfigFile &file)
virtual bool EraseEntry(LPCTSTR section, LPCTSTR entry)
TPoint is a support class, derived from tagPOINT.
Definition geometry.h:87
TRect is a mathematical class derived from tagRect.
Definition geometry.h:308
virtual bool EraseSection(LPCTSTR section)
virtual bool EraseEntry(LPCTSTR section, LPCTSTR entry)
virtual uint ReadSections(TCHAR *buffer, uint bufSize) const
Copies all section names to the specified buffer.
virtual ~TRegConfigFile()
TRegConfigFile(const tstring &name, HKEY hRoot=HKEY_CURRENT_USER)
This source file implements TRegConfigFile.
virtual void UpdateFile()
virtual bool WriteData(LPCTSTR section, LPCTSTR entry, void *buffer, uint size)
This method writes binary data.
virtual bool SectionExists(LPCTSTR section) const
virtual int ReadInteger(LPCTSTR section, LPCTSTR entry, int defint=0) const
virtual bool WriteString(LPCTSTR section, LPCTSTR entry, LPCTSTR value)
virtual uint ReadSection(LPCTSTR section, TCHAR *buffer, uint bufSize) const
Copies all value names of the given section to the specified buffer.
virtual bool WriteInteger(LPCTSTR section, LPCTSTR entry, int value)
virtual uint ReadString(LPCTSTR section, LPCTSTR entry, TCHAR *buffer, uint bufSize, LPCTSTR defstr=0) const
Looks up the value of the given entry of the given section, and if found, copies it to the given buff...
virtual bool ReadData(LPCTSTR section, LPCTSTR entry, void *buffer, uint size) const
This method reads binary data.
Encapsulates a registration key in the Windows Registry.
Definition registry.h:115
auto HasSubkey(const tstring &keyName) const -> bool
Returns true if this key has a subkey with the given name.
Definition registry.cpp:354
auto GetSubkey(const tstring &keyName, REGSAM samDesired=KEY_READ) const -> std::optional< TRegKey >
Returns the subkey with the given name, if it exists.
Definition registry.cpp:376
Iterator for walking thru the subkeys of a key.
Definition registry.h:403
Encapsulates a value-data entry within one registration key.
Definition registry.h:51
Iterator for walking through the values of a key.
Definition registry.h:429
The tagSIZE struct is defined as.
Definition geometry.h:234
TSystemTime is a class derived from the structure SYSTEMTIME.
Definition wsyscls.h:420
The TTextFile class is derived from TBufferedFile and encapsulates standard file characteristics and ...
Definition file.h:436
The TTime class encapsulates time functions and characteristics.
Definition time.h:38
Definition of windowing system color classes.
This header file declares the class: TConfigFile,TIniConfigFile, TRegConfigFile and TConfigFileSectio...
#define _stscanf
Definition cygwin.h:87
#define _istdigit
Definition cygwin.h:70
#define _tcscat
Definition cygwin.h:83
#define _tcscpy
Definition cygwin.h:79
#define _tcsncpy
Definition cygwin.h:80
#define _ttoi
Definition cygwin.h:64
#define _istalpha
Definition cygwin.h:71
#define _ltot
Definition cygwin.h:63
#define _stprintf
Definition cygwin.h:88
#define _itot
Definition cygwin.h:66
#define _tcstok
Definition cygwin.h:84
#define _tcstod
Definition cygwin.h:68
#define MAX_PATH
Definition cygwin.h:98
#define _totupper
Definition cygwin.h:73
#define _tcslen
Definition cygwin.h:74
#define _tcstol
Definition cygwin.h:67
#define _tcsicmp
Definition cygwin.h:76
#define _T(x)
Definition cygwin.h:51
#define _tcschr
Definition cygwin.h:85
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
std::ostringstream tostringstream
Definition strmdefs.h:36
bool is_integer(TCHAR *text)
Definition configfl.cpp:115
unsigned char uint8
Definition number.h:32
char tchar
Definition defs.h:77
std::istringstream tistringstream
Definition strmdefs.h:37
std::istream tistream
Definition strmdefs.h:39
std::string tstring
Definition defs.h:79
bool is_digit(tchar c)
where string is integer????
Definition configfl.cpp:108
TSortedObjectArray< TStringMapNode > TStringMap
Definition configfl.cpp:970
unsigned int uint
Definition number.h:25
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition defs.h:376
Various types of smart pointer templatized classes.
Definition of container classes used and made available by OWL.
Classes for window system structure and type encapsulation.