chore: initial commit (extracted from Launchers monorepo)
Plugin: ns7zip v2.0.0 Architectures: x86-ansi, x86-unicode, amd64-unicode License: LGPL-2.1-or-later
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
// Common/Lang.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Lang.h"
|
||||
#include "StringToInt.h"
|
||||
#include "UTFConvert.h"
|
||||
|
||||
#include "../Windows/FileIO.h"
|
||||
|
||||
void CLang::Clear() throw()
|
||||
{
|
||||
_ids.Clear();
|
||||
_offsets.Clear();
|
||||
Comments.Clear();
|
||||
delete []_text;
|
||||
_text = NULL;
|
||||
}
|
||||
|
||||
static const char * const kLangSignature = ";!@Lang2@!UTF-8!\n";
|
||||
|
||||
bool CLang::OpenFromString(const AString &s2)
|
||||
{
|
||||
UString su;
|
||||
if (!ConvertUTF8ToUnicode(s2, su))
|
||||
return false;
|
||||
if (su.IsEmpty())
|
||||
return false;
|
||||
const wchar_t *s = su;
|
||||
const wchar_t *sLim = s + su.Len();
|
||||
if (*s == 0xFEFF)
|
||||
s++;
|
||||
for (const char *p = kLangSignature;; s++)
|
||||
{
|
||||
const Byte c = (Byte)(*p++);
|
||||
if (c == 0)
|
||||
break;
|
||||
if (*s != c)
|
||||
return false;
|
||||
}
|
||||
|
||||
wchar_t *text = new wchar_t[(size_t)(sLim - s) + 1];
|
||||
_text = text;
|
||||
|
||||
UString comment;
|
||||
Int32 id = -1024;
|
||||
unsigned pos = 0;
|
||||
|
||||
while (s != sLim)
|
||||
{
|
||||
const unsigned start = pos;
|
||||
do
|
||||
{
|
||||
wchar_t c = *s++;
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (c == '\\')
|
||||
{
|
||||
if (s == sLim)
|
||||
return false;
|
||||
c = *s++;
|
||||
switch (c)
|
||||
{
|
||||
case '\n': return false;
|
||||
case 'n': c = '\n'; break;
|
||||
case 't': c = '\t'; break;
|
||||
case '\\': /* c = '\\'; */ break;
|
||||
default: text[pos++] = L'\\'; break;
|
||||
}
|
||||
}
|
||||
text[pos++] = c;
|
||||
}
|
||||
while (s != sLim);
|
||||
|
||||
{
|
||||
unsigned j = start;
|
||||
for (; j < pos; j++)
|
||||
if (text[j] != ' ' && text[j] != '\t')
|
||||
break;
|
||||
if (j == pos)
|
||||
{
|
||||
id++;
|
||||
pos = start;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// start != pos
|
||||
text[pos++] = 0;
|
||||
|
||||
if (text[start] == ';')
|
||||
{
|
||||
comment = text + start;
|
||||
comment.TrimRight();
|
||||
if (comment.Len() != 1)
|
||||
Comments.Add(comment);
|
||||
id++;
|
||||
pos = start;
|
||||
continue;
|
||||
}
|
||||
|
||||
const wchar_t *end;
|
||||
const UInt32 id32 = ConvertStringToUInt32(text + start, &end);
|
||||
if (*end == 0)
|
||||
{
|
||||
if (id32 > ((UInt32)1 << 30) || (Int32)id32 < id)
|
||||
return false;
|
||||
id = (Int32)id32;
|
||||
pos = start;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (id < 0)
|
||||
return false;
|
||||
_ids.Add((UInt32)id++);
|
||||
_offsets.Add(start);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLang::Open(CFSTR fileName, const char *id)
|
||||
{
|
||||
Clear();
|
||||
NWindows::NFile::NIO::CInFile file;
|
||||
if (!file.Open(fileName))
|
||||
return false;
|
||||
UInt64 length;
|
||||
if (!file.GetLength(length))
|
||||
return false;
|
||||
if (length > (1 << 20))
|
||||
return false;
|
||||
|
||||
AString s;
|
||||
const unsigned len = (unsigned)length;
|
||||
char *p = s.GetBuf(len);
|
||||
size_t processed;
|
||||
if (!file.ReadFull(p, len, processed))
|
||||
return false;
|
||||
file.Close();
|
||||
if (len != processed)
|
||||
return false;
|
||||
|
||||
char *p2 = p;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
const char c = p[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c != 0x0D)
|
||||
*p2++ = c;
|
||||
}
|
||||
*p2 = 0;
|
||||
s.ReleaseBuf_SetLen((unsigned)(p2 - p));
|
||||
|
||||
if (OpenFromString(s))
|
||||
{
|
||||
const wchar_t *name = Get(0);
|
||||
if (name && StringsAreEqual_Ascii(name, id))
|
||||
return true;
|
||||
}
|
||||
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
const wchar_t *CLang::Get(UInt32 id) const throw()
|
||||
{
|
||||
const int index = _ids.FindInSorted(id);
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
return _text + (size_t)_offsets[(unsigned)index];
|
||||
}
|
||||
Reference in New Issue
Block a user