xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/TextPairs.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // TextPairs.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "TextPairs.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker static const wchar_t kNewLineChar = '\n';
8*f6dc9357SAndroid Build Coastguard Worker static const wchar_t kQuoteChar = '\"';
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker static const wchar_t kBOM = (wchar_t)0xFEFF;
11*f6dc9357SAndroid Build Coastguard Worker 
IsSeparatorChar(wchar_t c)12*f6dc9357SAndroid Build Coastguard Worker static bool IsSeparatorChar(wchar_t c)
13*f6dc9357SAndroid Build Coastguard Worker {
14*f6dc9357SAndroid Build Coastguard Worker   return (c == ' ' || c == '\t');
15*f6dc9357SAndroid Build Coastguard Worker }
16*f6dc9357SAndroid Build Coastguard Worker 
RemoveCr(UString & s)17*f6dc9357SAndroid Build Coastguard Worker static void RemoveCr(UString &s)
18*f6dc9357SAndroid Build Coastguard Worker {
19*f6dc9357SAndroid Build Coastguard Worker   s.RemoveChar(L'\x0D');
20*f6dc9357SAndroid Build Coastguard Worker }
21*f6dc9357SAndroid Build Coastguard Worker 
GetIDString(const wchar_t * srcString,unsigned & finishPos)22*f6dc9357SAndroid Build Coastguard Worker static UString GetIDString(const wchar_t *srcString, unsigned &finishPos)
23*f6dc9357SAndroid Build Coastguard Worker {
24*f6dc9357SAndroid Build Coastguard Worker   UString result;
25*f6dc9357SAndroid Build Coastguard Worker   bool quotes = false;
26*f6dc9357SAndroid Build Coastguard Worker   for (finishPos = 0;;)
27*f6dc9357SAndroid Build Coastguard Worker   {
28*f6dc9357SAndroid Build Coastguard Worker     wchar_t c = srcString[finishPos];
29*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
30*f6dc9357SAndroid Build Coastguard Worker       break;
31*f6dc9357SAndroid Build Coastguard Worker     finishPos++;
32*f6dc9357SAndroid Build Coastguard Worker     bool isSeparatorChar = IsSeparatorChar(c);
33*f6dc9357SAndroid Build Coastguard Worker     if (c == kNewLineChar || (isSeparatorChar && !quotes)
34*f6dc9357SAndroid Build Coastguard Worker         || (c == kQuoteChar && quotes))
35*f6dc9357SAndroid Build Coastguard Worker       break;
36*f6dc9357SAndroid Build Coastguard Worker     else if (c == kQuoteChar)
37*f6dc9357SAndroid Build Coastguard Worker       quotes = true;
38*f6dc9357SAndroid Build Coastguard Worker     else
39*f6dc9357SAndroid Build Coastguard Worker       result += c;
40*f6dc9357SAndroid Build Coastguard Worker   }
41*f6dc9357SAndroid Build Coastguard Worker   result.Trim();
42*f6dc9357SAndroid Build Coastguard Worker   RemoveCr(result);
43*f6dc9357SAndroid Build Coastguard Worker   return result;
44*f6dc9357SAndroid Build Coastguard Worker }
45*f6dc9357SAndroid Build Coastguard Worker 
GetValueString(const wchar_t * srcString,unsigned & finishPos)46*f6dc9357SAndroid Build Coastguard Worker static UString GetValueString(const wchar_t *srcString, unsigned &finishPos)
47*f6dc9357SAndroid Build Coastguard Worker {
48*f6dc9357SAndroid Build Coastguard Worker   UString result;
49*f6dc9357SAndroid Build Coastguard Worker   for (finishPos = 0;;)
50*f6dc9357SAndroid Build Coastguard Worker   {
51*f6dc9357SAndroid Build Coastguard Worker     wchar_t c = srcString[finishPos];
52*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
53*f6dc9357SAndroid Build Coastguard Worker       break;
54*f6dc9357SAndroid Build Coastguard Worker     finishPos++;
55*f6dc9357SAndroid Build Coastguard Worker     if (c == kNewLineChar)
56*f6dc9357SAndroid Build Coastguard Worker       break;
57*f6dc9357SAndroid Build Coastguard Worker     result += c;
58*f6dc9357SAndroid Build Coastguard Worker   }
59*f6dc9357SAndroid Build Coastguard Worker   result.Trim();
60*f6dc9357SAndroid Build Coastguard Worker   RemoveCr(result);
61*f6dc9357SAndroid Build Coastguard Worker   return result;
62*f6dc9357SAndroid Build Coastguard Worker }
63*f6dc9357SAndroid Build Coastguard Worker 
GetTextPairs(const UString & srcString,CObjectVector<CTextPair> & pairs)64*f6dc9357SAndroid Build Coastguard Worker static bool GetTextPairs(const UString &srcString, CObjectVector<CTextPair> &pairs)
65*f6dc9357SAndroid Build Coastguard Worker {
66*f6dc9357SAndroid Build Coastguard Worker   pairs.Clear();
67*f6dc9357SAndroid Build Coastguard Worker   unsigned pos = 0;
68*f6dc9357SAndroid Build Coastguard Worker 
69*f6dc9357SAndroid Build Coastguard Worker   if (srcString.Len() > 0)
70*f6dc9357SAndroid Build Coastguard Worker   {
71*f6dc9357SAndroid Build Coastguard Worker     if (srcString[0] == kBOM)
72*f6dc9357SAndroid Build Coastguard Worker       pos++;
73*f6dc9357SAndroid Build Coastguard Worker   }
74*f6dc9357SAndroid Build Coastguard Worker   while (pos < srcString.Len())
75*f6dc9357SAndroid Build Coastguard Worker   {
76*f6dc9357SAndroid Build Coastguard Worker     unsigned finishPos;
77*f6dc9357SAndroid Build Coastguard Worker     UString id = GetIDString((const wchar_t *)srcString + pos, finishPos);
78*f6dc9357SAndroid Build Coastguard Worker     pos += finishPos;
79*f6dc9357SAndroid Build Coastguard Worker     if (id.IsEmpty())
80*f6dc9357SAndroid Build Coastguard Worker       continue;
81*f6dc9357SAndroid Build Coastguard Worker     UString value = GetValueString((const wchar_t *)srcString + pos, finishPos);
82*f6dc9357SAndroid Build Coastguard Worker     pos += finishPos;
83*f6dc9357SAndroid Build Coastguard Worker     if (!id.IsEmpty())
84*f6dc9357SAndroid Build Coastguard Worker     {
85*f6dc9357SAndroid Build Coastguard Worker       CTextPair pair;
86*f6dc9357SAndroid Build Coastguard Worker       pair.ID = id;
87*f6dc9357SAndroid Build Coastguard Worker       pair.Value = value;
88*f6dc9357SAndroid Build Coastguard Worker       pairs.Add(pair);
89*f6dc9357SAndroid Build Coastguard Worker     }
90*f6dc9357SAndroid Build Coastguard Worker   }
91*f6dc9357SAndroid Build Coastguard Worker   return true;
92*f6dc9357SAndroid Build Coastguard Worker }
93*f6dc9357SAndroid Build Coastguard Worker 
ComparePairIDs(const UString & s1,const UString & s2)94*f6dc9357SAndroid Build Coastguard Worker static int ComparePairIDs(const UString &s1, const UString &s2)
95*f6dc9357SAndroid Build Coastguard Worker   { return MyStringCompareNoCase(s1, s2); }
96*f6dc9357SAndroid Build Coastguard Worker 
ComparePairItems(const CTextPair & p1,const CTextPair & p2)97*f6dc9357SAndroid Build Coastguard Worker static int ComparePairItems(const CTextPair &p1, const CTextPair &p2)
98*f6dc9357SAndroid Build Coastguard Worker   { return ComparePairIDs(p1.ID, p2.ID); }
99*f6dc9357SAndroid Build Coastguard Worker 
ComparePairItems(void * const * a1,void * const * a2,void *)100*f6dc9357SAndroid Build Coastguard Worker static int ComparePairItems(void *const *a1, void *const *a2, void * /* param */)
101*f6dc9357SAndroid Build Coastguard Worker   { return ComparePairItems(**(const CTextPair *const *)a1, **(const CTextPair *const *)a2); }
102*f6dc9357SAndroid Build Coastguard Worker 
Sort()103*f6dc9357SAndroid Build Coastguard Worker void CPairsStorage::Sort() { Pairs.Sort(ComparePairItems, NULL); }
104*f6dc9357SAndroid Build Coastguard Worker 
FindID(const UString & id,unsigned & insertPos) const105*f6dc9357SAndroid Build Coastguard Worker int CPairsStorage::FindID(const UString &id, unsigned &insertPos) const
106*f6dc9357SAndroid Build Coastguard Worker {
107*f6dc9357SAndroid Build Coastguard Worker   unsigned left = 0, right = Pairs.Size();
108*f6dc9357SAndroid Build Coastguard Worker   while (left != right)
109*f6dc9357SAndroid Build Coastguard Worker   {
110*f6dc9357SAndroid Build Coastguard Worker     const unsigned mid = (left + right) / 2;
111*f6dc9357SAndroid Build Coastguard Worker     const int compResult = ComparePairIDs(id, Pairs[mid].ID);
112*f6dc9357SAndroid Build Coastguard Worker     if (compResult == 0)
113*f6dc9357SAndroid Build Coastguard Worker     {
114*f6dc9357SAndroid Build Coastguard Worker       insertPos = mid; // to disable GCC warning
115*f6dc9357SAndroid Build Coastguard Worker       return (int)mid;
116*f6dc9357SAndroid Build Coastguard Worker     }
117*f6dc9357SAndroid Build Coastguard Worker     if (compResult < 0)
118*f6dc9357SAndroid Build Coastguard Worker       right = mid;
119*f6dc9357SAndroid Build Coastguard Worker     else
120*f6dc9357SAndroid Build Coastguard Worker       left = mid + 1;
121*f6dc9357SAndroid Build Coastguard Worker   }
122*f6dc9357SAndroid Build Coastguard Worker   insertPos = left;
123*f6dc9357SAndroid Build Coastguard Worker   return -1;
124*f6dc9357SAndroid Build Coastguard Worker }
125*f6dc9357SAndroid Build Coastguard Worker 
FindID(const UString & id) const126*f6dc9357SAndroid Build Coastguard Worker int CPairsStorage::FindID(const UString &id) const
127*f6dc9357SAndroid Build Coastguard Worker {
128*f6dc9357SAndroid Build Coastguard Worker   unsigned pos;
129*f6dc9357SAndroid Build Coastguard Worker   return FindID(id, pos);
130*f6dc9357SAndroid Build Coastguard Worker }
131*f6dc9357SAndroid Build Coastguard Worker 
AddPair(const CTextPair & pair)132*f6dc9357SAndroid Build Coastguard Worker void CPairsStorage::AddPair(const CTextPair &pair)
133*f6dc9357SAndroid Build Coastguard Worker {
134*f6dc9357SAndroid Build Coastguard Worker   unsigned insertPos;
135*f6dc9357SAndroid Build Coastguard Worker   const int pos = FindID(pair.ID, insertPos);
136*f6dc9357SAndroid Build Coastguard Worker   if (pos >= 0)
137*f6dc9357SAndroid Build Coastguard Worker     Pairs[pos] = pair;
138*f6dc9357SAndroid Build Coastguard Worker   else
139*f6dc9357SAndroid Build Coastguard Worker     Pairs.Insert(insertPos, pair);
140*f6dc9357SAndroid Build Coastguard Worker }
141*f6dc9357SAndroid Build Coastguard Worker 
DeletePair(const UString & id)142*f6dc9357SAndroid Build Coastguard Worker void CPairsStorage::DeletePair(const UString &id)
143*f6dc9357SAndroid Build Coastguard Worker {
144*f6dc9357SAndroid Build Coastguard Worker   const int pos = FindID(id);
145*f6dc9357SAndroid Build Coastguard Worker   if (pos >= 0)
146*f6dc9357SAndroid Build Coastguard Worker     Pairs.Delete((unsigned)pos);
147*f6dc9357SAndroid Build Coastguard Worker }
148*f6dc9357SAndroid Build Coastguard Worker 
GetValue(const UString & id,UString & value) const149*f6dc9357SAndroid Build Coastguard Worker bool CPairsStorage::GetValue(const UString &id, UString &value) const
150*f6dc9357SAndroid Build Coastguard Worker {
151*f6dc9357SAndroid Build Coastguard Worker   value.Empty();
152*f6dc9357SAndroid Build Coastguard Worker   const int pos = FindID(id);
153*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0)
154*f6dc9357SAndroid Build Coastguard Worker     return false;
155*f6dc9357SAndroid Build Coastguard Worker   value = Pairs[pos].Value;
156*f6dc9357SAndroid Build Coastguard Worker   return true;
157*f6dc9357SAndroid Build Coastguard Worker }
158*f6dc9357SAndroid Build Coastguard Worker 
GetValue(const UString & id) const159*f6dc9357SAndroid Build Coastguard Worker UString CPairsStorage::GetValue(const UString &id) const
160*f6dc9357SAndroid Build Coastguard Worker {
161*f6dc9357SAndroid Build Coastguard Worker   const int pos = FindID(id);
162*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0)
163*f6dc9357SAndroid Build Coastguard Worker     return UString();
164*f6dc9357SAndroid Build Coastguard Worker   return Pairs[pos].Value;
165*f6dc9357SAndroid Build Coastguard Worker }
166*f6dc9357SAndroid Build Coastguard Worker 
ReadFromString(const UString & text)167*f6dc9357SAndroid Build Coastguard Worker bool CPairsStorage::ReadFromString(const UString &text)
168*f6dc9357SAndroid Build Coastguard Worker {
169*f6dc9357SAndroid Build Coastguard Worker   bool result = ::GetTextPairs(text, Pairs);
170*f6dc9357SAndroid Build Coastguard Worker   if (result)
171*f6dc9357SAndroid Build Coastguard Worker     Sort();
172*f6dc9357SAndroid Build Coastguard Worker   else
173*f6dc9357SAndroid Build Coastguard Worker     Pairs.Clear();
174*f6dc9357SAndroid Build Coastguard Worker   return result;
175*f6dc9357SAndroid Build Coastguard Worker }
176*f6dc9357SAndroid Build Coastguard Worker 
SaveToString(UString & text) const177*f6dc9357SAndroid Build Coastguard Worker void CPairsStorage::SaveToString(UString &text) const
178*f6dc9357SAndroid Build Coastguard Worker {
179*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, Pairs)
180*f6dc9357SAndroid Build Coastguard Worker   {
181*f6dc9357SAndroid Build Coastguard Worker     const CTextPair &pair = Pairs[i];
182*f6dc9357SAndroid Build Coastguard Worker     bool multiWord = (pair.ID.Find(L' ') >= 0);
183*f6dc9357SAndroid Build Coastguard Worker     if (multiWord)
184*f6dc9357SAndroid Build Coastguard Worker       text.Add_Char('\"');
185*f6dc9357SAndroid Build Coastguard Worker     text += pair.ID;
186*f6dc9357SAndroid Build Coastguard Worker     if (multiWord)
187*f6dc9357SAndroid Build Coastguard Worker       text.Add_Char('\"');
188*f6dc9357SAndroid Build Coastguard Worker     text.Add_Space();
189*f6dc9357SAndroid Build Coastguard Worker     text += pair.Value;
190*f6dc9357SAndroid Build Coastguard Worker     text.Add_Char('\x0D');
191*f6dc9357SAndroid Build Coastguard Worker     text.Add_LF();
192*f6dc9357SAndroid Build Coastguard Worker   }
193*f6dc9357SAndroid Build Coastguard Worker }
194