Home | History | Annotate | Download | only in Common
      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 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