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 an X,Y point.
795//
797{
799 tchar text[40];
801
802 if(!::_tcslen(text))
803 return false;
804
805 LPCTSTR sz;
806 bool b = false;
807 int array[2], i;
808
809 sz = text;
810
811 for ( i = 0; i < 2; i++){
812 sz = _tcschr (sz, _T('='));
813 if(! sz)
814 break;
815 sz++;
816 if(!_istdigit(*sz))
817 break;
818
819 array[i] = _ttoi(sz);
820 }
821
822 if (i == 2){
823 b = true;
824 point.x = array[0];
825 point.y = array[1];
826 }
827 return b;
828}
829//
830/// This method writes a TPoint.
831//
833{
835 tchar buf[20];
836
837 wsprintf(buf, _T("X=%d,Y=%d"), point.x, point.y);
838
839 return WriteString(section, entry, buf);
840}
841//
842/// This method reads a rectangle.
843//
845{
847 tchar text[40];
849
850 if(!::_tcslen(text))
851 return false;
852
853 LPCTSTR sz;
854 bool b = false;
855 int nArray[4], i;
856
857 sz = text;
858
859 for(i = 0; i < 4; i++){
860 sz = _tcschr(sz, _T('='));
861 if (!sz)
862 break;
863
864 sz++;
865 if(!_istdigit(*sz))
866 break;
867
868 nArray[i] = _ttoi(sz);
869 }
870
871 if(i == 4){
872 b = true;
873 rect.left = nArray[0];
874 rect.top = nArray[1];
875 rect.right = nArray[0] + nArray[2];
876 rect.bottom = nArray[1] + nArray[3];
877 }
878 return b;
879}
880//
881/// This method writes a rectangle.
882//
884{
886 tchar buf [40];
887
888 wsprintf (buf, _T("L=%d,T=%d,W=%d,H=%d"), r.left, r.top, r.Width(), r.Height());
889
890 return WriteString(section, entry, buf);
891}
892//
893/// This method writes a TSize.
894//
896{
898 tchar buf [80];
899
900 wsprintf(buf, _T("W=%d,H=%d"), size.cx, size.cy);
901
902 return WriteString(section, entry, buf);
903}
904//
906{
908 tchar buff[3];
909 return ReadSection(section, buff, 3) != 0;
910}
911///////////////////////////////////////////////////////////////////////////////////////
912//
913// class TIniConfigFile
914// ~~~~~ ~~~~~~~~~~~~~~
915//
921//
927//
928/// This method deletes the specified section.
929//
931{
933 return ::WritePrivateProfileString(section, 0, 0, FileName.c_str()) != 0;
934}
935//
936//
937//
938/// This method deletes the specified entry.
939//
941{
943 return ::WritePrivateProfileString (section, entry, 0, FileName.c_str()) != 0;
944}
945//
946//
947//
952//
953/// This method is the base method for reading strings.
954///
955/// \return The number of characters written to the output buffer (excluding the null-terminator, which is also written).
956///
957/// \note If the buffer is too small to hold the whole string, the string is truncated to (bufSize - 1) characters and
958/// null-terminated.
959//
962{
964 return ::GetPrivateProfileString (section, entry, def?def:_T(""), buffer, bufSize, FileName.c_str());
965}
966//
967/// This method is the low-level method for writing strings.
968//
970{
972 return ::WritePrivateProfileString (section, entry, value, FileName.c_str()) != 0;
973}
974//
975/// This method reads binary data.
976//
978{
980 return ::GetPrivateProfileStruct(section, entry, buffer, bufSize, FileName.c_str()) != 0;
981}
982//
983/// This method writes binary data.
984//
986{
988 return ::WritePrivateProfileStruct(section, entry, buffer, bufSize, FileName.c_str()) != 0;
989}
990//////////////////////////////////////////////////////////////////////////////////////////////////
991//
992/// Container support
993//
994class TStringMapNode: public TMapNode<tstring,tstring> {
995public:
996 TStringMapNode(const tstring& str, const tstring& val)
997 : TMapNode<tstring,tstring>() {Name = str; Value = val;}
998
999 TStringMapNode(const tstring& str)
1000 : TMapNode<tstring,tstring>() {Name = str;}
1001};
1002//
1004//
1005class TStringNode: public TMapNode<tstring,TStringMap> {
1006 public:
1007 TStringNode(const tstring& str)
1009};
1010//
1011class TMemConfigFileSections: public TIPtrArray<TStringNode*> {
1012 public:
1013 TMemConfigFileSections(){}
1014 ~TMemConfigFileSections(){}
1015
1016 bool DestroyItem(TStringNode* item);
1017 bool Destroy(int loc);
1018 int Add(TStringNode* item);
1019 bool HasMember(TStringNode* item) const;
1020 int Find(TStringNode* item) const;
1021};
1022//
1023bool TMemConfigFileSections::HasMember(TStringNode* item) const
1024{
1025 return Find(item) != NPOS;
1026}
1027//
1028bool TMemConfigFileSections::DestroyItem(TStringNode* item)
1029{
1030 const auto index = Find(item);
1031 if (index != NPOS)
1032 {
1033 TStringNode* item = Data[index];
1034 Remove(index);
1035 delete item;// using global delete because we didn't allocate it
1036 return true;
1037 }
1038 return false;
1039}
1040//
1041bool TMemConfigFileSections::Destroy(int loc)
1042{
1043 if(loc < (int)Size()){
1044 TStringNode* item = Data[loc];
1045 Remove(loc);
1046 delete item;// using global delete because we didn't allocate it
1047 return true;
1048 }
1049 return false;
1050}
1051//
1052int TMemConfigFileSections::Add(TStringNode* item)
1053{
1054 if(ItemCnt>=Reserved)
1055 Resize(ItemCnt+1); // on error -> throw xalloc
1056 unsigned loc = ItemCnt++;
1057 while( loc > 0 && *item < *Data[loc-1]) {
1058 Data[loc] = Data[loc-1];
1059 loc--;
1060 }
1061 Data[loc] = item;
1062 return loc;
1063}
1064//
1065int TMemConfigFileSections::Find(TStringNode* item) const
1066{
1067 auto lower = 0;
1068 auto upper = static_cast<int>(Size()) - 1;
1069 while (lower <= upper)
1070 {
1071 const auto middle = (lower + upper) / 2;
1072 if (*Data[middle] == *item)
1073 return middle;
1074 if (*Data[middle] < *item)
1075 lower = middle + 1;
1076 else
1077 upper = middle - 1;
1078 }
1079 return NPOS;
1080}
1081///////////////////////////////////////////////////////////////////////
1082//
1083// class TMemConfigFile
1084// ~~~~~ ~~~~~~~~~~~~~~
1086:
1088{
1089 Sections = new TMemConfigFileSections();
1090}
1091//
1093{
1094 Flush();
1095 delete Sections;
1096}
1097//
1099{
1100 Sections->Flush();
1101}
1102//
1108//
1109int TMemConfigFile::AddSection(const tstring& section)
1110{
1111 return Sections->Add(new TStringNode(section));
1112}
1113//
1115{
1117 TStringNode sn(section);
1118 const auto index = Sections->Find(&sn);
1119 if (index != Sections->NPOS)
1120 {
1121 return (*Sections)[index]->Value.DestroyItem(TStringMapNode(entry));
1122 }
1123 return false;
1124}
1125//
1127{
1129 TStringNode sn(section);
1130 return Sections->DestroyItem(&sn);
1131}
1132
1133//
1134/// Copies all value names of the given section 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{
1142 tchar* p = buffer;
1143 *p = _T('\0'); // Ensure the buffer is terminated, if we exit early.
1144 TStringNode sn(section);
1145 const auto k = Sections->Find(&sn);
1146 if (k == Sections->NPOS) return 0;
1147 const TStringMap& map = (*Sections)[k]->Value;
1148 if (map.Empty()) return 0;
1149 for (uint i = 0; i != map.Size(); ++i)
1150 {
1151 const tstring& s = map[i].Name;
1152 size_t m = static_cast<size_t>(buffer + bufSize - 1 - p); // space left
1153 if (m == 0) break; // We've run out of space.
1154 size_t n = min(s.size(), m - 1);
1155 ::_tcsncpy(p, s.c_str(), n);
1156 p += n;
1157 *p++ = _T('\0');
1158 }
1159
1160 // Add buffer terminator.
1161 //
1162 *p++ = _T('\0');
1163 return static_cast<uint>(p - buffer) - 2; // Exclude trailing nulls in the count.
1164}
1165
1166//
1167/// Copies all section names to the specified buffer.
1168/// Each string is null-terminated, and the buffer is then terminated with a trailing null.
1169/// Returns the number of characters written, excluding the trailing null-terminators.
1170/// If the buffer is too small, the last string copied to the buffer may be truncated.
1171//
1173{
1174 PRECONDITION(buffer && bufSize > 1);
1175 tchar* p = buffer;
1176 *p = _T('\0'); // Ensure the buffer is terminated, if we exit early.
1177 if (Sections->Empty()) return 0;
1178 for (uint i = 0; i != Sections->Size(); ++i)
1179 {
1180 const tstring& s = (*Sections)[i]->Name;
1181 size_t m = static_cast<size_t>(buffer + bufSize - 1 - p); // space left
1182 if (m == 0) break; // We've run out of space.
1183 size_t n = min(s.size(), m - 1);
1184 ::_tcsncpy(p, s.c_str(), n);
1185 p += n;
1186 *p++ = _T('\0');
1187 }
1188
1189 // Add buffer terminator.
1190 //
1191 *p++ = _T('\0');
1192 return static_cast<uint>(p - buffer) - 2; // Exclude trailing nulls in the count.
1193}
1194
1195//
1196/// Looks up the value of the given entry of the given section, and if found, copies it to the given buffer.
1197/// If not found, the given default value `defstr` is copied to the buffer, unless `defstr` is null, in which
1198/// case an empty string is copied to the buffer.
1199///
1200/// \return The number of characters written to the output buffer (excluding the null-terminator, which is also written).
1201///
1202/// \note If the buffer is too small to hold the whole string, the string is truncated to (bufSize - 1) characters and
1203/// null-terminated.
1204//
1206{
1207 PRECONDITION(section && entry && buffer && bufSize > 0);
1208 struct TLocal
1209 {
1210 static LPCTSTR Lookup(const TMemConfigFile& f, LPCTSTR section, LPCTSTR entry, LPCTSTR def)
1211 {
1212 TStringNode sn(section);
1213 const auto i = f.Sections->Find(&sn);
1214 if (i == f.Sections->NPOS) return def;
1215 const TStringMap& map = (*f.Sections)[i]->Value;
1216 const auto j = map.Find(TStringMapNode{entry});
1217 if (j == map.NPOS) return def;
1218 return map[j].Value.c_str();
1219 }
1220 };
1221 LPCTSTR s = TLocal::Lookup(*this, section, entry, defstr ? defstr : _T(""));
1222 size_t n = min(::_tcslen(s), static_cast<size_t>(bufSize - 1));
1223 ::_tcsncpy(buffer, s, n);
1224 buffer[n] = _T('\0');
1225 return static_cast<uint>(n); // Exclude null-terminator in the count.
1226}
1227
1228//
1230{
1232 TStringNode sn(section);
1233 auto index = Sections->Find(&sn);
1234 if (index == Sections->NPOS)
1235 index = AddSection(section);
1236 TStringMap& map = (*Sections)[index]->Value;
1237 index = map.Find(TStringMapNode(entry));
1238 if (index != map.NPOS)
1239 map[index].Value = tstring(value);
1240 else
1241 index = map.Add(TStringMapNode(entry,value));
1242 return index != map.NPOS;
1243}
1244//
1246{
1248 if(!file.IsOpen())
1249 return;
1250
1252 for(uint section = 0; section < Sections->Size(); section++){
1253 // Section name
1254 file << _T("[") << (*Sections)[section]->Name.c_str() << _T("]") << _T("\r\n");
1255
1256 TStringMap& map = (*Sections)[section]->Value;
1257 for(uint value = 0; value < map.Size(); value++)
1258 file << map[value].Name.c_str() << _T("=") << map[value].Value.c_str() << _T("\r\n");
1259 }
1260}
1261//
1262//
1263//
1264static LPTSTR getName(tstring& name,LPTSTR p)
1265{
1266 PRECONDITION(p);
1267 while(!_istalpha(*p))
1268 p++;
1269 tchar* p1 = p++;
1270 while(_istalpha(*p))
1271 p++;
1272
1273 tchar c = *p;
1274 *p = _T('\0');
1275
1276 name = p1;
1277 *p = c;
1278 return p;
1279}
1280//
1281static void getValue(tstring& name,LPTSTR p)
1282{
1283 PRECONDITION(p);
1284 while(*p && (*p==_T(' ') || *p ==_T('\t')) && *p != _T('='))
1285 p++;
1286 name = ++p;
1287}
1288//
1289//
1290//
1292{
1293 TTextFile file(FileName.c_str());
1294 if(!file.IsOpen())
1295 return;
1296
1297 Sections->Flush();
1299 int sec_index = -1;
1301
1302 while(fitr){
1303 LPTSTR p = skip_ws((LPTSTR)(LPCTSTR)fitr);
1304 if(::_tcslen(p) && *p != _T(';')){
1305 // read section
1306 if(*p == _T('[')){
1307 getName(tmp_name1,p);
1308 sec_index = AddSection(tmp_name1.c_str());
1309 }
1310 // else read value
1311 else if(sec_index >= 0){
1312 p = getName(tmp_name1,p);
1313 getValue(tmp_name2,p);
1314 (*Sections)[sec_index]->Value.Add(TStringMapNode(tmp_name1,tmp_name2));
1315 }
1316 }
1317 ++fitr;
1318 }
1319}
1320//
1321
1322//
1323/// \class TRegConfigFile
1324// ~~~~~ ~~~~~~~~~~~~~~
1325/// This source file implements TRegConfigFile. This class is derived from
1326/// TConfigFile and overrides the low-level storage methods to vector them
1327/// to the registry.
1328//
1329/// TRegConfigFile is not intended to handle all of an app's registry needs,
1330/// but rather to be used for a convenient wrapper for app preference
1331/// settings. All data is stored in HKEY_CURRENT_USER, using FileName like
1332/// so:
1333/// \code
1334/// HKEY_CURRENT_USER\Software\"FileName"\...
1335/// \endcode
1336/// FileName should contain the company name and product name to adhere to
1337/// standard registry practices. Eg:
1338/// \code
1339/// FileName = "My Company\\Product"
1340/// HKEY_CURRENT_USER\Software\My Company\Product\...
1341/// \endcode
1342/// A version number can also be used to allow multiple versions of the
1343/// same product to live together:
1344/// \code
1345/// mFile = "My Company\\Product\\V1.0"
1346/// HKEY_CURRENT_USER\Software\My Company\Product\V1.0\...
1347/// \endcode
1348/// \note FileName must not end with a backslash!
1349///
1350/// All sections are created under the subtree as described above. Eg,
1351/// \code
1352/// Section = "Options"
1353/// HKEY_CURRENT_USER\Software\My Company\Product\V1.0\Options
1354/// \endcode
1355/// Entries are stored under sections as REG_SZ values (for numbers it is REG_DWORD). Eg,
1356/// \code
1357/// entry = "Tile"
1358/// HKEY_CURRENT_USER\Software\My Company\Product\V1.0\Options\Tile
1359/// \endcode
1360//
1362 : TConfigFile{_T("Software\\") + name}, Root{root}
1363{}
1364
1365//
1369//
1371{
1373 return Root.HasSubkey(FileName + szSep + section);
1374}
1375
1376//
1377/// Copies all value names of the given section to the specified buffer.
1378/// Each string is null-terminated, and the buffer is then terminated with a trailing null.
1379/// Returns the number of characters written, excluding the trailing null-terminators.
1380/// If the buffer is too small, the last string copied to the buffer may be truncated.
1381//
1383{
1385 tchar* p = buffer;
1386 *p = _T('\0'); // Ensure the buffer is terminated, if we exit early.
1387 TRegKey root(Root, FileName + szSep + section);
1389 if (!i) return 0;
1390 for (; i; ++i)
1391 {
1392 TRegValue v(i);
1393 LPCTSTR s = v.GetName();
1394 size_t m = static_cast<size_t>(buffer + bufSize - 1 - p); // space left
1395 if (m == 0) break; // We've run out of space.
1396 size_t n = min(::_tcslen(s), m - 1);
1397 ::_tcsncpy(p, s, n);
1398 p += n;
1399 *p++ = _T('\0');
1400 }
1401
1402 // Add buffer terminator.
1403 //
1404 *p++ = _T('\0');
1405 return static_cast<uint>(p - buffer) - 2; // Exclude trailing nulls in the count.
1406}
1407
1408//
1409/// Copies all section names to the specified buffer.
1410/// Each string is null-terminated, and the buffer is then terminated with a trailing null.
1411/// Returns the number of characters written, excluding the trailing null-terminators.
1412/// If the buffer is too small, the last string copied to the buffer may be truncated.
1413//
1415{
1416 PRECONDITION(buffer && bufSize > 1);
1417 tchar* p = buffer;
1418 *p = _T('\0'); // Ensure the buffer is terminated, if we exit early.
1421 if (!i) return 0;
1422 for (; i; ++i)
1423 {
1424 TRegKey k(i);
1425 LPCTSTR s = k.GetName();
1426 size_t m = static_cast<size_t>(buffer + bufSize - 1 - p); // space left
1427 if (m == 0) break; // We've run out of space.
1428 size_t n = min(::_tcslen(s), m - 1);
1429 ::_tcsncpy(p, s, n);
1430 p += n;
1431 *p++ = _T('\0');
1432 }
1433
1434 // Add buffer terminator.
1435 //
1436 *p++ = _T('\0');
1437 return static_cast<uint>(p - buffer) - 2; // Exclude trailing nulls in the count.
1438}
1439
1440//
1446//
1448{
1450 return TRegKey{Root, FileName + szSep + section}.DeleteValue(entry) == ERROR_SUCCESS;
1451}
1452//
1454{
1455 // don't need this currently
1456}
1457//
1459{
1461 const auto k = Root.GetSubkey(FileName + szSep + section);
1462 return k ? static_cast<int>(k->GetValueOrDefault<uint32>(entry, defint)) : defint;
1463}
1464//
1466{
1468 const auto k = TRegKey{Root, FileName + szSep + section};
1469 return k.SetValue(entry, static_cast<uint32>(value)) == ERROR_SUCCESS;
1470}
1471
1472//
1473/// Looks up the value of the given entry of the given section, and if found, copies it to the given buffer.
1474/// If not found, the given default value `defstr` is copied to the buffer, unless `defstr` is null, in which case an empty
1475/// string is copied to the buffer.
1476///
1477/// \return The number of characters written to the output buffer (excluding the null-terminator, which is also written).
1478/// If an error occurs, e.g. registry access is denied, a TXRegistry exception is thrown.
1479///
1480/// \note If the buffer is too small to hold the whole string, the string is truncated to (bufSize - 1) characters and
1481/// null-terminated.
1482//
1484{
1485 PRECONDITION(section && entry && buffer && bufSize > 0);
1486 const auto k = Root.GetSubkey(FileName + szSep + section);
1487 const auto d = defstr ? defstr : tstring{};
1488 const auto s = k ? k->GetValueOrDefault(entry, d) : d;
1489 const auto n = min(static_cast<uint>(s.size()), bufSize - 1);
1490 const auto e = copy_n(s.begin(), n, buffer);
1491 *e = _T('\0');
1492 return n;
1493}
1494
1495//
1497{
1499 const auto k = TRegKey{Root, FileName + szSep + section};
1500 return k.SetValue(entry, value) == ERROR_SUCCESS;
1501}
1502
1503//
1504/// This method reads binary data.
1505//
1507{
1508 PRECONDITION(section && entry && buffer && bufSize > 0);
1509 const auto k = Root.GetSubkey(FileName + szSep + section);
1510 if (!k) return false;
1511 auto size = uint32{bufSize};
1512 auto type = uint32{};
1513 return k->QueryValue(entry, &type, reinterpret_cast<uint8*>(buffer), &size) == ERROR_SUCCESS;
1514}
1515//
1516/// This method writes binary data.
1517//
1519{
1521 const auto k = TRegKey{Root, FileName + szSep + section};
1522 return k.SetValue(entry, REG_BINARY, reinterpret_cast<const uint8*>(buffer), bufSize) == ERROR_SUCCESS;
1523}
1524//
1525} // OWL namespace
1526//============================================================================================
#define PRECONDITION(condition)
Definition checks.h:227
uint Size() const
Definition template.h:601
static const auto NPOS
Definition template.h:608
bool Empty() const
Definition template.h:603
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 rectangle.
Definition configfl.cpp:883
bool ReadDate(LPCTSTR section, LPCTSTR entry, TDate &value) const
Definition configfl.cpp:416
virtual bool SectionExists(LPCTSTR section) const
Definition configfl.cpp:905
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
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 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 rectangle.
Definition configfl.cpp:844
tstring FileName
Definition configfl.h:153
bool WritePoint(LPCTSTR section, LPCTSTR entry, const TPoint &point)
This method writes a TPoint.
Definition configfl.cpp:832
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:895
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:1772
virtual bool ReadData(LPCTSTR section, LPCTSTR entry, void *buffer, uint size) const
This method reads binary data.
Definition configfl.cpp:977
virtual uint ReadSections(TCHAR *buffer, uint bufSize) const
Definition configfl.cpp:922
virtual uint ReadSection(LPCTSTR section, TCHAR *buffer, uint bufSize) const
Definition configfl.cpp:916
virtual bool WriteString(LPCTSTR section, LPCTSTR entry, LPCTSTR value)
This method is the low-level method for writing strings.
Definition configfl.cpp:969
virtual void UpdateFile()
Definition configfl.cpp:948
virtual bool EraseEntry(LPCTSTR section, LPCTSTR entry)
This method deletes the specified entry.
Definition configfl.cpp:940
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:960
virtual bool WriteData(LPCTSTR section, LPCTSTR entry, void *buffer, uint size)
This method writes binary data.
Definition configfl.cpp:985
virtual bool EraseSection(LPCTSTR section)
This method deletes the specified section.
Definition configfl.cpp:930
Usage: typedef TMapNode<string,string> TStringMapNode; typedef TSortedObjectArray< TStringMapNode > T...
Definition template.h:568
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
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.