xref: /aosp_15_r20/external/lzma/CPP/Common/Lang.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Common/Lang.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 "Lang.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "StringToInt.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "UTFConvert.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #include "../Windows/FileIO.h"
10*f6dc9357SAndroid Build Coastguard Worker 
Clear()11*f6dc9357SAndroid Build Coastguard Worker void CLang::Clear() throw()
12*f6dc9357SAndroid Build Coastguard Worker {
13*f6dc9357SAndroid Build Coastguard Worker   _ids.Clear();
14*f6dc9357SAndroid Build Coastguard Worker   _offsets.Clear();
15*f6dc9357SAndroid Build Coastguard Worker   Comments.Clear();
16*f6dc9357SAndroid Build Coastguard Worker   delete []_text;
17*f6dc9357SAndroid Build Coastguard Worker   _text = NULL;
18*f6dc9357SAndroid Build Coastguard Worker }
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker static const char * const kLangSignature = ";!@Lang2@!UTF-8!\n";
21*f6dc9357SAndroid Build Coastguard Worker 
OpenFromString(const AString & s2)22*f6dc9357SAndroid Build Coastguard Worker bool CLang::OpenFromString(const AString &s2)
23*f6dc9357SAndroid Build Coastguard Worker {
24*f6dc9357SAndroid Build Coastguard Worker   UString su;
25*f6dc9357SAndroid Build Coastguard Worker   if (!ConvertUTF8ToUnicode(s2, su))
26*f6dc9357SAndroid Build Coastguard Worker     return false;
27*f6dc9357SAndroid Build Coastguard Worker   if (su.IsEmpty())
28*f6dc9357SAndroid Build Coastguard Worker     return false;
29*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *s = su;
30*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *sLim = s + su.Len();
31*f6dc9357SAndroid Build Coastguard Worker   if (*s == 0xFEFF)
32*f6dc9357SAndroid Build Coastguard Worker     s++;
33*f6dc9357SAndroid Build Coastguard Worker   for (const char *p = kLangSignature;; s++)
34*f6dc9357SAndroid Build Coastguard Worker   {
35*f6dc9357SAndroid Build Coastguard Worker     const Byte c = (Byte)(*p++);
36*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
37*f6dc9357SAndroid Build Coastguard Worker       break;
38*f6dc9357SAndroid Build Coastguard Worker     if (*s != c)
39*f6dc9357SAndroid Build Coastguard Worker       return false;
40*f6dc9357SAndroid Build Coastguard Worker   }
41*f6dc9357SAndroid Build Coastguard Worker 
42*f6dc9357SAndroid Build Coastguard Worker   wchar_t *text = new wchar_t[(size_t)(sLim - s) + 1];
43*f6dc9357SAndroid Build Coastguard Worker   _text = text;
44*f6dc9357SAndroid Build Coastguard Worker 
45*f6dc9357SAndroid Build Coastguard Worker   UString comment;
46*f6dc9357SAndroid Build Coastguard Worker   Int32 id = -1024;
47*f6dc9357SAndroid Build Coastguard Worker   unsigned pos = 0;
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker   while (s != sLim)
50*f6dc9357SAndroid Build Coastguard Worker   {
51*f6dc9357SAndroid Build Coastguard Worker     const unsigned start = pos;
52*f6dc9357SAndroid Build Coastguard Worker     do
53*f6dc9357SAndroid Build Coastguard Worker     {
54*f6dc9357SAndroid Build Coastguard Worker       wchar_t c = *s++;
55*f6dc9357SAndroid Build Coastguard Worker       if (c == '\n')
56*f6dc9357SAndroid Build Coastguard Worker         break;
57*f6dc9357SAndroid Build Coastguard Worker       if (c == '\\')
58*f6dc9357SAndroid Build Coastguard Worker       {
59*f6dc9357SAndroid Build Coastguard Worker         if (s == sLim)
60*f6dc9357SAndroid Build Coastguard Worker           return false;
61*f6dc9357SAndroid Build Coastguard Worker         c = *s++;
62*f6dc9357SAndroid Build Coastguard Worker         switch (c)
63*f6dc9357SAndroid Build Coastguard Worker         {
64*f6dc9357SAndroid Build Coastguard Worker           case '\n': return false;
65*f6dc9357SAndroid Build Coastguard Worker           case 'n': c = '\n'; break;
66*f6dc9357SAndroid Build Coastguard Worker           case 't': c = '\t'; break;
67*f6dc9357SAndroid Build Coastguard Worker           case '\\': /* c = '\\'; */ break;
68*f6dc9357SAndroid Build Coastguard Worker           default: text[pos++] = L'\\'; break;
69*f6dc9357SAndroid Build Coastguard Worker         }
70*f6dc9357SAndroid Build Coastguard Worker       }
71*f6dc9357SAndroid Build Coastguard Worker       text[pos++] = c;
72*f6dc9357SAndroid Build Coastguard Worker     }
73*f6dc9357SAndroid Build Coastguard Worker     while (s != sLim);
74*f6dc9357SAndroid Build Coastguard Worker 
75*f6dc9357SAndroid Build Coastguard Worker     {
76*f6dc9357SAndroid Build Coastguard Worker       unsigned j = start;
77*f6dc9357SAndroid Build Coastguard Worker       for (; j < pos; j++)
78*f6dc9357SAndroid Build Coastguard Worker         if (text[j] != ' ' && text[j] != '\t')
79*f6dc9357SAndroid Build Coastguard Worker           break;
80*f6dc9357SAndroid Build Coastguard Worker       if (j == pos)
81*f6dc9357SAndroid Build Coastguard Worker       {
82*f6dc9357SAndroid Build Coastguard Worker         id++;
83*f6dc9357SAndroid Build Coastguard Worker         pos = start;
84*f6dc9357SAndroid Build Coastguard Worker         continue;
85*f6dc9357SAndroid Build Coastguard Worker       }
86*f6dc9357SAndroid Build Coastguard Worker     }
87*f6dc9357SAndroid Build Coastguard Worker 
88*f6dc9357SAndroid Build Coastguard Worker     // start != pos
89*f6dc9357SAndroid Build Coastguard Worker     text[pos++] = 0;
90*f6dc9357SAndroid Build Coastguard Worker 
91*f6dc9357SAndroid Build Coastguard Worker     if (text[start] == ';')
92*f6dc9357SAndroid Build Coastguard Worker     {
93*f6dc9357SAndroid Build Coastguard Worker       comment = text + start;
94*f6dc9357SAndroid Build Coastguard Worker       comment.TrimRight();
95*f6dc9357SAndroid Build Coastguard Worker       if (comment.Len() != 1)
96*f6dc9357SAndroid Build Coastguard Worker         Comments.Add(comment);
97*f6dc9357SAndroid Build Coastguard Worker       id++;
98*f6dc9357SAndroid Build Coastguard Worker       pos = start;
99*f6dc9357SAndroid Build Coastguard Worker       continue;
100*f6dc9357SAndroid Build Coastguard Worker     }
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *end;
103*f6dc9357SAndroid Build Coastguard Worker     const UInt32 id32 = ConvertStringToUInt32(text + start, &end);
104*f6dc9357SAndroid Build Coastguard Worker     if (*end == 0)
105*f6dc9357SAndroid Build Coastguard Worker     {
106*f6dc9357SAndroid Build Coastguard Worker       if (id32 > ((UInt32)1 << 30) || (Int32)id32 < id)
107*f6dc9357SAndroid Build Coastguard Worker         return false;
108*f6dc9357SAndroid Build Coastguard Worker       id = (Int32)id32;
109*f6dc9357SAndroid Build Coastguard Worker       pos = start;
110*f6dc9357SAndroid Build Coastguard Worker       continue;
111*f6dc9357SAndroid Build Coastguard Worker     }
112*f6dc9357SAndroid Build Coastguard Worker 
113*f6dc9357SAndroid Build Coastguard Worker     if (id < 0)
114*f6dc9357SAndroid Build Coastguard Worker       return false;
115*f6dc9357SAndroid Build Coastguard Worker     _ids.Add((UInt32)id++);
116*f6dc9357SAndroid Build Coastguard Worker     _offsets.Add(start);
117*f6dc9357SAndroid Build Coastguard Worker   }
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker   return true;
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker 
Open(CFSTR fileName,const char * id)122*f6dc9357SAndroid Build Coastguard Worker bool CLang::Open(CFSTR fileName, const char *id)
123*f6dc9357SAndroid Build Coastguard Worker {
124*f6dc9357SAndroid Build Coastguard Worker   Clear();
125*f6dc9357SAndroid Build Coastguard Worker   NWindows::NFile::NIO::CInFile file;
126*f6dc9357SAndroid Build Coastguard Worker   if (!file.Open(fileName))
127*f6dc9357SAndroid Build Coastguard Worker     return false;
128*f6dc9357SAndroid Build Coastguard Worker   UInt64 length;
129*f6dc9357SAndroid Build Coastguard Worker   if (!file.GetLength(length))
130*f6dc9357SAndroid Build Coastguard Worker     return false;
131*f6dc9357SAndroid Build Coastguard Worker   if (length > (1 << 20))
132*f6dc9357SAndroid Build Coastguard Worker     return false;
133*f6dc9357SAndroid Build Coastguard Worker 
134*f6dc9357SAndroid Build Coastguard Worker   AString s;
135*f6dc9357SAndroid Build Coastguard Worker   const unsigned len = (unsigned)length;
136*f6dc9357SAndroid Build Coastguard Worker   char *p = s.GetBuf(len);
137*f6dc9357SAndroid Build Coastguard Worker   size_t processed;
138*f6dc9357SAndroid Build Coastguard Worker   if (!file.ReadFull(p, len, processed))
139*f6dc9357SAndroid Build Coastguard Worker     return false;
140*f6dc9357SAndroid Build Coastguard Worker   file.Close();
141*f6dc9357SAndroid Build Coastguard Worker   if (len != processed)
142*f6dc9357SAndroid Build Coastguard Worker     return false;
143*f6dc9357SAndroid Build Coastguard Worker 
144*f6dc9357SAndroid Build Coastguard Worker   char *p2 = p;
145*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < len; i++)
146*f6dc9357SAndroid Build Coastguard Worker   {
147*f6dc9357SAndroid Build Coastguard Worker     const char c = p[i];
148*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
149*f6dc9357SAndroid Build Coastguard Worker       break;
150*f6dc9357SAndroid Build Coastguard Worker     if (c != 0x0D)
151*f6dc9357SAndroid Build Coastguard Worker       *p2++ = c;
152*f6dc9357SAndroid Build Coastguard Worker   }
153*f6dc9357SAndroid Build Coastguard Worker   *p2 = 0;
154*f6dc9357SAndroid Build Coastguard Worker   s.ReleaseBuf_SetLen((unsigned)(p2 - p));
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker   if (OpenFromString(s))
157*f6dc9357SAndroid Build Coastguard Worker   {
158*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *name = Get(0);
159*f6dc9357SAndroid Build Coastguard Worker     if (name && StringsAreEqual_Ascii(name, id))
160*f6dc9357SAndroid Build Coastguard Worker       return true;
161*f6dc9357SAndroid Build Coastguard Worker   }
162*f6dc9357SAndroid Build Coastguard Worker 
163*f6dc9357SAndroid Build Coastguard Worker   Clear();
164*f6dc9357SAndroid Build Coastguard Worker   return false;
165*f6dc9357SAndroid Build Coastguard Worker }
166*f6dc9357SAndroid Build Coastguard Worker 
Get(UInt32 id) const167*f6dc9357SAndroid Build Coastguard Worker const wchar_t *CLang::Get(UInt32 id) const throw()
168*f6dc9357SAndroid Build Coastguard Worker {
169*f6dc9357SAndroid Build Coastguard Worker   const int index = _ids.FindInSorted(id);
170*f6dc9357SAndroid Build Coastguard Worker   if (index < 0)
171*f6dc9357SAndroid Build Coastguard Worker     return NULL;
172*f6dc9357SAndroid Build Coastguard Worker   return _text + (size_t)_offsets[(unsigned)index];
173*f6dc9357SAndroid Build Coastguard Worker }
174