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 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 28 bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, DWORD &lastError) 29 { 30 lastError = 0; 31 NWindows::NFile::NIO::CInFile file; 32 if (!file.Open(fileName)) 33 { 34 lastError = ::GetLastError(); 35 return false; 36 } 37 UInt64 fileSize; 38 if (!file.GetLength(fileSize)) 39 { 40 lastError = ::GetLastError(); 41 return false; 42 } 43 if (fileSize >= ((UInt32)1 << 31) - 32) 44 return false; 45 UString u; 46 if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE) 47 { 48 if ((fileSize & 1) != 0) 49 return false; 50 CByteArr buf((size_t)fileSize); 51 UInt32 processed; 52 if (!file.Read(buf, (UInt32)fileSize, processed)) 53 { 54 lastError = ::GetLastError(); 55 return false; 56 } 57 if (processed != fileSize) 58 return false; 59 file.Close(); 60 unsigned num = (unsigned)fileSize / 2; 61 wchar_t *p = u.GetBuf(num); 62 if (codePage == MY__CP_UTF16) 63 for (unsigned i = 0; i < num; i++) 64 { 65 wchar_t c = GetUi16(buf + (size_t)i * 2); 66 if (c == 0) 67 return false; 68 p[i] = c; 69 } 70 else 71 for (unsigned i = 0; i < num; i++) 72 { 73 wchar_t c = (wchar_t)GetBe16(buf + (size_t)i * 2); 74 if (c == 0) 75 return false; 76 p[i] = c; 77 } 78 p[num] = 0; 79 u.ReleaseBuf_SetLen(num); 80 } 81 else 82 { 83 AString s; 84 char *p = s.GetBuf((unsigned)fileSize); 85 UInt32 processed; 86 if (!file.Read(p, (UInt32)fileSize, processed)) 87 { 88 lastError = ::GetLastError(); 89 return false; 90 } 91 if (processed != fileSize) 92 return false; 93 file.Close(); 94 s.ReleaseBuf_CalcLen((unsigned)processed); 95 if (s.Len() != processed) 96 return false; 97 98 // #ifdef CP_UTF8 99 if (codePage == CP_UTF8) 100 { 101 if (!ConvertUTF8ToUnicode(s, u)) 102 return false; 103 } 104 else 105 // #endif 106 MultiByteToUnicodeString2(u, s, codePage); 107 } 108 109 const wchar_t kGoodBOM = 0xFEFF; 110 const wchar_t kBadBOM = 0xFFFE; 111 112 UString s; 113 unsigned i = 0; 114 for (; i < u.Len() && u[i] == kGoodBOM; i++); 115 for (; i < u.Len(); i++) 116 { 117 wchar_t c = u[i]; 118 if (c == kGoodBOM || c == kBadBOM) 119 return false; 120 if (c == '\n' || c == 0xD) 121 { 122 AddName(strings, s); 123 s.Empty(); 124 } 125 else 126 s += c; 127 } 128 AddName(strings, s); 129 return true; 130 } 131