summaryrefslogtreecommitdiffstats
path: root/other-licenses/7zstub/src/CPP/Common
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /other-licenses/7zstub/src/CPP/Common
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'other-licenses/7zstub/src/CPP/Common')
-rw-r--r--other-licenses/7zstub/src/CPP/Common/AutoPtr.h35
-rw-r--r--other-licenses/7zstub/src/CPP/Common/CRC.cpp7
-rw-r--r--other-licenses/7zstub/src/CPP/Common/C_FileIO.cpp92
-rw-r--r--other-licenses/7zstub/src/CPP/Common/C_FileIO.h53
-rw-r--r--other-licenses/7zstub/src/CPP/Common/ComTry.h21
-rw-r--r--other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp197
-rw-r--r--other-licenses/7zstub/src/CPP/Common/CommandLineParser.h63
-rw-r--r--other-licenses/7zstub/src/CPP/Common/Common.h43
-rw-r--r--other-licenses/7zstub/src/CPP/Common/CrcReg.cpp98
-rw-r--r--other-licenses/7zstub/src/CPP/Common/Defs.h15
-rw-r--r--other-licenses/7zstub/src/CPP/Common/DynamicBuffer.h64
-rw-r--r--other-licenses/7zstub/src/CPP/Common/IntToString.cpp193
-rw-r--r--other-licenses/7zstub/src/CPP/Common/IntToString.h28
-rw-r--r--other-licenses/7zstub/src/CPP/Common/Lang.h23
-rw-r--r--other-licenses/7zstub/src/CPP/Common/ListFileUtils.cpp117
-rw-r--r--other-licenses/7zstub/src/CPP/Common/ListFileUtils.h14
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyBuffer.h259
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyBuffer2.h45
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyCom.h277
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyException.h14
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyGuidDef.h54
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyInitGuid.h45
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyLinux.h42
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyString.cpp1659
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyString.h867
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyTypes.h35
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyUnknown.h17
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyVector.cpp3
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyVector.h634
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyWindows.cpp145
-rw-r--r--other-licenses/7zstub/src/CPP/Common/MyWindows.h231
-rw-r--r--other-licenses/7zstub/src/CPP/Common/NewHandler.cpp163
-rw-r--r--other-licenses/7zstub/src/CPP/Common/NewHandler.h88
-rw-r--r--other-licenses/7zstub/src/CPP/Common/Sha256Reg.cpp40
-rw-r--r--other-licenses/7zstub/src/CPP/Common/StdAfx.h8
-rw-r--r--other-licenses/7zstub/src/CPP/Common/StdInStream.cpp89
-rw-r--r--other-licenses/7zstub/src/CPP/Common/StdInStream.h38
-rw-r--r--other-licenses/7zstub/src/CPP/Common/StdOutStream.cpp163
-rw-r--r--other-licenses/7zstub/src/CPP/Common/StdOutStream.h71
-rw-r--r--other-licenses/7zstub/src/CPP/Common/StringConvert.cpp319
-rw-r--r--other-licenses/7zstub/src/CPP/Common/StringConvert.h88
-rw-r--r--other-licenses/7zstub/src/CPP/Common/StringToInt.cpp144
-rw-r--r--other-licenses/7zstub/src/CPP/Common/StringToInt.h21
-rw-r--r--other-licenses/7zstub/src/CPP/Common/TextConfig.cpp124
-rw-r--r--other-licenses/7zstub/src/CPP/Common/TextConfig.h19
-rw-r--r--other-licenses/7zstub/src/CPP/Common/UTFConvert.cpp288
-rw-r--r--other-licenses/7zstub/src/CPP/Common/UTFConvert.h12
-rw-r--r--other-licenses/7zstub/src/CPP/Common/Wildcard.cpp676
-rw-r--r--other-licenses/7zstub/src/CPP/Common/Wildcard.h149
-rw-r--r--other-licenses/7zstub/src/CPP/Common/XzCrc64Init.cpp7
-rw-r--r--other-licenses/7zstub/src/CPP/Common/XzCrc64Reg.cpp42
51 files changed, 7939 insertions, 0 deletions
diff --git a/other-licenses/7zstub/src/CPP/Common/AutoPtr.h b/other-licenses/7zstub/src/CPP/Common/AutoPtr.h
new file mode 100644
index 0000000000..e53fb7f5d5
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/AutoPtr.h
@@ -0,0 +1,35 @@
+// Common/AutoPtr.h
+
+#ifndef __COMMON_AUTOPTR_H
+#define __COMMON_AUTOPTR_H
+
+template<class T> class CMyAutoPtr
+{
+ T *_p;
+public:
+ CMyAutoPtr(T *p = 0) : _p(p) {}
+ CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {}
+ CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p)
+ {
+ reset(p.release());
+ return (*this);
+ }
+ ~CMyAutoPtr() { delete _p; }
+ T& operator*() const { return *_p; }
+ // T* operator->() const { return (&**this); }
+ T* get() const { return _p; }
+ T* release()
+ {
+ T *tmp = _p;
+ _p = 0;
+ return tmp;
+ }
+ void reset(T* p = 0)
+ {
+ if (p != _p)
+ delete _p;
+ _p = p;
+ }
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/CRC.cpp b/other-licenses/7zstub/src/CPP/Common/CRC.cpp
new file mode 100644
index 0000000000..6ac52c4c12
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/CRC.cpp
@@ -0,0 +1,7 @@
+// Common/CRC.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/7zCrc.h"
+
+struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit;
diff --git a/other-licenses/7zstub/src/CPP/Common/C_FileIO.cpp b/other-licenses/7zstub/src/CPP/Common/C_FileIO.cpp
new file mode 100644
index 0000000000..d68a427793
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/C_FileIO.cpp
@@ -0,0 +1,92 @@
+// Common/C_FileIO.cpp
+
+#include "C_FileIO.h"
+
+#include <fcntl.h>
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+namespace NC {
+namespace NFile {
+namespace NIO {
+
+bool CFileBase::OpenBinary(const char *name, int flags)
+{
+ #ifdef O_BINARY
+ flags |= O_BINARY;
+ #endif
+ Close();
+ _handle = ::open(name, flags, 0666);
+ return _handle != -1;
+}
+
+bool CFileBase::Close()
+{
+ if (_handle == -1)
+ return true;
+ if (close(_handle) != 0)
+ return false;
+ _handle = -1;
+ return true;
+}
+
+bool CFileBase::GetLength(UInt64 &length) const
+{
+ off_t curPos = Seek(0, SEEK_CUR);
+ off_t lengthTemp = Seek(0, SEEK_END);
+ Seek(curPos, SEEK_SET);
+ length = (UInt64)lengthTemp;
+ return true;
+}
+
+off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const
+{
+ return ::lseek(_handle, distanceToMove, moveMethod);
+}
+
+/////////////////////////
+// CInFile
+
+bool CInFile::Open(const char *name)
+{
+ return CFileBase::OpenBinary(name, O_RDONLY);
+}
+
+bool CInFile::OpenShared(const char *name, bool)
+{
+ return Open(name);
+}
+
+ssize_t CInFile::Read(void *data, size_t size)
+{
+ return read(_handle, data, size);
+}
+
+/////////////////////////
+// COutFile
+
+bool COutFile::Create(const char *name, bool createAlways)
+{
+ if (createAlways)
+ {
+ Close();
+ _handle = ::creat(name, 0666);
+ return _handle != -1;
+ }
+ return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY);
+}
+
+bool COutFile::Open(const char *name, DWORD creationDisposition)
+{
+ return Create(name, false);
+}
+
+ssize_t COutFile::Write(const void *data, size_t size)
+{
+ return write(_handle, data, size);
+}
+
+}}}
diff --git a/other-licenses/7zstub/src/CPP/Common/C_FileIO.h b/other-licenses/7zstub/src/CPP/Common/C_FileIO.h
new file mode 100644
index 0000000000..4c400b41f2
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/C_FileIO.h
@@ -0,0 +1,53 @@
+// Common/C_FileIO.h
+
+#ifndef __COMMON_C_FILEIO_H
+#define __COMMON_C_FILEIO_H
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "MyTypes.h"
+#include "MyWindows.h"
+
+#ifdef _WIN32
+#ifdef _MSC_VER
+typedef size_t ssize_t;
+#endif
+#endif
+
+namespace NC {
+namespace NFile {
+namespace NIO {
+
+class CFileBase
+{
+protected:
+ int _handle;
+ bool OpenBinary(const char *name, int flags);
+public:
+ CFileBase(): _handle(-1) {};
+ ~CFileBase() { Close(); }
+ bool Close();
+ bool GetLength(UInt64 &length) const;
+ off_t Seek(off_t distanceToMove, int moveMethod) const;
+};
+
+class CInFile: public CFileBase
+{
+public:
+ bool Open(const char *name);
+ bool OpenShared(const char *name, bool shareForWrite);
+ ssize_t Read(void *data, size_t size);
+};
+
+class COutFile: public CFileBase
+{
+public:
+ bool Create(const char *name, bool createAlways);
+ bool Open(const char *name, DWORD creationDisposition);
+ ssize_t Write(const void *data, size_t size);
+};
+
+}}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/ComTry.h b/other-licenses/7zstub/src/CPP/Common/ComTry.h
new file mode 100644
index 0000000000..e6b514d44e
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/ComTry.h
@@ -0,0 +1,21 @@
+// ComTry.h
+
+#ifndef __COM_TRY_H
+#define __COM_TRY_H
+
+#include "MyWindows.h"
+// #include "Exception.h"
+// #include "NewHandler.h"
+
+#define COM_TRY_BEGIN try {
+#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; }
+
+/*
+#define COM_TRY_END } \
+ catch(const CNewException &) { return E_OUTOFMEMORY; } \
+ catch(...) { return HRESULT_FROM_WIN32(ERROR_NOACCESS); } \
+*/
+ // catch(const CSystemException &e) { return e.ErrorCode; }
+ // catch(...) { return E_FAIL; }
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp b/other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp
new file mode 100644
index 0000000000..94aabce6dd
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp
@@ -0,0 +1,197 @@
+// CommandLineParser.cpp
+
+#include "StdAfx.h"
+
+#include "CommandLineParser.h"
+
+namespace NCommandLineParser {
+
+bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
+{
+ dest1.Empty();
+ dest2.Empty();
+ bool quoteMode = false;
+ unsigned i;
+ for (i = 0; i < src.Len(); i++)
+ {
+ wchar_t c = src[i];
+ if ((c == L' ' || c == L'\t') && !quoteMode)
+ {
+ dest2 = src.Ptr(i + 1);
+ return i != 0;
+ }
+ if (c == L'\"')
+ quoteMode = !quoteMode;
+ else
+ dest1 += c;
+ }
+ return i != 0;
+}
+
+void SplitCommandLine(const UString &s, UStringVector &parts)
+{
+ UString sTemp (s);
+ sTemp.Trim();
+ parts.Clear();
+ for (;;)
+ {
+ UString s1, s2;
+ if (SplitCommandLine(sTemp, s1, s2))
+ parts.Add(s1);
+ if (s2.IsEmpty())
+ break;
+ sTemp = s2;
+ }
+}
+
+
+static const char * const kStopSwitchParsing = "--";
+
+static bool inline IsItSwitchChar(wchar_t c)
+{
+ return (c == '-');
+}
+
+CParser::CParser():
+ _switches(NULL),
+ StopSwitchIndex(-1)
+{
+}
+
+CParser::~CParser()
+{
+ delete []_switches;
+}
+
+
+// if (s) contains switch then function updates switch structures
+// out: true, if (s) is a switch
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches)
+{
+ if (s.IsEmpty() || !IsItSwitchChar(s[0]))
+ return false;
+
+ unsigned pos = 1;
+ unsigned switchIndex = 0;
+ int maxLen = -1;
+
+ for (unsigned i = 0; i < numSwitches; i++)
+ {
+ const char * const key = switchForms[i].Key;
+ unsigned switchLen = MyStringLen(key);
+ if ((int)switchLen <= maxLen || pos + switchLen > s.Len())
+ continue;
+ if (IsString1PrefixedByString2_NoCase_Ascii((const wchar_t *)s + pos, key))
+ {
+ switchIndex = i;
+ maxLen = switchLen;
+ }
+ }
+
+ if (maxLen < 0)
+ {
+ ErrorMessage = "Unknown switch:";
+ return false;
+ }
+
+ pos += maxLen;
+
+ CSwitchResult &sw = _switches[switchIndex];
+ const CSwitchForm &form = switchForms[switchIndex];
+
+ if (!form.Multi && sw.ThereIs)
+ {
+ ErrorMessage = "Multiple instances for switch:";
+ return false;
+ }
+
+ sw.ThereIs = true;
+
+ int rem = s.Len() - pos;
+ if (rem < form.MinLen)
+ {
+ ErrorMessage = "Too short switch:";
+ return false;
+ }
+
+ sw.WithMinus = false;
+ sw.PostCharIndex = -1;
+
+ switch (form.Type)
+ {
+ case NSwitchType::kMinus:
+ if (rem == 1)
+ {
+ sw.WithMinus = (s[pos] == '-');
+ if (sw.WithMinus)
+ return true;
+ ErrorMessage = "Incorrect switch postfix:";
+ return false;
+ }
+ break;
+
+ case NSwitchType::kChar:
+ if (rem == 1)
+ {
+ wchar_t c = s[pos];
+ if (c <= 0x7F)
+ {
+ sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);
+ if (sw.PostCharIndex >= 0)
+ return true;
+ }
+ ErrorMessage = "Incorrect switch postfix:";
+ return false;
+ }
+ break;
+
+ case NSwitchType::kString:
+ {
+ sw.PostStrings.Add(s.Ptr(pos));
+ return true;
+ }
+ }
+
+ if (pos != s.Len())
+ {
+ ErrorMessage = "Too long switch:";
+ return false;
+ }
+ return true;
+}
+
+
+bool CParser::ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings)
+{
+ StopSwitchIndex = -1;
+ ErrorMessage.Empty();
+ ErrorLine.Empty();
+ NonSwitchStrings.Clear();
+ delete []_switches;
+ _switches = NULL;
+ _switches = new CSwitchResult[numSwitches];
+
+ FOR_VECTOR (i, commandStrings)
+ {
+ const UString &s = commandStrings[i];
+ if (StopSwitchIndex < 0)
+ {
+ if (s.IsEqualTo(kStopSwitchParsing))
+ {
+ StopSwitchIndex = NonSwitchStrings.Size();
+ continue;
+ }
+ if (!s.IsEmpty() && IsItSwitchChar(s[0]))
+ {
+ if (ParseString(s, switchForms, numSwitches))
+ continue;
+ ErrorLine = s;
+ return false;
+ }
+ }
+ NonSwitchStrings.Add(s);
+ }
+ return true;
+}
+
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/CommandLineParser.h b/other-licenses/7zstub/src/CPP/Common/CommandLineParser.h
new file mode 100644
index 0000000000..ec6336c81d
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/CommandLineParser.h
@@ -0,0 +1,63 @@
+// Common/CommandLineParser.h
+
+#ifndef __COMMON_COMMAND_LINE_PARSER_H
+#define __COMMON_COMMAND_LINE_PARSER_H
+
+#include "MyString.h"
+
+namespace NCommandLineParser {
+
+bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
+void SplitCommandLine(const UString &s, UStringVector &parts);
+
+namespace NSwitchType
+{
+ enum EEnum
+ {
+ kSimple,
+ kMinus,
+ kString,
+ kChar
+ };
+}
+
+struct CSwitchForm
+{
+ const char *Key;
+ Byte Type;
+ bool Multi;
+ Byte MinLen;
+ // int MaxLen;
+ const char *PostCharSet;
+};
+
+struct CSwitchResult
+{
+ bool ThereIs;
+ bool WithMinus;
+ int PostCharIndex;
+ UStringVector PostStrings;
+
+ CSwitchResult(): ThereIs(false) {};
+};
+
+class CParser
+{
+ CSwitchResult *_switches;
+
+ bool ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches);
+public:
+ UStringVector NonSwitchStrings;
+ int StopSwitchIndex; // NonSwitchStrings[StopSwitchIndex+] are after "--"
+ AString ErrorMessage;
+ UString ErrorLine;
+
+ CParser();
+ ~CParser();
+ bool ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings);
+ const CSwitchResult& operator[](unsigned index) const { return _switches[index]; }
+};
+
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/Common.h b/other-licenses/7zstub/src/CPP/Common/Common.h
new file mode 100644
index 0000000000..c1ecc7ed44
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/Common.h
@@ -0,0 +1,43 @@
+// Common.h
+
+#ifndef __COMMON_COMMON_H
+#define __COMMON_COMMON_H
+
+/*
+This file is included to all cpp files in 7-Zip.
+Each folder contains StdAfx.h file that includes "Common.h".
+So 7-Zip includes "Common.h" in both modes:
+ with precompiled StdAfx.h
+and
+ without precompiled StdAfx.h
+
+If you use 7-Zip code, you must include "Common.h" before other h files of 7-zip.
+If you don't need some things that are used in 7-Zip,
+you can change this h file or h files included in this file.
+*/
+
+// compiler pragmas to disable some warnings
+#include "../../C/Compiler.h"
+
+// it's <windows.h> or code that defines windows things, if it's not _WIN32
+#include "MyWindows.h"
+
+// NewHandler.h and NewHandler.cpp redefine operator new() to throw exceptions, if compiled with old MSVC compilers
+#include "NewHandler.h"
+
+
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+
+/* There is BUG in MSVC 6.0 compiler for operator new[]:
+ It doesn't check overflow, when it calculates size in bytes for allocated array.
+ So we can use MY_ARRAY_NEW macro instead of new[] operator. */
+
+#if defined(_MSC_VER) && (_MSC_VER == 1200) && !defined(_WIN64)
+ #define MY_ARRAY_NEW(p, T, size) p = new T[(size > (unsigned)0xFFFFFFFF / sizeof(T)) ? (unsigned)0xFFFFFFFF / sizeof(T) : size];
+#else
+ #define MY_ARRAY_NEW(p, T, size) p = new T[size];
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/CrcReg.cpp b/other-licenses/7zstub/src/CPP/Common/CrcReg.cpp
new file mode 100644
index 0000000000..1d9d009038
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/CrcReg.cpp
@@ -0,0 +1,98 @@
+// CrcReg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/7zCrc.h"
+#include "../../C/CpuArch.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/Common/RegisterCodec.h"
+
+EXTERN_C_BEGIN
+
+typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
+
+UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table);
+
+extern CRC_FUNC g_CrcUpdate;
+extern CRC_FUNC g_CrcUpdateT8;
+extern CRC_FUNC g_CrcUpdateT4;
+
+EXTERN_C_END
+
+class CCrcHasher:
+ public IHasher,
+ public ICompressSetCoderProperties,
+ public CMyUnknownImp
+{
+ UInt32 _crc;
+ CRC_FUNC _updateFunc;
+ Byte mtDummy[1 << 7];
+
+ bool SetFunctions(UInt32 tSize);
+public:
+ CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); }
+
+ MY_UNKNOWN_IMP2(IHasher, ICompressSetCoderProperties)
+ INTERFACE_IHasher(;)
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+};
+
+bool CCrcHasher::SetFunctions(UInt32 tSize)
+{
+ _updateFunc = g_CrcUpdate;
+
+ if (tSize == 1)
+ _updateFunc = CrcUpdateT1;
+ else if (tSize == 4)
+ {
+ if (g_CrcUpdateT4)
+ _updateFunc = g_CrcUpdateT4;
+ else
+ return false;
+ }
+ else if (tSize == 8)
+ {
+ if (g_CrcUpdateT8)
+ _updateFunc = g_CrcUpdateT8;
+ else
+ return false;
+ }
+
+ return true;
+}
+
+STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ if (propIDs[i] == NCoderPropID::kDefaultProp)
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ if (!SetFunctions(prop.ulVal))
+ return E_NOTIMPL;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP_(void) CCrcHasher::Init() throw()
+{
+ _crc = CRC_INIT_VAL;
+}
+
+STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size) throw()
+{
+ _crc = _updateFunc(_crc, data, size, g_CrcTable);
+}
+
+STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest) throw()
+{
+ UInt32 val = CRC_GET_DIGEST(_crc);
+ SetUi32(digest, val);
+}
+
+REGISTER_HASHER(CCrcHasher, 0x1, "CRC32", 4)
diff --git a/other-licenses/7zstub/src/CPP/Common/Defs.h b/other-licenses/7zstub/src/CPP/Common/Defs.h
new file mode 100644
index 0000000000..9416098132
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/Defs.h
@@ -0,0 +1,15 @@
+// Common/Defs.h
+
+#ifndef __COMMON_DEFS_H
+#define __COMMON_DEFS_H
+
+template <class T> inline T MyMin(T a, T b) { return a < b ? a : b; }
+template <class T> inline T MyMax(T a, T b) { return a > b ? a : b; }
+
+template <class T> inline int MyCompare(T a, T b)
+ { return a == b ? 0 : (a < b ? -1 : 1); }
+
+inline int BoolToInt(bool v) { return (v ? 1 : 0); }
+inline bool IntToBool(int v) { return (v != 0); }
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/DynamicBuffer.h b/other-licenses/7zstub/src/CPP/Common/DynamicBuffer.h
new file mode 100644
index 0000000000..16c925010e
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/DynamicBuffer.h
@@ -0,0 +1,64 @@
+// Common/DynamicBuffer.h
+
+#ifndef __COMMON_DYNAMIC_BUFFER_H
+#define __COMMON_DYNAMIC_BUFFER_H
+
+template <class T> class CDynamicBuffer
+{
+ T *_items;
+ size_t _size;
+ size_t _pos;
+
+ CDynamicBuffer(const CDynamicBuffer &buffer);
+ void operator=(const CDynamicBuffer &buffer);
+
+ void Grow(size_t size)
+ {
+ size_t delta = _size >= 64 ? _size : 64;
+ if (delta < size)
+ delta = size;
+ size_t newCap = _size + delta;
+ if (newCap < delta)
+ {
+ newCap = _size + size;
+ if (newCap < size)
+ throw 20120116;
+ }
+
+ T *newBuffer = new T[newCap];
+ if (_pos != 0)
+ memcpy(newBuffer, _items, _pos * sizeof(T));
+ delete []_items;
+ _items = newBuffer;
+ _size = newCap;
+ }
+
+public:
+ CDynamicBuffer(): _items(0), _size(0), _pos(0) {}
+ // operator T *() { return _items; }
+ operator const T *() const { return _items; }
+ ~CDynamicBuffer() { delete []_items; }
+
+ T *GetCurPtrAndGrow(size_t addSize)
+ {
+ size_t rem = _size - _pos;
+ if (rem < addSize)
+ Grow(addSize - rem);
+ T *res = _items + _pos;
+ _pos += addSize;
+ return res;
+ }
+
+ void AddData(const T *data, size_t size)
+ {
+ memcpy(GetCurPtrAndGrow(size), data, size * sizeof(T));
+ }
+
+ const size_t GetPos() const { return _pos; }
+
+ // void Empty() { _pos = 0; }
+};
+
+typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/IntToString.cpp b/other-licenses/7zstub/src/CPP/Common/IntToString.cpp
new file mode 100644
index 0000000000..da627caefc
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/IntToString.cpp
@@ -0,0 +1,193 @@
+// Common/IntToString.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/CpuArch.h"
+
+#include "IntToString.h"
+
+#define CONVERT_INT_TO_STR(charType, tempSize) \
+ unsigned char temp[tempSize]; unsigned i = 0; \
+ while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
+ *s++ = (charType)('0' + (unsigned)val); \
+ while (i != 0) { i--; *s++ = temp[i]; } \
+ *s = 0;
+
+void ConvertUInt32ToString(UInt32 val, char *s) throw()
+{
+ CONVERT_INT_TO_STR(char, 16);
+}
+
+void ConvertUInt64ToString(UInt64 val, char *s) throw()
+{
+ if (val <= (UInt32)0xFFFFFFFF)
+ {
+ ConvertUInt32ToString((UInt32)val, s);
+ return;
+ }
+ CONVERT_INT_TO_STR(char, 24);
+}
+
+void ConvertUInt64ToOct(UInt64 val, char *s) throw()
+{
+ UInt64 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 3;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
+ do
+ {
+ unsigned t = (unsigned)(val & 0x7);
+ val >>= 3;
+ s[--i] = (char)('0' + t);
+ }
+ while (i);
+}
+
+
+#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
+
+static inline char GetHexChar(unsigned t) { return GET_HEX_CHAR(t); }
+
+
+void ConvertUInt32ToHex(UInt32 val, char *s) throw()
+{
+ UInt32 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 4;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
+ do
+ {
+ unsigned t = (unsigned)(val & 0xF);
+ val >>= 4;
+ s[--i] = GET_HEX_CHAR(t);
+ }
+ while (i);
+}
+
+
+void ConvertUInt64ToHex(UInt64 val, char *s) throw()
+{
+ UInt64 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 4;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
+ do
+ {
+ unsigned t = (unsigned)(val & 0xF);
+ val >>= 4;
+ s[--i] = GET_HEX_CHAR(t);
+ }
+ while (i);
+}
+
+void ConvertUInt32ToHex8Digits(UInt32 val, char *s) throw()
+{
+ s[8] = 0;
+ for (int i = 7; i >= 0; i--)
+ {
+ unsigned t = val & 0xF;
+ val >>= 4;
+ s[i] = GET_HEX_CHAR(t);;
+ }
+}
+
+/*
+void ConvertUInt32ToHex8Digits(UInt32 val, wchar_t *s)
+{
+ s[8] = 0;
+ for (int i = 7; i >= 0; i--)
+ {
+ unsigned t = val & 0xF;
+ val >>= 4;
+ s[i] = (wchar_t)(((t < 10) ? ('0' + t) : ('A' + (t - 10))));
+ }
+}
+*/
+
+void ConvertUInt32ToString(UInt32 val, wchar_t *s) throw()
+{
+ CONVERT_INT_TO_STR(wchar_t, 16);
+}
+
+void ConvertUInt64ToString(UInt64 val, wchar_t *s) throw()
+{
+ if (val <= (UInt32)0xFFFFFFFF)
+ {
+ ConvertUInt32ToString((UInt32)val, s);
+ return;
+ }
+ CONVERT_INT_TO_STR(wchar_t, 24);
+}
+
+void ConvertInt64ToString(Int64 val, char *s) throw()
+{
+ if (val < 0)
+ {
+ *s++ = '-';
+ val = -val;
+ }
+ ConvertUInt64ToString(val, s);
+}
+
+void ConvertInt64ToString(Int64 val, wchar_t *s) throw()
+{
+ if (val < 0)
+ {
+ *s++ = L'-';
+ val = -val;
+ }
+ ConvertUInt64ToString(val, s);
+}
+
+
+static void ConvertByteToHex2Digits(unsigned v, char *s) throw()
+{
+ s[0] = GetHexChar(v >> 4);
+ s[1] = GetHexChar(v & 0xF);
+}
+
+static void ConvertUInt16ToHex4Digits(UInt32 val, char *s) throw()
+{
+ ConvertByteToHex2Digits(val >> 8, s);
+ ConvertByteToHex2Digits(val & 0xFF, s + 2);
+}
+
+char *RawLeGuidToString(const Byte *g, char *s) throw()
+{
+ ConvertUInt32ToHex8Digits(GetUi32(g ), s); s += 8; *s++ = '-';
+ ConvertUInt16ToHex4Digits(GetUi16(g + 4), s); s += 4; *s++ = '-';
+ ConvertUInt16ToHex4Digits(GetUi16(g + 6), s); s += 4; *s++ = '-';
+ for (unsigned i = 0; i < 8; i++)
+ {
+ if (i == 2)
+ *s++ = '-';
+ ConvertByteToHex2Digits(g[8 + i], s);
+ s += 2;
+ }
+ *s = 0;
+ return s;
+}
+
+char *RawLeGuidToString_Braced(const Byte *g, char *s) throw()
+{
+ *s++ = '{';
+ s = RawLeGuidToString(g, s);
+ *s++ = '}';
+ *s = 0;
+ return s;
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/IntToString.h b/other-licenses/7zstub/src/CPP/Common/IntToString.h
new file mode 100644
index 0000000000..07b67c31fa
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/IntToString.h
@@ -0,0 +1,28 @@
+// Common/IntToString.h
+
+#ifndef __COMMON_INT_TO_STRING_H
+#define __COMMON_INT_TO_STRING_H
+
+#include "MyTypes.h"
+
+void ConvertUInt32ToString(UInt32 value, char *s) throw();
+void ConvertUInt64ToString(UInt64 value, char *s) throw();
+
+void ConvertUInt32ToString(UInt32 value, wchar_t *s) throw();
+void ConvertUInt64ToString(UInt64 value, wchar_t *s) throw();
+
+void ConvertUInt64ToOct(UInt64 value, char *s) throw();
+
+void ConvertUInt32ToHex(UInt32 value, char *s) throw();
+void ConvertUInt64ToHex(UInt64 value, char *s) throw();
+void ConvertUInt32ToHex8Digits(UInt32 value, char *s) throw();
+// void ConvertUInt32ToHex8Digits(UInt32 value, wchar_t *s) throw();
+
+void ConvertInt64ToString(Int64 value, char *s) throw();
+void ConvertInt64ToString(Int64 value, wchar_t *s) throw();
+
+// use RawLeGuid only for RAW bytes that contain stored GUID as Little-endian.
+char *RawLeGuidToString(const Byte *guid, char *s) throw();
+char *RawLeGuidToString_Braced(const Byte *guid, char *s) throw();
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/Lang.h b/other-licenses/7zstub/src/CPP/Common/Lang.h
new file mode 100644
index 0000000000..e95de6859d
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/Lang.h
@@ -0,0 +1,23 @@
+// Common/Lang.h
+
+#ifndef __COMMON_LANG_H
+#define __COMMON_LANG_H
+
+#include "MyString.h"
+
+class CLang
+{
+ wchar_t *_text;
+ CRecordVector<UInt32> _ids;
+ CRecordVector<UInt32> _offsets;
+
+ bool OpenFromString(const AString &s);
+public:
+ CLang(): _text(0) {}
+ ~CLang() { Clear(); }
+ bool Open(CFSTR fileName, const char *id);
+ void Clear() throw();
+ const wchar_t *Get(UInt32 id) const throw();
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/ListFileUtils.cpp b/other-licenses/7zstub/src/CPP/Common/ListFileUtils.cpp
new file mode 100644
index 0000000000..f22680b504
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/ListFileUtils.cpp
@@ -0,0 +1,117 @@
+// Common/ListFileUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/CpuArch.h"
+
+#include "../Windows/FileIO.h"
+
+#include "ListFileUtils.h"
+#include "MyBuffer.h"
+#include "StringConvert.h"
+#include "UTFConvert.h"
+
+static const char kQuoteChar = '\"';
+
+static void AddName(UStringVector &strings, UString &s)
+{
+ s.Trim();
+ if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
+ {
+ s.DeleteBack();
+ s.Delete(0);
+ }
+ if (!s.IsEmpty())
+ strings.Add(s);
+}
+
+bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage)
+{
+ NWindows::NFile::NIO::CInFile file;
+ if (!file.Open(fileName))
+ return false;
+ UInt64 fileSize;
+ if (!file.GetLength(fileSize))
+ return false;
+ if (fileSize >= ((UInt32)1 << 31) - 32)
+ return false;
+ UString u;
+ if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE)
+ {
+ if ((fileSize & 1) != 0)
+ return false;
+ CByteArr buf((size_t)fileSize);
+ UInt32 processed;
+ if (!file.Read(buf, (UInt32)fileSize, processed))
+ return false;
+ if (processed != fileSize)
+ return false;
+ file.Close();
+ unsigned num = (unsigned)fileSize / 2;
+ wchar_t *p = u.GetBuf(num);
+ if (codePage == MY__CP_UTF16)
+ for (unsigned i = 0; i < num; i++)
+ {
+ wchar_t c = GetUi16(buf + (size_t)i * 2);
+ if (c == 0)
+ return false;
+ p[i] = c;
+ }
+ else
+ for (unsigned i = 0; i < num; i++)
+ {
+ wchar_t c = (wchar_t)GetBe16(buf + (size_t)i * 2);
+ if (c == 0)
+ return false;
+ p[i] = c;
+ }
+ p[num] = 0;
+ u.ReleaseBuf_SetLen(num);
+ }
+ else
+ {
+ AString s;
+ char *p = s.GetBuf((unsigned)fileSize);
+ UInt32 processed;
+ if (!file.Read(p, (UInt32)fileSize, processed))
+ return false;
+ if (processed != fileSize)
+ return false;
+ file.Close();
+ s.ReleaseBuf_CalcLen((unsigned)processed);
+ if (s.Len() != processed)
+ return false;
+
+ // #ifdef CP_UTF8
+ if (codePage == CP_UTF8)
+ {
+ if (!ConvertUTF8ToUnicode(s, u))
+ return false;
+ }
+ else
+ // #endif
+ MultiByteToUnicodeString2(u, s, codePage);
+ }
+
+ const wchar_t kGoodBOM = 0xFEFF;
+ const wchar_t kBadBOM = 0xFFFE;
+
+ UString s;
+ unsigned i = 0;
+ for (; i < u.Len() && u[i] == kGoodBOM; i++);
+ for (; i < u.Len(); i++)
+ {
+ wchar_t c = u[i];
+ if (c == kGoodBOM || c == kBadBOM)
+ return false;
+ if (c == '\n' || c == 0xD)
+ {
+ AddName(strings, s);
+ s.Empty();
+ }
+ else
+ s += c;
+ }
+ AddName(strings, s);
+ return true;
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/ListFileUtils.h b/other-licenses/7zstub/src/CPP/Common/ListFileUtils.h
new file mode 100644
index 0000000000..ec32d8e048
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/ListFileUtils.h
@@ -0,0 +1,14 @@
+// Common/ListFileUtils.h
+
+#ifndef __COMMON_LIST_FILE_UTILS_H
+#define __COMMON_LIST_FILE_UTILS_H
+
+#include "MyString.h"
+#include "MyTypes.h"
+
+#define MY__CP_UTF16 1200
+#define MY__CP_UTF16BE 1201
+
+bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyBuffer.h b/other-licenses/7zstub/src/CPP/Common/MyBuffer.h
new file mode 100644
index 0000000000..ae320eefe9
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyBuffer.h
@@ -0,0 +1,259 @@
+// Common/MyBuffer.h
+
+#ifndef __COMMON_MY_BUFFER_H
+#define __COMMON_MY_BUFFER_H
+
+#include "Defs.h"
+
+/* 7-Zip now uses CBuffer only as CByteBuffer.
+ So there is no need to use MY_ARRAY_NEW macro in CBuffer code. */
+
+template <class T> class CBuffer
+{
+ T *_items;
+ size_t _size;
+
+public:
+ void Free()
+ {
+ if (_items)
+ {
+ delete []_items;
+ _items = 0;
+ }
+ _size = 0;
+ }
+
+ CBuffer(): _items(0), _size(0) {};
+ CBuffer(size_t size): _items(0), _size(0) { _items = new T[size]; _size = size; }
+ CBuffer(const CBuffer &buffer): _items(0), _size(0)
+ {
+ size_t size = buffer._size;
+ if (size != 0)
+ {
+ _items = new T[size];
+ memcpy(_items, buffer._items, size * sizeof(T));
+ _size = size;
+ }
+ }
+
+ ~CBuffer() { delete []_items; }
+
+ operator T *() { return _items; }
+ operator const T *() const { return _items; }
+ size_t Size() const { return _size; }
+
+ void Alloc(size_t size)
+ {
+ if (size != _size)
+ {
+ Free();
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ }
+ }
+ }
+
+ void AllocAtLeast(size_t size)
+ {
+ if (size > _size)
+ {
+ Free();
+ _items = new T[size];
+ _size = size;
+ }
+ }
+
+ void CopyFrom(const T *data, size_t size)
+ {
+ Alloc(size);
+ if (size != 0)
+ memcpy(_items, data, size * sizeof(T));
+ }
+
+ void ChangeSize_KeepData(size_t newSize, size_t keepSize)
+ {
+ if (newSize == _size)
+ return;
+ T *newBuffer = NULL;
+ if (newSize != 0)
+ {
+ newBuffer = new T[newSize];
+ if (keepSize > _size)
+ keepSize = _size;
+ if (keepSize != 0)
+ memcpy(newBuffer, _items, MyMin(keepSize, newSize) * sizeof(T));
+ }
+ delete []_items;
+ _items = newBuffer;
+ _size = newSize;
+ }
+
+ CBuffer& operator=(const CBuffer &buffer)
+ {
+ if (&buffer != this)
+ CopyFrom(buffer, buffer._size);
+ return *this;
+ }
+};
+
+template <class T>
+bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ size_t size1 = b1.Size();
+ if (size1 != b2.Size())
+ return false;
+ if (size1 == 0)
+ return true;
+ return memcmp(b1, b2, size1 * sizeof(T)) == 0;
+}
+
+template <class T>
+bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ size_t size1 = b1.Size();
+ if (size1 != b2.Size())
+ return true;
+ if (size1 == 0)
+ return false;
+ return memcmp(b1, b2, size1 * sizeof(T)) != 0;
+}
+
+
+// typedef CBuffer<char> CCharBuffer;
+// typedef CBuffer<wchar_t> CWCharBuffer;
+typedef CBuffer<unsigned char> CByteBuffer;
+
+
+template <class T> class CObjArray
+{
+protected:
+ T *_items;
+private:
+ // we disable copy
+ CObjArray(const CObjArray &buffer);
+ void operator=(const CObjArray &buffer);
+public:
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ }
+ CObjArray(size_t size): _items(0)
+ {
+ if (size != 0)
+ {
+ MY_ARRAY_NEW(_items, T, size)
+ // _items = new T[size];
+ }
+ }
+ CObjArray(): _items(0) {};
+ ~CObjArray() { delete []_items; }
+
+ operator T *() { return _items; }
+ operator const T *() const { return _items; }
+
+ void Alloc(size_t newSize)
+ {
+ delete []_items;
+ _items = 0;
+ MY_ARRAY_NEW(_items, T, newSize)
+ // _items = new T[newSize];
+ }
+};
+
+typedef CObjArray<unsigned char> CByteArr;
+typedef CObjArray<bool> CBoolArr;
+typedef CObjArray<int> CIntArr;
+typedef CObjArray<unsigned> CUIntArr;
+
+
+template <class T> class CObjArray2
+{
+ T *_items;
+ unsigned _size;
+
+ // we disable copy
+ CObjArray2(const CObjArray2 &buffer);
+ void operator=(const CObjArray2 &buffer);
+public:
+
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ _size = 0;
+ }
+ CObjArray2(): _items(0), _size(0) {};
+ /*
+ CObjArray2(const CObjArray2 &buffer): _items(0), _size(0)
+ {
+ size_t newSize = buffer._size;
+ if (newSize != 0)
+ {
+ T *newBuffer = new T[newSize];;
+ _items = newBuffer;
+ _size = newSize;
+ const T *src = buffer;
+ for (size_t i = 0; i < newSize; i++)
+ newBuffer[i] = src[i];
+ }
+ }
+ */
+ /*
+ CObjArray2(size_t size): _items(0), _size(0)
+ {
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ }
+ }
+ */
+
+ ~CObjArray2() { delete []_items; }
+
+ operator T *() { return _items; }
+ operator const T *() const { return _items; }
+
+ unsigned Size() const { return (unsigned)_size; }
+ bool IsEmpty() const { return _size == 0; }
+
+ // SetSize doesn't keep old items. It allocates new array if size is not equal
+ void SetSize(unsigned size)
+ {
+ if (size == _size)
+ return;
+ T *newBuffer = NULL;
+ if (size != 0)
+ {
+ MY_ARRAY_NEW(newBuffer, T, size)
+ // newBuffer = new T[size];
+ }
+ delete []_items;
+ _items = newBuffer;
+ _size = size;
+ }
+
+ /*
+ CObjArray2& operator=(const CObjArray2 &buffer)
+ {
+ Free();
+ size_t newSize = buffer._size;
+ if (newSize != 0)
+ {
+ T *newBuffer = new T[newSize];;
+ _items = newBuffer;
+ _size = newSize;
+ const T *src = buffer;
+ for (size_t i = 0; i < newSize; i++)
+ newBuffer[i] = src[i];
+ }
+ return *this;
+ }
+ */
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyBuffer2.h b/other-licenses/7zstub/src/CPP/Common/MyBuffer2.h
new file mode 100644
index 0000000000..5cabd73c5e
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyBuffer2.h
@@ -0,0 +1,45 @@
+// Common/MyBuffer2.h
+
+#ifndef __COMMON_MY_BUFFER2_H
+#define __COMMON_MY_BUFFER2_H
+
+#include "../../C/Alloc.h"
+
+#include "Defs.h"
+
+class CMidBuffer
+{
+ Byte *_data;
+ size_t _size;
+
+ CLASS_NO_COPY(CMidBuffer)
+
+public:
+ CMidBuffer(): _data(NULL), _size(0) {};
+ ~CMidBuffer() { ::MidFree(_data); }
+
+ void Free() { ::MidFree(_data); _data = NULL; _size = 0; }
+
+ bool IsAllocated() const { return _data != NULL; }
+ operator Byte *() { return _data; }
+ operator const Byte *() const { return _data; }
+ size_t Size() const { return _size; }
+
+ void AllocAtLeast(size_t size)
+ {
+ if (!_data || size > _size)
+ {
+ const size_t kMinSize = (size_t)1 << 16;
+ if (size < kMinSize)
+ size = kMinSize;
+ ::MidFree(_data);
+ _size = 0;
+ _data = 0;
+ _data = (Byte *)::MidAlloc(size);
+ if (_data)
+ _size = size;
+ }
+ }
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyCom.h b/other-licenses/7zstub/src/CPP/Common/MyCom.h
new file mode 100644
index 0000000000..ca49ead992
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyCom.h
@@ -0,0 +1,277 @@
+// MyCom.h
+
+#ifndef __MY_COM_H
+#define __MY_COM_H
+
+#include "MyWindows.h"
+
+#ifndef RINOK
+#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }
+#endif
+
+template <class T>
+class CMyComPtr
+{
+ T* _p;
+public:
+ CMyComPtr(): _p(NULL) {}
+ CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); }
+ CMyComPtr(const CMyComPtr<T>& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); }
+ ~CMyComPtr() { if (_p) _p->Release(); }
+ void Release() { if (_p) { _p->Release(); _p = NULL; } }
+ operator T*() const { return (T*)_p; }
+ // T& operator*() const { return *_p; }
+ T** operator&() { return &_p; }
+ T* operator->() const { return _p; }
+ T* operator=(T* p)
+ {
+ if (p)
+ p->AddRef();
+ if (_p)
+ _p->Release();
+ _p = p;
+ return p;
+ }
+ T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
+ bool operator!() const { return (_p == NULL); }
+ // bool operator==(T* pT) const { return _p == pT; }
+ void Attach(T* p2)
+ {
+ Release();
+ _p = p2;
+ }
+ T* Detach()
+ {
+ T* pt = _p;
+ _p = NULL;
+ return pt;
+ }
+ #ifdef _WIN32
+ HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
+ }
+ #endif
+ /*
+ HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ CLSID clsid;
+ HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
+ ATLASSERT(_p == NULL);
+ if (SUCCEEDED(hr))
+ hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
+ return hr;
+ }
+ */
+ template <class Q>
+ HRESULT QueryInterface(REFGUID iid, Q** pp) const throw()
+ {
+ return _p->QueryInterface(iid, (void**)pp);
+ }
+};
+
+//////////////////////////////////////////////////////////
+
+inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)
+{
+ *bstr = ::SysAllocString(src);
+ return (*bstr) ? S_OK : E_OUTOFMEMORY;
+}
+
+class CMyComBSTR
+{
+ BSTR m_str;
+
+public:
+ CMyComBSTR(): m_str(NULL) {}
+ ~CMyComBSTR() { ::SysFreeString(m_str); }
+ BSTR* operator&() { return &m_str; }
+ operator LPCOLESTR() const { return m_str; }
+ // operator bool() const { return m_str != NULL; }
+ // bool operator!() const { return m_str == NULL; }
+private:
+ // operator BSTR() const { return m_str; }
+
+ CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }
+ // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
+ // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
+ CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
+
+ /*
+ CMyComBSTR(REFGUID src)
+ {
+ LPOLESTR szGuid;
+ StringFromCLSID(src, &szGuid);
+ m_str = ::SysAllocString(szGuid);
+ CoTaskMemFree(szGuid);
+ }
+ */
+
+ CMyComBSTR& operator=(const CMyComBSTR& src)
+ {
+ if (m_str != src.m_str)
+ {
+ if (m_str)
+ ::SysFreeString(m_str);
+ m_str = src.MyCopy();
+ }
+ return *this;
+ }
+
+ CMyComBSTR& operator=(LPCOLESTR src)
+ {
+ ::SysFreeString(m_str);
+ m_str = ::SysAllocString(src);
+ return *this;
+ }
+
+ unsigned Len() const { return ::SysStringLen(m_str); }
+
+ BSTR MyCopy() const
+ {
+ // We don't support Byte BSTRs here
+ return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
+ /*
+ UINT byteLen = ::SysStringByteLen(m_str);
+ BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
+ if (res && byteLen != 0 && m_str)
+ memcpy(res, m_str, byteLen);
+ return res;
+ */
+ }
+
+ /*
+ void Attach(BSTR src) { m_str = src; }
+ BSTR Detach()
+ {
+ BSTR s = m_str;
+ m_str = NULL;
+ return s;
+ }
+ */
+
+ void Empty()
+ {
+ ::SysFreeString(m_str);
+ m_str = NULL;
+ }
+};
+
+
+
+/*
+ If CMyUnknownImp doesn't use virtual destructor, the code size is smaller.
+ But if some class_1 derived from CMyUnknownImp
+ uses MY_ADDREF_RELEASE and IUnknown::Release()
+ and some another class_2 is derived from class_1,
+ then class_1 must use virtual destructor:
+ virtual ~class_1();
+ In that case, class_1::Release() calls correct destructor of class_2.
+
+ Also you can use virtual ~CMyUnknownImp(), if you want to disable warning
+ "class has virtual functions, but destructor is not virtual".
+*/
+
+class CMyUnknownImp
+{
+public:
+ ULONG __m_RefCount;
+ CMyUnknownImp(): __m_RefCount(0) {}
+
+ // virtual
+ ~CMyUnknownImp() {}
+};
+
+
+
+#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
+(REFGUID iid, void **outObject) throw() { *outObject = NULL;
+
+#define MY_QUERYINTERFACE_ENTRY(i) else if (iid == IID_ ## i) \
+ { *outObject = (void *)(i *)this; }
+
+#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
+ { *outObject = (void *)(IUnknown *)(i *)this; }
+
+#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
+ MY_QUERYINTERFACE_ENTRY(i)
+
+#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; ++__m_RefCount; /* AddRef(); */ return S_OK; }
+
+#define MY_ADDREF_RELEASE \
+STDMETHOD_(ULONG, AddRef)() throw() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
+ return __m_RefCount; delete this; return 0; }
+
+#define MY_UNKNOWN_IMP_SPEC(i) \
+ MY_QUERYINTERFACE_BEGIN \
+ i \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+
+#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
+ MY_QUERYINTERFACE_ENTRY(i) \
+ )
+
+#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ )
+
+#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ )
+
+#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ )
+
+#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ )
+
+#define MY_UNKNOWN_IMP6(i1, i2, i3, i4, i5, i6) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ MY_QUERYINTERFACE_ENTRY(i6) \
+ )
+
+#define MY_UNKNOWN_IMP7(i1, i2, i3, i4, i5, i6, i7) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ MY_QUERYINTERFACE_ENTRY(i6) \
+ MY_QUERYINTERFACE_ENTRY(i7) \
+ )
+
+const HRESULT k_My_HRESULT_WritingWasCut = 0x20000010;
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyException.h b/other-licenses/7zstub/src/CPP/Common/MyException.h
new file mode 100644
index 0000000000..cd9fe6948b
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyException.h
@@ -0,0 +1,14 @@
+// Common/Exception.h
+
+#ifndef __COMMON_EXCEPTION_H
+#define __COMMON_EXCEPTION_H
+
+#include "MyWindows.h"
+
+struct CSystemException
+{
+ HRESULT ErrorCode;
+ CSystemException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyGuidDef.h b/other-licenses/7zstub/src/CPP/Common/MyGuidDef.h
new file mode 100644
index 0000000000..e0359e203a
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyGuidDef.h
@@ -0,0 +1,54 @@
+// Common/MyGuidDef.h
+
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+
+#include "MyTypes.h"
+
+typedef struct {
+ UInt32 Data1;
+ UInt16 Data2;
+ UInt16 Data3;
+ unsigned char Data4[8];
+} GUID;
+
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#else
+#define REFGUID const GUID *
+#endif
+
+#define REFCLSID REFGUID
+#define REFIID REFGUID
+
+#ifdef __cplusplus
+inline int operator==(REFGUID g1, REFGUID g2)
+{
+ for (int i = 0; i < (int)sizeof(g1); i++)
+ if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
+ return 0;
+ return 1;
+}
+inline int operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
+#endif
+
+#ifdef __cplusplus
+ #define MY_EXTERN_C extern "C"
+#else
+ #define MY_EXTERN_C extern
+#endif
+
+#endif
+
+
+#ifdef DEFINE_GUID
+#undef DEFINE_GUID
+#endif
+
+#ifdef INITGUID
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+#else
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyInitGuid.h b/other-licenses/7zstub/src/CPP/Common/MyInitGuid.h
new file mode 100644
index 0000000000..79fea19ab8
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyInitGuid.h
@@ -0,0 +1,45 @@
+// Common/MyInitGuid.h
+
+#ifndef __COMMON_MY_INITGUID_H
+#define __COMMON_MY_INITGUID_H
+
+/*
+This file must be included only to one C++ file in project before
+declarations of COM interfaces with DEFINE_GUID macro.
+
+Each GUID must be initialized exactly once in project.
+There are two different versions of the DEFINE_GUID macro in guiddef.h (MyGuidDef.h):
+ - if INITGUID is not defined: DEFINE_GUID declares an external reference to the symbol name.
+ - if INITGUID is defined: DEFINE_GUID initializes the symbol name to the value of the GUID.
+
+Also we need IID_IUnknown that is initialized in some file for linking:
+ MSVC: by default the linker uses some lib file that contains IID_IUnknown
+ MinGW: add -luuid switch for linker
+ WinCE: we define IID_IUnknown in this file
+ Other: we define IID_IUnknown in this file
+*/
+
+#ifdef _WIN32
+
+#ifdef UNDER_CE
+#include <basetyps.h>
+#endif
+
+#include <initguid.h>
+
+#ifdef UNDER_CE
+DEFINE_GUID(IID_IUnknown,
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+#endif
+
+#else
+
+#define INITGUID
+#include "MyGuidDef.h"
+DEFINE_GUID(IID_IUnknown,
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+
+#endif
+
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyLinux.h b/other-licenses/7zstub/src/CPP/Common/MyLinux.h
new file mode 100644
index 0000000000..b4e7605226
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyLinux.h
@@ -0,0 +1,42 @@
+// MyLinux.h
+
+#ifndef __MY_LIN_LINUX_H
+#define __MY_LIN_LINUX_H
+
+#define MY_LIN_S_IFMT 00170000
+#define MY_LIN_S_IFSOCK 0140000
+#define MY_LIN_S_IFLNK 0120000
+#define MY_LIN_S_IFREG 0100000
+#define MY_LIN_S_IFBLK 0060000
+#define MY_LIN_S_IFDIR 0040000
+#define MY_LIN_S_IFCHR 0020000
+#define MY_LIN_S_IFIFO 0010000
+
+#define MY_LIN_S_ISLNK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFLNK)
+#define MY_LIN_S_ISREG(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFREG)
+#define MY_LIN_S_ISDIR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFDIR)
+#define MY_LIN_S_ISCHR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFCHR)
+#define MY_LIN_S_ISBLK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFBLK)
+#define MY_LIN_S_ISFIFO(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFIFO)
+#define MY_LIN_S_ISSOCK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFSOCK)
+
+#define MY_LIN_S_ISUID 0004000
+#define MY_LIN_S_ISGID 0002000
+#define MY_LIN_S_ISVTX 0001000
+
+#define MY_LIN_S_IRWXU 00700
+#define MY_LIN_S_IRUSR 00400
+#define MY_LIN_S_IWUSR 00200
+#define MY_LIN_S_IXUSR 00100
+
+#define MY_LIN_S_IRWXG 00070
+#define MY_LIN_S_IRGRP 00040
+#define MY_LIN_S_IWGRP 00020
+#define MY_LIN_S_IXGRP 00010
+
+#define MY_LIN_S_IRWXO 00007
+#define MY_LIN_S_IROTH 00004
+#define MY_LIN_S_IWOTH 00002
+#define MY_LIN_S_IXOTH 00001
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyString.cpp b/other-licenses/7zstub/src/CPP/Common/MyString.cpp
new file mode 100644
index 0000000000..bf62303df1
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyString.cpp
@@ -0,0 +1,1659 @@
+// Common/MyString.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include <wchar.h>
+#else
+#include <ctype.h>
+#endif
+
+#include "IntToString.h"
+
+#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING)
+#include "StringConvert.h"
+#endif
+
+#include "MyString.h"
+
+#define MY_STRING_NEW(_T_, _size_) new _T_[_size_]
+// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_)))
+
+/*
+inline const char* MyStringGetNextCharPointer(const char *p) throw()
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ return CharNextA(p);
+ #else
+ return p + 1;
+ #endif
+}
+*/
+
+#define MY_STRING_NEW_char(_size_) MY_STRING_NEW(char, _size_)
+#define MY_STRING_NEW_wchar_t(_size_) MY_STRING_NEW(wchar_t, _size_)
+
+
+int FindCharPosInString(const char *s, char c) throw()
+{
+ for (const char *p = s;; p++)
+ {
+ if (*p == c)
+ return (int)(p - s);
+ if (*p == 0)
+ return -1;
+ // MyStringGetNextCharPointer(p);
+ }
+}
+
+int FindCharPosInString(const wchar_t *s, wchar_t c) throw()
+{
+ for (const wchar_t *p = s;; p++)
+ {
+ if (*p == c)
+ return (int)(p - s);
+ if (*p == 0)
+ return -1;
+ }
+}
+
+/*
+void MyStringUpper_Ascii(char *s) throw()
+{
+ for (;;)
+ {
+ char c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharUpper_Ascii(c);
+ }
+}
+
+void MyStringUpper_Ascii(wchar_t *s) throw()
+{
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharUpper_Ascii(c);
+ }
+}
+*/
+
+void MyStringLower_Ascii(char *s) throw()
+{
+ for (;;)
+ {
+ char c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharLower_Ascii(c);
+ }
+}
+
+void MyStringLower_Ascii(wchar_t *s) throw()
+{
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharLower_Ascii(c);
+ }
+}
+
+#ifdef _WIN32
+
+#ifdef _UNICODE
+
+// wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
+// wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
+// for WinCE - FString - char
+// const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; }
+
+#else
+
+// const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); }
+// char * MyStringUpper(char *s) { return CharUpperA(s); }
+// char * MyStringLower(char *s) { return CharLowerA(s); }
+
+wchar_t MyCharUpper_WIN(wchar_t c) throw()
+{
+ wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
+ return c;
+ s[numChars] = 0;
+ ::CharUpperA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
+}
+
+/*
+wchar_t MyCharLower_WIN(wchar_t c)
+{
+ wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
+ return c;
+ s[numChars] = 0;
+ ::CharLowerA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
+}
+*/
+
+/*
+wchar_t * MyStringUpper(wchar_t *s)
+{
+ if (s == 0)
+ return 0;
+ wchar_t *res = CharUpperW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeUpper();
+ MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ return s;
+}
+*/
+
+/*
+wchar_t * MyStringLower(wchar_t *s)
+{
+ if (s == 0)
+ return 0;
+ wchar_t *res = CharLowerW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeLower();
+ MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ return s;
+}
+*/
+
+#endif
+
+#endif
+
+bool IsString1PrefixedByString2(const char *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true;
+ unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false;
+ }
+}
+
+bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false;
+ if (c1 == 0) return true;
+ }
+}
+
+// ---------- ASCII ----------
+
+bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
+{
+ const char *s1 = _chars;
+ for (;;)
+ {
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ char c1 = *s1++;
+ if (MyCharLower_Ascii(c1) !=
+ MyCharLower_Ascii(c2))
+ return false;
+ }
+}
+
+bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
+{
+ const wchar_t *s1 = _chars;
+ for (;;)
+ {
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ wchar_t c1 = *s1++;
+ if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))
+ return false;
+ }
+}
+
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw()
+{
+ for (;;)
+ {
+ unsigned char c = *a;
+ if (c != *u)
+ return false;
+ if (c == 0)
+ return true;
+ a++;
+ u++;
+ }
+}
+
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ char c1 = *s1++;
+ char c2 = *s2++;
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
+}
+
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
+}
+
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ char c2 = *s2++;
+ if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
+}
+
+bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++; if (c1 != c2) return false;
+ }
+}
+
+bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ unsigned char c2 = (unsigned char)(*s2++); if (c2 == 0) return true;
+ wchar_t c1 = *s1++; if (c1 != c2) return false;
+ }
+}
+
+bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ char c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++;
+ if (c1 != (unsigned char)c2 && MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))
+ return false;
+ }
+}
+
+bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++;
+ if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2))
+ return false;
+ }
+}
+
+// NTFS order: uses upper case
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2)
+ {
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ }
+ if (c1 == 0) return 0;
+ }
+}
+
+/*
+int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num)
+{
+ for (; num != 0; num--)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2)
+ {
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ }
+ if (c1 == 0) return 0;
+ }
+ return 0;
+}
+*/
+
+// ---------- AString ----------
+
+void AString::InsertSpace(unsigned &index, unsigned size)
+{
+ Grow(size);
+ MoveItems(index + size, index);
+}
+
+#define k_Alloc_Len_Limit 0x40000000
+
+void AString::ReAlloc(unsigned newLimit)
+{
+ if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130220;
+ // MY_STRING_REALLOC(_chars, char, newLimit + 1, _len + 1);
+ char *newBuf = MY_STRING_NEW_char(newLimit + 1);
+ memcpy(newBuf, _chars, (size_t)(_len + 1));
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = newLimit;
+}
+
+void AString::ReAlloc2(unsigned newLimit)
+{
+ if (newLimit >= k_Alloc_Len_Limit) throw 20130220;
+ // MY_STRING_REALLOC(_chars, char, newLimit + 1, 0);
+ char *newBuf = MY_STRING_NEW_char(newLimit + 1);
+ newBuf[0] = 0;
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = newLimit;
+}
+
+void AString::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW_char(len + 1);
+ _len = len;
+ _limit = len;
+}
+
+void AString::Grow_1()
+{
+ unsigned next = _len;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+void AString::Grow(unsigned n)
+{
+ unsigned freeSize = _limit - _len;
+ if (n <= freeSize)
+ return;
+
+ unsigned next = _len + n;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+AString::AString(unsigned num, const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (num > len)
+ num = len;
+ SetStartLen(num);
+ memcpy(_chars, s, num);
+ _chars[num] = 0;
+}
+
+AString::AString(unsigned num, const AString &s)
+{
+ if (num > s._len)
+ num = s._len;
+ SetStartLen(num);
+ memcpy(_chars, s._chars, num);
+ _chars[num] = 0;
+}
+
+AString::AString(const AString &s, char c)
+{
+ SetStartLen(s.Len() + 1);
+ char *chars = _chars;
+ unsigned len = s.Len();
+ memcpy(chars, s, len);
+ chars[len] = c;
+ chars[(size_t)len + 1] = 0;
+}
+
+AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2)
+{
+ SetStartLen(num1 + num2);
+ char *chars = _chars;
+ memcpy(chars, s1, num1);
+ memcpy(chars + num1, s2, num2 + 1);
+}
+
+AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); }
+AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); }
+AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); }
+
+static const unsigned kStartStringCapacity = 4;
+
+AString::AString()
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW_char(kStartStringCapacity);
+ _len = 0;
+ _limit = kStartStringCapacity - 1;
+ _chars[0] = 0;
+}
+
+AString::AString(char c)
+{
+ SetStartLen(1);
+ char *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
+}
+
+AString::AString(const char *s)
+{
+ SetStartLen(MyStringLen(s));
+ MyStringCopy(_chars, s);
+}
+
+AString::AString(const AString &s)
+{
+ SetStartLen(s._len);
+ MyStringCopy(_chars, s._chars);
+}
+
+AString &AString::operator=(char c)
+{
+ if (1 > _limit)
+ {
+ char *newBuf = MY_STRING_NEW_char(1 + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = 1;
+ }
+ _len = 1;
+ char *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
+ return *this;
+}
+
+AString &AString::operator=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW_char(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s);
+ return *this;
+}
+
+AString &AString::operator=(const AString &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW_char(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s._chars);
+ return *this;
+}
+
+void AString::SetFromWStr_if_Ascii(const wchar_t *s)
+{
+ unsigned len = 0;
+ {
+ for (;; len++)
+ {
+ wchar_t c = s[len];
+ if (c == 0)
+ break;
+ if (c >= 0x80)
+ return;
+ }
+ }
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW_char(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ char *dest = _chars;
+ unsigned i;
+ for (i = 0; i < len; i++)
+ dest[i] = (char)s[i];
+ dest[i] = 0;
+}
+
+/*
+void AString::SetFromBstr_if_Ascii(BSTR s)
+{
+ unsigned len = ::SysStringLen(s);
+ {
+ for (unsigned i = 0; i < len; i++)
+ if (s[i] <= 0 || s[i] >= 0x80)
+ return;
+ }
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW_char(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ char *dest = _chars;
+ unsigned i;
+ for (i = 0; i < len; i++)
+ dest[i] = (char)s[i];
+ dest[i] = 0;
+}
+*/
+
+void AString::Add_Space() { operator+=(' '); }
+void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
+void AString::Add_LF() { operator+=('\n'); }
+
+AString &AString::operator+=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ MyStringCopy(_chars + _len, s);
+ _len += len;
+ return *this;
+}
+
+void AString::Add_OptSpaced(const char *s)
+{
+ Add_Space_if_NotEmpty();
+ (*this) += s;
+}
+
+AString &AString::operator+=(const AString &s)
+{
+ Grow(s._len);
+ MyStringCopy(_chars + _len, s._chars);
+ _len += s._len;
+ return *this;
+}
+
+void AString::Add_UInt32(UInt32 v)
+{
+ char sz[16];
+ ConvertUInt32ToString(v, sz);
+ (*this) += sz;
+}
+
+void AString::SetFrom(const char *s, unsigned len) // no check
+{
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW_char(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ if (len != 0)
+ memcpy(_chars, s, len);
+ _chars[len] = 0;
+ _len = len;
+}
+
+void AString::SetFrom_CalcLen(const char *s, unsigned len) // no check
+{
+ unsigned i;
+ for (i = 0; i < len; i++)
+ if (s[i] == 0)
+ break;
+ SetFrom(s, i);
+}
+
+int AString::Find(const char *s, unsigned startIndex) const throw()
+{
+ const char *fs = strstr(_chars + startIndex, s);
+ if (!fs)
+ return -1;
+ return (int)(fs - _chars);
+
+ /*
+ if (s[0] == 0)
+ return startIndex;
+ unsigned len = MyStringLen(s);
+ const char *p = _chars + startIndex;
+ for (;; p++)
+ {
+ const char c = *p;
+ if (c != s[0])
+ {
+ if (c == 0)
+ return -1;
+ continue;
+ }
+ unsigned i;
+ for (i = 1; i < len; i++)
+ if (p[i] != s[i])
+ break;
+ if (i == len)
+ return (int)(p - _chars);
+ }
+ */
+}
+
+int AString::ReverseFind(char c) const throw()
+{
+ if (_len == 0)
+ return -1;
+ const char *p = _chars + _len - 1;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--; // p = GetPrevCharPointer(_chars, p);
+ }
+}
+
+int AString::ReverseFind_PathSepar() const throw()
+{
+ if (_len == 0)
+ return -1;
+ const char *p = _chars + _len - 1;
+ for (;;)
+ {
+ char c = *p;
+ if (IS_PATH_SEPAR(c))
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--;
+ }
+}
+
+void AString::TrimLeft() throw()
+{
+ const char *p = _chars;
+ for (;; p++)
+ {
+ char c = *p;
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ unsigned pos = (unsigned)(p - _chars);
+ if (pos != 0)
+ {
+ MoveItems(0, pos);
+ _len -= pos;
+ }
+}
+
+void AString::TrimRight() throw()
+{
+ const char *p = _chars;
+ unsigned i;
+ for (i = _len; i != 0; i--)
+ {
+ char c = p[(size_t)i - 1];
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ if (i != _len)
+ {
+ _chars[i] = 0;
+ _len = i;
+ }
+}
+
+void AString::InsertAtFront(char c)
+{
+ if (_limit == _len)
+ Grow_1();
+ MoveItems(1, 0);
+ _chars[0] = c;
+ _len++;
+}
+
+/*
+void AString::Insert(unsigned index, char c)
+{
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _len++;
+}
+*/
+
+void AString::Insert(unsigned index, const char *s)
+{
+ unsigned num = MyStringLen(s);
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ memcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void AString::Insert(unsigned index, const AString &s)
+{
+ unsigned num = s.Len();
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ memcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void AString::RemoveChar(char ch) throw()
+{
+ char *src = _chars;
+
+ for (;;)
+ {
+ char c = *src++;
+ if (c == 0)
+ return;
+ if (c == ch)
+ break;
+ }
+
+ char *dest = src - 1;
+
+ for (;;)
+ {
+ char c = *src++;
+ if (c == 0)
+ break;
+ if (c != ch)
+ *dest++ = c;
+ }
+
+ *dest = 0;
+ _len = (unsigned)(dest - _chars);
+}
+
+// !!!!!!!!!!!!!!! test it if newChar = '\0'
+void AString::Replace(char oldChar, char newChar) throw()
+{
+ if (oldChar == newChar)
+ return; // 0;
+ // unsigned number = 0;
+ int pos = 0;
+ char *chars = _chars;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ chars[(unsigned)pos] = newChar;
+ pos++;
+ // number++;
+ }
+ return; // number;
+}
+
+void AString::Replace(const AString &oldString, const AString &newString)
+{
+ if (oldString.IsEmpty())
+ return; // 0;
+ if (oldString == newString)
+ return; // 0;
+ unsigned oldLen = oldString.Len();
+ unsigned newLen = newString.Len();
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldLen);
+ Insert(pos, newString);
+ pos += newLen;
+ // number++;
+ }
+ // return number;
+}
+
+void AString::Delete(unsigned index) throw()
+{
+ MoveItems(index, index + 1);
+ _len--;
+}
+
+void AString::Delete(unsigned index, unsigned count) throw()
+{
+ if (index + count > _len)
+ count = _len - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _len -= count;
+ }
+}
+
+void AString::DeleteFrontal(unsigned num) throw()
+{
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _len -= num;
+ }
+}
+
+/*
+AString operator+(const AString &s1, const AString &s2)
+{
+ AString result(s1);
+ result += s2;
+ return result;
+}
+
+AString operator+(const AString &s, const char *chars)
+{
+ AString result(s);
+ result += chars;
+ return result;
+}
+
+AString operator+(const char *chars, const AString &s)
+{
+ AString result(chars);
+ result += s;
+ return result;
+}
+
+AString operator+(const AString &s, char c)
+{
+ AString result(s);
+ result += c;
+ return result;
+}
+*/
+
+/*
+AString operator+(char c, const AString &s)
+{
+ AString result(c);
+ result += s;
+ return result;
+}
+*/
+
+
+
+
+// ---------- UString ----------
+
+void UString::InsertSpace(unsigned index, unsigned size)
+{
+ Grow(size);
+ MoveItems(index + size, index);
+}
+
+void UString::ReAlloc(unsigned newLimit)
+{
+ if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130221;
+ // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, _len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(newLimit + 1);
+ wmemcpy(newBuf, _chars, _len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = newLimit;
+}
+
+void UString::ReAlloc2(unsigned newLimit)
+{
+ if (newLimit >= k_Alloc_Len_Limit) throw 20130221;
+ // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(newLimit + 1);
+ newBuf[0] = 0;
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = newLimit;
+}
+
+void UString::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW_wchar_t(len + 1);
+ _len = len;
+ _limit = len;
+}
+
+void UString::Grow_1()
+{
+ unsigned next = _len;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+void UString::Grow(unsigned n)
+{
+ unsigned freeSize = _limit - _len;
+ if (n <= freeSize)
+ return;
+
+ unsigned next = _len + n;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+
+UString::UString(unsigned num, const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (num > len)
+ num = len;
+ SetStartLen(num);
+ wmemcpy(_chars, s, num);
+ _chars[num] = 0;
+}
+
+
+UString::UString(unsigned num, const UString &s)
+{
+ if (num > s._len)
+ num = s._len;
+ SetStartLen(num);
+ wmemcpy(_chars, s._chars, num);
+ _chars[num] = 0;
+}
+
+UString::UString(const UString &s, wchar_t c)
+{
+ SetStartLen(s.Len() + 1);
+ wchar_t *chars = _chars;
+ unsigned len = s.Len();
+ wmemcpy(chars, s, len);
+ chars[len] = c;
+ chars[(size_t)len + 1] = 0;
+}
+
+UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2)
+{
+ SetStartLen(num1 + num2);
+ wchar_t *chars = _chars;
+ wmemcpy(chars, s1, num1);
+ wmemcpy(chars + num1, s2, num2 + 1);
+}
+
+UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); }
+UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); }
+UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); }
+
+UString::UString()
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW_wchar_t(kStartStringCapacity);
+ _len = 0;
+ _limit = kStartStringCapacity - 1;
+ _chars[0] = 0;
+}
+
+UString::UString(wchar_t c)
+{
+ SetStartLen(1);
+ wchar_t *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
+}
+
+UString::UString(char c)
+{
+ SetStartLen(1);
+ wchar_t *chars = _chars;
+ chars[0] = (unsigned char)c;
+ chars[1] = 0;
+}
+
+UString::UString(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ SetStartLen(len);
+ wmemcpy(_chars, s, len + 1);
+}
+
+UString::UString(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ SetStartLen(len);
+ wchar_t *chars = _chars;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = (unsigned char)s[i];
+ chars[len] = 0;
+}
+
+UString::UString(const UString &s)
+{
+ SetStartLen(s._len);
+ wmemcpy(_chars, s._chars, s._len + 1);
+}
+
+UString &UString::operator=(wchar_t c)
+{
+ if (1 > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = 1;
+ }
+ _len = 1;
+ wchar_t *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
+ return *this;
+}
+
+UString &UString::operator=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ wmemcpy(_chars, s, len + 1);
+ return *this;
+}
+
+UString &UString::operator=(const UString &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ wmemcpy(_chars, s._chars, len + 1);
+ return *this;
+}
+
+void UString::SetFrom(const wchar_t *s, unsigned len) // no check
+{
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ if (len != 0)
+ wmemcpy(_chars, s, len);
+ _chars[len] = 0;
+ _len = len;
+}
+
+void UString::SetFromBstr(BSTR s)
+{
+ unsigned len = ::SysStringLen(s);
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ // if (s)
+ wmemcpy(_chars, s, len + 1);
+}
+
+UString &UString::operator=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ wchar_t *chars = _chars;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = (unsigned char)s[i];
+ chars[len] = 0;
+ _len = len;
+ return *this;
+}
+
+void UString::Add_Space() { operator+=(L' '); }
+void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
+
+void UString::Add_LF()
+{
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ wchar_t *chars = _chars;
+ chars[len++] = L'\n';
+ chars[len] = 0;
+ _len = len;
+}
+
+UString &UString::operator+=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ wmemcpy(_chars + _len, s, len + 1);
+ _len += len;
+ return *this;
+}
+
+UString &UString::operator+=(const UString &s)
+{
+ Grow(s._len);
+ wmemcpy(_chars + _len, s._chars, s._len + 1);
+ _len += s._len;
+ return *this;
+}
+
+UString &UString::operator+=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ wchar_t *chars = _chars + _len;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = (unsigned char)s[i];
+ chars[len] = 0;
+ _len += len;
+ return *this;
+}
+
+
+void UString::Add_UInt32(UInt32 v)
+{
+ char sz[16];
+ ConvertUInt32ToString(v, sz);
+ (*this) += sz;
+}
+
+
+int UString::Find(const wchar_t *s, unsigned startIndex) const throw()
+{
+ const wchar_t *fs = wcsstr(_chars + startIndex, s);
+ if (!fs)
+ return -1;
+ return (int)(fs - _chars);
+
+ /*
+ if (s[0] == 0)
+ return startIndex;
+ unsigned len = MyStringLen(s);
+ const wchar_t *p = _chars + startIndex;
+ for (;; p++)
+ {
+ const wchar_t c = *p;
+ if (c != s[0])
+ {
+ if (c == 0)
+ return -1;
+ continue;
+ }
+ unsigned i;
+ for (i = 1; i < len; i++)
+ if (p[i] != s[i])
+ break;
+ if (i == len)
+ return (int)(p - _chars);
+ }
+ */
+}
+
+int UString::ReverseFind(wchar_t c) const throw()
+{
+ if (_len == 0)
+ return -1;
+ const wchar_t *p = _chars + _len - 1;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--;
+ }
+}
+
+int UString::ReverseFind_PathSepar() const throw()
+{
+ if (_len == 0)
+ return -1;
+ const wchar_t *p = _chars + _len - 1;
+ for (;;)
+ {
+ wchar_t c = *p;
+ if (IS_PATH_SEPAR(c))
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--;
+ }
+}
+
+void UString::TrimLeft() throw()
+{
+ const wchar_t *p = _chars;
+ for (;; p++)
+ {
+ wchar_t c = *p;
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ unsigned pos = (unsigned)(p - _chars);
+ if (pos != 0)
+ {
+ MoveItems(0, pos);
+ _len -= pos;
+ }
+}
+
+void UString::TrimRight() throw()
+{
+ const wchar_t *p = _chars;
+ unsigned i;
+ for (i = _len; i != 0; i--)
+ {
+ wchar_t c = p[(size_t)i - 1];
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ if (i != _len)
+ {
+ _chars[i] = 0;
+ _len = i;
+ }
+}
+
+void UString::InsertAtFront(wchar_t c)
+{
+ if (_limit == _len)
+ Grow_1();
+ MoveItems(1, 0);
+ _chars[0] = c;
+ _len++;
+}
+
+/*
+void UString::Insert(unsigned index, wchar_t c)
+{
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _len++;
+}
+*/
+
+void UString::Insert(unsigned index, const wchar_t *s)
+{
+ unsigned num = MyStringLen(s);
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ wmemcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void UString::Insert(unsigned index, const UString &s)
+{
+ unsigned num = s.Len();
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ wmemcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void UString::RemoveChar(wchar_t ch) throw()
+{
+ wchar_t *src = _chars;
+
+ for (;;)
+ {
+ wchar_t c = *src++;
+ if (c == 0)
+ return;
+ if (c == ch)
+ break;
+ }
+
+ wchar_t *dest = src - 1;
+
+ for (;;)
+ {
+ wchar_t c = *src++;
+ if (c == 0)
+ break;
+ if (c != ch)
+ *dest++ = c;
+ }
+
+ *dest = 0;
+ _len = (unsigned)(dest - _chars);
+}
+
+// !!!!!!!!!!!!!!! test it if newChar = '\0'
+void UString::Replace(wchar_t oldChar, wchar_t newChar) throw()
+{
+ if (oldChar == newChar)
+ return; // 0;
+ // unsigned number = 0;
+ int pos = 0;
+ wchar_t *chars = _chars;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ chars[(unsigned)pos] = newChar;
+ pos++;
+ // number++;
+ }
+ return; // number;
+}
+
+void UString::Replace(const UString &oldString, const UString &newString)
+{
+ if (oldString.IsEmpty())
+ return; // 0;
+ if (oldString == newString)
+ return; // 0;
+ unsigned oldLen = oldString.Len();
+ unsigned newLen = newString.Len();
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldLen);
+ Insert(pos, newString);
+ pos += newLen;
+ // number++;
+ }
+ // return number;
+}
+
+void UString::Delete(unsigned index) throw()
+{
+ MoveItems(index, index + 1);
+ _len--;
+}
+
+void UString::Delete(unsigned index, unsigned count) throw()
+{
+ if (index + count > _len)
+ count = _len - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _len -= count;
+ }
+}
+
+void UString::DeleteFrontal(unsigned num) throw()
+{
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _len -= num;
+ }
+}
+
+
+// ---------- UString2 ----------
+
+void UString2::ReAlloc2(unsigned newLimit)
+{
+ if (newLimit >= k_Alloc_Len_Limit) throw 20130221;
+ // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);
+ _chars = MY_STRING_NEW_wchar_t(newLimit + 1);
+}
+
+void UString2::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW_wchar_t(len + 1);
+ _len = len;
+}
+
+
+/*
+UString2::UString2(wchar_t c)
+{
+ SetStartLen(1);
+ wchar_t *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
+}
+*/
+
+UString2::UString2(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ SetStartLen(len);
+ wmemcpy(_chars, s, len + 1);
+}
+
+UString2::UString2(const UString2 &s): _chars(NULL), _len(0)
+{
+ if (s._chars)
+ {
+ SetStartLen(s._len);
+ wmemcpy(_chars, s._chars, s._len + 1);
+ }
+}
+
+/*
+UString2 &UString2::operator=(wchar_t c)
+{
+ if (1 > _len)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1);
+ if (_chars)
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ }
+ _len = 1;
+ wchar_t *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
+ return *this;
+}
+*/
+
+UString2 &UString2::operator=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _len)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ if (_chars)
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ }
+ _len = len;
+ MyStringCopy(_chars, s);
+ return *this;
+}
+
+void UString2::SetFromAscii(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _len)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ if (_chars)
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ }
+ wchar_t *chars = _chars;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = (unsigned char)s[i];
+ chars[len] = 0;
+ _len = len;
+}
+
+UString2 &UString2::operator=(const UString2 &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _len)
+ {
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ if (_chars)
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ }
+ _len = len;
+ MyStringCopy(_chars, s._chars);
+ return *this;
+}
+
+bool operator==(const UString2 &s1, const UString2 &s2)
+{
+ return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0);
+}
+
+bool operator==(const UString2 &s1, const wchar_t *s2)
+{
+ if (s1.IsEmpty())
+ return (*s2 == 0);
+ return wcscmp(s1.GetRawPtr(), s2) == 0;
+}
+
+bool operator==(const wchar_t *s1, const UString2 &s2)
+{
+ if (s2.IsEmpty())
+ return (*s1 == 0);
+ return wcscmp(s1, s2.GetRawPtr()) == 0;
+}
+
+
+
+// ----------------------------------------
+
+/*
+int MyStringCompareNoCase(const char *s1, const char *s2)
+{
+ return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
+}
+*/
+
+static inline UINT GetCurrentCodePage()
+{
+ #if defined(UNDER_CE) || !defined(_WIN32)
+ return CP_ACP;
+ #else
+ return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ #endif
+}
+
+#ifdef USE_UNICODE_FSTRING
+
+#ifndef _UNICODE
+
+AString fs2fas(CFSTR s)
+{
+ return UnicodeStringToMultiByte(s, GetCurrentCodePage());
+}
+
+FString fas2fs(const char *s)
+{
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
+}
+
+FString fas2fs(const AString &s)
+{
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
+}
+
+#endif
+
+#else
+
+UString fs2us(const FChar *s)
+{
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
+}
+
+UString fs2us(const FString &s)
+{
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
+}
+
+FString us2fs(const wchar_t *s)
+{
+ return UnicodeStringToMultiByte(s, GetCurrentCodePage());
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyString.h b/other-licenses/7zstub/src/CPP/Common/MyString.h
new file mode 100644
index 0000000000..f484ad225f
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyString.h
@@ -0,0 +1,867 @@
+// Common/String.h
+
+#ifndef __COMMON_STRING_H
+#define __COMMON_STRING_H
+
+#include <string.h>
+
+#ifndef _WIN32
+#include <wctype.h>
+#include <wchar.h>
+#endif
+
+#include "MyWindows.h"
+#include "MyTypes.h"
+#include "MyVector.h"
+
+
+#ifdef _MSC_VER
+ #ifdef _NATIVE_WCHAR_T_DEFINED
+ #define MY_NATIVE_WCHAR_T_DEFINED
+ #endif
+#else
+ #define MY_NATIVE_WCHAR_T_DEFINED
+#endif
+
+/*
+ native support for wchar_t:
+ _MSC_VER == 1600 : /Zc:wchar_t is not supported
+ _MSC_VER == 1310 (VS2003)
+ ? _MSC_VER == 1400 (VS2005) : wchar_t <- unsigned short
+ /Zc:wchar_t : wchar_t <- __wchar_t, _WCHAR_T_DEFINED and _NATIVE_WCHAR_T_DEFINED
+ _MSC_VER > 1400 (VS2008+)
+ /Zc:wchar_t[-]
+ /Zc:wchar_t is on by default
+*/
+
+#ifdef _WIN32
+#define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/')
+#else
+#define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR)
+#endif
+
+inline bool IsPathSepar(char c) { return IS_PATH_SEPAR(c); }
+inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); }
+
+inline unsigned MyStringLen(const char *s)
+{
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
+ return i;
+}
+
+inline void MyStringCopy(char *dest, const char *src)
+{
+ while ((*dest++ = *src++) != 0);
+}
+
+inline char *MyStpCpy(char *dest, const char *src)
+{
+ for (;;)
+ {
+ char c = *src;
+ *dest = c;
+ if (c == 0)
+ return dest;
+ src++;
+ dest++;
+ }
+}
+
+inline unsigned MyStringLen(const wchar_t *s)
+{
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
+ return i;
+}
+
+inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
+{
+ while ((*dest++ = *src++) != 0);
+}
+
+inline void MyStringCat(wchar_t *dest, const wchar_t *src)
+{
+ MyStringCopy(dest + MyStringLen(dest), src);
+}
+
+
+/*
+inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src)
+{
+ for (;;)
+ {
+ wchar_t c = *src;
+ *dest = c;
+ if (c == 0)
+ return dest;
+ src++;
+ dest++;
+ }
+}
+*/
+
+int FindCharPosInString(const char *s, char c) throw();
+int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
+
+#ifdef _WIN32
+ #ifndef _UNICODE
+ #define STRING_UNICODE_THROW
+ #endif
+#endif
+
+#ifndef STRING_UNICODE_THROW
+ #define STRING_UNICODE_THROW throw()
+#endif
+
+
+inline char MyCharUpper_Ascii(char c)
+{
+ if (c >= 'a' && c <= 'z')
+ return (char)((unsigned char)c - 0x20);
+ return c;
+}
+
+/*
+inline wchar_t MyCharUpper_Ascii(wchar_t c)
+{
+ if (c >= 'a' && c <= 'z')
+ return (wchar_t)(c - 0x20);
+ return c;
+}
+*/
+
+inline char MyCharLower_Ascii(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return (char)((unsigned char)c + 0x20);
+ return c;
+}
+
+inline wchar_t MyCharLower_Ascii(wchar_t c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return (wchar_t)(c + 0x20);
+ return c;
+}
+
+wchar_t MyCharUpper_WIN(wchar_t c) throw();
+
+inline wchar_t MyCharUpper(wchar_t c) throw()
+{
+ if (c < 'a') return c;
+ if (c <= 'z') return (wchar_t)(c - 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharUpper_WIN(c);
+ #endif
+ #else
+ return (wchar_t)towupper(c);
+ #endif
+}
+
+/*
+wchar_t MyCharLower_WIN(wchar_t c) throw();
+
+inline wchar_t MyCharLower(wchar_t c) throw()
+{
+ if (c < 'A') return c;
+ if (c <= 'Z') return (wchar_t)(c + 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharLower_WIN(c);
+ #endif
+ #else
+ return (wchar_t)tolower(c);
+ #endif
+}
+*/
+
+// char *MyStringUpper(char *s) throw();
+// char *MyStringLower(char *s) throw();
+
+// void MyStringUpper_Ascii(char *s) throw();
+// void MyStringUpper_Ascii(wchar_t *s) throw();
+void MyStringLower_Ascii(char *s) throw();
+void MyStringLower_Ascii(wchar_t *s) throw();
+// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW;
+// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW;
+
+bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw();
+
+bool IsString1PrefixedByString2(const char *s1, const char *s2) throw();
+bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw();
+bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw();
+bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *u, const char *a) throw();
+bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
+
+#define MyStringCompare(s1, s2) wcscmp(s1, s2)
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
+// int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
+
+// ---------- ASCII ----------
+// char values in ASCII strings must be less then 128
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw();
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw();
+
+#define MY_STRING_DELETE(_p_) delete []_p_;
+// #define MY_STRING_DELETE(_p_) my_delete(_p_);
+
+
+#define FORBID_STRING_OPS_2(cls, t) \
+ void Find(t) const; \
+ void Find(t, unsigned startIndex) const; \
+ void ReverseFind(t) const; \
+ void InsertAtFront(t); \
+ void RemoveChar(t); \
+ void Replace(t, t); \
+
+#define FORBID_STRING_OPS(cls, t) \
+ explicit cls(t); \
+ explicit cls(const t *); \
+ cls &operator=(t); \
+ cls &operator=(const t *); \
+ cls &operator+=(t); \
+ cls &operator+=(const t *); \
+ FORBID_STRING_OPS_2(cls, t); \
+
+/*
+ cls &operator+(t); \
+ cls &operator+(const t *); \
+*/
+
+#define FORBID_STRING_OPS_AString(t) FORBID_STRING_OPS(AString, t)
+#define FORBID_STRING_OPS_UString(t) FORBID_STRING_OPS(UString, t)
+#define FORBID_STRING_OPS_UString2(t) FORBID_STRING_OPS(UString2, t)
+
+class AString
+{
+ char *_chars;
+ unsigned _len;
+ unsigned _limit;
+
+ void MoveItems(unsigned dest, unsigned src)
+ {
+ memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char));
+ }
+
+ void InsertSpace(unsigned &index, unsigned size);
+
+ void ReAlloc(unsigned newLimit);
+ void ReAlloc2(unsigned newLimit);
+ void SetStartLen(unsigned len);
+ void Grow_1();
+ void Grow(unsigned n);
+
+ AString(unsigned num, const char *s);
+ AString(unsigned num, const AString &s);
+ AString(const AString &s, char c); // it's for String + char
+ AString(const char *s1, unsigned num1, const char *s2, unsigned num2);
+
+ friend AString operator+(const AString &s, char c) { return AString(s, c); } ;
+ // friend AString operator+(char c, const AString &s); // is not supported
+
+ friend AString operator+(const AString &s1, const AString &s2);
+ friend AString operator+(const AString &s1, const char *s2);
+ friend AString operator+(const char *s1, const AString &s2);
+
+ // ---------- forbidden functions ----------
+
+ #ifdef MY_NATIVE_WCHAR_T_DEFINED
+ FORBID_STRING_OPS_AString(wchar_t)
+ #endif
+
+ FORBID_STRING_OPS_AString(signed char)
+ FORBID_STRING_OPS_AString(unsigned char)
+ FORBID_STRING_OPS_AString(short)
+ FORBID_STRING_OPS_AString(unsigned short)
+ FORBID_STRING_OPS_AString(int)
+ FORBID_STRING_OPS_AString(unsigned)
+ FORBID_STRING_OPS_AString(long)
+ FORBID_STRING_OPS_AString(unsigned long)
+
+public:
+ explicit AString();
+ explicit AString(char c);
+ explicit AString(const char *s);
+ AString(const AString &s);
+ ~AString() { MY_STRING_DELETE(_chars); }
+
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ void Empty() { _len = 0; _chars[0] = 0; }
+
+ operator const char *() const { return _chars; }
+ const char *Ptr() const { return _chars; }
+ const char *Ptr(unsigned pos) const { return _chars + pos; }
+ const char *RightPtr(unsigned num) const { return _chars + _len - num; }
+ char Back() const { return _chars[(size_t)_len - 1]; }
+
+ void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
+
+ /* GetBuf(minLen): provides the buffer that can store
+ at least (minLen) characters and additional null terminator.
+ 9.35: GetBuf doesn't preserve old characters and terminator */
+ char *GetBuf(unsigned minLen)
+ {
+ if (minLen > _limit)
+ ReAlloc2(minLen);
+ return _chars;
+ }
+ char *GetBuf_SetEnd(unsigned minLen)
+ {
+ if (minLen > _limit)
+ ReAlloc2(minLen);
+ char *chars = _chars;
+ chars[minLen] = 0;
+ _len = minLen;
+ return chars;
+ }
+
+ void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
+ void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
+ void ReleaseBuf_CalcLen(unsigned maxLen)
+ {
+ char *chars = _chars;
+ chars[maxLen] = 0;
+ _len = MyStringLen(chars);
+ }
+
+ AString &operator=(char c);
+ AString &operator=(const char *s);
+ AString &operator=(const AString &s);
+ void SetFromWStr_if_Ascii(const wchar_t *s);
+ // void SetFromBstr_if_Ascii(BSTR s);
+
+ AString &operator+=(char c)
+ {
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ char *chars = _chars;
+ chars[len++] = c;
+ chars[len] = 0;
+ _len = len;
+ return *this;
+ }
+
+ void Add_Space();
+ void Add_Space_if_NotEmpty();
+ void Add_OptSpaced(const char *s);
+ void Add_LF();
+ void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
+
+ AString &operator+=(const char *s);
+ AString &operator+=(const AString &s);
+
+ void Add_UInt32(UInt32 v);
+
+ void SetFrom(const char *s, unsigned len); // no check
+ void SetFrom_CalcLen(const char *s, unsigned len);
+
+ AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
+ AString Left(unsigned count) const { return AString(count, *this); }
+
+ // void MakeUpper() { MyStringUpper(_chars); }
+ // void MakeLower() { MyStringLower(_chars); }
+ void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
+
+
+ bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; }
+ bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
+ // int Compare(const char *s) const { return MyStringCompare(_chars, s); }
+ // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
+ // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
+ // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
+ bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
+ bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
+
+ bool IsAscii() const
+ {
+ unsigned len = Len();
+ const char *s = _chars;
+ for (unsigned i = 0; i < len; i++)
+ if ((unsigned char)s[i] >= 0x80)
+ return false;
+ return true;
+ }
+ int Find(char c) const { return FindCharPosInString(_chars, c); }
+ int Find(char c, unsigned startIndex) const
+ {
+ int pos = FindCharPosInString(_chars + startIndex, c);
+ return pos < 0 ? -1 : (int)startIndex + pos;
+ }
+
+ int ReverseFind(char c) const throw();
+ int ReverseFind_Dot() const throw() { return ReverseFind('.'); }
+ int ReverseFind_PathSepar() const throw();
+
+ int Find(const char *s) const { return Find(s, 0); }
+ int Find(const char *s, unsigned startIndex) const throw();
+
+ void TrimLeft() throw();
+ void TrimRight() throw();
+ void Trim()
+ {
+ TrimRight();
+ TrimLeft();
+ }
+
+ void InsertAtFront(char c);
+ // void Insert(unsigned index, char c);
+ void Insert(unsigned index, const char *s);
+ void Insert(unsigned index, const AString &s);
+
+ void RemoveChar(char ch) throw();
+
+ void Replace(char oldChar, char newChar) throw();
+ void Replace(const AString &oldString, const AString &newString);
+
+ void Delete(unsigned index) throw();
+ void Delete(unsigned index, unsigned count) throw();
+ void DeleteFrontal(unsigned num) throw();
+ void DeleteBack() { _chars[--_len] = 0; }
+ void DeleteFrom(unsigned index)
+ {
+ if (index < _len)
+ {
+ _len = index;
+ _chars[index] = 0;
+ }
+ }
+};
+
+bool operator<(const AString &s1, const AString &s2);
+bool operator>(const AString &s1, const AString &s2);
+
+/*
+bool operator==(const AString &s1, const AString &s2);
+bool operator==(const AString &s1, const char *s2);
+bool operator==(const char *s1, const AString &s2);
+
+bool operator!=(const AString &s1, const AString &s2);
+bool operator!=(const AString &s1, const char *s2);
+bool operator!=(const char *s1, const AString &s2);
+*/
+
+inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
+inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; }
+inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
+
+inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
+inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; }
+inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
+
+// ---------- forbidden functions ----------
+
+void operator==(char c1, const AString &s2);
+void operator==(const AString &s1, char c2);
+
+void operator+(char c, const AString &s); // this function can be OK, but we don't use it
+
+void operator+(const AString &s, int c);
+void operator+(const AString &s, unsigned c);
+void operator+(int c, const AString &s);
+void operator+(unsigned c, const AString &s);
+void operator-(const AString &s, int c);
+void operator-(const AString &s, unsigned c);
+
+
+class UString
+{
+ wchar_t *_chars;
+ unsigned _len;
+ unsigned _limit;
+
+ void MoveItems(unsigned dest, unsigned src)
+ {
+ memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t));
+ }
+
+ void InsertSpace(unsigned index, unsigned size);
+
+ void ReAlloc(unsigned newLimit);
+ void ReAlloc2(unsigned newLimit);
+ void SetStartLen(unsigned len);
+ void Grow_1();
+ void Grow(unsigned n);
+
+ UString(unsigned num, const wchar_t *s); // for Mid
+ UString(unsigned num, const UString &s); // for Left
+ UString(const UString &s, wchar_t c); // it's for String + char
+ UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2);
+
+ friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ;
+ // friend UString operator+(wchar_t c, const UString &s); // is not supported
+
+ friend UString operator+(const UString &s1, const UString &s2);
+ friend UString operator+(const UString &s1, const wchar_t *s2);
+ friend UString operator+(const wchar_t *s1, const UString &s2);
+
+ // ---------- forbidden functions ----------
+
+ FORBID_STRING_OPS_UString(signed char)
+ FORBID_STRING_OPS_UString(unsigned char)
+ FORBID_STRING_OPS_UString(short)
+
+ #ifdef MY_NATIVE_WCHAR_T_DEFINED
+ FORBID_STRING_OPS_UString(unsigned short)
+ #endif
+
+ FORBID_STRING_OPS_UString(int)
+ FORBID_STRING_OPS_UString(unsigned)
+ FORBID_STRING_OPS_UString(long)
+ FORBID_STRING_OPS_UString(unsigned long)
+
+ FORBID_STRING_OPS_2(UString, char)
+
+public:
+ UString();
+ explicit UString(wchar_t c);
+ explicit UString(char c);
+ explicit UString(const char *s);
+ // UString(const AString &s);
+ UString(const wchar_t *s);
+ UString(const UString &s);
+ ~UString() { MY_STRING_DELETE(_chars); }
+
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ void Empty() { _len = 0; _chars[0] = 0; }
+
+ operator const wchar_t *() const { return _chars; }
+ const wchar_t *Ptr() const { return _chars; }
+ const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
+ const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
+ wchar_t Back() const { return _chars[(size_t)_len - 1]; }
+
+ void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
+
+ wchar_t *GetBuf() { return _chars; }
+
+ wchar_t *GetBuf(unsigned minLen)
+ {
+ if (minLen > _limit)
+ ReAlloc2(minLen);
+ return _chars;
+ }
+ wchar_t *GetBuf_SetEnd(unsigned minLen)
+ {
+ if (minLen > _limit)
+ ReAlloc2(minLen);
+ wchar_t *chars = _chars;
+ chars[minLen] = 0;
+ _len = minLen;
+ return chars;
+ }
+
+ void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
+ void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
+ void ReleaseBuf_CalcLen(unsigned maxLen)
+ {
+ wchar_t *chars = _chars;
+ chars[maxLen] = 0;
+ _len = MyStringLen(chars);
+ }
+
+ UString &operator=(wchar_t c);
+ UString &operator=(char c) { return (*this)=((wchar_t)(unsigned char)c); }
+ UString &operator=(const wchar_t *s);
+ UString &operator=(const UString &s);
+ void SetFrom(const wchar_t *s, unsigned len); // no check
+ void SetFromBstr(BSTR s);
+ UString &operator=(const char *s);
+ UString &operator=(const AString &s) { return operator=(s.Ptr()); }
+
+ UString &operator+=(wchar_t c)
+ {
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ wchar_t *chars = _chars;
+ chars[len++] = c;
+ chars[len] = 0;
+ _len = len;
+ return *this;
+ }
+
+ UString &operator+=(char c) { return (*this)+=((wchar_t)(unsigned char)c); }
+
+ void Add_Space();
+ void Add_Space_if_NotEmpty();
+ void Add_LF();
+ void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); }
+
+ UString &operator+=(const wchar_t *s);
+ UString &operator+=(const UString &s);
+ UString &operator+=(const char *s);
+ UString &operator+=(const AString &s) { return operator+=(s.Ptr()); }
+
+ void Add_UInt32(UInt32 v);
+
+ UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
+ UString Left(unsigned count) const { return UString(count, *this); }
+
+ // void MakeUpper() { MyStringUpper(_chars); }
+ // void MakeUpper() { MyStringUpper_Ascii(_chars); }
+ // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); }
+ void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
+
+ bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
+ bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
+ bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
+ int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
+ // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); }
+ // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); }
+ // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
+ bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }
+ bool IsPrefixedBy_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); }
+ bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
+
+ bool IsAscii() const
+ {
+ unsigned len = Len();
+ const wchar_t *s = _chars;
+ for (unsigned i = 0; i < len; i++)
+ if (s[i] >= 0x80)
+ return false;
+ return true;
+ }
+ int Find(wchar_t c) const { return FindCharPosInString(_chars, c); }
+ int Find(wchar_t c, unsigned startIndex) const
+ {
+ int pos = FindCharPosInString(_chars + startIndex, c);
+ return pos < 0 ? -1 : (int)startIndex + pos;
+ }
+
+ int ReverseFind(wchar_t c) const throw();
+ int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); }
+ int ReverseFind_PathSepar() const throw();
+
+ int Find(const wchar_t *s) const { return Find(s, 0); }
+ int Find(const wchar_t *s, unsigned startIndex) const throw();
+
+ void TrimLeft() throw();
+ void TrimRight() throw();
+ void Trim()
+ {
+ TrimRight();
+ TrimLeft();
+ }
+
+ void InsertAtFront(wchar_t c);
+ // void Insert(unsigned index, wchar_t c);
+ void Insert(unsigned index, const wchar_t *s);
+ void Insert(unsigned index, const UString &s);
+
+ void RemoveChar(wchar_t ch) throw();
+
+ void Replace(wchar_t oldChar, wchar_t newChar) throw();
+ void Replace(const UString &oldString, const UString &newString);
+
+ void Delete(unsigned index) throw();
+ void Delete(unsigned index, unsigned count) throw();
+ void DeleteFrontal(unsigned num) throw();
+ void DeleteBack() { _chars[--_len] = 0; }
+ void DeleteFrom(unsigned index)
+ {
+ if (index < _len)
+ {
+ _len = index;
+ _chars[index] = 0;
+ }
+ }
+};
+
+bool operator<(const UString &s1, const UString &s2);
+bool operator>(const UString &s1, const UString &s2);
+
+inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
+inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
+inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
+
+inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
+inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
+inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
+
+
+// ---------- forbidden functions ----------
+
+void operator==(wchar_t c1, const UString &s2);
+void operator==(const UString &s1, wchar_t c2);
+
+void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it
+
+void operator+(const AString &s1, const UString &s2);
+void operator+(const UString &s1, const AString &s2);
+
+void operator+(const UString &s1, const char *s2);
+void operator+(const char *s1, const UString &s2);
+
+void operator+(const UString &s, char c);
+void operator+(const UString &s, unsigned char c);
+void operator+(char c, const UString &s);
+void operator+(unsigned char c, const UString &s);
+void operator-(const UString &s1, wchar_t c);
+
+#ifdef _WIN32
+// can we forbid these functions, if wchar_t is 32-bit ?
+void operator+(const UString &s, int c);
+void operator+(const UString &s, unsigned c);
+void operator+(int c, const UString &s);
+void operator+(unsigned c, const UString &s);
+void operator-(const UString &s1, int c);
+void operator-(const UString &s1, unsigned c);
+#endif
+
+
+
+
+
+
+
+class UString2
+{
+ wchar_t *_chars;
+ unsigned _len;
+
+ void ReAlloc2(unsigned newLimit);
+ void SetStartLen(unsigned len);
+
+ // ---------- forbidden functions ----------
+
+ FORBID_STRING_OPS_UString2(char)
+ FORBID_STRING_OPS_UString2(signed char)
+ FORBID_STRING_OPS_UString2(unsigned char)
+ FORBID_STRING_OPS_UString2(short)
+
+ UString2 &operator=(wchar_t c);
+ UString2(wchar_t c);
+
+public:
+ UString2(): _chars(NULL), _len(0) {}
+ UString2(const wchar_t *s);
+ UString2(const UString2 &s);
+ ~UString2() { if (_chars) MY_STRING_DELETE(_chars); }
+
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ // void Empty() { _len = 0; _chars[0] = 0; }
+
+ // operator const wchar_t *() const { return _chars; }
+ const wchar_t *GetRawPtr() const { return _chars; }
+
+ int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
+
+ wchar_t *GetBuf(unsigned minLen)
+ {
+ if (!_chars || minLen > _len)
+ ReAlloc2(minLen);
+ return _chars;
+ }
+ void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
+
+ UString2 &operator=(const wchar_t *s);
+ UString2 &operator=(const UString2 &s);
+ void SetFromAscii(const char *s);
+};
+
+bool operator==(const UString2 &s1, const UString2 &s2);
+bool operator==(const UString2 &s1, const wchar_t *s2);
+bool operator==(const wchar_t *s1, const UString2 &s2);
+
+inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); }
+inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); }
+inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); }
+
+
+// ---------- forbidden functions ----------
+
+void operator==(wchar_t c1, const UString2 &s2);
+void operator==(const UString2 &s1, wchar_t c2);
+bool operator<(const UString2 &s1, const UString2 &s2);
+bool operator>(const UString2 &s1, const UString2 &s2);
+
+void operator+(const UString2 &s1, const UString2 &s2);
+void operator+(const UString2 &s1, const wchar_t *s2);
+void operator+(const wchar_t *s1, const UString2 &s2);
+void operator+(wchar_t c, const UString2 &s);
+void operator+(const UString2 &s, wchar_t c);
+void operator+(const UString2 &s, char c);
+void operator+(const UString2 &s, unsigned char c);
+void operator+(char c, const UString2 &s);
+void operator+(unsigned char c, const UString2 &s);
+void operator-(const UString2 &s1, wchar_t c);
+
+
+
+
+
+
+typedef CObjectVector<AString> AStringVector;
+typedef CObjectVector<UString> UStringVector;
+
+#ifdef _UNICODE
+ typedef UString CSysString;
+#else
+ typedef AString CSysString;
+#endif
+
+typedef CObjectVector<CSysString> CSysStringVector;
+
+
+// ---------- FString ----------
+
+#ifdef _WIN32
+ #define USE_UNICODE_FSTRING
+#endif
+
+#ifdef USE_UNICODE_FSTRING
+
+ #define __FTEXT(quote) L##quote
+
+ typedef wchar_t FChar;
+ typedef UString FString;
+
+ #define fs2us(_x_) (_x_)
+ #define us2fs(_x_) (_x_)
+ FString fas2fs(const char *s);
+ FString fas2fs(const AString &s);
+ AString fs2fas(const FChar *s);
+
+#else
+
+ #define __FTEXT(quote) quote
+
+ typedef char FChar;
+ typedef AString FString;
+
+ UString fs2us(const FChar *s);
+ UString fs2us(const FString &s);
+ FString us2fs(const wchar_t *s);
+ #define fas2fs(_x_) (_x_)
+ #define fs2fas(_x_) (_x_)
+
+#endif
+
+#define FTEXT(quote) __FTEXT(quote)
+
+#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR)
+#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR)
+
+// #define FCHAR_ANY_MASK FTEXT('*')
+// #define FSTRING_ANY_MASK FTEXT("*")
+
+typedef const FChar *CFSTR;
+
+typedef CObjectVector<FString> FStringVector;
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyTypes.h b/other-licenses/7zstub/src/CPP/Common/MyTypes.h
new file mode 100644
index 0000000000..6e73aca31e
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyTypes.h
@@ -0,0 +1,35 @@
+// Common/MyTypes.h
+
+#ifndef __COMMON_MY_TYPES_H
+#define __COMMON_MY_TYPES_H
+
+#include "../../C/7zTypes.h"
+
+typedef int HRes;
+
+struct CBoolPair
+{
+ bool Val;
+ bool Def;
+
+ CBoolPair(): Val(false), Def(false) {}
+
+ void Init()
+ {
+ Val = false;
+ Def = false;
+ }
+
+ void SetTrueTrue()
+ {
+ Val = true;
+ Def = true;
+ }
+};
+
+#define CLASS_NO_COPY(cls) \
+ private: \
+ cls(const cls &); \
+ cls &operator=(const cls &);
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyUnknown.h b/other-licenses/7zstub/src/CPP/Common/MyUnknown.h
new file mode 100644
index 0000000000..b1d476ffb8
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyUnknown.h
@@ -0,0 +1,17 @@
+// MyUnknown.h
+
+#ifndef __MY_UNKNOWN_H
+#define __MY_UNKNOWN_H
+
+#include "MyWindows.h"
+
+/*
+#ifdef _WIN32
+#include <basetyps.h>
+#include <unknwn.h>
+#else
+#include "MyWindows.h"
+#endif
+*/
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyVector.cpp b/other-licenses/7zstub/src/CPP/Common/MyVector.cpp
new file mode 100644
index 0000000000..9a6d1d5aee
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyVector.cpp
@@ -0,0 +1,3 @@
+// Common/MyVector.cpp
+
+#include "StdAfx.h"
diff --git a/other-licenses/7zstub/src/CPP/Common/MyVector.h b/other-licenses/7zstub/src/CPP/Common/MyVector.h
new file mode 100644
index 0000000000..21125fa7da
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyVector.h
@@ -0,0 +1,634 @@
+// Common/MyVector.h
+
+#ifndef __COMMON_MY_VECTOR_H
+#define __COMMON_MY_VECTOR_H
+
+#include <string.h>
+
+template <class T>
+class CRecordVector
+{
+ T *_items;
+ unsigned _size;
+ unsigned _capacity;
+
+ void MoveItems(unsigned destIndex, unsigned srcIndex)
+ {
+ memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T));
+ }
+
+ void ReserveOnePosition()
+ {
+ if (_size == _capacity)
+ {
+ unsigned newCapacity = _capacity + (_capacity >> 2) + 1;
+ T *p;
+ MY_ARRAY_NEW(p, T, newCapacity);
+ // p = new T[newCapacity];
+ if (_size != 0)
+ memcpy(p, _items, (size_t)_size * sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
+ }
+ }
+
+public:
+
+ CRecordVector(): _items(0), _size(0), _capacity(0) {}
+
+ CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0)
+ {
+ unsigned size = v.Size();
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ _capacity = size;
+ memcpy(_items, v._items, (size_t)size * sizeof(T));
+ }
+ }
+
+ unsigned Size() const { return _size; }
+ bool IsEmpty() const { return _size == 0; }
+
+ void ConstructReserve(unsigned size)
+ {
+ if (size != 0)
+ {
+ MY_ARRAY_NEW(_items, T, size)
+ // _items = new T[size];
+ _capacity = size;
+ }
+ }
+
+ void Reserve(unsigned newCapacity)
+ {
+ if (newCapacity > _capacity)
+ {
+ T *p;
+ MY_ARRAY_NEW(p, T, newCapacity);
+ // p = new T[newCapacity];
+ if (_size != 0)
+ memcpy(p, _items, (size_t)_size * sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
+ }
+ }
+
+ void ClearAndReserve(unsigned newCapacity)
+ {
+ Clear();
+ if (newCapacity > _capacity)
+ {
+ delete []_items;
+ _items = NULL;
+ _capacity = 0;
+ MY_ARRAY_NEW(_items, T, newCapacity)
+ // _items = new T[newCapacity];
+ _capacity = newCapacity;
+ }
+ }
+
+ void ClearAndSetSize(unsigned newSize)
+ {
+ ClearAndReserve(newSize);
+ _size = newSize;
+ }
+
+ void ChangeSize_KeepData(unsigned newSize)
+ {
+ if (newSize > _capacity)
+ {
+ T *p;
+ MY_ARRAY_NEW(p, T, newSize)
+ // p = new T[newSize];
+ if (_size != 0)
+ memcpy(p, _items, (size_t)_size * sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newSize;
+ }
+ _size = newSize;
+ }
+
+ void ReserveDown()
+ {
+ if (_size == _capacity)
+ return;
+ T *p = NULL;
+ if (_size != 0)
+ {
+ p = new T[_size];
+ memcpy(p, _items, (size_t)_size * sizeof(T));
+ }
+ delete []_items;
+ _items = p;
+ _capacity = _size;
+ }
+
+ ~CRecordVector() { delete []_items; }
+
+ void ClearAndFree()
+ {
+ delete []_items;
+ _items = NULL;
+ _size = 0;
+ _capacity = 0;
+ }
+
+ void Clear() { _size = 0; }
+
+ void DeleteBack() { _size--; }
+
+ void DeleteFrom(unsigned index)
+ {
+ // if (index <= _size)
+ _size = index;
+ }
+
+ void DeleteFrontal(unsigned num)
+ {
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _size -= num;
+ }
+ }
+
+ void Delete(unsigned index)
+ {
+ MoveItems(index, index + 1);
+ _size -= 1;
+ }
+
+ /*
+ void Delete(unsigned index, unsigned num)
+ {
+ if (num > 0)
+ {
+ MoveItems(index, index + num);
+ _size -= num;
+ }
+ }
+ */
+
+ CRecordVector& operator=(const CRecordVector &v)
+ {
+ if (&v == this)
+ return *this;
+ unsigned size = v.Size();
+ if (size > _capacity)
+ {
+ delete []_items;
+ _capacity = 0;
+ _size = 0;
+ _items = NULL;
+ _items = new T[size];
+ _capacity = size;
+ }
+ _size = size;
+ if (size != 0)
+ memcpy(_items, v._items, (size_t)size * sizeof(T));
+ return *this;
+ }
+
+ CRecordVector& operator+=(const CRecordVector &v)
+ {
+ unsigned size = v.Size();
+ Reserve(_size + size);
+ if (size != 0)
+ memcpy(_items + _size, v._items, (size_t)size * sizeof(T));
+ _size += size;
+ return *this;
+ }
+
+ unsigned Add(const T item)
+ {
+ ReserveOnePosition();
+ _items[_size] = item;
+ return _size++;
+ }
+
+ void AddInReserved(const T item)
+ {
+ _items[_size++] = item;
+ }
+
+ void Insert(unsigned index, const T item)
+ {
+ ReserveOnePosition();
+ MoveItems(index + 1, index);
+ _items[index] = item;
+ _size++;
+ }
+
+ void MoveToFront(unsigned index)
+ {
+ if (index != 0)
+ {
+ T temp = _items[index];
+ memmove(_items + 1, _items, (size_t)index * sizeof(T));
+ _items[0] = temp;
+ }
+ }
+
+ const T& operator[](unsigned index) const { return _items[index]; }
+ T& operator[](unsigned index) { return _items[index]; }
+ const T& Front() const { return _items[0]; }
+ T& Front() { return _items[0]; }
+ const T& Back() const { return _items[(size_t)_size - 1]; }
+ T& Back() { return _items[(size_t)_size - 1]; }
+
+ /*
+ void Swap(unsigned i, unsigned j)
+ {
+ T temp = _items[i];
+ _items[i] = _items[j];
+ _items[j] = temp;
+ }
+ */
+
+ int FindInSorted(const T item, unsigned left, unsigned right) const
+ {
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T midVal = (*this)[mid];
+ if (item == midVal)
+ return mid;
+ if (item < midVal)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+ }
+
+ int FindInSorted2(const T &item, unsigned left, unsigned right) const
+ {
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ return mid;
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+ }
+
+ int FindInSorted(const T item) const
+ {
+ return FindInSorted(item, 0, _size);
+ }
+
+ int FindInSorted2(const T &item) const
+ {
+ return FindInSorted2(item, 0, _size);
+ }
+
+ unsigned AddToUniqueSorted(const T item)
+ {
+ unsigned left = 0, right = _size;
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T midVal = (*this)[mid];
+ if (item == midVal)
+ return mid;
+ if (item < midVal)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ unsigned AddToUniqueSorted2(const T &item)
+ {
+ unsigned left = 0, right = _size;
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ return mid;
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param)
+ {
+ T temp = p[k];
+ for (;;)
+ {
+ unsigned s = (k << 1);
+ if (s > size)
+ break;
+ if (s < size && compare(p + s + 1, p + s, param) > 0)
+ s++;
+ if (compare(&temp, p + s, param) >= 0)
+ break;
+ p[k] = p[s];
+ k = s;
+ }
+ p[k] = temp;
+ }
+
+ void Sort(int (*compare)(const T*, const T*, void *), void *param)
+ {
+ unsigned size = _size;
+ if (size <= 1)
+ return;
+ T* p = (&Front()) - 1;
+ {
+ unsigned i = size >> 1;
+ do
+ SortRefDown(p, i, size, compare, param);
+ while (--i != 0);
+ }
+ do
+ {
+ T temp = p[size];
+ p[size--] = p[1];
+ p[1] = temp;
+ SortRefDown(p, 1, size, compare, param);
+ }
+ while (size > 1);
+ }
+
+ static void SortRefDown2(T* p, unsigned k, unsigned size)
+ {
+ T temp = p[k];
+ for (;;)
+ {
+ unsigned s = (k << 1);
+ if (s > size)
+ break;
+ if (s < size && p[(size_t)s + 1].Compare(p[s]) > 0)
+ s++;
+ if (temp.Compare(p[s]) >= 0)
+ break;
+ p[k] = p[s];
+ k = s;
+ }
+ p[k] = temp;
+ }
+
+ void Sort2()
+ {
+ unsigned size = _size;
+ if (size <= 1)
+ return;
+ T* p = (&Front()) - 1;
+ {
+ unsigned i = size >> 1;
+ do
+ SortRefDown2(p, i, size);
+ while (--i != 0);
+ }
+ do
+ {
+ T temp = p[size];
+ p[size--] = p[1];
+ p[1] = temp;
+ SortRefDown2(p, 1, size);
+ }
+ while (size > 1);
+ }
+};
+
+typedef CRecordVector<int> CIntVector;
+typedef CRecordVector<unsigned int> CUIntVector;
+typedef CRecordVector<bool> CBoolVector;
+typedef CRecordVector<unsigned char> CByteVector;
+typedef CRecordVector<void *> CPointerVector;
+
+template <class T>
+class CObjectVector
+{
+ CPointerVector _v;
+public:
+ unsigned Size() const { return _v.Size(); }
+ bool IsEmpty() const { return _v.IsEmpty(); }
+ void ReserveDown() { _v.ReserveDown(); }
+ // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); }
+ void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); }
+
+ CObjectVector() {};
+ CObjectVector(const CObjectVector &v)
+ {
+ unsigned size = v.Size();
+ _v.ConstructReserve(size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
+ }
+ CObjectVector& operator=(const CObjectVector &v)
+ {
+ if (&v == this)
+ return *this;
+ Clear();
+ unsigned size = v.Size();
+ _v.Reserve(size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
+ return *this;
+ }
+
+ CObjectVector& operator+=(const CObjectVector &v)
+ {
+ unsigned size = v.Size();
+ _v.Reserve(Size() + size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
+ return *this;
+ }
+
+ const T& operator[](unsigned index) const { return *((T *)_v[index]); }
+ T& operator[](unsigned index) { return *((T *)_v[index]); }
+ const T& Front() const { return operator[](0); }
+ T& Front() { return operator[](0); }
+ const T& Back() const { return *(T *)_v.Back(); }
+ T& Back() { return *(T *)_v.Back(); }
+
+ void MoveToFront(unsigned index) { _v.MoveToFront(index); }
+
+ unsigned Add(const T& item) { return _v.Add(new T(item)); }
+
+ void AddInReserved(const T& item) { _v.AddInReserved(new T(item)); }
+
+ T& AddNew()
+ {
+ T *p = new T;
+ _v.Add(p);
+ return *p;
+ }
+
+ T& AddNewInReserved()
+ {
+ T *p = new T;
+ _v.AddInReserved(p);
+ return *p;
+ }
+
+ void Insert(unsigned index, const T& item) { _v.Insert(index, new T(item)); }
+
+ T& InsertNew(unsigned index)
+ {
+ T *p = new T;
+ _v.Insert(index, p);
+ return *p;
+ }
+
+ ~CObjectVector()
+ {
+ for (unsigned i = _v.Size(); i != 0;)
+ delete (T *)_v[--i];
+ }
+
+ void ClearAndFree()
+ {
+ Clear();
+ _v.ClearAndFree();
+ }
+
+ void Clear()
+ {
+ for (unsigned i = _v.Size(); i != 0;)
+ delete (T *)_v[--i];
+ _v.Clear();
+ }
+
+ void DeleteFrom(unsigned index)
+ {
+ unsigned size = _v.Size();
+ for (unsigned i = index; i < size; i++)
+ delete (T *)_v[i];
+ _v.DeleteFrom(index);
+ }
+
+ void DeleteFrontal(unsigned num)
+ {
+ for (unsigned i = 0; i < num; i++)
+ delete (T *)_v[i];
+ _v.DeleteFrontal(num);
+ }
+
+ void DeleteBack()
+ {
+ delete (T *)_v.Back();
+ _v.DeleteBack();
+ }
+
+ void Delete(unsigned index)
+ {
+ delete (T *)_v[index];
+ _v.Delete(index);
+ }
+
+ /*
+ void Delete(unsigned index, unsigned num)
+ {
+ for (unsigned i = 0; i < num; i++)
+ delete (T *)_v[index + i];
+ _v.Delete(index, num);
+ }
+ */
+
+ /*
+ int Find(const T& item) const
+ {
+ unsigned size = Size();
+ for (unsigned i = 0; i < size; i++)
+ if (item == (*this)[i])
+ return i;
+ return -1;
+ }
+ */
+
+ int FindInSorted(const T& item) const
+ {
+ unsigned left = 0, right = Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ return mid;
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+ }
+
+ unsigned AddToUniqueSorted(const T& item)
+ {
+ unsigned left = 0, right = Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ return mid;
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ /*
+ unsigned AddToSorted(const T& item)
+ {
+ unsigned left = 0, right = Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ {
+ right = mid + 1;
+ break;
+ }
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+ */
+
+ void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
+ { _v.Sort(compare, param); }
+
+ static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
+ { return (*(*((const T **)a1))).Compare(*(*((const T **)a2))); }
+
+ void Sort() { _v.Sort(CompareObjectItems, 0); }
+};
+
+#define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++)
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyWindows.cpp b/other-licenses/7zstub/src/CPP/Common/MyWindows.cpp
new file mode 100644
index 0000000000..bc9f7be3f5
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyWindows.cpp
@@ -0,0 +1,145 @@
+// MyWindows.cpp
+
+#include "StdAfx.h"
+
+#ifndef _WIN32
+
+#include <stdlib.h>
+
+#include "MyWindows.h"
+
+static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); }
+static inline void FreeForBSTR(void *pv) { ::free(pv);}
+
+/* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string.
+ We must select CBstrSizeType for another systems (not Win32):
+
+ if (CBstrSizeType is UINT32),
+ then we support only strings smaller than 4 GB.
+ Win32 version always has that limitation.
+
+ if (CBstrSizeType is UINT),
+ (UINT can be 16/32/64-bit)
+ We can support strings larger than 4 GB (if UINT is 64-bit),
+ but sizeof(UINT) can be different in parts compiled by
+ different compilers/settings,
+ and we can't send such BSTR strings between such parts.
+*/
+
+typedef UINT32 CBstrSizeType;
+// typedef UINT CBstrSizeType;
+
+#define k_BstrSize_Max 0xFFFFFFFF
+// #define k_BstrSize_Max UINT_MAX
+// #define k_BstrSize_Max ((UINT)(INT)-1)
+
+BSTR SysAllocStringByteLen(LPCSTR s, UINT len)
+{
+ /* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end.
+ We provide also aligned null OLECHAR at the end. */
+
+ if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(OLECHAR) - sizeof(CBstrSizeType)))
+ return NULL;
+
+ UINT size = (len + sizeof(OLECHAR) + sizeof(OLECHAR) - 1) & ~(sizeof(OLECHAR) - 1);
+ void *p = AllocateForBSTR(size + sizeof(CBstrSizeType));
+ if (!p)
+ return NULL;
+ *(CBstrSizeType *)p = (CBstrSizeType)len;
+ BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
+ if (s)
+ memcpy(bstr, s, len);
+ for (; len < size; len++)
+ ((Byte *)bstr)[len] = 0;
+ return bstr;
+}
+
+BSTR SysAllocStringLen(const OLECHAR *s, UINT len)
+{
+ if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(CBstrSizeType)) / sizeof(OLECHAR))
+ return NULL;
+
+ UINT size = len * sizeof(OLECHAR);
+ void *p = AllocateForBSTR(size + sizeof(CBstrSizeType) + sizeof(OLECHAR));
+ if (!p)
+ return NULL;
+ *(CBstrSizeType *)p = (CBstrSizeType)size;
+ BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
+ if (s)
+ memcpy(bstr, s, size);
+ bstr[len] = 0;
+ return bstr;
+}
+
+BSTR SysAllocString(const OLECHAR *s)
+{
+ if (!s)
+ return 0;
+ const OLECHAR *s2 = s;
+ while (*s2 != 0)
+ s2++;
+ return SysAllocStringLen(s, (UINT)(s2 - s));
+}
+
+void SysFreeString(BSTR bstr)
+{
+ if (bstr)
+ FreeForBSTR((CBstrSizeType *)bstr - 1);
+}
+
+UINT SysStringByteLen(BSTR bstr)
+{
+ if (!bstr)
+ return 0;
+ return *((CBstrSizeType *)bstr - 1);
+}
+
+UINT SysStringLen(BSTR bstr)
+{
+ if (!bstr)
+ return 0;
+ return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR);
+}
+
+
+HRESULT VariantClear(VARIANTARG *prop)
+{
+ if (prop->vt == VT_BSTR)
+ SysFreeString(prop->bstrVal);
+ prop->vt = VT_EMPTY;
+ return S_OK;
+}
+
+HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src)
+{
+ HRESULT res = ::VariantClear(dest);
+ if (res != S_OK)
+ return res;
+ if (src->vt == VT_BSTR)
+ {
+ dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal,
+ SysStringByteLen(src->bstrVal));
+ if (!dest->bstrVal)
+ return E_OUTOFMEMORY;
+ dest->vt = VT_BSTR;
+ }
+ else
+ *dest = *src;
+ return S_OK;
+}
+
+LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2)
+{
+ if (ft1->dwHighDateTime < ft2->dwHighDateTime) return -1;
+ if (ft1->dwHighDateTime > ft2->dwHighDateTime) return 1;
+ if (ft1->dwLowDateTime < ft2->dwLowDateTime) return -1;
+ if (ft1->dwLowDateTime > ft2->dwLowDateTime) return 1;
+ return 0;
+}
+
+DWORD GetLastError()
+{
+ return 0;
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/MyWindows.h b/other-licenses/7zstub/src/CPP/Common/MyWindows.h
new file mode 100644
index 0000000000..cc78478150
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/MyWindows.h
@@ -0,0 +1,231 @@
+// MyWindows.h
+
+#ifndef __MY_WINDOWS_H
+#define __MY_WINDOWS_H
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+#ifdef UNDER_CE
+ #undef VARIANT_TRUE
+ #define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#endif
+
+#else
+
+#include <stddef.h> // for wchar_t
+#include <string.h>
+// #include <stdint.h> // for uintptr_t
+
+#include "MyGuidDef.h"
+
+#define WINAPI
+
+typedef char CHAR;
+typedef unsigned char UCHAR;
+
+#undef BYTE
+typedef unsigned char BYTE;
+
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+#undef WORD
+typedef unsigned short WORD;
+typedef short VARIANT_BOOL;
+
+typedef int INT;
+typedef Int32 INT32;
+typedef unsigned int UINT;
+typedef UInt32 UINT32;
+typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit
+typedef UINT32 ULONG;
+
+#undef DWORD
+typedef UINT32 DWORD;
+
+typedef long BOOL;
+
+#ifndef FALSE
+ #define FALSE 0
+ #define TRUE 1
+#endif
+
+// typedef size_t ULONG_PTR;
+typedef size_t DWORD_PTR;
+// typedef uintptr_t UINT_PTR;
+// typedef ptrdiff_t UINT_PTR;
+
+typedef Int64 LONGLONG;
+typedef UInt64 ULONGLONG;
+
+typedef struct _LARGE_INTEGER { LONGLONG QuadPart; } LARGE_INTEGER;
+typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart; } ULARGE_INTEGER;
+
+typedef const CHAR *LPCSTR;
+typedef CHAR TCHAR;
+typedef const TCHAR *LPCTSTR;
+typedef wchar_t WCHAR;
+typedef WCHAR OLECHAR;
+typedef const WCHAR *LPCWSTR;
+typedef OLECHAR *BSTR;
+typedef const OLECHAR *LPCOLESTR;
+typedef OLECHAR *LPOLESTR;
+
+typedef struct _FILETIME
+{
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+} FILETIME;
+
+#define HRESULT LONG
+#define FAILED(Status) ((HRESULT)(Status)<0)
+typedef ULONG PROPID;
+typedef LONG SCODE;
+
+#define ERROR_NEGATIVE_SEEK 131L
+
+#define S_OK ((HRESULT)0x00000000L)
+#define S_FALSE ((HRESULT)0x00000001L)
+#define E_NOTIMPL ((HRESULT)0x80004001L)
+#define E_NOINTERFACE ((HRESULT)0x80004002L)
+#define E_ABORT ((HRESULT)0x80004004L)
+#define E_FAIL ((HRESULT)0x80004005L)
+#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)
+#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
+#define E_INVALIDARG ((HRESULT)0x80070057L)
+
+#ifdef _MSC_VER
+#define STDMETHODCALLTYPE __stdcall
+#else
+#define STDMETHODCALLTYPE
+#endif
+
+#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
+#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
+#define STDMETHODIMP STDMETHODIMP_(HRESULT)
+
+#define PURE = 0
+
+#define MIDL_INTERFACE(x) struct
+
+#ifdef __cplusplus
+
+DEFINE_GUID(IID_IUnknown,
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+struct IUnknown
+{
+ STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
+ STDMETHOD_(ULONG, AddRef)() PURE;
+ STDMETHOD_(ULONG, Release)() PURE;
+ #ifndef _WIN32
+ virtual ~IUnknown() {}
+ #endif
+};
+
+typedef IUnknown *LPUNKNOWN;
+
+#endif
+
+#define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#define VARIANT_FALSE ((VARIANT_BOOL)0)
+
+enum VARENUM
+{
+ VT_EMPTY = 0,
+ VT_NULL = 1,
+ VT_I2 = 2,
+ VT_I4 = 3,
+ VT_R4 = 4,
+ VT_R8 = 5,
+ VT_CY = 6,
+ VT_DATE = 7,
+ VT_BSTR = 8,
+ VT_DISPATCH = 9,
+ VT_ERROR = 10,
+ VT_BOOL = 11,
+ VT_VARIANT = 12,
+ VT_UNKNOWN = 13,
+ VT_DECIMAL = 14,
+ VT_I1 = 16,
+ VT_UI1 = 17,
+ VT_UI2 = 18,
+ VT_UI4 = 19,
+ VT_I8 = 20,
+ VT_UI8 = 21,
+ VT_INT = 22,
+ VT_UINT = 23,
+ VT_VOID = 24,
+ VT_HRESULT = 25,
+ VT_FILETIME = 64
+};
+
+typedef unsigned short VARTYPE;
+typedef WORD PROPVAR_PAD1;
+typedef WORD PROPVAR_PAD2;
+typedef WORD PROPVAR_PAD3;
+
+typedef struct tagPROPVARIANT
+{
+ VARTYPE vt;
+ PROPVAR_PAD1 wReserved1;
+ PROPVAR_PAD2 wReserved2;
+ PROPVAR_PAD3 wReserved3;
+ union
+ {
+ CHAR cVal;
+ UCHAR bVal;
+ SHORT iVal;
+ USHORT uiVal;
+ LONG lVal;
+ ULONG ulVal;
+ INT intVal;
+ UINT uintVal;
+ LARGE_INTEGER hVal;
+ ULARGE_INTEGER uhVal;
+ VARIANT_BOOL boolVal;
+ SCODE scode;
+ FILETIME filetime;
+ BSTR bstrVal;
+ };
+} PROPVARIANT;
+
+typedef PROPVARIANT tagVARIANT;
+typedef tagVARIANT VARIANT;
+typedef VARIANT VARIANTARG;
+
+MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src);
+
+typedef struct tagSTATPROPSTG
+{
+ LPOLESTR lpwstrName;
+ PROPID propid;
+ VARTYPE vt;
+} STATPROPSTG;
+
+MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocStringLen(const OLECHAR *sz, UINT len);
+MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
+MY_EXTERN_C void SysFreeString(BSTR bstr);
+MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
+MY_EXTERN_C UINT SysStringLen(BSTR bstr);
+
+MY_EXTERN_C DWORD GetLastError();
+MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
+
+#define CP_ACP 0
+#define CP_OEMCP 1
+#define CP_UTF8 65001
+
+typedef enum tagSTREAM_SEEK
+{
+ STREAM_SEEK_SET = 0,
+ STREAM_SEEK_CUR = 1,
+ STREAM_SEEK_END = 2
+} STREAM_SEEK;
+
+#endif
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/NewHandler.cpp b/other-licenses/7zstub/src/CPP/Common/NewHandler.cpp
new file mode 100644
index 0000000000..18d2d1865b
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/NewHandler.cpp
@@ -0,0 +1,163 @@
+// NewHandler.cpp
+
+#include "StdAfx.h"
+
+#include <stdlib.h>
+
+#include "NewHandler.h"
+
+// #define DEBUG_MEMORY_LEAK
+
+#ifndef DEBUG_MEMORY_LEAK
+
+#ifdef _7ZIP_REDEFINE_OPERATOR_NEW
+
+/*
+void * my_new(size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void my_delete(void *p) throw()
+{
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
+ ::free(p);
+}
+
+void * my_Realloc(void *p, size_t newSize, size_t oldSize)
+{
+ void *newBuf = my_new(newSize);
+ if (oldSize != 0)
+ memcpy(newBuf, p, oldSize);
+ my_delete(p);
+ return newBuf;
+}
+*/
+
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new(size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete(void *p) throw()
+{
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
+ ::free(p);
+}
+
+/*
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new[](size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete[](void *p) throw()
+{
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
+ ::free(p);
+}
+*/
+
+#endif
+
+#else
+
+#include <stdio.h>
+
+// #pragma init_seg(lib)
+const int kDebugSize = 1000000;
+static void *a[kDebugSize];
+static int index = 0;
+
+static int numAllocs = 0;
+void * __cdecl operator new(size_t size)
+{
+ numAllocs++;
+ void *p = HeapAlloc(GetProcessHeap(), 0, size);
+ if (index < kDebugSize)
+ {
+ a[index] = p;
+ index++;
+ }
+ if (p == 0)
+ throw CNewException();
+ printf("Alloc %6d, size = %8u\n", numAllocs, (unsigned)size);
+ return p;
+}
+
+class CC
+{
+public:
+ CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ a[i] = 0;
+ }
+ ~CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ if (a[i] != 0)
+ return;
+ }
+} g_CC;
+
+
+void __cdecl operator delete(void *p)
+{
+ if (p == 0)
+ return;
+ /*
+ for (int i = 0; i < index; i++)
+ if (a[i] == p)
+ a[i] = 0;
+ */
+ HeapFree(GetProcessHeap(), 0, p);
+ numAllocs--;
+ printf("Free %d\n", numAllocs);
+}
+
+#endif
+
+/*
+int MemErrorVC(size_t)
+{
+ throw CNewException();
+ // return 1;
+}
+CNewHandlerSetter::CNewHandlerSetter()
+{
+ // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
+}
+CNewHandlerSetter::~CNewHandlerSetter()
+{
+ // _set_new_handler(MemErrorOldVCFunction);
+}
+*/
diff --git a/other-licenses/7zstub/src/CPP/Common/NewHandler.h b/other-licenses/7zstub/src/CPP/Common/NewHandler.h
new file mode 100644
index 0000000000..9d20ee1347
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/NewHandler.h
@@ -0,0 +1,88 @@
+// Common/NewHandler.h
+
+#ifndef __COMMON_NEW_HANDLER_H
+#define __COMMON_NEW_HANDLER_H
+
+/*
+NewHandler.h and NewHandler.cpp allows to solve problem with compilers that
+don't throw exception in operator new().
+
+This file must be included before any code that uses operators new() or delete()
+and you must compile and link "NewHandler.cpp", if you use some old MSVC compiler.
+
+The operator new() in some MSVC versions doesn't throw exception std::bad_alloc.
+MSVC 6.0 (_MSC_VER == 1200) doesn't throw exception.
+The code produced by some another MSVC compilers also can be linked
+to library that doesn't throw exception.
+We suppose that code compiled with VS2015+ (_MSC_VER >= 1900) throws exception std::bad_alloc.
+For older _MSC_VER versions we redefine operator new() and operator delete().
+Our version of operator new() throws CNewException() exception on failure.
+
+It's still allowed to use redefined version of operator new() from "NewHandler.cpp"
+with any compiler. 7-Zip's code can work with std::bad_alloc and CNewException() exceptions.
+But if you use some additional code (outside of 7-Zip's code), you must check
+that redefined version of operator new() is not problem for your code.
+*/
+
+#include <stddef.h>
+
+#ifdef _WIN32
+// We can compile my_new and my_delete with _fastcall
+/*
+void * my_new(size_t size);
+void my_delete(void *p) throw();
+// void * my_Realloc(void *p, size_t newSize, size_t oldSize);
+*/
+#endif
+
+
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+ // If you want to use default operator new(), you can disable the following line
+ #define _7ZIP_REDEFINE_OPERATOR_NEW
+#endif
+
+
+#ifdef _7ZIP_REDEFINE_OPERATOR_NEW
+
+// std::bad_alloc can require additional DLL dependency.
+// So we don't define CNewException as std::bad_alloc here.
+
+class CNewException {};
+
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new(size_t size);
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete(void *p) throw();
+
+#else
+
+#include <new>
+
+#define CNewException std::bad_alloc
+
+#endif
+
+/*
+#ifdef _WIN32
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new[](size_t size);
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete[](void *p) throw();
+#endif
+*/
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/Sha256Reg.cpp b/other-licenses/7zstub/src/CPP/Common/Sha256Reg.cpp
new file mode 100644
index 0000000000..14a3652377
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/Sha256Reg.cpp
@@ -0,0 +1,40 @@
+// Sha256Reg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/Sha256.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/Common/RegisterCodec.h"
+
+class CSha256Hasher:
+ public IHasher,
+ public CMyUnknownImp
+{
+ CSha256 _sha;
+ Byte mtDummy[1 << 7];
+
+public:
+ CSha256Hasher() { Sha256_Init(&_sha); }
+
+ MY_UNKNOWN_IMP1(IHasher)
+ INTERFACE_IHasher(;)
+};
+
+STDMETHODIMP_(void) CSha256Hasher::Init() throw()
+{
+ Sha256_Init(&_sha);
+}
+
+STDMETHODIMP_(void) CSha256Hasher::Update(const void *data, UInt32 size) throw()
+{
+ Sha256_Update(&_sha, (const Byte *)data, size);
+}
+
+STDMETHODIMP_(void) CSha256Hasher::Final(Byte *digest) throw()
+{
+ Sha256_Final(&_sha, digest);
+}
+
+REGISTER_HASHER(CSha256Hasher, 0xA, "SHA256", SHA256_DIGEST_SIZE)
diff --git a/other-licenses/7zstub/src/CPP/Common/StdAfx.h b/other-licenses/7zstub/src/CPP/Common/StdAfx.h
new file mode 100644
index 0000000000..3f1890a278
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "Common.h"
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/StdInStream.cpp b/other-licenses/7zstub/src/CPP/Common/StdInStream.cpp
new file mode 100644
index 0000000000..f547b54fb5
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/StdInStream.cpp
@@ -0,0 +1,89 @@
+// Common/StdInStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+
+#include "StdInStream.h"
+#include "StringConvert.h"
+#include "UTFConvert.h"
+
+// #define kEOFMessage "Unexpected end of input stream"
+// #define kReadErrorMessage "Error reading input stream"
+// #define kIllegalCharMessage "Illegal zero character in input stream"
+
+#define kFileOpenMode TEXT("r")
+
+extern int g_CodePage;
+
+CStdInStream g_StdIn(stdin);
+
+bool CStdInStream::Open(LPCTSTR fileName) throw()
+{
+ Close();
+ _stream = _tfopen(fileName, kFileOpenMode);
+ _streamIsOpen = (_stream != 0);
+ return _streamIsOpen;
+}
+
+bool CStdInStream::Close() throw()
+{
+ if (!_streamIsOpen)
+ return true;
+ _streamIsOpen = (fclose(_stream) != 0);
+ return !_streamIsOpen;
+}
+
+bool CStdInStream::ScanAStringUntilNewLine(AString &s)
+{
+ s.Empty();
+ for (;;)
+ {
+ int intChar = GetChar();
+ if (intChar == EOF)
+ return true;
+ char c = (char)intChar;
+ if (c == 0)
+ return false;
+ if (c == '\n')
+ return true;
+ s += c;
+ }
+}
+
+bool CStdInStream::ScanUStringUntilNewLine(UString &dest)
+{
+ dest.Empty();
+ AString s;
+ bool res = ScanAStringUntilNewLine(s);
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUTF8ToUnicode(s, dest);
+ else
+ MultiByteToUnicodeString2(dest, s, (UINT)codePage);
+ return res;
+}
+
+/*
+bool CStdInStream::ReadToString(AString &resultString)
+{
+ resultString.Empty();
+ for (;;)
+ {
+ int intChar = GetChar();
+ if (intChar == EOF)
+ return !Error();
+ char c = (char)intChar;
+ if (c == 0)
+ return false;
+ resultString += c;
+ }
+}
+*/
+
+int CStdInStream::GetChar()
+{
+ return fgetc(_stream); // getc() doesn't work in BeOS?
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/StdInStream.h b/other-licenses/7zstub/src/CPP/Common/StdInStream.h
new file mode 100644
index 0000000000..20f9ce3436
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/StdInStream.h
@@ -0,0 +1,38 @@
+// Common/StdInStream.h
+
+#ifndef __COMMON_STD_IN_STREAM_H
+#define __COMMON_STD_IN_STREAM_H
+
+#include <stdio.h>
+
+#include "MyString.h"
+#include "MyTypes.h"
+
+class CStdInStream
+{
+ FILE *_stream;
+ bool _streamIsOpen;
+public:
+ CStdInStream(): _stream(0), _streamIsOpen(false) {};
+ CStdInStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
+ ~CStdInStream() { Close(); }
+
+ bool Open(LPCTSTR fileName) throw();
+ bool Close() throw();
+
+ // returns:
+ // false, if ZERO character in stream
+ // true, if EOF or '\n'
+ bool ScanAStringUntilNewLine(AString &s);
+ bool ScanUStringUntilNewLine(UString &s);
+ // bool ReadToString(AString &resultString);
+
+ bool Eof() const throw() { return (feof(_stream) != 0); }
+ bool Error() const throw() { return (ferror(_stream) != 0); }
+
+ int GetChar();
+};
+
+extern CStdInStream g_StdIn;
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/StdOutStream.cpp b/other-licenses/7zstub/src/CPP/Common/StdOutStream.cpp
new file mode 100644
index 0000000000..dc6d4bd4a9
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/StdOutStream.cpp
@@ -0,0 +1,163 @@
+// Common/StdOutStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+
+#include "IntToString.h"
+#include "StdOutStream.h"
+#include "StringConvert.h"
+#include "UTFConvert.h"
+
+#define kFileOpenMode "wt"
+
+extern int g_CodePage;
+
+CStdOutStream g_StdOut(stdout);
+CStdOutStream g_StdErr(stderr);
+
+bool CStdOutStream::Open(const char *fileName) throw()
+{
+ Close();
+ _stream = fopen(fileName, kFileOpenMode);
+ _streamIsOpen = (_stream != 0);
+ return _streamIsOpen;
+}
+
+bool CStdOutStream::Close() throw()
+{
+ if (!_streamIsOpen)
+ return true;
+ if (fclose(_stream) != 0)
+ return false;
+ _stream = 0;
+ _streamIsOpen = false;
+ return true;
+}
+
+bool CStdOutStream::Flush() throw()
+{
+ return (fflush(_stream) == 0);
+}
+
+CStdOutStream & endl(CStdOutStream & outStream) throw()
+{
+ return outStream << '\n';
+}
+
+CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)
+{
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ AString dest;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, dest);
+ else
+ UnicodeStringToMultiByte2(dest, s, (UINT)codePage);
+ return operator<<((const char *)dest);
+}
+
+void StdOut_Convert_UString_to_AString(const UString &s, AString &temp)
+{
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
+}
+
+void CStdOutStream::PrintUString(const UString &s, AString &temp)
+{
+ StdOut_Convert_UString_to_AString(s, temp);
+ *this << (const char *)temp;
+}
+
+
+static const wchar_t kReplaceChar = '_';
+
+void CStdOutStream::Normalize_UString__LF_Allowed(UString &s)
+{
+ unsigned len = s.Len();
+ wchar_t *d = s.GetBuf();
+
+ if (IsTerminalMode)
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = d[i];
+ if (c <= 13 && c >= 7 && c != '\n')
+ d[i] = kReplaceChar;
+ }
+}
+
+void CStdOutStream::Normalize_UString(UString &s)
+{
+ unsigned len = s.Len();
+ wchar_t *d = s.GetBuf();
+
+ if (IsTerminalMode)
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = d[i];
+ if (c <= 13 && c >= 7)
+ d[i] = kReplaceChar;
+ }
+ else
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = d[i];
+ if (c == '\n')
+ d[i] = kReplaceChar;
+ }
+}
+
+void CStdOutStream::NormalizePrint_UString(const UString &s, UString &tempU, AString &tempA)
+{
+ tempU = s;
+ Normalize_UString(tempU);
+ PrintUString(tempU, tempA);
+}
+
+void CStdOutStream::NormalizePrint_UString(const UString &s)
+{
+ NormalizePrint_wstr(s);
+}
+
+void CStdOutStream::NormalizePrint_wstr(const wchar_t *s)
+{
+ UString tempU = s;
+ Normalize_UString(tempU);
+ AString tempA;
+ PrintUString(tempU, tempA);
+}
+
+
+CStdOutStream & CStdOutStream::operator<<(Int32 number) throw()
+{
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
+}
+
+CStdOutStream & CStdOutStream::operator<<(Int64 number) throw()
+{
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
+}
+
+CStdOutStream & CStdOutStream::operator<<(UInt32 number) throw()
+{
+ char s[16];
+ ConvertUInt32ToString(number, s);
+ return operator<<(s);
+}
+
+CStdOutStream & CStdOutStream::operator<<(UInt64 number) throw()
+{
+ char s[32];
+ ConvertUInt64ToString(number, s);
+ return operator<<(s);
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/StdOutStream.h b/other-licenses/7zstub/src/CPP/Common/StdOutStream.h
new file mode 100644
index 0000000000..475954c069
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/StdOutStream.h
@@ -0,0 +1,71 @@
+// Common/StdOutStream.h
+
+#ifndef __COMMON_STD_OUT_STREAM_H
+#define __COMMON_STD_OUT_STREAM_H
+
+#include <stdio.h>
+
+#include "MyString.h"
+#include "MyTypes.h"
+
+class CStdOutStream
+{
+ FILE *_stream;
+ bool _streamIsOpen;
+public:
+ bool IsTerminalMode;
+
+ CStdOutStream(): _stream(0), _streamIsOpen(false), IsTerminalMode(false) {};
+ CStdOutStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
+ ~CStdOutStream() { Close(); }
+
+ // void AttachStdStream(FILE *stream) { _stream = stream; _streamIsOpen = false; }
+ // bool IsDefined() const { return _stream != NULL; }
+
+ operator FILE *() { return _stream; }
+ bool Open(const char *fileName) throw();
+ bool Close() throw();
+ bool Flush() throw();
+
+ CStdOutStream & operator<<(CStdOutStream & (* func)(CStdOutStream &))
+ {
+ (*func)(*this);
+ return *this;
+ }
+
+ CStdOutStream & operator<<(const char *s) throw()
+ {
+ fputs(s, _stream);
+ return *this;
+ }
+
+ CStdOutStream & operator<<(char c) throw()
+ {
+ fputc((unsigned char)c, _stream);
+ return *this;
+ }
+
+ CStdOutStream & operator<<(Int32 number) throw();
+ CStdOutStream & operator<<(Int64 number) throw();
+ CStdOutStream & operator<<(UInt32 number) throw();
+ CStdOutStream & operator<<(UInt64 number) throw();
+
+ CStdOutStream & operator<<(const wchar_t *s);
+ void PrintUString(const UString &s, AString &temp);
+
+ void Normalize_UString__LF_Allowed(UString &s);
+ void Normalize_UString(UString &s);
+
+ void NormalizePrint_UString(const UString &s, UString &tempU, AString &tempA);
+ void NormalizePrint_UString(const UString &s);
+ void NormalizePrint_wstr(const wchar_t *s);
+};
+
+CStdOutStream & endl(CStdOutStream & outStream) throw();
+
+extern CStdOutStream g_StdOut;
+extern CStdOutStream g_StdErr;
+
+void StdOut_Convert_UString_to_AString(const UString &s, AString &temp);
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/StringConvert.cpp b/other-licenses/7zstub/src/CPP/Common/StringConvert.cpp
new file mode 100644
index 0000000000..b8f33cd63a
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/StringConvert.cpp
@@ -0,0 +1,319 @@
+// Common/StringConvert.cpp
+
+#include "StdAfx.h"
+
+#include "StringConvert.h"
+
+#ifndef _WIN32
+#include <stdlib.h>
+#endif
+
+static const char k_DefultChar = '_';
+
+#ifdef _WIN32
+
+/*
+MultiByteToWideChar(CodePage, DWORD dwFlags,
+ LPCSTR lpMultiByteStr, int cbMultiByte,
+ LPWSTR lpWideCharStr, int cchWideChar)
+
+ if (cbMultiByte == 0)
+ return: 0. ERR: ERROR_INVALID_PARAMETER
+
+ if (cchWideChar == 0)
+ return: the required buffer size in characters.
+
+ if (supplied buffer size was not large enough)
+ return: 0. ERR: ERROR_INSUFFICIENT_BUFFER
+ The number of filled characters in lpWideCharStr can be smaller than cchWideChar (if last character is complex)
+
+ If there are illegal characters:
+ if MB_ERR_INVALID_CHARS is set in dwFlags:
+ - the function stops conversion on illegal character.
+ - Return: 0. ERR: ERROR_NO_UNICODE_TRANSLATION.
+
+ if MB_ERR_INVALID_CHARS is NOT set in dwFlags:
+ before Vista: illegal character is dropped (skipped). WinXP-64: GetLastError() returns 0.
+ in Vista+: illegal character is not dropped (MSDN). Undocumented: illegal
+ character is converted to U+FFFD, which is REPLACEMENT CHARACTER.
+*/
+
+
+void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage)
+{
+ dest.Empty();
+ if (src.IsEmpty())
+ return;
+ {
+ /*
+ wchar_t *d = dest.GetBuf(src.Len());
+ const char *s = (const char *)src;
+ unsigned i;
+
+ for (i = 0;;)
+ {
+ Byte c = (Byte)s[i];
+ if (c >= 0x80 || c == 0)
+ break;
+ d[i++] = (wchar_t)c;
+ }
+
+ if (i != src.Len())
+ {
+ unsigned len = MultiByteToWideChar(codePage, 0, s + i,
+ src.Len() - i, d + i,
+ src.Len() + 1 - i);
+ if (len == 0)
+ throw 282228;
+ i += len;
+ }
+
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
+ */
+ unsigned len = MultiByteToWideChar(codePage, 0, src, src.Len(), NULL, 0);
+ if (len == 0)
+ {
+ if (GetLastError() != 0)
+ throw 282228;
+ }
+ else
+ {
+ len = MultiByteToWideChar(codePage, 0, src, src.Len(), dest.GetBuf(len), len);
+ if (len == 0)
+ throw 282228;
+ dest.ReleaseBuf_SetEnd(len);
+ }
+ }
+}
+
+/*
+ int WideCharToMultiByte(
+ UINT CodePage, DWORD dwFlags,
+ LPCWSTR lpWideCharStr, int cchWideChar,
+ LPSTR lpMultiByteStr, int cbMultiByte,
+ LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
+
+if (lpDefaultChar == NULL),
+ - it uses system default value.
+
+if (CodePage == CP_UTF7 || CodePage == CP_UTF8)
+ if (lpDefaultChar != NULL || lpUsedDefaultChar != NULL)
+ return: 0. ERR: ERROR_INVALID_PARAMETER.
+
+The function operates most efficiently, if (lpDefaultChar == NULL && lpUsedDefaultChar == NULL)
+
+*/
+
+static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
+{
+ dest.Empty();
+ defaultCharWasUsed = false;
+ if (src.IsEmpty())
+ return;
+ {
+ /*
+ unsigned numRequiredBytes = src.Len() * 2;
+ char *d = dest.GetBuf(numRequiredBytes);
+ const wchar_t *s = (const wchar_t *)src;
+ unsigned i;
+
+ for (i = 0;;)
+ {
+ wchar_t c = s[i];
+ if (c >= 0x80 || c == 0)
+ break;
+ d[i++] = (char)c;
+ }
+
+ if (i != src.Len())
+ {
+ BOOL defUsed = FALSE;
+ defaultChar = defaultChar;
+
+ bool isUtf = (codePage == CP_UTF8 || codePage == CP_UTF7);
+ unsigned len = WideCharToMultiByte(codePage, 0, s + i, src.Len() - i,
+ d + i, numRequiredBytes + 1 - i,
+ (isUtf ? NULL : &defaultChar),
+ (isUtf ? NULL : &defUsed));
+ defaultCharWasUsed = (defUsed != FALSE);
+ if (len == 0)
+ throw 282229;
+ i += len;
+ }
+
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
+ */
+
+ /*
+ if (codePage != CP_UTF7)
+ {
+ const wchar_t *s = (const wchar_t *)src;
+ unsigned i;
+ for (i = 0;; i++)
+ {
+ wchar_t c = s[i];
+ if (c >= 0x80 || c == 0)
+ break;
+ }
+
+ if (s[i] == 0)
+ {
+ char *d = dest.GetBuf(src.Len());
+ for (i = 0;;)
+ {
+ wchar_t c = s[i];
+ if (c == 0)
+ break;
+ d[i++] = (char)c;
+ }
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
+ return;
+ }
+ }
+ */
+
+ unsigned len = WideCharToMultiByte(codePage, 0, src, src.Len(), NULL, 0, NULL, NULL);
+ if (len == 0)
+ {
+ if (GetLastError() != 0)
+ throw 282228;
+ }
+ else
+ {
+ BOOL defUsed = FALSE;
+ bool isUtf = (codePage == CP_UTF8 || codePage == CP_UTF7);
+ // defaultChar = defaultChar;
+ len = WideCharToMultiByte(codePage, 0, src, src.Len(),
+ dest.GetBuf(len), len,
+ (isUtf ? NULL : &defaultChar),
+ (isUtf ? NULL : &defUsed)
+ );
+ if (!isUtf)
+ defaultCharWasUsed = (defUsed != FALSE);
+ if (len == 0)
+ throw 282228;
+ dest.ReleaseBuf_SetEnd(len);
+ }
+ }
+}
+
+/*
+#ifndef UNDER_CE
+AString SystemStringToOemString(const CSysString &src)
+{
+ AString dest;
+ const unsigned len = src.Len() * 2;
+ CharToOem(src, dest.GetBuf(len));
+ dest.ReleaseBuf_CalcLen(len);
+ return dest;
+}
+#endif
+*/
+
+#else
+
+void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT /* codePage */)
+{
+ dest.Empty();
+ if (src.IsEmpty())
+ return;
+
+ size_t limit = ((size_t)src.Len() + 1) * 2;
+ wchar_t *d = dest.GetBuf((unsigned)limit);
+ size_t len = mbstowcs(d, src, limit);
+ if (len != (size_t)-1)
+ {
+ dest.ReleaseBuf_SetEnd((unsigned)len);
+ return;
+ }
+
+ {
+ unsigned i;
+ const char *s = (const char *)src;
+ for (i = 0;;)
+ {
+ Byte c = (Byte)s[i];
+ if (c == 0)
+ break;
+ d[i++] = (wchar_t)c;
+ }
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
+ }
+}
+
+static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT /* codePage */, char defaultChar, bool &defaultCharWasUsed)
+{
+ dest.Empty();
+ defaultCharWasUsed = false;
+ if (src.IsEmpty())
+ return;
+
+ size_t limit = ((size_t)src.Len() + 1) * 6;
+ char *d = dest.GetBuf((unsigned)limit);
+ size_t len = wcstombs(d, src, limit);
+ if (len != (size_t)-1)
+ {
+ dest.ReleaseBuf_SetEnd((unsigned)len);
+ return;
+ }
+
+ {
+ const wchar_t *s = (const wchar_t *)src;
+ unsigned i;
+ for (i = 0;;)
+ {
+ wchar_t c = s[i];
+ if (c == 0)
+ break;
+ if (c >= 0x100)
+ {
+ c = defaultChar;
+ defaultCharWasUsed = true;
+ }
+ d[i++] = (char)c;
+ }
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
+ }
+}
+
+#endif
+
+
+UString MultiByteToUnicodeString(const AString &src, UINT codePage)
+{
+ UString dest;
+ MultiByteToUnicodeString2(dest, src, codePage);
+ return dest;
+}
+
+UString MultiByteToUnicodeString(const char *src, UINT codePage)
+{
+ return MultiByteToUnicodeString(AString(src), codePage);
+}
+
+
+void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage)
+{
+ bool defaultCharWasUsed;
+ UnicodeStringToMultiByte2(dest, src, codePage, k_DefultChar, defaultCharWasUsed);
+}
+
+AString UnicodeStringToMultiByte(const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
+{
+ AString dest;
+ UnicodeStringToMultiByte2(dest, src, codePage, defaultChar, defaultCharWasUsed);
+ return dest;
+}
+
+AString UnicodeStringToMultiByte(const UString &src, UINT codePage)
+{
+ AString dest;
+ bool defaultCharWasUsed;
+ UnicodeStringToMultiByte2(dest, src, codePage, k_DefultChar, defaultCharWasUsed);
+ return dest;
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/StringConvert.h b/other-licenses/7zstub/src/CPP/Common/StringConvert.h
new file mode 100644
index 0000000000..05a21556d4
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/StringConvert.h
@@ -0,0 +1,88 @@
+// Common/StringConvert.h
+
+#ifndef __COMMON_STRING_CONVERT_H
+#define __COMMON_STRING_CONVERT_H
+
+#include "MyString.h"
+#include "MyWindows.h"
+
+UString MultiByteToUnicodeString(const AString &src, UINT codePage = CP_ACP);
+UString MultiByteToUnicodeString(const char *src, UINT codePage = CP_ACP);
+
+// optimized versions that work faster for ASCII strings
+void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage = CP_ACP);
+// void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
+void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage);
+
+AString UnicodeStringToMultiByte(const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
+AString UnicodeStringToMultiByte(const UString &src, UINT codePage = CP_ACP);
+
+inline const wchar_t* GetUnicodeString(const wchar_t *u) { return u; }
+inline const UString& GetUnicodeString(const UString &u) { return u; }
+
+inline UString GetUnicodeString(const AString &a) { return MultiByteToUnicodeString(a); }
+inline UString GetUnicodeString(const char *a) { return MultiByteToUnicodeString(a); }
+
+inline UString GetUnicodeString(const AString &a, UINT codePage)
+ { return MultiByteToUnicodeString(a, codePage); }
+inline UString GetUnicodeString(const char *a, UINT codePage)
+ { return MultiByteToUnicodeString(a, codePage); }
+
+inline const wchar_t* GetUnicodeString(const wchar_t *u, UINT) { return u; }
+inline const UString& GetUnicodeString(const UString &u, UINT) { return u; }
+
+inline const char* GetAnsiString(const char *a) { return a; }
+inline const AString& GetAnsiString(const AString &a) { return a; }
+
+inline AString GetAnsiString(const wchar_t *u) { return UnicodeStringToMultiByte(UString(u)); }
+inline AString GetAnsiString(const UString &u) { return UnicodeStringToMultiByte(u); }
+
+/*
+inline const char* GetOemString(const char* oem)
+ { return oem; }
+inline const AString& GetOemString(const AString &oem)
+ { return oem; }
+*/
+const char* GetOemString(const char* oem);
+const AString& GetOemString(const AString &oem);
+inline AString GetOemString(const UString &u)
+ { return UnicodeStringToMultiByte(u, CP_OEMCP); }
+
+#ifdef _UNICODE
+ inline const wchar_t* GetSystemString(const wchar_t *u) { return u;}
+ inline const UString& GetSystemString(const UString &u) { return u;}
+ inline const wchar_t* GetSystemString(const wchar_t *u, UINT /* codePage */) { return u;}
+ inline const UString& GetSystemString(const UString &u, UINT /* codePage */) { return u;}
+
+ inline UString GetSystemString(const AString &a, UINT codePage) { return MultiByteToUnicodeString(a, codePage); }
+ inline UString GetSystemString(const char *a, UINT codePage) { return MultiByteToUnicodeString(a, codePage); }
+ inline UString GetSystemString(const AString &a) { return MultiByteToUnicodeString(a); }
+ inline UString GetSystemString(const char *a) { return MultiByteToUnicodeString(a); }
+#else
+ inline const char* GetSystemString(const char *a) { return a; }
+ inline const AString& GetSystemString(const AString &a) { return a; }
+ inline const char* GetSystemString(const char *a, UINT) { return a; }
+ inline const AString& GetSystemString(const AString &a, UINT) { return a; }
+
+ inline AString GetSystemString(const wchar_t *u) { return UnicodeStringToMultiByte(UString(u)); }
+ inline AString GetSystemString(const UString &u) { return UnicodeStringToMultiByte(u); }
+ inline AString GetSystemString(const UString &u, UINT codePage) { return UnicodeStringToMultiByte(u, codePage); }
+
+
+
+ /*
+ inline AString GetSystemString(const wchar_t *u)
+ {
+ UString s;
+ s = u;
+ return UnicodeStringToMultiByte(s);
+ }
+ */
+
+#endif
+
+#ifndef UNDER_CE
+AString SystemStringToOemString(const CSysString &src);
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/StringToInt.cpp b/other-licenses/7zstub/src/CPP/Common/StringToInt.cpp
new file mode 100644
index 0000000000..295816e16f
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/StringToInt.cpp
@@ -0,0 +1,144 @@
+// Common/StringToInt.cpp
+
+#include "StdAfx.h"
+
+#include "StringToInt.h"
+
+static const UInt32 k_UInt32_max = 0xFFFFFFFF;
+static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF);
+// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1;
+
+#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType, charTypeUnsigned) \
+ uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \
+ if (end) *end = s; \
+ uintType res = 0; \
+ for (;; s++) { \
+ charTypeUnsigned c = (charTypeUnsigned)*s; \
+ if (c < '0' || c > '9') { if (end) *end = s; return res; } \
+ if (res > (k_ ## uintType ## _max) / 10) return 0; \
+ res *= 10; \
+ unsigned v = (c - '0'); \
+ if (res > (k_ ## uintType ## _max) - v) return 0; \
+ res += v; }}
+
+CONVERT_STRING_TO_UINT_FUNC(UInt32, char, Byte)
+CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t, wchar_t)
+CONVERT_STRING_TO_UINT_FUNC(UInt64, char, Byte)
+CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t, wchar_t)
+
+Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw()
+{
+ if (end)
+ *end = s;
+ const wchar_t *s2 = s;
+ if (*s == '-')
+ s2++;
+ if (*s2 == 0)
+ return 0;
+ const wchar_t *end2;
+ UInt32 res = ConvertStringToUInt32(s2, &end2);
+ if (*s == '-')
+ {
+ if (res > ((UInt32)1 << (32 - 1)))
+ return 0;
+ }
+ else if ((res & ((UInt32)1 << (32 - 1))) != 0)
+ return 0;
+ if (end)
+ *end = end2;
+ if (*s == '-')
+ return -(Int32)res;
+ return (Int32)res;
+}
+
+UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw()
+{
+ if (end)
+ *end = s;
+ UInt32 res = 0;
+ for (;; s++)
+ {
+ unsigned c = (unsigned char)*s;
+ if (c < '0' || c > '7')
+ {
+ if (end)
+ *end = s;
+ return res;
+ }
+ if ((res & (UInt32)7 << (32 - 3)) != 0)
+ return 0;
+ res <<= 3;
+ res |= (unsigned)(c - '0');
+ }
+}
+
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw()
+{
+ if (end)
+ *end = s;
+ UInt64 res = 0;
+ for (;; s++)
+ {
+ unsigned c = (unsigned char)*s;
+ if (c < '0' || c > '7')
+ {
+ if (end)
+ *end = s;
+ return res;
+ }
+ if ((res & (UInt64)7 << (64 - 3)) != 0)
+ return 0;
+ res <<= 3;
+ res |= (unsigned)(c - '0');
+ }
+}
+
+UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw()
+{
+ if (end)
+ *end = s;
+ UInt32 res = 0;
+ for (;; s++)
+ {
+ unsigned c = (Byte)*s;
+ unsigned v;
+ if (c >= '0' && c <= '9') v = (c - '0');
+ else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
+ else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
+ else
+ {
+ if (end)
+ *end = s;
+ return res;
+ }
+ if ((res & (UInt32)0xF << (32 - 4)) != 0)
+ return 0;
+ res <<= 4;
+ res |= v;
+ }
+}
+
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw()
+{
+ if (end)
+ *end = s;
+ UInt64 res = 0;
+ for (;; s++)
+ {
+ unsigned c = (Byte)*s;
+ unsigned v;
+ if (c >= '0' && c <= '9') v = (c - '0');
+ else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
+ else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
+ else
+ {
+ if (end)
+ *end = s;
+ return res;
+ }
+ if ((res & (UInt64)0xF << (64 - 4)) != 0)
+ return 0;
+ res <<= 4;
+ res |= v;
+ }
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/StringToInt.h b/other-licenses/7zstub/src/CPP/Common/StringToInt.h
new file mode 100644
index 0000000000..140d1ee2dd
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/StringToInt.h
@@ -0,0 +1,21 @@
+// Common/StringToInt.h
+
+#ifndef __COMMON_STRING_TO_INT_H
+#define __COMMON_STRING_TO_INT_H
+
+#include "MyTypes.h"
+
+UInt32 ConvertStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertStringToUInt64(const char *s, const char **end) throw();
+UInt32 ConvertStringToUInt32(const wchar_t *s, const wchar_t **end) throw();
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) throw();
+
+Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw();
+
+UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw();
+
+UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw();
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/TextConfig.cpp b/other-licenses/7zstub/src/CPP/Common/TextConfig.cpp
new file mode 100644
index 0000000000..f54aa3f6d4
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/TextConfig.cpp
@@ -0,0 +1,124 @@
+// Common/TextConfig.cpp
+
+#include "StdAfx.h"
+
+#include "TextConfig.h"
+#include "UTFConvert.h"
+
+static inline bool IsDelimitChar(char c)
+{
+ return (c == ' ' || c == 0x0A || c == 0x0D || c == '\0' || c == '\t');
+}
+
+static AString GetIDString(const char *s, unsigned &finishPos)
+{
+ AString result;
+ for (finishPos = 0; ; finishPos++)
+ {
+ char c = s[finishPos];
+ if (IsDelimitChar(c) || c == '=')
+ break;
+ result += c;
+ }
+ return result;
+}
+
+static bool WaitNextLine(const AString &s, unsigned &pos)
+{
+ for (; pos < s.Len(); pos++)
+ if (s[pos] == 0x0A)
+ return true;
+ return false;
+}
+
+static bool SkipSpaces(const AString &s, unsigned &pos)
+{
+ for (; pos < s.Len(); pos++)
+ {
+ char c = s[pos];
+ if (!IsDelimitChar(c))
+ {
+ if (c != ';')
+ return true;
+ if (!WaitNextLine(s, pos))
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs)
+{
+ pairs.Clear();
+ unsigned pos = 0;
+
+ /////////////////////
+ // read strings
+
+ for (;;)
+ {
+ if (!SkipSpaces(s, pos))
+ break;
+ CTextConfigPair pair;
+ unsigned finishPos;
+ const AString temp (GetIDString(((const char *)s) + pos, finishPos));
+ if (!ConvertUTF8ToUnicode(temp, pair.ID))
+ return false;
+ if (finishPos == 0)
+ return false;
+ pos += finishPos;
+ if (!SkipSpaces(s, pos))
+ return false;
+ if (s[pos] != '=')
+ return false;
+ pos++;
+ if (!SkipSpaces(s, pos))
+ return false;
+ if (s[pos] != '\"')
+ return false;
+ pos++;
+ AString message;
+ for (;;)
+ {
+ if (pos >= s.Len())
+ return false;
+ char c = s[pos++];
+ if (c == '\"')
+ break;
+ if (c == '\\')
+ {
+ c = s[pos++];
+ switch (c)
+ {
+ case 'n': message += '\n'; break;
+ case 't': message += '\t'; break;
+ case '\\': message += '\\'; break;
+ case '\"': message += '\"'; break;
+ default: message += '\\'; message += c; break;
+ }
+ }
+ else
+ message += c;
+ }
+ if (!ConvertUTF8ToUnicode(message, pair.String))
+ return false;
+ pairs.Add(pair);
+ }
+ return true;
+}
+
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const char *id) throw()
+{
+ FOR_VECTOR (i, pairs)
+ if (pairs[i].ID.IsEqualTo(id))
+ return i;
+ return -1;
+}
+
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const char *id)
+{
+ int index = FindTextConfigItem(pairs, id);
+ if (index < 0)
+ return UString();
+ return pairs[index].String;
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/TextConfig.h b/other-licenses/7zstub/src/CPP/Common/TextConfig.h
new file mode 100644
index 0000000000..c39e3634fb
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/TextConfig.h
@@ -0,0 +1,19 @@
+// Common/TextConfig.h
+
+#ifndef __COMMON_TEXT_CONFIG_H
+#define __COMMON_TEXT_CONFIG_H
+
+#include "MyString.h"
+
+struct CTextConfigPair
+{
+ UString ID;
+ UString String;
+};
+
+bool GetTextConfig(const AString &text, CObjectVector<CTextConfigPair> &pairs);
+
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const char *id) throw();
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const char *id);
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/UTFConvert.cpp b/other-licenses/7zstub/src/CPP/Common/UTFConvert.cpp
new file mode 100644
index 0000000000..b09bbcdb37
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/UTFConvert.cpp
@@ -0,0 +1,288 @@
+// UTFConvert.cpp
+
+#include "StdAfx.h"
+
+#include "MyTypes.h"
+#include "UTFConvert.h"
+
+#ifdef _WIN32
+#define _WCHART_IS_16BIT 1
+#endif
+
+/*
+ _UTF8_START(n) - is a base value for start byte (head), if there are (n) additional bytes after start byte
+
+ n : _UTF8_START(n) : Bits of code point
+
+ 0 : 0x80 : : unused
+ 1 : 0xC0 : 11 :
+ 2 : 0xE0 : 16 : Basic Multilingual Plane
+ 3 : 0xF0 : 21 : Unicode space
+ 3 : 0xF8 : 26 :
+ 5 : 0xFC : 31 : UCS-4
+ 6 : 0xFE : 36 : We can use it, if we want to encode any 32-bit value
+ 7 : 0xFF :
+*/
+
+#define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
+
+#define _UTF8_HEAD_PARSE2(n) if (c < _UTF8_START((n) + 1)) { numBytes = (n); c -= _UTF8_START(n); }
+
+#define _UTF8_HEAD_PARSE \
+ _UTF8_HEAD_PARSE2(1) \
+ else _UTF8_HEAD_PARSE2(2) \
+ else _UTF8_HEAD_PARSE2(3) \
+ else _UTF8_HEAD_PARSE2(4) \
+ else _UTF8_HEAD_PARSE2(5) \
+
+ // else _UTF8_HEAD_PARSE2(6)
+
+bool CheckUTF8(const char *src, bool allowReduced) throw()
+{
+ for (;;)
+ {
+ Byte c = *src++;
+ if (c == 0)
+ return true;
+
+ if (c < 0x80)
+ continue;
+ if (c < 0xC0) // (c < 0xC0 + 2) // if we support only optimal encoding chars
+ return false;
+
+ unsigned numBytes;
+ _UTF8_HEAD_PARSE
+ else
+ return false;
+
+ UInt32 val = c;
+
+ do
+ {
+ Byte c2 = *src++;
+ if (c2 < 0x80 || c2 >= 0xC0)
+ return allowReduced && c2 == 0;
+ val <<= 6;
+ val |= (c2 - 0x80);
+ }
+ while (--numBytes);
+
+ if (val >= 0x110000)
+ return false;
+ }
+}
+
+
+#define _ERROR_UTF8 \
+ { if (dest) dest[destPos] = (wchar_t)0xFFFD; destPos++; ok = false; continue; }
+
+static bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, const char *srcLim) throw()
+{
+ size_t destPos = 0;
+ bool ok = true;
+
+ for (;;)
+ {
+ Byte c;
+ if (src == srcLim)
+ {
+ *destLen = destPos;
+ return ok;
+ }
+ c = *src++;
+
+ if (c < 0x80)
+ {
+ if (dest)
+ dest[destPos] = (wchar_t)c;
+ destPos++;
+ continue;
+ }
+ if (c < 0xC0)
+ _ERROR_UTF8
+
+ unsigned numBytes;
+ _UTF8_HEAD_PARSE
+ else
+ _ERROR_UTF8
+
+ UInt32 val = c;
+
+ do
+ {
+ Byte c2;
+ if (src == srcLim)
+ break;
+ c2 = *src;
+ if (c2 < 0x80 || c2 >= 0xC0)
+ break;
+ src++;
+ val <<= 6;
+ val |= (c2 - 0x80);
+ }
+ while (--numBytes);
+
+ if (numBytes != 0)
+ _ERROR_UTF8
+
+ if (val < 0x10000)
+ {
+ if (dest)
+ dest[destPos] = (wchar_t)val;
+ destPos++;
+ }
+ else
+ {
+ val -= 0x10000;
+ if (val >= 0x100000)
+ _ERROR_UTF8
+ if (dest)
+ {
+ dest[destPos + 0] = (wchar_t)(0xD800 + (val >> 10));
+ dest[destPos + 1] = (wchar_t)(0xDC00 + (val & 0x3FF));
+ }
+ destPos += 2;
+ }
+ }
+}
+
+#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
+
+#define _UTF8_HEAD(n, val) ((char)(_UTF8_START(n) + (val >> (6 * (n)))))
+#define _UTF8_CHAR(n, val) ((char)(0x80 + (((val) >> (6 * (n))) & 0x3F)))
+
+static size_t Utf16_To_Utf8_Calc(const wchar_t *src, const wchar_t *srcLim)
+{
+ size_t size = srcLim - src;
+ for (;;)
+ {
+ if (src == srcLim)
+ return size;
+
+ UInt32 val = *src++;
+
+ if (val < 0x80)
+ continue;
+
+ if (val < _UTF8_RANGE(1))
+ {
+ size++;
+ continue;
+ }
+
+ if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
+ {
+ UInt32 c2 = *src;
+ if (c2 >= 0xDC00 && c2 < 0xE000)
+ {
+ src++;
+ size += 2;
+ continue;
+ }
+ }
+
+ #ifdef _WCHART_IS_16BIT
+
+ size += 2;
+
+ #else
+
+ if (val < _UTF8_RANGE(2)) size += 2;
+ else if (val < _UTF8_RANGE(3)) size += 3;
+ else if (val < _UTF8_RANGE(4)) size += 4;
+ else if (val < _UTF8_RANGE(5)) size += 5;
+ else size += 6;
+
+ #endif
+ }
+}
+
+static char *Utf16_To_Utf8(char *dest, const wchar_t *src, const wchar_t *srcLim)
+{
+ for (;;)
+ {
+ if (src == srcLim)
+ return dest;
+
+ UInt32 val = *src++;
+
+ if (val < 0x80)
+ {
+ *dest++ = (char)val;
+ continue;
+ }
+
+ if (val < _UTF8_RANGE(1))
+ {
+ dest[0] = _UTF8_HEAD(1, val);
+ dest[1] = _UTF8_CHAR(0, val);
+ dest += 2;
+ continue;
+ }
+
+ if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
+ {
+ UInt32 c2 = *src;
+ if (c2 >= 0xDC00 && c2 < 0xE000)
+ {
+ src++;
+ val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
+ dest[0] = _UTF8_HEAD(3, val);
+ dest[1] = _UTF8_CHAR(2, val);
+ dest[2] = _UTF8_CHAR(1, val);
+ dest[3] = _UTF8_CHAR(0, val);
+ dest += 4;
+ continue;
+ }
+ }
+
+ #ifndef _WCHART_IS_16BIT
+ if (val < _UTF8_RANGE(2))
+ #endif
+ {
+ dest[0] = _UTF8_HEAD(2, val);
+ dest[1] = _UTF8_CHAR(1, val);
+ dest[2] = _UTF8_CHAR(0, val);
+ dest += 3;
+ continue;
+ }
+
+ #ifndef _WCHART_IS_16BIT
+
+ UInt32 b;
+ unsigned numBits;
+ if (val < _UTF8_RANGE(3)) { numBits = 6 * 3; b = _UTF8_HEAD(3, val); }
+ else if (val < _UTF8_RANGE(4)) { numBits = 6 * 4; b = _UTF8_HEAD(4, val); }
+ else if (val < _UTF8_RANGE(5)) { numBits = 6 * 5; b = _UTF8_HEAD(5, val); }
+ else { numBits = 6 * 6; b = _UTF8_START(6); }
+
+ *dest++ = (Byte)b;
+
+ do
+ {
+ numBits -= 6;
+ *dest++ = (char)(0x80 + ((val >> numBits) & 0x3F));
+ }
+ while (numBits != 0);
+
+ #endif
+ }
+}
+
+bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
+{
+ dest.Empty();
+ size_t destLen = 0;
+ Utf8_To_Utf16(NULL, &destLen, src, src.Ptr(src.Len()));
+ bool res = Utf8_To_Utf16(dest.GetBuf((unsigned)destLen), &destLen, src, src.Ptr(src.Len()));
+ dest.ReleaseBuf_SetEnd((unsigned)destLen);
+ return res;
+}
+
+void ConvertUnicodeToUTF8(const UString &src, AString &dest)
+{
+ dest.Empty();
+ size_t destLen = Utf16_To_Utf8_Calc(src, src.Ptr(src.Len()));
+ Utf16_To_Utf8(dest.GetBuf((unsigned)destLen), src, src.Ptr(src.Len()));
+ dest.ReleaseBuf_SetEnd((unsigned)destLen);
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/UTFConvert.h b/other-licenses/7zstub/src/CPP/Common/UTFConvert.h
new file mode 100644
index 0000000000..11831700c7
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/UTFConvert.h
@@ -0,0 +1,12 @@
+// Common/UTFConvert.h
+
+#ifndef __COMMON_UTF_CONVERT_H
+#define __COMMON_UTF_CONVERT_H
+
+#include "MyString.h"
+
+bool CheckUTF8(const char *src, bool allowReduced = false) throw();
+bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
+void ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/Wildcard.cpp b/other-licenses/7zstub/src/CPP/Common/Wildcard.cpp
new file mode 100644
index 0000000000..43e4baa179
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/Wildcard.cpp
@@ -0,0 +1,676 @@
+// Common/Wildcard.cpp
+
+#include "StdAfx.h"
+
+#include "Wildcard.h"
+
+bool g_CaseSensitive =
+ #ifdef _WIN32
+ false;
+ #else
+ true;
+ #endif
+
+
+bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
+{
+ if (g_CaseSensitive)
+ return IsString1PrefixedByString2(s1, s2);
+ return IsString1PrefixedByString2_NoCase(s1, s2);
+}
+
+int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
+{
+ if (g_CaseSensitive)
+ return MyStringCompare(s1, s2);
+ return MyStringCompareNoCase(s1, s2);
+}
+
+#ifndef USE_UNICODE_FSTRING
+int CompareFileNames(const char *s1, const char *s2)
+{
+ const UString u1 = fs2us(s1);
+ const UString u2 = fs2us(s2);
+ if (g_CaseSensitive)
+ return MyStringCompare(u1, u2);
+ return MyStringCompareNoCase(u1, u2);
+}
+#endif
+
+// -----------------------------------------
+// this function compares name with mask
+// ? - any char
+// * - any char or empty
+
+static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
+{
+ for (;;)
+ {
+ wchar_t m = *mask;
+ wchar_t c = *name;
+ if (m == 0)
+ return (c == 0);
+ if (m == '*')
+ {
+ if (EnhancedMaskTest(mask + 1, name))
+ return true;
+ if (c == 0)
+ return false;
+ }
+ else
+ {
+ if (m == '?')
+ {
+ if (c == 0)
+ return false;
+ }
+ else if (m != c)
+ if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c))
+ return false;
+ mask++;
+ }
+ name++;
+ }
+}
+
+// --------------------------------------------------
+// Splits path to strings
+
+void SplitPathToParts(const UString &path, UStringVector &pathParts)
+{
+ pathParts.Clear();
+ unsigned len = path.Len();
+ if (len == 0)
+ return;
+ UString name;
+ unsigned prev = 0;
+ for (unsigned i = 0; i < len; i++)
+ if (IsPathSepar(path[i]))
+ {
+ name.SetFrom(path.Ptr(prev), i - prev);
+ pathParts.Add(name);
+ prev = i + 1;
+ }
+ name.SetFrom(path.Ptr(prev), len - prev);
+ pathParts.Add(name);
+}
+
+void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name)
+{
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsPathSepar(*(p - 1)))
+ break;
+ dirPrefix.SetFrom(path, (unsigned)(p - start));
+ name = p;
+}
+
+void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name)
+{
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ if (p != start)
+ {
+ if (IsPathSepar(*(p - 1)))
+ p--;
+ for (; p != start; p--)
+ if (IsPathSepar(*(p - 1)))
+ break;
+ }
+ dirPrefix.SetFrom(path, (unsigned)(p - start));
+ name = p;
+}
+
+/*
+UString ExtractDirPrefixFromPath(const UString &path)
+{
+ return path.Left(path.ReverseFind_PathSepar() + 1));
+}
+*/
+
+UString ExtractFileNameFromPath(const UString &path)
+{
+ return UString(path.Ptr(path.ReverseFind_PathSepar() + 1));
+}
+
+
+bool DoesWildcardMatchName(const UString &mask, const UString &name)
+{
+ return EnhancedMaskTest(mask, name);
+}
+
+bool DoesNameContainWildcard(const UString &path)
+{
+ for (unsigned i = 0; i < path.Len(); i++)
+ {
+ wchar_t c = path[i];
+ if (c == '*' || c == '?')
+ return true;
+ }
+ return false;
+}
+
+
+// ----------------------------------------------------------'
+// NWildcard
+
+namespace NWildcard {
+
+/*
+
+M = MaskParts.Size();
+N = TestNameParts.Size();
+
+ File Dir
+ForFile rec M<=N [N-M, N) -
+!ForDir nonrec M=N [0, M) -
+
+ForDir rec M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
+!ForFile nonrec [0, M) same as ForBoth-File
+
+ForFile rec m<=N [0, M) ... [N-M, N) same as ForBoth-File
+ForDir nonrec [0, M) same as ForBoth-File
+
+*/
+
+bool CItem::AreAllAllowed() const
+{
+ return ForFile && ForDir && WildcardMatching && PathParts.Size() == 1 && PathParts.Front() == L"*";
+}
+
+bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
+{
+ if (!isFile && !ForDir)
+ return false;
+
+ /*
+ if (PathParts.IsEmpty())
+ {
+ // PathParts.IsEmpty() means all items (universal wildcard)
+ if (!isFile)
+ return true;
+ if (pathParts.Size() <= 1)
+ return ForFile;
+ return (ForDir || Recursive && ForFile);
+ }
+ */
+
+ int delta = (int)pathParts.Size() - (int)PathParts.Size();
+ if (delta < 0)
+ return false;
+ int start = 0;
+ int finish = 0;
+
+ if (isFile)
+ {
+ if (!ForDir)
+ {
+ if (Recursive)
+ start = delta;
+ else if (delta !=0)
+ return false;
+ }
+ if (!ForFile && delta == 0)
+ return false;
+ }
+
+ if (Recursive)
+ {
+ finish = delta;
+ if (isFile && !ForFile)
+ finish = delta - 1;
+ }
+
+ for (int d = start; d <= finish; d++)
+ {
+ unsigned i;
+ for (i = 0; i < PathParts.Size(); i++)
+ {
+ if (WildcardMatching)
+ {
+ if (!DoesWildcardMatchName(PathParts[i], pathParts[i + d]))
+ break;
+ }
+ else
+ {
+ if (CompareFileNames(PathParts[i], pathParts[i + d]) != 0)
+ break;
+ }
+ }
+ if (i == PathParts.Size())
+ return true;
+ }
+ return false;
+}
+
+bool CCensorNode::AreAllAllowed() const
+{
+ if (!Name.IsEmpty() ||
+ !SubNodes.IsEmpty() ||
+ !ExcludeItems.IsEmpty() ||
+ IncludeItems.Size() != 1)
+ return false;
+ return IncludeItems.Front().AreAllAllowed();
+}
+
+int CCensorNode::FindSubNode(const UString &name) const
+{
+ FOR_VECTOR (i, SubNodes)
+ if (CompareFileNames(SubNodes[i].Name, name) == 0)
+ return i;
+ return -1;
+}
+
+void CCensorNode::AddItemSimple(bool include, CItem &item)
+{
+ if (include)
+ IncludeItems.Add(item);
+ else
+ ExcludeItems.Add(item);
+}
+
+void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex)
+{
+ if (item.PathParts.Size() <= 1)
+ {
+ if (item.PathParts.Size() != 0 && item.WildcardMatching)
+ {
+ if (!DoesNameContainWildcard(item.PathParts.Front()))
+ item.WildcardMatching = false;
+ }
+ AddItemSimple(include, item);
+ return;
+ }
+ const UString &front = item.PathParts.Front();
+
+ // WIN32 doesn't support wildcards in file names
+ if (item.WildcardMatching
+ && ignoreWildcardIndex != 0
+ && DoesNameContainWildcard(front))
+ {
+ AddItemSimple(include, item);
+ return;
+ }
+ int index = FindSubNode(front);
+ if (index < 0)
+ index = SubNodes.Add(CCensorNode(front, this));
+ item.PathParts.Delete(0);
+ SubNodes[index].AddItem(include, item, ignoreWildcardIndex - 1);
+}
+
+void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching)
+{
+ CItem item;
+ SplitPathToParts(path, item.PathParts);
+ item.Recursive = recursive;
+ item.ForFile = forFile;
+ item.ForDir = forDir;
+ item.WildcardMatching = wildcardMatching;
+ AddItem(include, item);
+}
+
+bool CCensorNode::NeedCheckSubDirs() const
+{
+ FOR_VECTOR (i, IncludeItems)
+ {
+ const CItem &item = IncludeItems[i];
+ if (item.Recursive || item.PathParts.Size() > 1)
+ return true;
+ }
+ return false;
+}
+
+bool CCensorNode::AreThereIncludeItems() const
+{
+ if (IncludeItems.Size() > 0)
+ return true;
+ FOR_VECTOR (i, SubNodes)
+ if (SubNodes[i].AreThereIncludeItems())
+ return true;
+ return false;
+}
+
+bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
+{
+ const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
+ FOR_VECTOR (i, items)
+ if (items[i].CheckPath(pathParts, isFile))
+ return true;
+ return false;
+}
+
+bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const
+{
+ if (CheckPathCurrent(false, pathParts, isFile))
+ {
+ include = false;
+ return true;
+ }
+ include = true;
+ bool finded = CheckPathCurrent(true, pathParts, isFile);
+ if (pathParts.Size() <= 1)
+ return finded;
+ int index = FindSubNode(pathParts.Front());
+ if (index >= 0)
+ {
+ UStringVector pathParts2 = pathParts;
+ pathParts2.Delete(0);
+ if (SubNodes[index].CheckPathVect(pathParts2, isFile, include))
+ return true;
+ }
+ return finded;
+}
+
+/*
+bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ if (CheckPathVect(pathParts, isFile, include))
+ {
+ if (!include || !isAltStream)
+ return true;
+ }
+ if (isAltStream && !pathParts.IsEmpty())
+ {
+ UString &back = pathParts.Back();
+ int pos = back.Find(L':');
+ if (pos > 0)
+ {
+ back.DeleteFrom(pos);
+ return CheckPathVect(pathParts, isFile, include);
+ }
+ }
+ return false;
+}
+
+bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) const
+{
+ bool include;
+ if (CheckPath2(isAltStream, path, isFile, include))
+ return include;
+ return false;
+}
+*/
+
+bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const
+{
+ if (CheckPathCurrent(include, pathParts, isFile))
+ return true;
+ if (Parent == 0)
+ return false;
+ pathParts.Insert(0, Name);
+ return Parent->CheckPathToRoot(include, pathParts, isFile);
+}
+
+/*
+bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ return CheckPathToRoot(include, pathParts, isFile);
+}
+*/
+
+void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching)
+{
+ if (path.IsEmpty())
+ return;
+ bool forFile = true;
+ bool forFolder = true;
+ UString path2 (path);
+ if (IsPathSepar(path.Back()))
+ {
+ path2.DeleteBack();
+ forFile = false;
+ }
+ AddItem(include, path2, recursive, forFile, forFolder, wildcardMatching);
+}
+
+void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
+{
+ ExcludeItems += fromNodes.ExcludeItems;
+ FOR_VECTOR (i, fromNodes.SubNodes)
+ {
+ const CCensorNode &node = fromNodes.SubNodes[i];
+ int subNodeIndex = FindSubNode(node.Name);
+ if (subNodeIndex < 0)
+ subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this));
+ SubNodes[subNodeIndex].ExtendExclude(node);
+ }
+}
+
+int CCensor::FindPrefix(const UString &prefix) const
+{
+ FOR_VECTOR (i, Pairs)
+ if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)
+ return i;
+ return -1;
+}
+
+#ifdef _WIN32
+
+bool IsDriveColonName(const wchar_t *s)
+{
+ wchar_t c = s[0];
+ return c != 0 && s[1] == ':' && s[2] == 0 && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
+}
+
+unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts)
+{
+ if (pathParts.IsEmpty())
+ return 0;
+
+ unsigned testIndex = 0;
+ if (pathParts[0].IsEmpty())
+ {
+ if (pathParts.Size() < 4
+ || !pathParts[1].IsEmpty()
+ || pathParts[2] != L"?")
+ return 0;
+ testIndex = 3;
+ }
+ if (NWildcard::IsDriveColonName(pathParts[testIndex]))
+ return testIndex + 1;
+ return 0;
+}
+
+#endif
+
+static unsigned GetNumPrefixParts(const UStringVector &pathParts)
+{
+ if (pathParts.IsEmpty())
+ return 0;
+
+ #ifdef _WIN32
+
+ if (IsDriveColonName(pathParts[0]))
+ return 1;
+ if (!pathParts[0].IsEmpty())
+ return 0;
+
+ if (pathParts.Size() == 1)
+ return 1;
+ if (!pathParts[1].IsEmpty())
+ return 1;
+ if (pathParts.Size() == 2)
+ return 2;
+ if (pathParts[2] == L".")
+ return 3;
+
+ unsigned networkParts = 2;
+ if (pathParts[2] == L"?")
+ {
+ if (pathParts.Size() == 3)
+ return 3;
+ if (IsDriveColonName(pathParts[3]))
+ return 4;
+ if (!pathParts[3].IsEqualTo_Ascii_NoCase("UNC"))
+ return 3;
+ networkParts = 4;
+ }
+
+ networkParts +=
+ // 2; // server/share
+ 1; // server
+ if (pathParts.Size() <= networkParts)
+ return pathParts.Size();
+ return networkParts;
+
+ #else
+
+ return pathParts[0].IsEmpty() ? 1 : 0;
+
+ #endif
+}
+
+void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching)
+{
+ if (path.IsEmpty())
+ throw "Empty file path";
+
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+
+ bool forFile = true;
+ if (pathParts.Back().IsEmpty())
+ {
+ forFile = false;
+ pathParts.DeleteBack();
+ }
+
+ UString prefix;
+
+ int ignoreWildcardIndex = -1;
+
+ // #ifdef _WIN32
+ // we ignore "?" wildcard in "\\?\" prefix.
+ if (pathParts.Size() >= 3
+ && pathParts[0].IsEmpty()
+ && pathParts[1].IsEmpty()
+ && pathParts[2] == L"?")
+ ignoreWildcardIndex = 2;
+ // #endif
+
+ if (pathMode != k_AbsPath)
+ {
+ ignoreWildcardIndex = -1;
+
+ const unsigned numPrefixParts = GetNumPrefixParts(pathParts);
+ unsigned numSkipParts = numPrefixParts;
+
+ if (pathMode != k_FullPath)
+ {
+ if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts)
+ numSkipParts = pathParts.Size() - 1;
+ }
+ {
+ int dotsIndex = -1;
+ for (unsigned i = numPrefixParts; i < pathParts.Size(); i++)
+ {
+ const UString &part = pathParts[i];
+ if (part == L".." || part == L".")
+ dotsIndex = i;
+ }
+
+ if (dotsIndex >= 0)
+ if (dotsIndex == (int)pathParts.Size() - 1)
+ numSkipParts = pathParts.Size();
+ else
+ numSkipParts = pathParts.Size() - 1;
+ }
+
+ for (unsigned i = 0; i < numSkipParts; i++)
+ {
+ {
+ const UString &front = pathParts.Front();
+ // WIN32 doesn't support wildcards in file names
+ if (wildcardMatching)
+ if (i >= numPrefixParts && DoesNameContainWildcard(front))
+ break;
+ prefix += front;
+ prefix.Add_PathSepar();
+ }
+ pathParts.Delete(0);
+ }
+ }
+
+ int index = FindPrefix(prefix);
+ if (index < 0)
+ index = Pairs.Add(CPair(prefix));
+
+ if (pathMode != k_AbsPath)
+ {
+ if (pathParts.IsEmpty() || pathParts.Size() == 1 && pathParts[0].IsEmpty())
+ {
+ // we create universal item, if we skip all parts as prefix (like \ or L:\ )
+ pathParts.Clear();
+ pathParts.Add(UString("*"));
+ forFile = true;
+ wildcardMatching = true;
+ recursive = false;
+ }
+ }
+
+ CItem item;
+ item.PathParts = pathParts;
+ item.ForDir = true;
+ item.ForFile = forFile;
+ item.Recursive = recursive;
+ item.WildcardMatching = wildcardMatching;
+ Pairs[index].Head.AddItem(include, item, ignoreWildcardIndex);
+}
+
+/*
+bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const
+{
+ bool finded = false;
+ FOR_VECTOR (i, Pairs)
+ {
+ bool include;
+ if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include))
+ {
+ if (!include)
+ return false;
+ finded = true;
+ }
+ }
+ return finded;
+}
+*/
+
+void CCensor::ExtendExclude()
+{
+ unsigned i;
+ for (i = 0; i < Pairs.Size(); i++)
+ if (Pairs[i].Prefix.IsEmpty())
+ break;
+ if (i == Pairs.Size())
+ return;
+ unsigned index = i;
+ for (i = 0; i < Pairs.Size(); i++)
+ if (index != i)
+ Pairs[i].Head.ExtendExclude(Pairs[index].Head);
+}
+
+void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode)
+{
+ FOR_VECTOR(i, CensorPaths)
+ {
+ const CCensorPath &cp = CensorPaths[i];
+ AddItem(censorPathMode, cp.Include, cp.Path, cp.Recursive, cp.WildcardMatching);
+ }
+ CensorPaths.Clear();
+}
+
+void CCensor::AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching)
+{
+ CCensorPath &cp = CensorPaths.AddNew();
+ cp.Path = path;
+ cp.Include = include;
+ cp.Recursive = recursive;
+ cp.WildcardMatching = wildcardMatching;
+}
+
+}
diff --git a/other-licenses/7zstub/src/CPP/Common/Wildcard.h b/other-licenses/7zstub/src/CPP/Common/Wildcard.h
new file mode 100644
index 0000000000..6e5f013418
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/Wildcard.h
@@ -0,0 +1,149 @@
+// Common/Wildcard.h
+
+#ifndef __COMMON_WILDCARD_H
+#define __COMMON_WILDCARD_H
+
+#include "MyString.h"
+
+int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW;
+#ifndef USE_UNICODE_FSTRING
+ int CompareFileNames(const char *s1, const char *s2);
+#endif
+
+bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2);
+
+void SplitPathToParts(const UString &path, UStringVector &pathParts);
+void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name);
+void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name); // ignores dir delimiter at the end of (path)
+
+UString ExtractDirPrefixFromPath(const UString &path);
+UString ExtractFileNameFromPath(const UString &path);
+
+bool DoesNameContainWildcard(const UString &path);
+bool DoesWildcardMatchName(const UString &mask, const UString &name);
+
+namespace NWildcard {
+
+#ifdef _WIN32
+// returns true, if name is like "a:", "c:", ...
+bool IsDriveColonName(const wchar_t *s);
+unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts);
+#endif
+
+struct CItem
+{
+ UStringVector PathParts;
+ bool Recursive;
+ bool ForFile;
+ bool ForDir;
+ bool WildcardMatching;
+
+ #ifdef _WIN32
+ bool IsDriveItem() const
+ {
+ return PathParts.Size() == 1 && !ForFile && ForDir && IsDriveColonName(PathParts[0]);
+ }
+ #endif
+
+ // CItem(): WildcardMatching(true) {}
+
+ bool AreAllAllowed() const;
+ bool CheckPath(const UStringVector &pathParts, bool isFile) const;
+};
+
+class CCensorNode
+{
+ CCensorNode *Parent;
+
+ bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const;
+ void AddItemSimple(bool include, CItem &item);
+public:
+ bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const;
+
+ CCensorNode(): Parent(0) { };
+ CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { };
+
+ UString Name; // WIN32 doesn't support wildcards in file names
+ CObjectVector<CCensorNode> SubNodes;
+ CObjectVector<CItem> IncludeItems;
+ CObjectVector<CItem> ExcludeItems;
+
+ bool AreAllAllowed() const;
+
+ int FindSubNode(const UString &path) const;
+
+ void AddItem(bool include, CItem &item, int ignoreWildcardIndex = -1);
+ void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching);
+ void AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching);
+
+ bool NeedCheckSubDirs() const;
+ bool AreThereIncludeItems() const;
+
+ // bool CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const;
+ // bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
+
+ bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const;
+ // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const;
+ void ExtendExclude(const CCensorNode &fromNodes);
+};
+
+struct CPair
+{
+ UString Prefix;
+ CCensorNode Head;
+
+ CPair(const UString &prefix): Prefix(prefix) { };
+};
+
+enum ECensorPathMode
+{
+ k_RelatPath, // absolute prefix as Prefix, remain path in Tree
+ k_FullPath, // drive prefix as Prefix, remain path in Tree
+ k_AbsPath // full path in Tree
+};
+
+struct CCensorPath
+{
+ UString Path;
+ bool Include;
+ bool Recursive;
+ bool WildcardMatching;
+
+ CCensorPath():
+ Include(true),
+ Recursive(false),
+ WildcardMatching(true)
+ {}
+};
+
+class CCensor
+{
+ int FindPrefix(const UString &prefix) const;
+public:
+ CObjectVector<CPair> Pairs;
+
+ CObjectVector<NWildcard::CCensorPath> CensorPaths;
+
+ bool AllAreRelative() const
+ { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); }
+
+ void AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching);
+ // bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
+ void ExtendExclude();
+
+ void AddPathsToCensor(NWildcard::ECensorPathMode censorPathMode);
+ void AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching);
+ void AddPreItem(const UString &path)
+ {
+ AddPreItem(true, path, false, false);
+ }
+ void AddPreItem_Wildcard()
+ {
+ AddPreItem(true, UString("*"), false, true);
+ }
+};
+
+
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/Common/XzCrc64Init.cpp b/other-licenses/7zstub/src/CPP/Common/XzCrc64Init.cpp
new file mode 100644
index 0000000000..1eae72ad9b
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/XzCrc64Init.cpp
@@ -0,0 +1,7 @@
+// XzCrc64Init.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/XzCrc64.h"
+
+static struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;
diff --git a/other-licenses/7zstub/src/CPP/Common/XzCrc64Reg.cpp b/other-licenses/7zstub/src/CPP/Common/XzCrc64Reg.cpp
new file mode 100644
index 0000000000..92fce0a1a0
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/XzCrc64Reg.cpp
@@ -0,0 +1,42 @@
+// XzCrc64Reg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/CpuArch.h"
+#include "../../C/XzCrc64.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/Common/RegisterCodec.h"
+
+class CXzCrc64Hasher:
+ public IHasher,
+ public CMyUnknownImp
+{
+ UInt64 _crc;
+ Byte mtDummy[1 << 7];
+
+public:
+ CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {}
+
+ MY_UNKNOWN_IMP1(IHasher)
+ INTERFACE_IHasher(;)
+};
+
+STDMETHODIMP_(void) CXzCrc64Hasher::Init() throw()
+{
+ _crc = CRC64_INIT_VAL;
+}
+
+STDMETHODIMP_(void) CXzCrc64Hasher::Update(const void *data, UInt32 size) throw()
+{
+ _crc = Crc64Update(_crc, data, size);
+}
+
+STDMETHODIMP_(void) CXzCrc64Hasher::Final(Byte *digest) throw()
+{
+ UInt64 val = CRC64_GET_DIGEST(_crc);
+ SetUi64(digest, val);
+}
+
+REGISTER_HASHER(CXzCrc64Hasher, 0x4, "CRC64", 8)