1 // Common/TextConfig.cpp
2
3 #include "StdAfx.h"
4
5 #include "TextConfig.h"
6 #include "UTFConvert.h"
7
IsDelimitChar(char c)8 static inline bool IsDelimitChar(char c)
9 {
10 return (c == ' ' || c == 0x0A || c == 0x0D || c == '\0' || c == '\t');
11 }
12
GetIDString(const char * s,unsigned & finishPos)13 static AString GetIDString(const char *s, unsigned &finishPos)
14 {
15 AString result;
16 for (finishPos = 0; ; finishPos++)
17 {
18 char c = s[finishPos];
19 if (IsDelimitChar(c) || c == '=')
20 break;
21 result += c;
22 }
23 return result;
24 }
25
WaitNextLine(const AString & s,unsigned & pos)26 static bool WaitNextLine(const AString &s, unsigned &pos)
27 {
28 for (; pos < s.Len(); pos++)
29 if (s[pos] == 0x0A)
30 return true;
31 return false;
32 }
33
SkipSpaces(const AString & s,unsigned & pos)34 static bool SkipSpaces(const AString &s, unsigned &pos)
35 {
36 for (; pos < s.Len(); pos++)
37 {
38 char c = s[pos];
39 if (!IsDelimitChar(c))
40 {
41 if (c != ';')
42 return true;
43 if (!WaitNextLine(s, pos))
44 return false;
45 }
46 }
47 return false;
48 }
49
GetTextConfig(const AString & s,CObjectVector<CTextConfigPair> & pairs)50 bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs)
51 {
52 pairs.Clear();
53 unsigned pos = 0;
54
55 /////////////////////
56 // read strings
57
58 for (;;)
59 {
60 if (!SkipSpaces(s, pos))
61 break;
62 CTextConfigPair pair;
63 unsigned finishPos;
64 const AString temp (GetIDString(((const char *)s) + pos, finishPos));
65 if (!ConvertUTF8ToUnicode(temp, pair.ID))
66 return false;
67 if (finishPos == 0)
68 return false;
69 pos += finishPos;
70 if (!SkipSpaces(s, pos))
71 return false;
72 if (s[pos] != '=')
73 return false;
74 pos++;
75 if (!SkipSpaces(s, pos))
76 return false;
77 if (s[pos] != '\"')
78 return false;
79 pos++;
80 AString message;
81 for (;;)
82 {
83 if (pos >= s.Len())
84 return false;
85 char c = s[pos++];
86 if (c == '\"')
87 break;
88 if (c == '\\')
89 {
90 c = s[pos++];
91 switch (c)
92 {
93 case 'n': message += '\n'; break;
94 case 't': message += '\t'; break;
95 case '\\': message += '\\'; break;
96 case '\"': message += '\"'; break;
97 default: message += '\\'; message += c; break;
98 }
99 }
100 else
101 message += c;
102 }
103 if (!ConvertUTF8ToUnicode(message, pair.String))
104 return false;
105 pairs.Add(pair);
106 }
107 return true;
108 }
109
FindTextConfigItem(const CObjectVector<CTextConfigPair> & pairs,const char * id)110 int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const char *id) throw()
111 {
112 FOR_VECTOR (i, pairs)
113 if (pairs[i].ID.IsEqualTo(id))
114 return i;
115 return -1;
116 }
117
GetTextConfigValue(const CObjectVector<CTextConfigPair> & pairs,const char * id)118 UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const char *id)
119 {
120 int index = FindTextConfigItem(pairs, id);
121 if (index < 0)
122 return UString();
123 return pairs[index].String;
124 }
125