mirror of
https://github.com/holub/mame
synced 2025-06-08 05:44:09 +03:00
151 lines
3.0 KiB
C++
151 lines
3.0 KiB
C++
// Common/ListFileUtils.cpp
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "../../C/CpuArch.h"
|
|
|
|
#include "ListFileUtils.h"
|
|
#include "MyBuffer.h"
|
|
#include "StringConvert.h"
|
|
#include "UTFConvert.h"
|
|
|
|
#include "../Windows/FileIO.h"
|
|
|
|
#define CSysInFile NWindows::NFile::NIO::CInFile
|
|
#define MY_GET_LAST_ERROR ::GetLastError()
|
|
|
|
|
|
#define kQuoteChar '\"'
|
|
|
|
|
|
static void AddName(UStringVector &strings, UString &s)
|
|
{
|
|
s.Trim();
|
|
if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
|
|
{
|
|
s.DeleteBack();
|
|
s.Delete(0);
|
|
}
|
|
if (!s.IsEmpty())
|
|
strings.Add(s);
|
|
}
|
|
|
|
|
|
static bool My_File_Read(CSysInFile &file, void *data, size_t size, DWORD &lastError)
|
|
{
|
|
size_t processed;
|
|
if (!file.ReadFull(data, size, processed))
|
|
{
|
|
lastError = MY_GET_LAST_ERROR;
|
|
return false;
|
|
}
|
|
if (processed != size)
|
|
{
|
|
lastError = 1; // error: size of listfile was changed
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, DWORD &lastError)
|
|
{
|
|
lastError = 0;
|
|
CSysInFile file;
|
|
if (!file.Open(fileName))
|
|
{
|
|
lastError = MY_GET_LAST_ERROR;
|
|
return false;
|
|
}
|
|
UInt64 fileSize;
|
|
if (!file.GetLength(fileSize))
|
|
{
|
|
lastError = MY_GET_LAST_ERROR;
|
|
return false;
|
|
}
|
|
if (fileSize >= ((UInt32)1 << 31) - 32)
|
|
return false;
|
|
UString u;
|
|
if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE)
|
|
{
|
|
if ((fileSize & 1) != 0)
|
|
return false;
|
|
CByteArr buf((size_t)fileSize);
|
|
|
|
if (!My_File_Read(file, buf, (size_t)fileSize, lastError))
|
|
return false;
|
|
|
|
file.Close();
|
|
const unsigned num = (unsigned)fileSize / 2;
|
|
wchar_t *p = u.GetBuf(num);
|
|
if (codePage == MY__CP_UTF16)
|
|
for (unsigned i = 0; i < num; i++)
|
|
{
|
|
wchar_t c = GetUi16(buf + (size_t)i * 2);
|
|
if (c == 0)
|
|
return false;
|
|
p[i] = c;
|
|
}
|
|
else
|
|
for (unsigned i = 0; i < num; i++)
|
|
{
|
|
wchar_t c = (wchar_t)GetBe16(buf + (size_t)i * 2);
|
|
if (c == 0)
|
|
return false;
|
|
p[i] = c;
|
|
}
|
|
p[num] = 0;
|
|
u.ReleaseBuf_SetLen(num);
|
|
}
|
|
else
|
|
{
|
|
AString s;
|
|
char *p = s.GetBuf((unsigned)fileSize);
|
|
|
|
if (!My_File_Read(file, p, (size_t)fileSize, lastError))
|
|
return false;
|
|
|
|
file.Close();
|
|
s.ReleaseBuf_CalcLen((unsigned)fileSize);
|
|
if (s.Len() != fileSize)
|
|
return false;
|
|
|
|
// #ifdef CP_UTF8
|
|
if (codePage == CP_UTF8)
|
|
{
|
|
// we must check UTF8 here, if convert function doesn't check
|
|
if (!CheckUTF8_AString(s))
|
|
return false;
|
|
if (!ConvertUTF8ToUnicode(s, u))
|
|
return false;
|
|
}
|
|
else
|
|
// #endif
|
|
MultiByteToUnicodeString2(u, s, codePage);
|
|
}
|
|
|
|
const wchar_t kGoodBOM = 0xFEFF;
|
|
// const wchar_t kBadBOM = 0xFFFE;
|
|
|
|
UString s;
|
|
unsigned i = 0;
|
|
for (; i < u.Len() && u[i] == kGoodBOM; i++);
|
|
for (; i < u.Len(); i++)
|
|
{
|
|
wchar_t c = u[i];
|
|
/*
|
|
if (c == kGoodBOM || c == kBadBOM)
|
|
return false;
|
|
*/
|
|
if (c == '\n' || c == 0xD)
|
|
{
|
|
AddName(strings, s);
|
|
s.Empty();
|
|
}
|
|
else
|
|
s += c;
|
|
}
|
|
AddName(strings, s);
|
|
return true;
|
|
}
|