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 Workervoid 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 Workerbool 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 Workerbool 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 Workerconst 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