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     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 UString & id)110 int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id) throw()
111 {
112   FOR_VECTOR (i, pairs)
113     if (pairs[i].ID == id)
114       return i;
115   return -1;
116 }
117 
GetTextConfigValue(const CObjectVector<CTextConfigPair> & pairs,const UString & id)118 UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id)
119 {
120   int index = FindTextConfigItem(pairs, id);
121   if (index < 0)
122     return UString();
123   return pairs[index].String;
124 }
125