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 14static const char kQuoteChar = '\"'; 15 16static 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 28bool 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