1 // Common/ListFileUtils.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../C/CpuArch.h"
6
7 #include "../Windows/FileIO.h"
8
9 #include "ListFileUtils.h"
10 #include "MyBuffer.h"
11 #include "StringConvert.h"
12 #include "UTFConvert.h"
13
14 static const char kQuoteChar = '\"';
15
AddName(UStringVector & strings,UString & s)16 static void AddName(UStringVector &strings, UString &s)
17 {
18 s.Trim();
19 if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
20 {
21 s.DeleteBack();
22 s.Delete(0);
23 }
24 if (!s.IsEmpty())
25 strings.Add(s);
26 }
27
ReadNamesFromListFile(CFSTR fileName,UStringVector & strings,UINT codePage)28 bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage)
29 {
30 NWindows::NFile::NIO::CInFile file;
31 if (!file.Open(fileName))
32 return false;
33 UInt64 fileSize;
34 if (!file.GetLength(fileSize))
35 return false;
36 if (fileSize >= ((UInt32)1 << 31) - 32)
37 return false;
38 UString u;
39 if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE)
40 {
41 if ((fileSize & 1) != 0)
42 return false;
43 CByteArr buf((size_t)fileSize);
44 UInt32 processed;
45 if (!file.Read(buf, (UInt32)fileSize, processed))
46 return false;
47 if (processed != fileSize)
48 return false;
49 file.Close();
50 unsigned num = (unsigned)fileSize / 2;
51 wchar_t *p = u.GetBuf(num);
52 if (codePage == MY__CP_UTF16)
53 for (unsigned i = 0; i < num; i++)
54 {
55 wchar_t c = GetUi16(buf + i * 2);
56 if (c == 0)
57 return false;
58 p[i] = c;
59 }
60 else
61 for (unsigned i = 0; i < num; i++)
62 {
63 wchar_t c = (wchar_t)GetBe16(buf + i * 2);
64 if (c == 0)
65 return false;
66 p[i] = c;
67 }
68 p[num] = 0;
69 u.ReleaseBuf_SetLen(num);
70 }
71 else
72 {
73 AString s;
74 char *p = s.GetBuf((unsigned)fileSize);
75 UInt32 processed;
76 if (!file.Read(p, (UInt32)fileSize, processed))
77 return false;
78 if (processed != fileSize)
79 return false;
80 file.Close();
81 s.ReleaseBuf_CalcLen((unsigned)processed);
82 if (s.Len() != processed)
83 return false;
84
85 // #ifdef CP_UTF8
86 if (codePage == CP_UTF8)
87 {
88 if (!ConvertUTF8ToUnicode(s, u))
89 return false;
90 }
91 else
92 // #endif
93 MultiByteToUnicodeString2(u, s, codePage);
94 }
95
96 const wchar_t kGoodBOM = 0xFEFF;
97 const wchar_t kBadBOM = 0xFFFE;
98
99 UString s;
100 unsigned i = 0;
101 for (; i < u.Len() && u[i] == kGoodBOM; i++);
102 for (; i < u.Len(); i++)
103 {
104 wchar_t c = u[i];
105 if (c == kGoodBOM || c == kBadBOM)
106 return false;
107 if (c == L'\n' || c == 0xD)
108 {
109 AddName(strings, s);
110 s.Empty();
111 }
112 else
113 s += c;
114 }
115 AddName(strings, s);
116 return true;
117 }
118