1// Common/TextConfig.cpp
2
3#include "StdAfx.h"
4
5#include "TextConfig.h"
6#include "UTFConvert.h"
7
8static inline bool IsDelimitChar(char c)
9{
10  return (c == ' ' || c == 0x0A || c == 0x0D || c == '\0' || c == '\t');
11}
12
13static 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
26static 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
34static 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
50bool 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        char 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
110int 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
118UString 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