xref: /aosp_15_r20/external/lzma/CPP/Common/ListFileUtils.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Common/ListFileUtils.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../C/CpuArch.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "ListFileUtils.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "MyBuffer.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "StringConvert.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "UTFConvert.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "../Windows/FileIO.h"
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #define CSysInFile NWindows::NFile::NIO::CInFile
15*f6dc9357SAndroid Build Coastguard Worker #define MY_GET_LAST_ERROR ::GetLastError()
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker #define kQuoteChar '\"'
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker 
AddName(UStringVector & strings,UString & s)21*f6dc9357SAndroid Build Coastguard Worker static void AddName(UStringVector &strings, UString &s)
22*f6dc9357SAndroid Build Coastguard Worker {
23*f6dc9357SAndroid Build Coastguard Worker   s.Trim();
24*f6dc9357SAndroid Build Coastguard Worker   if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
25*f6dc9357SAndroid Build Coastguard Worker   {
26*f6dc9357SAndroid Build Coastguard Worker     s.DeleteBack();
27*f6dc9357SAndroid Build Coastguard Worker     s.Delete(0);
28*f6dc9357SAndroid Build Coastguard Worker   }
29*f6dc9357SAndroid Build Coastguard Worker   if (!s.IsEmpty())
30*f6dc9357SAndroid Build Coastguard Worker     strings.Add(s);
31*f6dc9357SAndroid Build Coastguard Worker }
32*f6dc9357SAndroid Build Coastguard Worker 
33*f6dc9357SAndroid Build Coastguard Worker 
My_File_Read(CSysInFile & file,void * data,size_t size,DWORD & lastError)34*f6dc9357SAndroid Build Coastguard Worker static bool My_File_Read(CSysInFile &file, void *data, size_t size, DWORD &lastError)
35*f6dc9357SAndroid Build Coastguard Worker {
36*f6dc9357SAndroid Build Coastguard Worker   size_t processed;
37*f6dc9357SAndroid Build Coastguard Worker   if (!file.ReadFull(data, size, processed))
38*f6dc9357SAndroid Build Coastguard Worker   {
39*f6dc9357SAndroid Build Coastguard Worker     lastError = MY_GET_LAST_ERROR;
40*f6dc9357SAndroid Build Coastguard Worker     return false;
41*f6dc9357SAndroid Build Coastguard Worker   }
42*f6dc9357SAndroid Build Coastguard Worker   if (processed != size)
43*f6dc9357SAndroid Build Coastguard Worker   {
44*f6dc9357SAndroid Build Coastguard Worker     lastError = 1; // error: size of listfile was changed
45*f6dc9357SAndroid Build Coastguard Worker     return false;
46*f6dc9357SAndroid Build Coastguard Worker   }
47*f6dc9357SAndroid Build Coastguard Worker   return true;
48*f6dc9357SAndroid Build Coastguard Worker }
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker 
ReadNamesFromListFile2(CFSTR fileName,UStringVector & strings,UINT codePage,DWORD & lastError)51*f6dc9357SAndroid Build Coastguard Worker bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, DWORD &lastError)
52*f6dc9357SAndroid Build Coastguard Worker {
53*f6dc9357SAndroid Build Coastguard Worker   lastError = 0;
54*f6dc9357SAndroid Build Coastguard Worker   CSysInFile file;
55*f6dc9357SAndroid Build Coastguard Worker   if (!file.Open(fileName))
56*f6dc9357SAndroid Build Coastguard Worker   {
57*f6dc9357SAndroid Build Coastguard Worker     lastError = MY_GET_LAST_ERROR;
58*f6dc9357SAndroid Build Coastguard Worker     return false;
59*f6dc9357SAndroid Build Coastguard Worker   }
60*f6dc9357SAndroid Build Coastguard Worker   UInt64 fileSize;
61*f6dc9357SAndroid Build Coastguard Worker   if (!file.GetLength(fileSize))
62*f6dc9357SAndroid Build Coastguard Worker   {
63*f6dc9357SAndroid Build Coastguard Worker     lastError = MY_GET_LAST_ERROR;
64*f6dc9357SAndroid Build Coastguard Worker     return false;
65*f6dc9357SAndroid Build Coastguard Worker   }
66*f6dc9357SAndroid Build Coastguard Worker   if (fileSize >= ((UInt32)1 << 31) - 32)
67*f6dc9357SAndroid Build Coastguard Worker     return false;
68*f6dc9357SAndroid Build Coastguard Worker   UString u;
69*f6dc9357SAndroid Build Coastguard Worker   if (codePage == Z7_WIN_CP_UTF16 || codePage == Z7_WIN_CP_UTF16BE)
70*f6dc9357SAndroid Build Coastguard Worker   {
71*f6dc9357SAndroid Build Coastguard Worker     if ((fileSize & 1) != 0)
72*f6dc9357SAndroid Build Coastguard Worker       return false;
73*f6dc9357SAndroid Build Coastguard Worker     CByteArr buf((size_t)fileSize);
74*f6dc9357SAndroid Build Coastguard Worker 
75*f6dc9357SAndroid Build Coastguard Worker     if (!My_File_Read(file, buf, (size_t)fileSize, lastError))
76*f6dc9357SAndroid Build Coastguard Worker       return false;
77*f6dc9357SAndroid Build Coastguard Worker 
78*f6dc9357SAndroid Build Coastguard Worker     file.Close();
79*f6dc9357SAndroid Build Coastguard Worker     const size_t num = (size_t)fileSize / 2;
80*f6dc9357SAndroid Build Coastguard Worker     wchar_t *p = u.GetBuf((unsigned)num);
81*f6dc9357SAndroid Build Coastguard Worker     if (codePage == Z7_WIN_CP_UTF16)
82*f6dc9357SAndroid Build Coastguard Worker       for (size_t i = 0; i < num; i++)
83*f6dc9357SAndroid Build Coastguard Worker       {
84*f6dc9357SAndroid Build Coastguard Worker         const wchar_t c = GetUi16(buf.ConstData() + (size_t)i * 2);
85*f6dc9357SAndroid Build Coastguard Worker         if (c == 0)
86*f6dc9357SAndroid Build Coastguard Worker           return false;
87*f6dc9357SAndroid Build Coastguard Worker         p[i] = c;
88*f6dc9357SAndroid Build Coastguard Worker       }
89*f6dc9357SAndroid Build Coastguard Worker     else
90*f6dc9357SAndroid Build Coastguard Worker       for (size_t i = 0; i < num; i++)
91*f6dc9357SAndroid Build Coastguard Worker       {
92*f6dc9357SAndroid Build Coastguard Worker         const wchar_t c = (wchar_t)GetBe16(buf.ConstData() + (size_t)i * 2);
93*f6dc9357SAndroid Build Coastguard Worker         if (c == 0)
94*f6dc9357SAndroid Build Coastguard Worker           return false;
95*f6dc9357SAndroid Build Coastguard Worker         p[i] = c;
96*f6dc9357SAndroid Build Coastguard Worker       }
97*f6dc9357SAndroid Build Coastguard Worker     p[num] = 0;
98*f6dc9357SAndroid Build Coastguard Worker     u.ReleaseBuf_SetLen((unsigned)num);
99*f6dc9357SAndroid Build Coastguard Worker   }
100*f6dc9357SAndroid Build Coastguard Worker   else
101*f6dc9357SAndroid Build Coastguard Worker   {
102*f6dc9357SAndroid Build Coastguard Worker     AString s;
103*f6dc9357SAndroid Build Coastguard Worker     char *p = s.GetBuf((unsigned)fileSize);
104*f6dc9357SAndroid Build Coastguard Worker 
105*f6dc9357SAndroid Build Coastguard Worker     if (!My_File_Read(file, p, (size_t)fileSize, lastError))
106*f6dc9357SAndroid Build Coastguard Worker       return false;
107*f6dc9357SAndroid Build Coastguard Worker 
108*f6dc9357SAndroid Build Coastguard Worker     file.Close();
109*f6dc9357SAndroid Build Coastguard Worker     s.ReleaseBuf_CalcLen((unsigned)fileSize);
110*f6dc9357SAndroid Build Coastguard Worker     if (s.Len() != fileSize)
111*f6dc9357SAndroid Build Coastguard Worker       return false;
112*f6dc9357SAndroid Build Coastguard Worker 
113*f6dc9357SAndroid Build Coastguard Worker     // #ifdef CP_UTF8
114*f6dc9357SAndroid Build Coastguard Worker     if (codePage == CP_UTF8)
115*f6dc9357SAndroid Build Coastguard Worker     {
116*f6dc9357SAndroid Build Coastguard Worker       // we must check UTF8 here, if convert function doesn't check
117*f6dc9357SAndroid Build Coastguard Worker       if (!CheckUTF8_AString(s))
118*f6dc9357SAndroid Build Coastguard Worker         return false;
119*f6dc9357SAndroid Build Coastguard Worker       if (!ConvertUTF8ToUnicode(s, u))
120*f6dc9357SAndroid Build Coastguard Worker         return false;
121*f6dc9357SAndroid Build Coastguard Worker     }
122*f6dc9357SAndroid Build Coastguard Worker     else
123*f6dc9357SAndroid Build Coastguard Worker     // #endif
124*f6dc9357SAndroid Build Coastguard Worker       MultiByteToUnicodeString2(u, s, codePage);
125*f6dc9357SAndroid Build Coastguard Worker   }
126*f6dc9357SAndroid Build Coastguard Worker 
127*f6dc9357SAndroid Build Coastguard Worker   const wchar_t kGoodBOM = 0xFEFF;
128*f6dc9357SAndroid Build Coastguard Worker   // const wchar_t kBadBOM  = 0xFFFE;
129*f6dc9357SAndroid Build Coastguard Worker 
130*f6dc9357SAndroid Build Coastguard Worker   UString s;
131*f6dc9357SAndroid Build Coastguard Worker   unsigned i = 0;
132*f6dc9357SAndroid Build Coastguard Worker   for (; i < u.Len() && u[i] == kGoodBOM; i++);
133*f6dc9357SAndroid Build Coastguard Worker   for (; i < u.Len(); i++)
134*f6dc9357SAndroid Build Coastguard Worker   {
135*f6dc9357SAndroid Build Coastguard Worker     wchar_t c = u[i];
136*f6dc9357SAndroid Build Coastguard Worker     /*
137*f6dc9357SAndroid Build Coastguard Worker     if (c == kGoodBOM || c == kBadBOM)
138*f6dc9357SAndroid Build Coastguard Worker       return false;
139*f6dc9357SAndroid Build Coastguard Worker     */
140*f6dc9357SAndroid Build Coastguard Worker     if (c == '\n' || c == 0xD)
141*f6dc9357SAndroid Build Coastguard Worker     {
142*f6dc9357SAndroid Build Coastguard Worker       AddName(strings, s);
143*f6dc9357SAndroid Build Coastguard Worker       s.Empty();
144*f6dc9357SAndroid Build Coastguard Worker     }
145*f6dc9357SAndroid Build Coastguard Worker     else
146*f6dc9357SAndroid Build Coastguard Worker       s += c;
147*f6dc9357SAndroid Build Coastguard Worker   }
148*f6dc9357SAndroid Build Coastguard Worker   AddName(strings, s);
149*f6dc9357SAndroid Build Coastguard Worker   return true;
150*f6dc9357SAndroid Build Coastguard Worker }
151