1370b324cSopenharmony_ci// Common/ListFileUtils.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../C/CpuArch.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "ListFileUtils.h"
8370b324cSopenharmony_ci#include "MyBuffer.h"
9370b324cSopenharmony_ci#include "StringConvert.h"
10370b324cSopenharmony_ci#include "UTFConvert.h"
11370b324cSopenharmony_ci
12370b324cSopenharmony_ci#include "../Windows/FileIO.h"
13370b324cSopenharmony_ci
14370b324cSopenharmony_ci#define CSysInFile NWindows::NFile::NIO::CInFile
15370b324cSopenharmony_ci#define MY_GET_LAST_ERROR ::GetLastError()
16370b324cSopenharmony_ci
17370b324cSopenharmony_ci
18370b324cSopenharmony_ci#define kQuoteChar '\"'
19370b324cSopenharmony_ci
20370b324cSopenharmony_ci
21370b324cSopenharmony_cistatic void AddName(UStringVector &strings, UString &s)
22370b324cSopenharmony_ci{
23370b324cSopenharmony_ci  s.Trim();
24370b324cSopenharmony_ci  if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
25370b324cSopenharmony_ci  {
26370b324cSopenharmony_ci    s.DeleteBack();
27370b324cSopenharmony_ci    s.Delete(0);
28370b324cSopenharmony_ci  }
29370b324cSopenharmony_ci  if (!s.IsEmpty())
30370b324cSopenharmony_ci    strings.Add(s);
31370b324cSopenharmony_ci}
32370b324cSopenharmony_ci
33370b324cSopenharmony_ci
34370b324cSopenharmony_cistatic bool My_File_Read(CSysInFile &file, void *data, size_t size, DWORD &lastError)
35370b324cSopenharmony_ci{
36370b324cSopenharmony_ci  size_t processed;
37370b324cSopenharmony_ci  if (!file.ReadFull(data, size, processed))
38370b324cSopenharmony_ci  {
39370b324cSopenharmony_ci    lastError = MY_GET_LAST_ERROR;
40370b324cSopenharmony_ci    return false;
41370b324cSopenharmony_ci  }
42370b324cSopenharmony_ci  if (processed != size)
43370b324cSopenharmony_ci  {
44370b324cSopenharmony_ci    lastError = 1; // error: size of listfile was changed
45370b324cSopenharmony_ci    return false;
46370b324cSopenharmony_ci  }
47370b324cSopenharmony_ci  return true;
48370b324cSopenharmony_ci}
49370b324cSopenharmony_ci
50370b324cSopenharmony_ci
51370b324cSopenharmony_cibool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, DWORD &lastError)
52370b324cSopenharmony_ci{
53370b324cSopenharmony_ci  lastError = 0;
54370b324cSopenharmony_ci  CSysInFile file;
55370b324cSopenharmony_ci  if (!file.Open(fileName))
56370b324cSopenharmony_ci  {
57370b324cSopenharmony_ci    lastError = MY_GET_LAST_ERROR;
58370b324cSopenharmony_ci    return false;
59370b324cSopenharmony_ci  }
60370b324cSopenharmony_ci  UInt64 fileSize;
61370b324cSopenharmony_ci  if (!file.GetLength(fileSize))
62370b324cSopenharmony_ci  {
63370b324cSopenharmony_ci    lastError = MY_GET_LAST_ERROR;
64370b324cSopenharmony_ci    return false;
65370b324cSopenharmony_ci  }
66370b324cSopenharmony_ci  if (fileSize >= ((UInt32)1 << 31) - 32)
67370b324cSopenharmony_ci    return false;
68370b324cSopenharmony_ci  UString u;
69370b324cSopenharmony_ci  if (codePage == Z7_WIN_CP_UTF16 || codePage == Z7_WIN_CP_UTF16BE)
70370b324cSopenharmony_ci  {
71370b324cSopenharmony_ci    if ((fileSize & 1) != 0)
72370b324cSopenharmony_ci      return false;
73370b324cSopenharmony_ci    CByteArr buf((size_t)fileSize);
74370b324cSopenharmony_ci
75370b324cSopenharmony_ci    if (!My_File_Read(file, buf, (size_t)fileSize, lastError))
76370b324cSopenharmony_ci      return false;
77370b324cSopenharmony_ci
78370b324cSopenharmony_ci    file.Close();
79370b324cSopenharmony_ci    const unsigned num = (unsigned)fileSize / 2;
80370b324cSopenharmony_ci    wchar_t *p = u.GetBuf(num);
81370b324cSopenharmony_ci    if (codePage == Z7_WIN_CP_UTF16)
82370b324cSopenharmony_ci      for (unsigned i = 0; i < num; i++)
83370b324cSopenharmony_ci      {
84370b324cSopenharmony_ci        wchar_t c = GetUi16(buf + (size_t)i * 2);
85370b324cSopenharmony_ci        if (c == 0)
86370b324cSopenharmony_ci          return false;
87370b324cSopenharmony_ci        p[i] = c;
88370b324cSopenharmony_ci      }
89370b324cSopenharmony_ci    else
90370b324cSopenharmony_ci      for (unsigned i = 0; i < num; i++)
91370b324cSopenharmony_ci      {
92370b324cSopenharmony_ci        wchar_t c = (wchar_t)GetBe16(buf + (size_t)i * 2);
93370b324cSopenharmony_ci        if (c == 0)
94370b324cSopenharmony_ci          return false;
95370b324cSopenharmony_ci        p[i] = c;
96370b324cSopenharmony_ci      }
97370b324cSopenharmony_ci    p[num] = 0;
98370b324cSopenharmony_ci    u.ReleaseBuf_SetLen(num);
99370b324cSopenharmony_ci  }
100370b324cSopenharmony_ci  else
101370b324cSopenharmony_ci  {
102370b324cSopenharmony_ci    AString s;
103370b324cSopenharmony_ci    char *p = s.GetBuf((unsigned)fileSize);
104370b324cSopenharmony_ci
105370b324cSopenharmony_ci    if (!My_File_Read(file, p, (size_t)fileSize, lastError))
106370b324cSopenharmony_ci      return false;
107370b324cSopenharmony_ci
108370b324cSopenharmony_ci    file.Close();
109370b324cSopenharmony_ci    s.ReleaseBuf_CalcLen((unsigned)fileSize);
110370b324cSopenharmony_ci    if (s.Len() != fileSize)
111370b324cSopenharmony_ci      return false;
112370b324cSopenharmony_ci
113370b324cSopenharmony_ci    // #ifdef CP_UTF8
114370b324cSopenharmony_ci    if (codePage == CP_UTF8)
115370b324cSopenharmony_ci    {
116370b324cSopenharmony_ci      // we must check UTF8 here, if convert function doesn't check
117370b324cSopenharmony_ci      if (!CheckUTF8_AString(s))
118370b324cSopenharmony_ci        return false;
119370b324cSopenharmony_ci      if (!ConvertUTF8ToUnicode(s, u))
120370b324cSopenharmony_ci        return false;
121370b324cSopenharmony_ci    }
122370b324cSopenharmony_ci    else
123370b324cSopenharmony_ci    // #endif
124370b324cSopenharmony_ci      MultiByteToUnicodeString2(u, s, codePage);
125370b324cSopenharmony_ci  }
126370b324cSopenharmony_ci
127370b324cSopenharmony_ci  const wchar_t kGoodBOM = 0xFEFF;
128370b324cSopenharmony_ci  // const wchar_t kBadBOM  = 0xFFFE;
129370b324cSopenharmony_ci
130370b324cSopenharmony_ci  UString s;
131370b324cSopenharmony_ci  unsigned i = 0;
132370b324cSopenharmony_ci  for (; i < u.Len() && u[i] == kGoodBOM; i++);
133370b324cSopenharmony_ci  for (; i < u.Len(); i++)
134370b324cSopenharmony_ci  {
135370b324cSopenharmony_ci    wchar_t c = u[i];
136370b324cSopenharmony_ci    /*
137370b324cSopenharmony_ci    if (c == kGoodBOM || c == kBadBOM)
138370b324cSopenharmony_ci      return false;
139370b324cSopenharmony_ci    */
140370b324cSopenharmony_ci    if (c == '\n' || c == 0xD)
141370b324cSopenharmony_ci    {
142370b324cSopenharmony_ci      AddName(strings, s);
143370b324cSopenharmony_ci      s.Empty();
144370b324cSopenharmony_ci    }
145370b324cSopenharmony_ci    else
146370b324cSopenharmony_ci      s += c;
147370b324cSopenharmony_ci  }
148370b324cSopenharmony_ci  AddName(strings, s);
149370b324cSopenharmony_ci  return true;
150370b324cSopenharmony_ci}
151