Imported Upstream version 9.20
[platform/upstream/7zip.git] / CPP / Common / Lang.cpp
1 // Common/Lang.cpp\r
2 \r
3 #include "StdAfx.h"\r
4 \r
5 #include "Lang.h"\r
6 #include "TextConfig.h"\r
7 \r
8 #include "../Windows/FileIO.h"\r
9 #include "UTFConvert.h"\r
10 #include "Defs.h"\r
11 \r
12 static bool HexStringToNumber(const UString &s, UInt32 &value)\r
13 {\r
14   value = 0;\r
15   if (s.IsEmpty())\r
16     return false;\r
17   for (int i = 0; i < s.Length(); i++)\r
18   {\r
19     wchar_t c = s[i];\r
20     int a;\r
21     if (c >= L'0' && c <= L'9')\r
22       a = c - L'0';\r
23     else if (c >= L'A' && c <= L'F')\r
24       a = 10 + c - L'A';\r
25     else if (c >= L'a' && c <= L'f')\r
26       a = 10 + c - L'a';\r
27     else\r
28       return false;\r
29     value *= 0x10;\r
30     value += a;\r
31   }\r
32   return true;\r
33 }\r
34 \r
35 \r
36 static bool WaitNextLine(const AString &s, int &pos)\r
37 {\r
38   for (; pos < s.Length(); pos++)\r
39     if (s[pos] == 0x0A)\r
40       return true;\r
41   return false;\r
42 }\r
43 \r
44 static int CompareLangItems(void *const *elem1, void *const *elem2, void *)\r
45 {\r
46   const CLangPair &langPair1 = *(*((const CLangPair **)elem1));\r
47   const CLangPair &langPair2 = *(*((const CLangPair **)elem2));\r
48   return MyCompare(langPair1.Value, langPair2.Value);\r
49 }\r
50 \r
51 bool CLang::Open(LPCWSTR fileName)\r
52 {\r
53   _langPairs.Clear();\r
54   NWindows::NFile::NIO::CInFile file;\r
55   if (!file.Open(fileName))\r
56     return false;\r
57   UInt64 length;\r
58   if (!file.GetLength(length))\r
59     return false;\r
60   if (length > (1 << 20))\r
61     return false;\r
62   AString s;\r
63   char *p = s.GetBuffer((int)length + 1);\r
64   UInt32 processed;\r
65   if (!file.Read(p, (UInt32)length, processed))\r
66     return false;\r
67   p[(UInt32)length] = 0;\r
68   s.ReleaseBuffer();\r
69   file.Close();\r
70   int pos = 0;\r
71   if (s.Length() >= 3)\r
72   {\r
73     if (Byte(s[0]) == 0xEF && Byte(s[1]) == 0xBB && Byte(s[2]) == 0xBF)\r
74       pos += 3;\r
75   }\r
76 \r
77   /////////////////////\r
78   // read header\r
79 \r
80   AString stringID = ";!@Lang@!UTF-8!";\r
81   if (s.Mid(pos, stringID.Length()) != stringID)\r
82     return false;\r
83   pos += stringID.Length();\r
84   \r
85   if (!WaitNextLine(s, pos))\r
86     return false;\r
87 \r
88   CObjectVector<CTextConfigPair> pairs;\r
89   if (!GetTextConfig(s.Mid(pos), pairs))\r
90     return false;\r
91 \r
92   _langPairs.Reserve(_langPairs.Size());\r
93   for (int i = 0; i < pairs.Size(); i++)\r
94   {\r
95     CTextConfigPair textConfigPair = pairs[i];\r
96     CLangPair langPair;\r
97     if (!HexStringToNumber(textConfigPair.ID, langPair.Value))\r
98       return false;\r
99     langPair.String = textConfigPair.String;\r
100     _langPairs.Add(langPair);\r
101   }\r
102   _langPairs.Sort(CompareLangItems, NULL);\r
103   return true;\r
104 }\r
105 \r
106 int CLang::FindItem(UInt32 value) const\r
107 {\r
108   int left = 0, right = _langPairs.Size();\r
109   while (left != right)\r
110   {\r
111     UInt32 mid = (left + right) / 2;\r
112     UInt32 midValue = _langPairs[mid].Value;\r
113     if (value == midValue)\r
114       return mid;\r
115     if (value < midValue)\r
116       right = mid;\r
117     else\r
118       left = mid + 1;\r
119   }\r
120   return -1;\r
121 }\r
122 \r
123 bool CLang::GetMessage(UInt32 value, UString &message) const\r
124 {\r
125   int index =  FindItem(value);\r
126   if (index < 0)\r
127     return false;\r
128   message = _langPairs[index].String;\r
129   return true;\r
130 }\r