• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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