• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Common/ListFileUtils.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../C/CpuArch.h"
6 
7 #include "ListFileUtils.h"
8 #include "MyBuffer.h"
9 #include "StringConvert.h"
10 #include "UTFConvert.h"
11 
12 #include "../Windows/FileIO.h"
13 
14 #define CSysInFile NWindows::NFile::NIO::CInFile
15 #define MY_GET_LAST_ERROR ::GetLastError()
16 
17 
18 #define kQuoteChar '\"'
19 
20 
AddName(UStringVector & strings,UString & s)21 static void AddName(UStringVector &strings, UString &s)
22 {
23   s.Trim();
24   if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
25   {
26     s.DeleteBack();
27     s.Delete(0);
28   }
29   if (!s.IsEmpty())
30     strings.Add(s);
31 }
32 
33 
My_File_Read(CSysInFile & file,void * data,size_t size,DWORD & lastError)34 static bool My_File_Read(CSysInFile &file, void *data, size_t size, DWORD &lastError)
35 {
36   size_t processed;
37   if (!file.ReadFull(data, size, processed))
38   {
39     lastError = MY_GET_LAST_ERROR;
40     return false;
41   }
42   if (processed != size)
43   {
44     lastError = 1; // error: size of listfile was changed
45     return false;
46   }
47   return true;
48 }
49 
50 
ReadNamesFromListFile2(CFSTR fileName,UStringVector & strings,UINT codePage,DWORD & lastError)51 bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, DWORD &lastError)
52 {
53   lastError = 0;
54   CSysInFile file;
55   if (!file.Open(fileName))
56   {
57     lastError = MY_GET_LAST_ERROR;
58     return false;
59   }
60   UInt64 fileSize;
61   if (!file.GetLength(fileSize))
62   {
63     lastError = MY_GET_LAST_ERROR;
64     return false;
65   }
66   if (fileSize >= ((UInt32)1 << 31) - 32)
67     return false;
68   UString u;
69   if (codePage == Z7_WIN_CP_UTF16 || codePage == Z7_WIN_CP_UTF16BE)
70   {
71     if ((fileSize & 1) != 0)
72       return false;
73     CByteArr buf((size_t)fileSize);
74 
75     if (!My_File_Read(file, buf, (size_t)fileSize, lastError))
76       return false;
77 
78     file.Close();
79     const unsigned num = (unsigned)fileSize / 2;
80     wchar_t *p = u.GetBuf(num);
81     if (codePage == Z7_WIN_CP_UTF16)
82       for (unsigned i = 0; i < num; i++)
83       {
84         wchar_t c = GetUi16(buf + (size_t)i * 2);
85         if (c == 0)
86           return false;
87         p[i] = c;
88       }
89     else
90       for (unsigned i = 0; i < num; i++)
91       {
92         wchar_t c = (wchar_t)GetBe16(buf + (size_t)i * 2);
93         if (c == 0)
94           return false;
95         p[i] = c;
96       }
97     p[num] = 0;
98     u.ReleaseBuf_SetLen(num);
99   }
100   else
101   {
102     AString s;
103     char *p = s.GetBuf((unsigned)fileSize);
104 
105     if (!My_File_Read(file, p, (size_t)fileSize, lastError))
106       return false;
107 
108     file.Close();
109     s.ReleaseBuf_CalcLen((unsigned)fileSize);
110     if (s.Len() != fileSize)
111       return false;
112 
113     // #ifdef CP_UTF8
114     if (codePage == CP_UTF8)
115     {
116       // we must check UTF8 here, if convert function doesn't check
117       if (!CheckUTF8_AString(s))
118         return false;
119       if (!ConvertUTF8ToUnicode(s, u))
120         return false;
121     }
122     else
123     // #endif
124       MultiByteToUnicodeString2(u, s, codePage);
125   }
126 
127   const wchar_t kGoodBOM = 0xFEFF;
128   // const wchar_t kBadBOM  = 0xFFFE;
129 
130   UString s;
131   unsigned i = 0;
132   for (; i < u.Len() && u[i] == kGoodBOM; i++);
133   for (; i < u.Len(); i++)
134   {
135     wchar_t c = u[i];
136     /*
137     if (c == kGoodBOM || c == kBadBOM)
138       return false;
139     */
140     if (c == '\n' || c == 0xD)
141     {
142       AddName(strings, s);
143       s.Empty();
144     }
145     else
146       s += c;
147   }
148   AddName(strings, s);
149   return true;
150 }
151