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