diff options
Diffstat (limited to '3rdparty/lzma/CPP/Common')
54 files changed, 5021 insertions, 1281 deletions
diff --git a/3rdparty/lzma/CPP/Common/AutoPtr.h b/3rdparty/lzma/CPP/Common/AutoPtr.h index 006d315512b..0be8a7a41d2 100644 --- a/3rdparty/lzma/CPP/Common/AutoPtr.h +++ b/3rdparty/lzma/CPP/Common/AutoPtr.h @@ -1,13 +1,13 @@ // Common/AutoPtr.h -#ifndef __COMMON_AUTOPTR_H -#define __COMMON_AUTOPTR_H +#ifndef ZIP7_INC_COMMON_AUTOPTR_H +#define ZIP7_INC_COMMON_AUTOPTR_H template<class T> class CMyAutoPtr { T *_p; public: - CMyAutoPtr(T *p = 0) : _p(p) {} + CMyAutoPtr(T *p = NULL) : _p(p) {} CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {} CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p) { @@ -21,10 +21,10 @@ public: T* release() { T *tmp = _p; - _p = 0; + _p = NULL; return tmp; } - void reset(T* p = 0) + void reset(T* p = NULL) { if (p != _p) delete _p; diff --git a/3rdparty/lzma/CPP/Common/CRC.cpp b/3rdparty/lzma/CPP/Common/CRC.cpp index 9a9f81fb713..c6b7d5e4a7e 100644 --- a/3rdparty/lzma/CPP/Common/CRC.cpp +++ b/3rdparty/lzma/CPP/Common/CRC.cpp @@ -4,4 +4,4 @@ #include "../../C/7zCrc.h" -struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit; +static struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit; diff --git a/3rdparty/lzma/CPP/Common/C_FileIO.cpp b/3rdparty/lzma/CPP/Common/C_FileIO.cpp index 7c629390232..4bd3fadc448 100644 --- a/3rdparty/lzma/CPP/Common/C_FileIO.cpp +++ b/3rdparty/lzma/CPP/Common/C_FileIO.cpp @@ -1,92 +1,3 @@ // 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); -} - -}}} +#include "StdAfx.h" diff --git a/3rdparty/lzma/CPP/Common/C_FileIO.h b/3rdparty/lzma/CPP/Common/C_FileIO.h index ff4ec162c59..12d94391016 100644 --- a/3rdparty/lzma/CPP/Common/C_FileIO.h +++ b/3rdparty/lzma/CPP/Common/C_FileIO.h @@ -1,53 +1,6 @@ // 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); -}; - -}}} +#ifndef ZIP7_INC_COMMON_C_FILEIO_H +#define ZIP7_INC_COMMON_C_FILEIO_H #endif diff --git a/3rdparty/lzma/CPP/Common/ComTry.h b/3rdparty/lzma/CPP/Common/ComTry.h index fb4ef04594a..84746a7d084 100644 --- a/3rdparty/lzma/CPP/Common/ComTry.h +++ b/3rdparty/lzma/CPP/Common/ComTry.h @@ -1,7 +1,7 @@ // ComTry.h -#ifndef __COM_TRY_H -#define __COM_TRY_H +#ifndef ZIP7_INC_COM_TRY_H +#define ZIP7_INC_COM_TRY_H #include "MyWindows.h" // #include "Exception.h" @@ -10,7 +10,11 @@ #define COM_TRY_BEGIN try { #define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; } - // catch(const CNewException &) { 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; } diff --git a/3rdparty/lzma/CPP/Common/CommandLineParser.cpp b/3rdparty/lzma/CPP/Common/CommandLineParser.cpp index 1c7f26547c8..465e0fde853 100644 --- a/3rdparty/lzma/CPP/Common/CommandLineParser.cpp +++ b/3rdparty/lzma/CPP/Common/CommandLineParser.cpp @@ -4,20 +4,6 @@ #include "CommandLineParser.h" -static bool IsString1PrefixedByString2_NoCase(const wchar_t *u, const char *a) -{ - for (;;) - { - char c = *a; - if (c == 0) - return true; - if ((unsigned char)MyCharLower_Ascii(c) != MyCharLower_Ascii(*u)) - return false; - a++; - u++; - } -} - namespace NCommandLineParser { bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2) @@ -44,7 +30,7 @@ bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2) void SplitCommandLine(const UString &s, UStringVector &parts) { - UString sTemp = s; + UString sTemp (s); sTemp.Trim(); parts.Clear(); for (;;) @@ -59,18 +45,17 @@ void SplitCommandLine(const UString &s, UStringVector &parts) } -static const char *kStopSwitchParsing = "--"; +static const char * const kStopSwitchParsing = "--"; static bool inline IsItSwitchChar(wchar_t c) { return (c == '-'); } -CParser::CParser(unsigned numSwitches): - _numSwitches(numSwitches), - _switches(0) +CParser::CParser(): + _switches(NULL), + StopSwitchIndex(-1) { - _switches = new CSwitchResult[numSwitches]; } CParser::~CParser() @@ -81,7 +66,7 @@ CParser::~CParser() // 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) +bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches) { if (s.IsEmpty() || !IsItSwitchChar(s[0])) return false; @@ -90,16 +75,16 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) unsigned switchIndex = 0; int maxLen = -1; - for (unsigned i = 0; i < _numSwitches; i++) + for (unsigned i = 0; i < numSwitches; i++) { - const char *key = switchForms[i].Key; + const char * const key = switchForms[i].Key; unsigned switchLen = MyStringLen(key); if ((int)switchLen <= maxLen || pos + switchLen > s.Len()) continue; - if (IsString1PrefixedByString2_NoCase((const wchar_t *)s + pos, key)) + if (IsString1PrefixedByString2_NoCase_Ascii((const wchar_t *)s + pos, key)) { switchIndex = i; - maxLen = switchLen; + maxLen = (int)switchLen; } } @@ -109,7 +94,7 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) return false; } - pos += maxLen; + pos += (unsigned)maxLen; CSwitchResult &sw = _switches[switchIndex]; const CSwitchForm &form = switchForms[switchIndex]; @@ -122,7 +107,7 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) sw.ThereIs = true; - int rem = s.Len() - pos; + const unsigned rem = s.Len() - pos; if (rem < form.MinLen) { ErrorMessage = "Too short switch:"; @@ -161,8 +146,10 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) break; case NSwitchType::kString: - sw.PostStrings.Add((const wchar_t *)s + pos); + { + sw.PostStrings.Add(s.Ptr(pos)); return true; + } } if (pos != s.Len()) @@ -173,23 +160,30 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) return true; } -bool CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings) + +bool CParser::ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings) { + StopSwitchIndex = -1; + ErrorMessage.Empty(); ErrorLine.Empty(); - bool stopSwitch = false; + NonSwitchStrings.Clear(); + delete []_switches; + _switches = NULL; + _switches = new CSwitchResult[numSwitches]; + FOR_VECTOR (i, commandStrings) { const UString &s = commandStrings[i]; - if (!stopSwitch) + if (StopSwitchIndex < 0) { if (s.IsEqualTo(kStopSwitchParsing)) { - stopSwitch = true; + StopSwitchIndex = (int)NonSwitchStrings.Size(); continue; } if (!s.IsEmpty() && IsItSwitchChar(s[0])) { - if (ParseString(s, switchForms)) + if (ParseString(s, switchForms, numSwitches)) continue; ErrorLine = s; return false; diff --git a/3rdparty/lzma/CPP/Common/CommandLineParser.h b/3rdparty/lzma/CPP/Common/CommandLineParser.h index c9fd2956186..fc6f028e6d5 100644 --- a/3rdparty/lzma/CPP/Common/CommandLineParser.h +++ b/3rdparty/lzma/CPP/Common/CommandLineParser.h @@ -1,7 +1,7 @@ // Common/CommandLineParser.h -#ifndef __COMMON_COMMAND_LINE_PARSER_H -#define __COMMON_COMMAND_LINE_PARSER_H +#ifndef ZIP7_INC_COMMON_COMMAND_LINE_PARSER_H +#define ZIP7_INC_COMMON_COMMAND_LINE_PARSER_H #include "MyString.h" @@ -38,24 +38,24 @@ struct CSwitchResult int PostCharIndex; UStringVector PostStrings; - CSwitchResult(): ThereIs(false) {}; + CSwitchResult(): ThereIs(false) {} }; class CParser { - unsigned _numSwitches; CSwitchResult *_switches; - bool ParseString(const UString &s, const CSwitchForm *switchForms); + bool ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches); public: UStringVector NonSwitchStrings; + int StopSwitchIndex; // NonSwitchStrings[StopSwitchIndex+] are after "--" AString ErrorMessage; UString ErrorLine; - CParser(unsigned numSwitches); + CParser(); ~CParser(); - bool ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings); - const CSwitchResult& operator[](size_t index) const { return _switches[index]; } + bool ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings); + const CSwitchResult& operator[](unsigned index) const { return _switches[index]; } }; } diff --git a/3rdparty/lzma/CPP/Common/Common.h b/3rdparty/lzma/CPP/Common/Common.h index 9dd30f4bef2..0c77ab439f2 100644 --- a/3rdparty/lzma/CPP/Common/Common.h +++ b/3rdparty/lzma/CPP/Common/Common.h @@ -1,13 +1,313 @@ // Common.h -#ifndef __COMMON_COMMON_H -#define __COMMON_COMMON_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#ifndef ZIP7_INC_COMMON_H +#define ZIP7_INC_COMMON_H #include "../../C/Compiler.h" -#include "MyWindows.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. +*/ + +#ifdef _MSC_VER + #pragma warning(disable : 4710) // function not inlined + // 'CUncopyable::CUncopyable': + #pragma warning(disable : 4514) // unreferenced inline function has been removed + #if _MSC_VER < 1300 + #pragma warning(disable : 4702) // unreachable code + #pragma warning(disable : 4714) // function marked as __forceinline not inlined + #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information + #endif + #if _MSC_VER < 1400 + #pragma warning(disable : 4511) // copy constructor could not be generated // #pragma warning(disable : 4512) // assignment operator could not be generated + #pragma warning(disable : 4512) // assignment operator could not be generated + #endif + #if _MSC_VER > 1400 && _MSC_VER <= 1900 + // #pragma warning(disable : 4996) + // strcat: This function or variable may be unsafe + // GetVersion was declared deprecated + #endif + +#if _MSC_VER > 1200 +// -Wall warnings + +#if _MSC_VER <= 1600 +#pragma warning(disable : 4917) // 'OLE_HANDLE' : a GUID can only be associated with a class, interface or namespace +#endif + +// #pragma warning(disable : 4061) // enumerator '' in switch of enum '' is not explicitly handled by a case label +// #pragma warning(disable : 4266) // no override available for virtual member function from base ''; function is hidden +#pragma warning(disable : 4625) // copy constructor was implicitly defined as deleted +#pragma warning(disable : 4626) // assignment operator was implicitly defined as deleted +#if _MSC_VER >= 1600 && _MSC_VER < 1920 +#pragma warning(disable : 4571) // Informational: catch(...) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught +#endif +#if _MSC_VER >= 1600 +#pragma warning(disable : 4365) // 'initializing' : conversion from 'int' to 'unsigned int', signed / unsigned mismatch +#endif +#if _MSC_VER < 1800 +// we disable the warning, if we don't use 'final' in class +#pragma warning(disable : 4265) // class has virtual functions, but destructor is not virtual +#endif + +#if _MSC_VER >= 1900 +#pragma warning(disable : 5026) // move constructor was implicitly defined as deleted +#pragma warning(disable : 5027) // move assignment operator was implicitly defined as deleted +#endif +#if _MSC_VER >= 1912 +#pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an exception. +#endif +#if _MSC_VER >= 1925 +// #pragma warning(disable : 5204) // 'ISequentialInStream' : class has virtual functions, but its trivial destructor is not virtual; instances of objects derived from this class may not be destructed correctly +#endif +#if _MSC_VER >= 1934 +// #pragma warning(disable : 5264) // const variable is not used +#endif + +#endif // _MSC_VER > 1200 +#endif // _MSC_VER + + +#if defined(_MSC_VER) // && !defined(__clang__) +#define Z7_DECLSPEC_NOTHROW __declspec(nothrow) +#elif defined(__clang__) || defined(__GNUC__) +#define Z7_DECLSPEC_NOTHROW __attribute__((nothrow)) +#else +#define Z7_DECLSPEC_NOTHROW +#endif + +/* +#if defined (_MSC_VER) && _MSC_VER >= 1900 \ + || defined(__clang__) && __clang_major__ >= 6 \ + || defined(__GNUC__) && __GNUC__ >= 6 + #define Z7_noexcept noexcept +#else + #define Z7_noexcept throw() +#endif +*/ + + +#if defined(__clang__) + +// noexcept, final, = delete +#pragma GCC diagnostic ignored "-Wc++98-compat" +#if __clang_major__ >= 4 +// throw() dynamic exception specifications are deprecated +#pragma GCC diagnostic ignored "-Wdeprecated-dynamic-exception-spec" +#endif +#pragma GCC diagnostic ignored "-Wold-style-cast" +#pragma GCC diagnostic ignored "-Wglobal-constructors" +#pragma GCC diagnostic ignored "-Wexit-time-destructors" + +// #pragma GCC diagnostic ignored "-Wunused-private-field" +// #pragma GCC diagnostic ignored "-Wnonportable-system-include-path" +// #pragma GCC diagnostic ignored "-Wsuggest-override" +// #pragma GCC diagnostic ignored "-Wsign-conversion" +// #pragma GCC diagnostic ignored "-Winconsistent-missing-override" +// #pragma GCC diagnostic ignored "-Wsuggest-destructor-override" +// #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +// #pragma GCC diagnostic ignored "-Wdeprecated-copy-with-user-provided-dtor" +// #pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor" +// #ifndef _WIN32 +// #pragma GCC diagnostic ignored "-Wweak-vtables" +// #endif +/* +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) \ + || defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30000) +// enumeration values not explicitly handled in switch +#pragma GCC diagnostic ignored "-Wswitch-enum" +#endif +*/ +#endif // __clang__ + + +#ifdef __GNUC__ +// #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" +#endif + + +/* 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 Z7_ARRAY_NEW macro instead of new[] operator. */ + +#if defined(_MSC_VER) && (_MSC_VER == 1200) && !defined(_WIN64) + #define Z7_ARRAY_NEW(p, T, size) p = new T[((size) > (unsigned)0xFFFFFFFF / sizeof(T)) ? (unsigned)0xFFFFFFFF / sizeof(T) : (size)]; +#else + #define Z7_ARRAY_NEW(p, T, size) p = new T[size]; +#endif + +#if (defined(__GNUC__) && (__GNUC__ >= 8)) + #define Z7_ATTR_NORETURN __attribute__((noreturn)) +#elif (defined(__clang__) && (__clang_major__ >= 3)) + #if __has_feature(cxx_attributes) + #define Z7_ATTR_NORETURN [[noreturn]] + #else + #define Z7_ATTR_NORETURN __attribute__((noreturn)) + #endif +#elif (defined(_MSC_VER) && (_MSC_VER >= 1900)) + #define Z7_ATTR_NORETURN [[noreturn]] +#else + #define Z7_ATTR_NORETURN +#endif + + +// final in "GCC 4.7.0" +// In C++98 and C++03 code the alternative spelling __final can be used instead (this is a GCC extension.) + +#if defined (__cplusplus) && __cplusplus >= 201103L \ + || defined(_MSC_VER) && _MSC_VER >= 1800 \ + || defined(__clang__) && __clang_major__ >= 4 \ + /* || defined(__GNUC__) && __GNUC__ >= 9 */ + #define Z7_final final + #if defined(__clang__) && __cplusplus < 201103L + #pragma GCC diagnostic ignored "-Wc++11-extensions" + #endif +#elif defined (__cplusplus) && __cplusplus >= 199711L \ + && defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) + #define Z7_final __final +#else + #define Z7_final + #if defined(__clang__) && __clang_major__ >= 4 \ + || defined(__GNUC__) && __GNUC__ >= 4 + #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" + #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" + #endif +#endif + +#define Z7_class_final(c) class c Z7_final + + +#if defined (__cplusplus) && __cplusplus >= 201103L \ + || (defined(_MSC_VER) && _MSC_VER >= 1800) + #define Z7_CPP_IS_SUPPORTED_default + #define Z7_eq_delete = delete + // #define Z7_DECL_DEFAULT_COPY_CONSTRUCTOR_IF_SUPPORTED(c) c(const c& k) = default; +#else + #define Z7_eq_delete + // #define Z7_DECL_DEFAULT_COPY_CONSTRUCTOR_IF_SUPPORTED(c) +#endif + + +#if defined(__cplusplus) && (__cplusplus >= 201103L) \ + || defined(_MSC_VER) && (_MSC_VER >= 1400) /* && (_MSC_VER != 1600) */ \ + || defined(__clang__) && __clang_major__ >= 4 + #if defined(_MSC_VER) && (_MSC_VER == 1600) /* && (_MSC_VER != 1600) */ + #pragma warning(disable : 4481) // nonstandard extension used: override specifier 'override' + #define Z7_DESTRUCTOR_override + #else + #define Z7_DESTRUCTOR_override override + #endif + #define Z7_override override +#else + #define Z7_override + #define Z7_DESTRUCTOR_override +#endif + + + +#define Z7_CLASS_NO_COPY(cls) \ + private: \ + cls(const cls &) Z7_eq_delete; \ + cls &operator=(const cls &) Z7_eq_delete; + +class CUncopyable +{ +protected: + CUncopyable() {} // allow constructor + // ~CUncopyable() {} + Z7_CLASS_NO_COPY(CUncopyable) +}; + +#define MY_UNCOPYABLE :private CUncopyable +// #define MY_UNCOPYABLE + + +typedef void (*Z7_void_Function)(void); + +#if defined(__clang__) || defined(__GNUC__) +#define Z7_CAST_FUNC(t, e) reinterpret_cast<t>(reinterpret_cast<Z7_void_Function>(e)) +#else +#define Z7_CAST_FUNC(t, e) reinterpret_cast<t>(reinterpret_cast<void*>(e)) +// #define Z7_CAST_FUNC(t, e) reinterpret_cast<t>(e) +#endif + +#define Z7_GET_PROC_ADDRESS(func_type, hmodule, func_name) \ + Z7_CAST_FUNC(func_type, GetProcAddress(hmodule, func_name)) + +// || defined(__clang__) +// || defined(__GNUC__) + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define Z7_DECLSPEC_NOVTABLE __declspec(novtable) +#else +#define Z7_DECLSPEC_NOVTABLE +#endif + +#ifdef __clang__ +#define Z7_PURE_INTERFACES_BEGIN \ +_Pragma("GCC diagnostic push") \ +_Pragma("GCC diagnostic ignored \"-Wnon-virtual-dtor\"") +_Pragma("GCC diagnostic ignored \"-Wweak-vtables\"") +#define Z7_PURE_INTERFACES_END \ +_Pragma("GCC diagnostic pop") +#else +#define Z7_PURE_INTERFACES_BEGIN +#define Z7_PURE_INTERFACES_END +#endif + +// 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)[1])) +/* +// #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) Z7_ARRAY_SIZE(a) +#endif +*/ + +#endif // ZIP7_INC_COMMON_H + + +// #define Z7_REDEFINE_NULL + +#if defined(Z7_REDEFINE_NULL) /* && (!defined(__clang__) || defined(_MSC_VER)) */ + +// NULL is defined in <stddef.h> +#include <stddef.h> +#undef NULL + +#ifdef __cplusplus + #if defined (__cplusplus) && __cplusplus >= 201103L \ + || (defined(_MSC_VER) && _MSC_VER >= 1800) + #define NULL nullptr + #else + #define NULL 0 + #endif +#else + #define NULL ((void *)0) #endif + +#else // Z7_REDEFINE_NULL + +#if defined(__clang__) && __clang_major__ >= 5 +#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +#endif // Z7_REDEFINE_NULL + +// for precompiler: +#include "MyWindows.h" diff --git a/3rdparty/lzma/CPP/Common/CrcReg.cpp b/3rdparty/lzma/CPP/Common/CrcReg.cpp index 4b662f52251..6cda892f98d 100644 --- a/3rdparty/lzma/CPP/Common/CrcReg.cpp +++ b/3rdparty/lzma/CPP/Common/CrcReg.cpp @@ -11,65 +11,59 @@ 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); +// UInt32 Z7_FASTCALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); extern CRC_FUNC g_CrcUpdate; +// extern CRC_FUNC g_CrcUpdateT4; extern CRC_FUNC g_CrcUpdateT8; -extern CRC_FUNC g_CrcUpdateT4; +extern CRC_FUNC g_CrcUpdateT0_32; +extern CRC_FUNC g_CrcUpdateT0_64; EXTERN_C_END -class CCrcHasher: - public IHasher, - public ICompressSetCoderProperties, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_2( + CCrcHasher + , IHasher + , ICompressSetCoderProperties +) UInt32 _crc; CRC_FUNC _updateFunc; - Byte mtDummy[1 << 7]; - + + Z7_CLASS_NO_COPY(CCrcHasher) + bool SetFunctions(UInt32 tSize); public: - CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); } + Byte _mtDummy[1 << 7]; // it's public to eliminate clang warning: unused private field - MY_UNKNOWN_IMP2(IHasher, ICompressSetCoderProperties) - INTERFACE_IHasher(;) - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); + CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); } }; bool CCrcHasher::SetFunctions(UInt32 tSize) { - _updateFunc = g_CrcUpdate; + CRC_FUNC f = NULL; + if (tSize == 0) f = g_CrcUpdate; + // else if (tSize == 1) f = CrcUpdateT1; + // else if (tSize == 4) f = g_CrcUpdateT4; + else if (tSize == 8) f = g_CrcUpdateT8; + else if (tSize == 32) f = g_CrcUpdateT0_32; + else if (tSize == 64) f = g_CrcUpdateT0_64; - if (tSize == 1) - _updateFunc = CrcUpdateT1; - else if (tSize == 4) + if (!f) { - if (g_CrcUpdateT4) - _updateFunc = g_CrcUpdateT4; - else - return false; + _updateFunc = g_CrcUpdate; + return false; } - else if (tSize == 8) - { - if (g_CrcUpdateT8) - _updateFunc = g_CrcUpdateT8; - else - return false; - } - + _updateFunc = f; return true; } -STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(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) { + const PROPVARIANT &prop = coderProps[i]; if (prop.vt != VT_UI4) return E_INVALIDARG; if (!SetFunctions(prop.ulVal)) @@ -79,20 +73,20 @@ STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs, const PROPVAR return S_OK; } -STDMETHODIMP_(void) CCrcHasher::Init() throw() +Z7_COM7F_IMF2(void, CCrcHasher::Init()) { _crc = CRC_INIT_VAL; } -STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size) throw() +Z7_COM7F_IMF2(void, CCrcHasher::Update(const void *data, UInt32 size)) { _crc = _updateFunc(_crc, data, size, g_CrcTable); } -STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest) throw() +Z7_COM7F_IMF2(void, CCrcHasher::Final(Byte *digest)) { - UInt32 val = CRC_GET_DIGEST(_crc); - SetUi32(digest, val); + const UInt32 val = CRC_GET_DIGEST(_crc); + SetUi32(digest, val) } REGISTER_HASHER(CCrcHasher, 0x1, "CRC32", 4) diff --git a/3rdparty/lzma/CPP/Common/Defs.h b/3rdparty/lzma/CPP/Common/Defs.h index 1fbd78bda7f..e302f358722 100644 --- a/3rdparty/lzma/CPP/Common/Defs.h +++ b/3rdparty/lzma/CPP/Common/Defs.h @@ -1,7 +1,7 @@ // Common/Defs.h -#ifndef __COMMON_DEFS_H -#define __COMMON_DEFS_H +#ifndef ZIP7_INC_COMMON_DEFS_H +#define ZIP7_INC_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; } @@ -10,6 +10,7 @@ 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 unsigned BoolToUInt(bool v) { return (v ? 1u : 0u); } inline bool IntToBool(int v) { return (v != 0); } #endif diff --git a/3rdparty/lzma/CPP/Common/DynLimBuf.cpp b/3rdparty/lzma/CPP/Common/DynLimBuf.cpp new file mode 100644 index 00000000000..1d92af39942 --- /dev/null +++ b/3rdparty/lzma/CPP/Common/DynLimBuf.cpp @@ -0,0 +1,93 @@ +// Common/DynLimBuf.cpp + +#include "StdAfx.h" + +#include "DynLimBuf.h" +#include "MyString.h" + +CDynLimBuf::CDynLimBuf(size_t limit) throw() +{ + _chars = NULL; + _pos = 0; + _size = 0; + _sizeLimit = limit; + _error = true; + unsigned size = 1 << 4; + if (size > limit) + size = (unsigned)limit; + _chars = (Byte *)MyAlloc(size); + if (_chars) + { + _size = size; + _error = false; + } +} + +CDynLimBuf & CDynLimBuf::operator+=(char c) throw() +{ + if (_error) + return *this; + if (_size == _pos) + { + size_t n = _sizeLimit - _size; + if (n == 0) + { + _error = true; + return *this; + } + if (n > _size) + n = _size; + + n += _pos; + + Byte *newBuf = (Byte *)MyAlloc(n); + if (!newBuf) + { + _error = true; + return *this; + } + memcpy(newBuf, _chars, _pos); + MyFree(_chars); + _chars = newBuf; + _size = n; + } + _chars[_pos++] = (Byte)c; + return *this; +} + +CDynLimBuf &CDynLimBuf::operator+=(const char *s) throw() +{ + if (_error) + return *this; + unsigned len = MyStringLen(s); + size_t rem = _sizeLimit - _pos; + if (rem < len) + { + len = (unsigned)rem; + _error = true; + } + if (_size - _pos < len) + { + size_t n = _pos + len; + if (n - _size < _size) + { + n = _sizeLimit; + if (n - _size > _size) + n = _size * 2; + } + + Byte *newBuf = (Byte *)MyAlloc(n); + if (!newBuf) + { + _error = true; + return *this; + } + memcpy(newBuf, _chars, _pos); + MyFree(_chars); + _chars = newBuf; + _size = n; + } + memcpy(_chars + _pos, s, len); + _pos += len; + return *this; +} diff --git a/3rdparty/lzma/CPP/Common/DynLimBuf.h b/3rdparty/lzma/CPP/Common/DynLimBuf.h new file mode 100644 index 00000000000..af22f076485 --- /dev/null +++ b/3rdparty/lzma/CPP/Common/DynLimBuf.h @@ -0,0 +1,41 @@ +// Common/DynLimBuf.h + +#ifndef ZIP7_INC_COMMON_DYN_LIM_BUF_H +#define ZIP7_INC_COMMON_DYN_LIM_BUF_H + +#include <string.h> + +#include "../../C/Alloc.h" + +#include "MyString.h" + +class CDynLimBuf +{ + Byte *_chars; + size_t _pos; + size_t _size; + size_t _sizeLimit; + bool _error; + + CDynLimBuf(const CDynLimBuf &s); + + // ---------- forbidden functions ---------- + CDynLimBuf &operator+=(wchar_t c); + +public: + CDynLimBuf(size_t limit) throw(); + ~CDynLimBuf() { MyFree(_chars); } + + size_t Len() const { return _pos; } + bool IsError() const { return _error; } + void Empty() { _pos = 0; _error = false; } + + operator const Byte *() const { return _chars; } + // const char *Ptr() const { return _chars; } + + CDynLimBuf &operator+=(char c) throw(); + CDynLimBuf &operator+=(const char *s) throw(); +}; + + +#endif diff --git a/3rdparty/lzma/CPP/Common/DynamicBuffer.h b/3rdparty/lzma/CPP/Common/DynamicBuffer.h index 44e3df7fd4a..714be4a7e03 100644 --- a/3rdparty/lzma/CPP/Common/DynamicBuffer.h +++ b/3rdparty/lzma/CPP/Common/DynamicBuffer.h @@ -1,7 +1,11 @@ // Common/DynamicBuffer.h -#ifndef __COMMON_DYNAMIC_BUFFER_H -#define __COMMON_DYNAMIC_BUFFER_H +#ifndef ZIP7_INC_COMMON_DYNAMIC_BUFFER_H +#define ZIP7_INC_COMMON_DYNAMIC_BUFFER_H + +#include <string.h> + +#include "Common.h" template <class T> class CDynamicBuffer { @@ -34,7 +38,7 @@ template <class T> class CDynamicBuffer } public: - CDynamicBuffer(): _items(0), _size(0), _pos(0) {} + CDynamicBuffer(): _items(NULL), _size(0), _pos(0) {} // operator T *() { return _items; } operator const T *() const { return _items; } ~CDynamicBuffer() { delete []_items; } @@ -54,7 +58,7 @@ public: memcpy(GetCurPtrAndGrow(size), data, size * sizeof(T)); } - const size_t GetPos() const { return _pos; } + size_t GetPos() const { return _pos; } // void Empty() { _pos = 0; } }; diff --git a/3rdparty/lzma/CPP/Common/IntToString.cpp b/3rdparty/lzma/CPP/Common/IntToString.cpp index ed217c72c0a..21b068061f0 100644 --- a/3rdparty/lzma/CPP/Common/IntToString.cpp +++ b/3rdparty/lzma/CPP/Common/IntToString.cpp @@ -2,28 +2,30 @@ #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; + while (i != 0) { i--; *s++ = (charType)temp[i]; } \ + *s = 0; \ + return s; -void ConvertUInt32ToString(UInt32 val, char *s) throw() +char * ConvertUInt32ToString(UInt32 val, char *s) throw() { - CONVERT_INT_TO_STR(char, 16); + CONVERT_INT_TO_STR(char, 16) } -void ConvertUInt64ToString(UInt64 val, char *s) throw() +char * ConvertUInt64ToString(UInt64 val, char *s) throw() { if (val <= (UInt32)0xFFFFFFFF) { - ConvertUInt32ToString((UInt32)val, s); - return; + return ConvertUInt32ToString((UInt32)val, s); } - CONVERT_INT_TO_STR(char, 24); + CONVERT_INT_TO_STR(char, 24) } void ConvertUInt64ToOct(UInt64 val, char *s) throw() @@ -46,6 +48,12 @@ void ConvertUInt64ToOct(UInt64 val, char *s) throw() 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; @@ -59,13 +67,14 @@ void ConvertUInt32ToHex(UInt32 val, char *s) throw() s[i] = 0; do { - unsigned t = (unsigned)((val & 0xF)); + unsigned t = (unsigned)(val & 0xF); val >>= 4; - s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + s[--i] = GET_HEX_CHAR(t); } while (i); } + void ConvertUInt64ToHex(UInt64 val, char *s) throw() { UInt64 v = val; @@ -79,9 +88,9 @@ void ConvertUInt64ToHex(UInt64 val, char *s) throw() s[i] = 0; do { - unsigned t = (unsigned)((val & 0xF)); + unsigned t = (unsigned)(val & 0xF); val >>= 4; - s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + s[--i] = GET_HEX_CHAR(t); } while (i); } @@ -93,7 +102,7 @@ void ConvertUInt32ToHex8Digits(UInt32 val, char *s) throw() { unsigned t = val & 0xF; val >>= 4; - s[i] = (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); + s[i] = GET_HEX_CHAR(t); } } @@ -110,19 +119,18 @@ void ConvertUInt32ToHex8Digits(UInt32 val, wchar_t *s) } */ -void ConvertUInt32ToString(UInt32 val, wchar_t *s) throw() +wchar_t * ConvertUInt32ToString(UInt32 val, wchar_t *s) throw() { - CONVERT_INT_TO_STR(wchar_t, 16); + CONVERT_INT_TO_STR(wchar_t, 16) } -void ConvertUInt64ToString(UInt64 val, wchar_t *s) throw() +wchar_t * ConvertUInt64ToString(UInt64 val, wchar_t *s) throw() { if (val <= (UInt32)0xFFFFFFFF) { - ConvertUInt32ToString((UInt32)val, s); - return; + return ConvertUInt32ToString((UInt32)val, s); } - CONVERT_INT_TO_STR(wchar_t, 24); + CONVERT_INT_TO_STR(wchar_t, 24) } void ConvertInt64ToString(Int64 val, char *s) throw() @@ -132,7 +140,7 @@ void ConvertInt64ToString(Int64 val, char *s) throw() *s++ = '-'; val = -val; } - ConvertUInt64ToString(val, s); + ConvertUInt64ToString((UInt64)val, s); } void ConvertInt64ToString(Int64 val, wchar_t *s) throw() @@ -142,5 +150,43 @@ void ConvertInt64ToString(Int64 val, wchar_t *s) throw() *s++ = L'-'; val = -val; } - ConvertUInt64ToString(val, s); + ConvertUInt64ToString((UInt64)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/3rdparty/lzma/CPP/Common/IntToString.h b/3rdparty/lzma/CPP/Common/IntToString.h index 69605ab76ce..f4fc662e64a 100644 --- a/3rdparty/lzma/CPP/Common/IntToString.h +++ b/3rdparty/lzma/CPP/Common/IntToString.h @@ -1,15 +1,17 @@ // Common/IntToString.h -#ifndef __COMMON_INT_TO_STRING_H -#define __COMMON_INT_TO_STRING_H +#ifndef ZIP7_INC_COMMON_INT_TO_STRING_H +#define ZIP7_INC_COMMON_INT_TO_STRING_H #include "MyTypes.h" -void ConvertUInt32ToString(UInt32 value, char *s) throw(); -void ConvertUInt64ToString(UInt64 value, char *s) throw(); +// return: the pointer to the "terminating" null character after written characters -void ConvertUInt32ToString(UInt32 value, wchar_t *s) throw(); -void ConvertUInt64ToString(UInt64 value, wchar_t *s) throw(); +char * ConvertUInt32ToString(UInt32 value, char *s) throw(); +char * ConvertUInt64ToString(UInt64 value, char *s) throw(); + +wchar_t * ConvertUInt32ToString(UInt32 value, wchar_t *s) throw(); +wchar_t * ConvertUInt64ToString(UInt64 value, wchar_t *s) throw(); void ConvertUInt64ToOct(UInt64 value, char *s) throw(); @@ -21,4 +23,8 @@ void ConvertUInt32ToHex8Digits(UInt32 value, char *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/3rdparty/lzma/CPP/Common/Lang.h b/3rdparty/lzma/CPP/Common/Lang.h index 22e42574eaa..76d5418e6e3 100644 --- a/3rdparty/lzma/CPP/Common/Lang.h +++ b/3rdparty/lzma/CPP/Common/Lang.h @@ -1,23 +1,30 @@ // Common/Lang.h -#ifndef __COMMON_LANG_H -#define __COMMON_LANG_H +#ifndef ZIP7_INC_COMMON_LANG_H +#define ZIP7_INC_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) {} + CRecordVector<UInt32> _ids; + CRecordVector<UInt32> _offsets; + UStringVector Comments; + + CLang(): _text(NULL) {} ~CLang() { Clear(); } - bool Open(CFSTR fileName, const wchar_t *id); + bool Open(CFSTR fileName, const char *id); void Clear() throw(); + bool IsEmpty() const { return _ids.IsEmpty(); } const wchar_t *Get(UInt32 id) const throw(); + const wchar_t *Get_by_index(unsigned index) const throw() + { + return _text + (size_t)_offsets[index]; + } }; #endif diff --git a/3rdparty/lzma/CPP/Common/ListFileUtils.cpp b/3rdparty/lzma/CPP/Common/ListFileUtils.cpp index 3bf4ec29d9f..e43dbc9c936 100644 --- a/3rdparty/lzma/CPP/Common/ListFileUtils.cpp +++ b/3rdparty/lzma/CPP/Common/ListFileUtils.cpp @@ -4,14 +4,19 @@ #include "../../C/CpuArch.h" -#include "../Windows/FileIO.h" - #include "ListFileUtils.h" #include "MyBuffer.h" #include "StringConvert.h" #include "UTFConvert.h" -static const char kQuoteChar = '\"'; +#include "../Windows/FileIO.h" + +#define CSysInFile NWindows::NFile::NIO::CInFile +#define MY_GET_LAST_ERROR ::GetLastError() + + +#define kQuoteChar '\"' + static void AddName(UStringVector &strings, UString &s) { @@ -25,34 +30,58 @@ static void AddName(UStringVector &strings, UString &s) strings.Add(s); } -bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage) + +static bool My_File_Read(CSysInFile &file, void *data, size_t size, DWORD &lastError) +{ + size_t processed; + if (!file.ReadFull(data, size, processed)) + { + lastError = MY_GET_LAST_ERROR; + return false; + } + if (processed != size) + { + lastError = 1; // error: size of listfile was changed + return false; + } + return true; +} + + +bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, DWORD &lastError) { - NWindows::NFile::NIO::CInFile file; + lastError = 0; + CSysInFile file; if (!file.Open(fileName)) + { + lastError = MY_GET_LAST_ERROR; return false; + } UInt64 fileSize; if (!file.GetLength(fileSize)) + { + lastError = MY_GET_LAST_ERROR; return false; + } if (fileSize >= ((UInt32)1 << 31) - 32) return false; UString u; - if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE) + if (codePage == Z7_WIN_CP_UTF16 || codePage == Z7_WIN_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) + + if (!My_File_Read(file, buf, (size_t)fileSize, lastError)) return false; + file.Close(); - unsigned num = (unsigned)fileSize / 2; + const unsigned num = (unsigned)fileSize / 2; wchar_t *p = u.GetBuf(num); - if (codePage == MY__CP_UTF16) + if (codePage == Z7_WIN_CP_UTF16) for (unsigned i = 0; i < num; i++) { - wchar_t c = GetUi16(buf + i * 2); + wchar_t c = GetUi16(buf + (size_t)i * 2); if (c == 0) return false; p[i] = c; @@ -60,7 +89,7 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage else for (unsigned i = 0; i < num; i++) { - wchar_t c = (wchar_t)GetBe16(buf + i * 2); + wchar_t c = (wchar_t)GetBe16(buf + (size_t)i * 2); if (c == 0) return false; p[i] = c; @@ -72,19 +101,21 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage { AString s; char *p = s.GetBuf((unsigned)fileSize); - UInt32 processed; - if (!file.Read(p, (UInt32)fileSize, processed)) - return false; - if (processed != fileSize) + + if (!My_File_Read(file, p, (size_t)fileSize, lastError)) return false; + file.Close(); - s.ReleaseBuf_CalcLen((unsigned)processed); - if (s.Len() != processed) + s.ReleaseBuf_CalcLen((unsigned)fileSize); + if (s.Len() != fileSize) return false; // #ifdef CP_UTF8 if (codePage == CP_UTF8) { + // we must check UTF8 here, if convert function doesn't check + if (!CheckUTF8_AString(s)) + return false; if (!ConvertUTF8ToUnicode(s, u)) return false; } @@ -94,7 +125,7 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage } const wchar_t kGoodBOM = 0xFEFF; - const wchar_t kBadBOM = 0xFFFE; + // const wchar_t kBadBOM = 0xFFFE; UString s; unsigned i = 0; @@ -102,9 +133,11 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage for (; i < u.Len(); i++) { wchar_t c = u[i]; + /* if (c == kGoodBOM || c == kBadBOM) return false; - if (c == L'\n' || c == 0xD) + */ + if (c == '\n' || c == 0xD) { AddName(strings, s); s.Empty(); diff --git a/3rdparty/lzma/CPP/Common/ListFileUtils.h b/3rdparty/lzma/CPP/Common/ListFileUtils.h index e8d833fdb8c..d43cc378fbd 100644 --- a/3rdparty/lzma/CPP/Common/ListFileUtils.h +++ b/3rdparty/lzma/CPP/Common/ListFileUtils.h @@ -1,14 +1,18 @@ // Common/ListFileUtils.h -#ifndef __COMMON_LIST_FILE_UTILS_H -#define __COMMON_LIST_FILE_UTILS_H +#ifndef ZIP7_INC_COMMON_LIST_FILE_UTILS_H +#define ZIP7_INC_COMMON_LIST_FILE_UTILS_H #include "MyString.h" #include "MyTypes.h" -#define MY__CP_UTF16 1200 -#define MY__CP_UTF16BE 1201 +#define Z7_WIN_CP_UTF16 1200 +#define Z7_WIN_CP_UTF16BE 1201 -bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP); +// bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP); + + // = CP_OEMCP +bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, + DWORD &lastError); #endif diff --git a/3rdparty/lzma/CPP/Common/LzFindPrepare.cpp b/3rdparty/lzma/CPP/Common/LzFindPrepare.cpp new file mode 100644 index 00000000000..8845e4a55bc --- /dev/null +++ b/3rdparty/lzma/CPP/Common/LzFindPrepare.cpp @@ -0,0 +1,7 @@ +// Sha256Prepare.cpp + +#include "StdAfx.h" + +#include "../../C/LzFind.h" + +static struct CLzFindPrepare { CLzFindPrepare() { LzFindPrepare(); } } g_CLzFindPrepare; diff --git a/3rdparty/lzma/CPP/Common/MyBuffer.h b/3rdparty/lzma/CPP/Common/MyBuffer.h index d0378057a95..bc829f4e09b 100644 --- a/3rdparty/lzma/CPP/Common/MyBuffer.h +++ b/3rdparty/lzma/CPP/Common/MyBuffer.h @@ -1,9 +1,15 @@ // Common/MyBuffer.h -#ifndef __COMMON_MY_BUFFER_H -#define __COMMON_MY_BUFFER_H +#ifndef ZIP7_INC_COMMON_MY_BUFFER_H +#define ZIP7_INC_COMMON_MY_BUFFER_H + +#include <string.h> #include "Defs.h" +#include "MyTypes.h" + +/* 7-Zip now uses CBuffer only as CByteBuffer. + So there is no need to use Z7_ARRAY_NEW macro in CBuffer code. */ template <class T> class CBuffer { @@ -16,16 +22,23 @@ public: if (_items) { delete []_items; - _items = 0; + _items = NULL; } _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) + CBuffer(): _items(NULL), _size(0) {} + CBuffer(size_t size): _items(NULL), _size(0) { - size_t size = buffer._size; + if (size != 0) + { + _items = new T[size]; + _size = size; + } + } + CBuffer(const CBuffer &buffer): _items(NULL), _size(0) + { + const size_t size = buffer._size; if (size != 0) { _items = new T[size]; @@ -88,6 +101,12 @@ public: _size = newSize; } + void Wipe() + { + if (_size != 0) + memset(_items, 0, _size * sizeof(T)); + } + CBuffer& operator=(const CBuffer &buffer) { if (&buffer != this) @@ -119,27 +138,45 @@ bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2) } -typedef CBuffer<char> CCharBuffer; +// typedef CBuffer<char> CCharBuffer; // typedef CBuffer<wchar_t> CWCharBuffer; typedef CBuffer<unsigned char> CByteBuffer; +class CByteBuffer_Wipe: public CByteBuffer +{ + Z7_CLASS_NO_COPY(CByteBuffer_Wipe) +public: + // CByteBuffer_Wipe(): CBuffer<unsigned char>() {} + CByteBuffer_Wipe(size_t size): CBuffer<unsigned char>(size) {} + ~CByteBuffer_Wipe() { Wipe(); } +}; + + + template <class T> class CObjArray { protected: T *_items; private: - // we disable constructors + // we disable copy CObjArray(const CObjArray &buffer); void operator=(const CObjArray &buffer); public: void Free() { delete []_items; - _items = 0; + _items = NULL; + } + CObjArray(size_t size): _items(NULL) + { + if (size != 0) + { + Z7_ARRAY_NEW(_items, T, size) + // _items = new T[size]; + } } - CObjArray(size_t size): _items(0) { if (size != 0) _items = new T[size]; } - CObjArray(): _items(0) {}; + CObjArray(): _items(NULL) {} ~CObjArray() { delete []_items; } operator T *() { return _items; } @@ -148,8 +185,9 @@ public: void Alloc(size_t newSize) { delete []_items; - _items = 0; - _items = new T[newSize]; + _items = NULL; + Z7_ARRAY_NEW(_items, T, newSize) + // _items = new T[newSize]; } }; @@ -164,6 +202,7 @@ template <class T> class CObjArray2 T *_items; unsigned _size; + // we disable copy CObjArray2(const CObjArray2 &buffer); void operator=(const CObjArray2 &buffer); public: @@ -171,12 +210,12 @@ public: void Free() { delete []_items; - _items = 0; + _items = NULL; _size = 0; } - CObjArray2(): _items(0), _size(0) {}; + CObjArray2(): _items(NULL), _size(0) {} /* - CObjArray2(const CObjArray2 &buffer): _items(0), _size(0) + CObjArray2(const CObjArray2 &buffer): _items(NULL), _size(0) { size_t newSize = buffer._size; if (newSize != 0) @@ -191,7 +230,7 @@ public: } */ /* - CObjArray2(size_t size): _items(0), _size(0) + CObjArray2(size_t size): _items(NULL), _size(0) { if (size != 0) { @@ -216,7 +255,10 @@ public: return; T *newBuffer = NULL; if (size != 0) - newBuffer = new T[size]; + { + Z7_ARRAY_NEW(newBuffer, T, size) + // newBuffer = new T[size]; + } delete []_items; _items = newBuffer; _size = size; diff --git a/3rdparty/lzma/CPP/Common/MyBuffer2.h b/3rdparty/lzma/CPP/Common/MyBuffer2.h new file mode 100644 index 00000000000..23394f8a8a5 --- /dev/null +++ b/3rdparty/lzma/CPP/Common/MyBuffer2.h @@ -0,0 +1,164 @@ +// Common/MyBuffer2.h + +#ifndef ZIP7_INC_COMMON_MY_BUFFER2_H +#define ZIP7_INC_COMMON_MY_BUFFER2_H + +#include "../../C/Alloc.h" + +#include "MyTypes.h" + +class CMidBuffer +{ + Byte *_data; + size_t _size; + + Z7_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 Alloc(size_t size) + { + if (!_data || size != _size) + { + ::MidFree(_data); + _size = 0; + _data = NULL; + _data = (Byte *)::MidAlloc(size); + if (_data) + _size = size; + } + } + + void AllocAtLeast(size_t size) + { + if (!_data || size > _size) + { + ::MidFree(_data); + const size_t kMinSize = (size_t)1 << 16; + if (size < kMinSize) + size = kMinSize; + _size = 0; + _data = NULL; + _data = (Byte *)::MidAlloc(size); + if (_data) + _size = size; + } + } +}; + + +class CAlignedBuffer1 +{ + Byte *_data; + + Z7_CLASS_NO_COPY(CAlignedBuffer1) + +public: + ~CAlignedBuffer1() + { + ISzAlloc_Free(&g_AlignedAlloc, _data); + } + + CAlignedBuffer1(size_t size) + { + _data = NULL; + _data = (Byte *)ISzAlloc_Alloc(&g_AlignedAlloc, size); + if (!_data) + throw 1; + } + + operator Byte *() { return _data; } + operator const Byte *() const { return _data; } +}; + + +class CAlignedBuffer +{ + Byte *_data; + size_t _size; + + Z7_CLASS_NO_COPY(CAlignedBuffer) + +public: + CAlignedBuffer(): _data(NULL), _size(0) {} + ~CAlignedBuffer() + { + ISzAlloc_Free(&g_AlignedAlloc, _data); + } + + CAlignedBuffer(size_t size): _size(0) + { + _data = NULL; + _data = (Byte *)ISzAlloc_Alloc(&g_AlignedAlloc, size); + if (!_data) + throw 1; + _size = size; + } + + void Free() + { + ISzAlloc_Free(&g_AlignedAlloc, _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 Alloc(size_t size) + { + if (!_data || size != _size) + { + ISzAlloc_Free(&g_AlignedAlloc, _data); + _size = 0; + _data = NULL; + _data = (Byte *)ISzAlloc_Alloc(&g_AlignedAlloc, size); + if (_data) + _size = size; + } + } + + void AllocAtLeast(size_t size) + { + if (!_data || size > _size) + { + ISzAlloc_Free(&g_AlignedAlloc, _data); + _size = 0; + _data = NULL; + _data = (Byte *)ISzAlloc_Alloc(&g_AlignedAlloc, size); + if (_data) + _size = size; + } + } +}; + +/* + CMidAlignedBuffer must return aligned pointer. + - in Windows it uses CMidBuffer(): MidAlloc() : VirtualAlloc() + VirtualAlloc(): Memory allocated is automatically initialized to zero. + MidAlloc(0) returns NULL + - in non-Windows systems it uses g_AlignedAlloc. + g_AlignedAlloc::Alloc(size = 0) can return non NULL. +*/ + +typedef +#ifdef _WIN32 + CMidBuffer +#else + CAlignedBuffer +#endif + CMidAlignedBuffer; + + +#endif diff --git a/3rdparty/lzma/CPP/Common/MyCom.h b/3rdparty/lzma/CPP/Common/MyCom.h index 7c725c9136e..65c4330ce41 100644 --- a/3rdparty/lzma/CPP/Common/MyCom.h +++ b/3rdparty/lzma/CPP/Common/MyCom.h @@ -1,14 +1,10 @@ // MyCom.h -#ifndef __MY_COM_H -#define __MY_COM_H +#ifndef ZIP7_INC_MY_COM_H +#define ZIP7_INC_MY_COM_H #include "MyWindows.h" -#include "NewHandler.h" - -#ifndef RINOK -#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; } -#endif +#include "MyTypes.h" template <class T> class CMyComPtr @@ -67,10 +63,15 @@ public: template <class Q> HRESULT QueryInterface(REFGUID iid, Q** pp) const throw() { + // if (*pp) throw 20220216; // for debug return _p->QueryInterface(iid, (void**)pp); } }; +#define Z7_DECL_CMyComPtr_QI_FROM(i, v, unk) \ + CMyComPtr<i> v; (unk)->QueryInterface(IID_ ## i, (void **)&v); + + ////////////////////////////////////////////////////////// inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr) @@ -82,7 +83,7 @@ inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr) class CMyComBSTR { BSTR m_str; - + Z7_CLASS_NO_COPY(CMyComBSTR) public: CMyComBSTR(): m_str(NULL) {} ~CMyComBSTR() { ::SysFreeString(m_str); } @@ -90,13 +91,23 @@ public: operator LPCOLESTR() const { return m_str; } // operator bool() const { return m_str != NULL; } // bool operator!() const { return m_str == NULL; } + + void Wipe_and_Free() + { + if (m_str) + { + memset(m_str, 0, ::SysStringLen(m_str) * sizeof(*m_str)); + Empty(); + } + } + 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(const CMyComBSTR& src) { m_str = src.MyCopy(); } /* CMyComBSTR(REFGUID src) @@ -108,6 +119,7 @@ private: } */ + /* CMyComBSTR& operator=(const CMyComBSTR& src) { if (m_str != src.m_str) @@ -118,6 +130,7 @@ private: } return *this; } + */ CMyComBSTR& operator=(LPCOLESTR src) { @@ -158,105 +171,339 @@ private: } }; -////////////////////////////////////////////////////////// -class CMyUnknownImp +class CMyComBSTR_Wipe: public CMyComBSTR { + Z7_CLASS_NO_COPY(CMyComBSTR_Wipe) public: - ULONG __m_RefCount; - CMyUnknownImp(): __m_RefCount(0) {} + CMyComBSTR_Wipe(): CMyComBSTR() {} + ~CMyComBSTR_Wipe() { Wipe_and_Free(); } +}; + + + +/* + If CMyUnknownImp doesn't use virtual destructor, the code size is smaller. + But if some class_1 derived from CMyUnknownImp + uses Z7_COM_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. + We can use virtual ~CMyUnknownImp() to disable warning + "class has virtual functions, but destructor is not virtual". + Also we can use virtual ~IUnknown() {} in MyWindows.h +*/ + +class CMyUnknownImp +{ + Z7_CLASS_NO_COPY(CMyUnknownImp) +protected: + ULONG _m_RefCount; + CMyUnknownImp(): _m_RefCount(0) {} - // virtual ~CMyUnknownImp() {}; + #ifdef _WIN32 + #if defined(__GNUC__) || defined(__clang__) + // virtual ~CMyUnknownImp() {} // to disable GCC/CLANG varnings + #endif + #endif }; -#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 Z7_COM_QI_BEGIN \ + private: STDMETHOD(QueryInterface) (REFGUID iid, void **outObject) throw() Z7_override Z7_final \ + { *outObject = NULL; + +#define Z7_COM_QI_ENTRY(i) \ + else if (iid == IID_ ## i) \ + { i *ti = this; *outObject = ti; } +// { *outObject = (void *)(i *)this; } -#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ - MY_QUERYINTERFACE_ENTRY(i) +#define Z7_COM_QI_ENTRY_UNKNOWN_0 \ + if (iid == IID_IUnknown) \ + { IUnknown *tu = this; *outObject = tu; } -#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; ++__m_RefCount; /* AddRef(); */ return S_OK; } +#define Z7_COM_QI_ENTRY_UNKNOWN(i) \ + if (iid == IID_IUnknown) \ + { i *ti = this; IUnknown *tu = ti; *outObject = tu; } +// { *outObject = (void *)(IUnknown *)(i *)this; } -#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 Z7_COM_QI_BEGIN2(i) \ + Z7_COM_QI_BEGIN \ + Z7_COM_QI_ENTRY_UNKNOWN(i) \ + Z7_COM_QI_ENTRY(i) -#define MY_UNKNOWN_IMP_SPEC(i) \ - MY_QUERYINTERFACE_BEGIN \ +#define Z7_COM_QI_END \ + else return E_NOINTERFACE; \ + ++_m_RefCount; /* AddRef(); */ return S_OK; } + +#define Z7_COM_ADDREF_RELEASE \ + private: \ + STDMETHOD_(ULONG, AddRef)() throw() Z7_override Z7_final \ + { return ++_m_RefCount; } \ + STDMETHOD_(ULONG, Release)() throw() Z7_override Z7_final \ + { if (--_m_RefCount != 0) return _m_RefCount; delete this; return 0; } \ + +#define Z7_COM_UNKNOWN_IMP_SPEC(i) \ + Z7_COM_QI_BEGIN \ i \ - MY_QUERYINTERFACE_END \ - MY_ADDREF_RELEASE + Z7_COM_QI_END \ + Z7_COM_ADDREF_RELEASE -#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \ - MY_QUERYINTERFACE_END \ - MY_ADDREF_RELEASE +#define Z7_COM_UNKNOWN_IMP_0 \ + Z7_COM_QI_BEGIN \ + Z7_COM_QI_ENTRY_UNKNOWN_0 \ + Z7_COM_QI_END \ + Z7_COM_ADDREF_RELEASE -#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ - MY_QUERYINTERFACE_ENTRY(i) \ +#define Z7_COM_UNKNOWN_IMP_1(i) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i) \ + Z7_COM_QI_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 Z7_COM_UNKNOWN_IMP_2(i1, i2) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_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 Z7_COM_UNKNOWN_IMP_3(i1, i2, i3) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_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 Z7_COM_UNKNOWN_IMP_4(i1, i2, i3, i4) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_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 Z7_COM_UNKNOWN_IMP_5(i1, i2, i3, i4, i5) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + Z7_COM_QI_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 Z7_COM_UNKNOWN_IMP_6(i1, i2, i3, i4, i5, i6) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + Z7_COM_QI_ENTRY(i5) \ + Z7_COM_QI_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) \ +#define Z7_COM_UNKNOWN_IMP_7(i1, i2, i3, i4, i5, i6, i7) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + Z7_COM_QI_ENTRY(i5) \ + Z7_COM_QI_ENTRY(i6) \ + Z7_COM_QI_ENTRY(i7) \ ) -const HRESULT k_My_HRESULT_WritingWasCut = 0x20000010; + +#define Z7_IFACES_IMP_UNK_1(i1) \ + Z7_COM_UNKNOWN_IMP_1(i1) \ + Z7_IFACE_COM7_IMP(i1) \ + +#define Z7_IFACES_IMP_UNK_2(i1, i2) \ + Z7_COM_UNKNOWN_IMP_2(i1, i2) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + +#define Z7_IFACES_IMP_UNK_3(i1, i2, i3) \ + Z7_COM_UNKNOWN_IMP_3(i1, i2, i3) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + +#define Z7_IFACES_IMP_UNK_4(i1, i2, i3, i4) \ + Z7_COM_UNKNOWN_IMP_4(i1, i2, i3, i4) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + +#define Z7_IFACES_IMP_UNK_5(i1, i2, i3, i4, i5) \ + Z7_COM_UNKNOWN_IMP_5(i1, i2, i3, i4, i5) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + Z7_IFACE_COM7_IMP(i5) \ + +#define Z7_IFACES_IMP_UNK_6(i1, i2, i3, i4, i5, i6) \ + Z7_COM_UNKNOWN_IMP_6(i1, i2, i3, i4, i5, i6) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + Z7_IFACE_COM7_IMP(i5) \ + Z7_IFACE_COM7_IMP(i6) \ + + +#define Z7_CLASS_IMP_COM_0(c) \ + Z7_class_final(c) : \ + public IUnknown, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_0 \ + private: + +#define Z7_CLASS_IMP_COM_1(c, i1) \ + Z7_class_final(c) : \ + public i1, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_1(i1) \ + private: + +#define Z7_CLASS_IMP_COM_2(c, i1, i2) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_2(i1, i2) \ + private: + +#define Z7_CLASS_IMP_COM_3(c, i1, i2, i3) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_3(i1, i2, i3) \ + private: + +#define Z7_CLASS_IMP_COM_4(c, i1, i2, i3, i4) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_4(i1, i2, i3, i4) \ + private: + +#define Z7_CLASS_IMP_COM_5(c, i1, i2, i3, i4, i5) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public i5, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_5(i1, i2, i3, i4, i5) \ + private: + +#define Z7_CLASS_IMP_COM_6(c, i1, i2, i3, i4, i5, i6) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public i5, \ + public i6, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_6(i1, i2, i3, i4, i5, i6) \ + private: + + +/* +#define Z7_CLASS_IMP_NOQIB_0(c) \ + Z7_class_final(c) : \ + public IUnknown, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_0 \ + private: +*/ + +#define Z7_CLASS_IMP_NOQIB_1(c, i1) \ + Z7_class_final(c) : \ + public i1, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_0 \ + Z7_IFACE_COM7_IMP(i1) \ + private: + +#define Z7_CLASS_IMP_NOQIB_2(c, i1, i2) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_1(i2) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + private: + +#define Z7_CLASS_IMP_NOQIB_3(c, i1, i2, i3) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_2(i2, i3) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + private: + +#define Z7_CLASS_IMP_NOQIB_4(c, i1, i2, i3, i4) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_3(i2, i3, i4) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + +/* +#define Z7_CLASS_IMP_NOQIB_5(c, i1, i2, i3, i4, i5) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public i5, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_4(i2, i3, i4, i5) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + Z7_IFACE_COM7_IMP(i5) \ +*/ + + +#define Z7_CLASS_IMP_IInStream(c) \ + class c Z7_final : \ + public IInStream, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_2(ISequentialInStream, IInStream) \ + + +#define k_My_HRESULT_WritingWasCut 0x20000010 #endif diff --git a/3rdparty/lzma/CPP/Common/MyException.h b/3rdparty/lzma/CPP/Common/MyException.h index f0ad111589f..06fbdea15d6 100644 --- a/3rdparty/lzma/CPP/Common/MyException.h +++ b/3rdparty/lzma/CPP/Common/MyException.h @@ -1,7 +1,7 @@ // Common/Exception.h -#ifndef __COMMON_EXCEPTION_H -#define __COMMON_EXCEPTION_H +#ifndef ZIP7_INC_COMMON_EXCEPTION_H +#define ZIP7_INC_COMMON_EXCEPTION_H #include "MyWindows.h" diff --git a/3rdparty/lzma/CPP/Common/MyGuidDef.h b/3rdparty/lzma/CPP/Common/MyGuidDef.h index 68745870ee3..ab9993bdeb1 100644 --- a/3rdparty/lzma/CPP/Common/MyGuidDef.h +++ b/3rdparty/lzma/CPP/Common/MyGuidDef.h @@ -1,8 +1,12 @@ // Common/MyGuidDef.h +// #pragma message "Common/MyGuidDef.h" + #ifndef GUID_DEFINED #define GUID_DEFINED +// #pragma message "GUID_DEFINED" + #include "MyTypes.h" typedef struct { @@ -18,37 +22,42 @@ typedef struct { #define REFGUID const GUID * #endif +// typedef GUID IID; +typedef GUID CLSID; + #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]) + for (unsigned i = 0; i < sizeof(g1); i++) + if (((const unsigned char *)&g1)[i] != ((const unsigned char *)&g2)[i]) return 0; return 1; } inline int operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); } #endif +#endif // GUID_DEFINED + +#ifndef EXTERN_C #ifdef __cplusplus - #define MY_EXTERN_C extern "C" + #define EXTERN_C extern "C" #else - #define MY_EXTERN_C extern + #define 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 } } + EXTERN_C const GUID name; \ + 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 + EXTERN_C const GUID name #endif diff --git a/3rdparty/lzma/CPP/Common/MyInitGuid.h b/3rdparty/lzma/CPP/Common/MyInitGuid.h index 279fba5d612..3745c79a091 100644 --- a/3rdparty/lzma/CPP/Common/MyInitGuid.h +++ b/3rdparty/lzma/CPP/Common/MyInitGuid.h @@ -1,7 +1,7 @@ // Common/MyInitGuid.h -#ifndef __COMMON_MY_INITGUID_H -#define __COMMON_MY_INITGUID_H +#ifndef ZIP7_INC_COMMON_MY_INITGUID_H +#define ZIP7_INC_COMMON_MY_INITGUID_H /* This file must be included only to one C++ file in project before @@ -19,12 +19,25 @@ Also we need IID_IUnknown that is initialized in some file for linking: Other: we define IID_IUnknown in this file */ +// #include "Common.h" +/* vc6 without sdk needs <objbase.h> before <initguid.h>, + but it doesn't work in new msvc. + So we include full "MyWindows.h" instead of <objbase.h> */ +// #include <objbase.h> +#include "MyWindows.h" + #ifdef _WIN32 +#ifdef __clang__ + // #pragma GCC diagnostic ignored "-Wmissing-variable-declarations" +#endif + #ifdef UNDER_CE #include <basetyps.h> #endif +// for vc6 without sdk we must define INITGUID here +#define INITGUID #include <initguid.h> #ifdef UNDER_CE @@ -32,14 +45,13 @@ DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); #endif -#else +#else // _WIN32 #define INITGUID #include "MyGuidDef.h" DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); -#endif - +#endif // _WIN32 #endif diff --git a/3rdparty/lzma/CPP/Common/MyLinux.h b/3rdparty/lzma/CPP/Common/MyLinux.h index 1a918993527..a8454d7f58e 100644 --- a/3rdparty/lzma/CPP/Common/MyLinux.h +++ b/3rdparty/lzma/CPP/Common/MyLinux.h @@ -1,7 +1,19 @@ // MyLinux.h -#ifndef __MY_LIN_LINUX_H -#define __MY_LIN_LINUX_H +#ifndef ZIP7_INC_COMMON_MY_LINUX_H +#define ZIP7_INC_COMMON_MY_LINUX_H + +// #include "../../C/7zTypes.h" + +#define MY_LIN_DT_UNKNOWN 0 +#define MY_LIN_DT_FIFO 1 +#define MY_LIN_DT_CHR 2 +#define MY_LIN_DT_DIR 4 +#define MY_LIN_DT_BLK 6 +#define MY_LIN_DT_REG 8 +#define MY_LIN_DT_LNK 10 +#define MY_LIN_DT_SOCK 12 +#define MY_LIN_DT_WHT 14 #define MY_LIN_S_IFMT 00170000 #define MY_LIN_S_IFSOCK 0140000 @@ -39,4 +51,25 @@ #define MY_LIN_S_IWOTH 00002 #define MY_LIN_S_IXOTH 00001 +/* +// major/minor encoding for makedev(): MMMMMmmmmmmMMMmm: + +inline UInt32 MY_dev_major(UInt64 dev) +{ + return ((UInt32)(dev >> 8) & (UInt32)0xfff) | ((UInt32)(dev >> 32) & ~(UInt32)0xfff); +} + +inline UInt32 MY_dev_minor(UInt64 dev) +{ + return ((UInt32)(dev) & 0xff) | ((UInt32)(dev >> 12) & ~0xff); +} + +inline UInt64 MY_dev_makedev(UInt32 __major, UInt32 __minor) +{ + return (__minor & 0xff) | ((__major & 0xfff) << 8) + | ((UInt64) (__minor & ~0xff) << 12) + | ((UInt64) (__major & ~0xfff) << 32); +} +*/ + #endif diff --git a/3rdparty/lzma/CPP/Common/MyString.cpp b/3rdparty/lzma/CPP/Common/MyString.cpp index a2d4cc4e6d0..51c1c3be0fc 100644 --- a/3rdparty/lzma/CPP/Common/MyString.cpp +++ b/3rdparty/lzma/CPP/Common/MyString.cpp @@ -8,6 +8,8 @@ #include <ctype.h> #endif +#include "IntToString.h" + #if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING) #include "StringConvert.h" #endif @@ -28,6 +30,10 @@ inline const char* MyStringGetNextCharPointer(const char *p) throw() } */ +#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++) @@ -52,7 +58,18 @@ int FindCharPosInString(const wchar_t *s, wchar_t c) throw() } /* -void MyStringUpper_Ascii(wchar_t *s) +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 (;;) { @@ -173,8 +190,8 @@ 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; + const unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true; + const unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false; } } @@ -182,8 +199,8 @@ bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw() { for (;;) { - wchar_t c1 = *s1++; - wchar_t c2 = *s2++; + const wchar_t c1 = *s1++; + const wchar_t c2 = *s2++; if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false; if (c1 == 0) return true; } @@ -196,10 +213,10 @@ bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() const char *s1 = _chars; for (;;) { - char c2 = *s++; + const char c2 = *s++; if (c2 == 0) return true; - char c1 = *s1++; + const char c1 = *s1++; if (MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) return false; @@ -211,20 +228,34 @@ bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() const wchar_t *s1 = _chars; for (;;) { - char c2 = *s++; + const char c2 = *s++; if (c2 == 0) return true; - wchar_t c1 = *s1++; + const wchar_t c1 = *s1++; if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)) return false; } } +bool StringsAreEqual_Ascii(const char *u, const char *a) throw() +{ + for (;;) + { + const char c = *a; + if (c != *u) + return false; + if (c == 0) + return true; + a++; + u++; + } +} + bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw() { for (;;) { - unsigned char c = *a; + const unsigned char c = (unsigned char)*a; if (c != *u) return false; if (c == 0) @@ -238,8 +269,8 @@ bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw() { for (;;) { - char c1 = *s1++; - char c2 = *s2++; + const char c1 = *s1++; + const char c2 = *s2++; if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) return false; if (c1 == 0) @@ -251,8 +282,8 @@ bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw() { for (;;) { - wchar_t c1 = *s1++; - wchar_t c2 = *s2++; + const wchar_t c1 = *s1++; + const wchar_t c2 = *s2++; if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) return false; if (c1 == 0) @@ -264,8 +295,8 @@ bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw() { for (;;) { - wchar_t c1 = *s1++; - char c2 = *s2++; + const wchar_t c1 = *s1++; + const char c2 = *s2++; if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))) return false; if (c1 == 0) @@ -277,8 +308,39 @@ 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; + const wchar_t c2 = *s2++; if (c2 == 0) return true; + const wchar_t c1 = *s1++; if (c1 != c2) return false; + } +} + +bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw() +{ + for (;;) + { + const unsigned char c2 = (unsigned char)(*s2++); if (c2 == 0) return true; + const wchar_t c1 = *s1++; if (c1 != c2) return false; + } +} + +bool IsString1PrefixedByString2_NoCase_Ascii(const char *s1, const char *s2) throw() +{ + for (;;) + { + const char c2 = *s2++; if (c2 == 0) return true; + const char c1 = *s1++; + if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) + return false; + } +} + +bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *s1, const char *s2) throw() +{ + for (;;) + { + const char c2 = *s2++; if (c2 == 0) return true; + const wchar_t c1 = *s1++; + if (c1 != (unsigned char)c2 && MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)) + return false; } } @@ -286,8 +348,8 @@ bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) thr { for (;;) { - wchar_t c2 = *s2++; if (c2 == 0) return true; - wchar_t c1 = *s1++; + const wchar_t c2 = *s2++; if (c2 == 0) return true; + const wchar_t c1 = *s1++; if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false; } @@ -298,12 +360,12 @@ int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw() { for (;;) { - wchar_t c1 = *s1++; - wchar_t c2 = *s2++; + const wchar_t c1 = *s1++; + const wchar_t c2 = *s2++; if (c1 != c2) { - wchar_t u1 = MyCharUpper(c1); - wchar_t u2 = MyCharUpper(c2); + const wchar_t u1 = MyCharUpper(c1); + const wchar_t u2 = MyCharUpper(c2); if (u1 < u2) return -1; if (u1 > u2) return 1; } @@ -339,34 +401,34 @@ void AString::InsertSpace(unsigned &index, unsigned size) MoveItems(index + size, index); } -#define k_Alloc_Len_Limit 0x40000000 +#define k_Alloc_Len_Limit (0x40000000 - 2) 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); + // MY_STRING_REALLOC(_chars, char, (size_t)newLimit + 1, (size_t)_len + 1); + char *newBuf = MY_STRING_NEW_char((size_t)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); + if (newLimit > k_Alloc_Len_Limit) throw 20130220; + // MY_STRING_REALLOC(_chars, char, (size_t)newLimit + 1, 0); + char *newBuf = MY_STRING_NEW_char((size_t)newLimit + 1); newBuf[0] = 0; - MY_STRING_DELETE(_chars); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = newLimit; + _len = 0; } void AString::SetStartLen(unsigned len) { - _chars = 0; - _chars = MY_STRING_NEW(char, len + 1); + _chars = NULL; + _chars = MY_STRING_NEW_char((size_t)len + 1); _len = len; _limit = len; } @@ -377,23 +439,32 @@ void AString::Grow_1() next += next / 2; next += 16; next &= ~(unsigned)15; - ReAlloc(next - 1); + next--; + if (next < _len || next > k_Alloc_Len_Limit) + next = k_Alloc_Len_Limit; + if (next <= _len) + throw 20130220; + ReAlloc(next); + // Grow(1); } void AString::Grow(unsigned n) { - unsigned freeSize = _limit - _len; + const unsigned freeSize = _limit - _len; if (n <= freeSize) return; - unsigned next = _len + n; next += next / 2; next += 16; next &= ~(unsigned)15; - ReAlloc(next - 1); + next--; + if (next < _len || next > k_Alloc_Len_Limit) + next = k_Alloc_Len_Limit; + if (next <= _len || next - _len < n) + throw 20130220; + ReAlloc(next); } -/* AString::AString(unsigned num, const char *s) { unsigned len = MyStringLen(s); @@ -403,7 +474,6 @@ AString::AString(unsigned num, const char *s) memcpy(_chars, s, num); _chars[num] = 0; } -*/ AString::AString(unsigned num, const AString &s) { @@ -421,7 +491,7 @@ AString::AString(const AString &s, char c) unsigned len = s.Len(); memcpy(chars, s, len); chars[len] = c; - chars[len + 1] = 0; + chars[(size_t)len + 1] = 0; } AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2) @@ -436,20 +506,23 @@ AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1. 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, 4); + _chars = NULL; + _chars = MY_STRING_NEW_char(kStartStringCapacity); _len = 0; - _limit = 4 - 1; + _limit = kStartStringCapacity - 1; _chars[0] = 0; } AString::AString(char c) { SetStartLen(1); - _chars[0] = c; - _chars[1] = 0; + char *chars = _chars; + chars[0] = c; + chars[1] = 0; } AString::AString(const char *s) @@ -468,14 +541,15 @@ AString &AString::operator=(char c) { if (1 > _limit) { - char *newBuf = MY_STRING_NEW(char, 1 + 1); - MY_STRING_DELETE(_chars); + char *newBuf = MY_STRING_NEW_char(1 + 1); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = 1; } _len = 1; - _chars[0] = c; - _chars[1] = 0; + char *chars = _chars; + chars[0] = c; + chars[1] = 0; return *this; } @@ -484,8 +558,8 @@ 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); + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = len; } @@ -501,8 +575,8 @@ AString &AString::operator=(const AString &s) unsigned len = s._len; if (len > _limit) { - char *newBuf = MY_STRING_NEW(char, len + 1); - MY_STRING_DELETE(_chars); + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = len; } @@ -526,8 +600,8 @@ void AString::SetFromWStr_if_Ascii(const wchar_t *s) } if (len > _limit) { - char *newBuf = MY_STRING_NEW(char, len + 1); - MY_STRING_DELETE(_chars); + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = len; } @@ -550,8 +624,8 @@ void AString::SetFromBstr_if_Ascii(BSTR s) } if (len > _limit) { - char *newBuf = MY_STRING_NEW(char, len + 1); - MY_STRING_DELETE(_chars); + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = len; } @@ -567,6 +641,9 @@ void AString::SetFromBstr_if_Ascii(BSTR s) void AString::Add_Space() { operator+=(' '); } void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); } void AString::Add_LF() { operator+=('\n'); } +void AString::Add_Slash() { operator+=('/'); } +void AString::Add_Dot() { operator+=('.'); } +void AString::Add_Minus() { operator+=('-'); } AString &AString::operator+=(const char *s) { @@ -577,6 +654,12 @@ AString &AString::operator+=(const char *s) return *this; } +void AString::Add_OptSpaced(const char *s) +{ + Add_Space_if_NotEmpty(); + (*this) += s; +} + AString &AString::operator+=(const AString &s) { Grow(s._len); @@ -585,12 +668,36 @@ AString &AString::operator+=(const AString &s) return *this; } +void AString::Add_UInt32(UInt32 v) +{ + Grow(10); + _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars); +} + +void UString::Add_UInt64(UInt64 v) +{ + Grow(20); + _len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars); +} + +void AString::AddFrom(const char *s, unsigned len) // no check +{ + if (len != 0) + { + Grow(len); + memcpy(_chars + _len, s, len); + len += _len; + _chars[len] = 0; + _len = len; + } +} + 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); + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = len; } @@ -662,7 +769,7 @@ int AString::ReverseFind_PathSepar() const throw() const char *p = _chars + _len - 1; for (;;) { - char c = *p; + const char c = *p; if (IS_PATH_SEPAR(c)) return (int)(p - _chars); if (p == _chars) @@ -694,7 +801,7 @@ void AString::TrimRight() throw() unsigned i; for (i = _len; i != 0; i--) { - char c = p[i - 1]; + char c = p[(size_t)i - 1]; if (c != ' ' && c != '\n' && c != '\t') break; } @@ -780,12 +887,13 @@ void AString::Replace(char oldChar, char newChar) throw() return; // 0; // unsigned number = 0; int pos = 0; + char *chars = _chars; while ((unsigned)pos < _len) { - pos = Find(oldChar, pos); + pos = Find(oldChar, (unsigned)pos); if (pos < 0) break; - _chars[(unsigned)pos] = newChar; + chars[(unsigned)pos] = newChar; pos++; // number++; } @@ -804,11 +912,11 @@ void AString::Replace(const AString &oldString, const AString &newString) int pos = 0; while ((unsigned)pos < _len) { - pos = Find(oldString, pos); + pos = Find(oldString, (unsigned)pos); if (pos < 0) break; - Delete(pos, oldLen); - Insert(pos, newString); + Delete((unsigned)pos, oldLen); + Insert((unsigned)pos, newString); pos += newLen; // number++; } @@ -893,30 +1001,30 @@ void UString::InsertSpace(unsigned index, unsigned size) 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); + // MY_STRING_REALLOC(_chars, wchar_t, (size_t)newLimit + 1, (size_t)_len + 1); + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)newLimit + 1); wmemcpy(newBuf, _chars, _len + 1); - MY_STRING_DELETE(_chars); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = newLimit; } void UString::ReAlloc2(unsigned newLimit) { - if (newLimit >= k_Alloc_Len_Limit) throw 20130221; + 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); + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)newLimit + 1); newBuf[0] = 0; - MY_STRING_DELETE(_chars); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = newLimit; + _len = 0; } void UString::SetStartLen(unsigned len) { - _chars = 0; - _chars = MY_STRING_NEW(wchar_t, len + 1); + _chars = NULL; + _chars = MY_STRING_NEW_wchar_t((size_t)len + 1); _len = len; _limit = len; } @@ -927,19 +1035,28 @@ void UString::Grow_1() next += next / 2; next += 16; next &= ~(unsigned)15; - ReAlloc(next - 1); + next--; + if (next < _len || next > k_Alloc_Len_Limit) + next = k_Alloc_Len_Limit; + if (next <= _len) + throw 20130220; + ReAlloc(next); } void UString::Grow(unsigned n) { - unsigned freeSize = _limit - _len; + const unsigned freeSize = _limit - _len; if (n <= freeSize) return; - unsigned next = _len + n; next += next / 2; next += 16; next &= ~(unsigned)15; + next--; + if (next < _len || next > k_Alloc_Len_Limit) + next = k_Alloc_Len_Limit; + if (next <= _len || next - _len < n) + throw 20130220; ReAlloc(next - 1); } @@ -971,7 +1088,7 @@ UString::UString(const UString &s, wchar_t c) unsigned len = s.Len(); wmemcpy(chars, s, len); chars[len] = c; - chars[len + 1] = 0; + chars[(size_t)len + 1] = 0; } UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2) @@ -988,27 +1105,57 @@ UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyS UString::UString() { - _chars = 0; - _chars = MY_STRING_NEW(wchar_t, 4); + _chars = NULL; + _chars = MY_STRING_NEW_wchar_t(kStartStringCapacity); _len = 0; - _limit = 4 - 1; + _limit = kStartStringCapacity - 1; _chars[0] = 0; } UString::UString(wchar_t c) { SetStartLen(1); - _chars[0] = c; - _chars[1] = 0; + 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); + const unsigned len = MyStringLen(s); SetStartLen(len); wmemcpy(_chars, s, len + 1); } +UString::UString(const char *s) +{ + const 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 AString &s) +{ + const unsigned len = s.Len(); + SetStartLen(len); + wchar_t *chars = _chars; + const char *s2 = s.Ptr(); + for (unsigned i = 0; i < len; i++) + chars[i] = (unsigned char)s2[i]; + chars[len] = 0; +} + UString::UString(const UString &s) { SetStartLen(s._len); @@ -1019,14 +1166,15 @@ UString &UString::operator=(wchar_t c) { if (1 > _limit) { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1); - MY_STRING_DELETE(_chars); + wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = 1; } _len = 1; - _chars[0] = c; - _chars[1] = 0; + wchar_t *chars = _chars; + chars[0] = c; + chars[1] = 0; return *this; } @@ -1035,8 +1183,8 @@ 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); + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = len; } @@ -1052,8 +1200,8 @@ UString &UString::operator=(const UString &s) unsigned len = s._len; if (len > _limit) { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - MY_STRING_DELETE(_chars); + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + MY_STRING_DELETE(_chars) _chars = newBuf; _limit = len; } @@ -1062,21 +1210,102 @@ UString &UString::operator=(const UString &s) return *this; } -void UString::SetFromBstr(BSTR s) +void UString::SetFrom(const wchar_t *s, unsigned len) // no check { - unsigned len = ::SysStringLen(s); if (len > _limit) { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - MY_STRING_DELETE(_chars); + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_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(LPCOLESTR s) +{ + unsigned len = ::SysStringLen((BSTR)(void *)(s)); + + /* + #if WCHAR_MAX > 0xffff + size_t num_wchars = 0; + for (size_t i = 0; i < len;) + { + wchar_t c = s[i++]; + if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) + { + wchar_t c2 = s[i]; + if (c2 >= 0xdc00 && c2 < 0x10000) + { + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + i++; + } + } + num_wchars++; + } + len = num_wchars; + #endif + */ + + if (len > _limit) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + _len = len; + + /* + #if WCHAR_MAX > 0xffff + + wchar_t *chars = _chars; + for (size_t i = 0; i <= len; i++) + { + wchar_t c = *s++; + if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) + { + wchar_t c2 = *s; + if (c2 >= 0xdc00 && c2 < 0x10000) + { + s++; + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + } + } + chars[i] = c; + } + + #else + */ + // if (s) wmemcpy(_chars, s, len + 1); + + // #endif } +UString &UString::operator=(const char *s) +{ + unsigned len = MyStringLen(s); + if (len > _limit) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_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_Dot() { operator+=(L'.'); } void UString::Add_Space() { operator+=(L' '); } void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); } @@ -1108,39 +1337,7 @@ UString &UString::operator+=(const UString &s) 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::SetFromAscii(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; -} - -void UString::AddAscii(const char *s) +UString &UString::operator+=(const char *s) { unsigned len = MyStringLen(s); Grow(len); @@ -1149,8 +1346,21 @@ void UString::AddAscii(const char *s) chars[i] = (unsigned char)s[i]; chars[len] = 0; _len += len; + return *this; +} + + +void UString::Add_UInt32(UInt32 v) +{ + Grow(10); + _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars); } +void AString::Add_UInt64(UInt64 v) +{ + Grow(20); + _len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars); +} int UString::Find(const wchar_t *s, unsigned startIndex) const throw() @@ -1188,31 +1398,26 @@ int UString::ReverseFind(wchar_t c) const throw() { if (_len == 0) return -1; - const wchar_t *p = _chars + _len - 1; - for (;;) + const wchar_t *p = _chars + _len; + do { - if (*p == c) + if (*(--p) == c) return (int)(p - _chars); - if (p == _chars) - return -1; - p--; } + while (p != _chars); + return -1; } int UString::ReverseFind_PathSepar() const throw() { - if (_len == 0) - return -1; - const wchar_t *p = _chars + _len - 1; - for (;;) + const wchar_t *p = _chars + _len; + while (p != _chars) { - wchar_t c = *p; + const wchar_t c = *(--p); if (IS_PATH_SEPAR(c)) return (int)(p - _chars); - if (p == _chars) - return -1; - p--; } + return -1; } void UString::TrimLeft() throw() @@ -1238,7 +1443,7 @@ void UString::TrimRight() throw() unsigned i; for (i = _len; i != 0; i--) { - wchar_t c = p[i - 1]; + wchar_t c = p[(size_t)i - 1]; if (c != ' ' && c != '\n' && c != '\t') break; } @@ -1259,7 +1464,7 @@ void UString::InsertAtFront(wchar_t c) } /* -void UString::Insert(unsigned index, wchar_t c) +void UString::Insert_wchar_t(unsigned index, wchar_t c) { InsertSpace(index, 1); _chars[index] = c; @@ -1324,12 +1529,13 @@ void UString::Replace(wchar_t oldChar, wchar_t newChar) throw() return; // 0; // unsigned number = 0; int pos = 0; + wchar_t *chars = _chars; while ((unsigned)pos < _len) { - pos = Find(oldChar, pos); + pos = Find(oldChar, (unsigned)pos); if (pos < 0) break; - _chars[(unsigned)pos] = newChar; + chars[(unsigned)pos] = newChar; pos++; // number++; } @@ -1348,11 +1554,11 @@ void UString::Replace(const UString &oldString, const UString &newString) int pos = 0; while ((unsigned)pos < _len) { - pos = Find(oldString, pos); + pos = Find(oldString, (unsigned)pos); if (pos < 0) break; - Delete(pos, oldLen); - Insert(pos, newString); + Delete((unsigned)pos, oldLen); + Insert((unsigned)pos, newString); pos += newLen; // number++; } @@ -1390,15 +1596,24 @@ void UString::DeleteFrontal(unsigned num) throw() void UString2::ReAlloc2(unsigned newLimit) { - if (newLimit >= k_Alloc_Len_Limit) throw 20130221; + // wrong (_len) is allowed after this function + 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); + if (_chars) + { + MY_STRING_DELETE(_chars) + _chars = NULL; + // _len = 0; + } + _chars = MY_STRING_NEW_wchar_t((size_t)newLimit + 1); + _chars[0] = 0; + // _len = newLimit; } void UString2::SetStartLen(unsigned len) { - _chars = 0; - _chars = MY_STRING_NEW(wchar_t, len + 1); + _chars = NULL; + _chars = MY_STRING_NEW_wchar_t((size_t)len + 1); _len = len; } @@ -1407,14 +1622,15 @@ void UString2::SetStartLen(unsigned len) UString2::UString2(wchar_t c) { SetStartLen(1); - _chars[0] = c; - _chars[1] = 0; + wchar_t *chars = _chars; + chars[0] = c; + chars[1] = 0; } */ UString2::UString2(const wchar_t *s) { - unsigned len = MyStringLen(s); + const unsigned len = MyStringLen(s); SetStartLen(len); wmemcpy(_chars, s, len + 1); } @@ -1433,14 +1649,15 @@ UString2 &UString2::operator=(wchar_t c) { if (1 > _len) { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1); + wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1); if (_chars) - MY_STRING_DELETE(_chars); + MY_STRING_DELETE(_chars) _chars = newBuf; } _len = 1; - _chars[0] = c; - _chars[1] = 0; + wchar_t *chars = _chars; + chars[0] = c; + chars[1] = 0; return *this; } */ @@ -1450,9 +1667,9 @@ UString2 &UString2::operator=(const wchar_t *s) unsigned len = MyStringLen(s); if (len > _len) { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); if (_chars) - MY_STRING_DELETE(_chars); + MY_STRING_DELETE(_chars) _chars = newBuf; } _len = len; @@ -1465,9 +1682,9 @@ void UString2::SetFromAscii(const char *s) unsigned len = MyStringLen(s); if (len > _len) { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); if (_chars) - MY_STRING_DELETE(_chars); + MY_STRING_DELETE(_chars) _chars = newBuf; } wchar_t *chars = _chars; @@ -1484,9 +1701,9 @@ UString2 &UString2::operator=(const UString2 &s) unsigned len = s._len; if (len > _len) { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); if (_chars) - MY_STRING_DELETE(_chars); + MY_STRING_DELETE(_chars) _chars = newBuf; } _len = len; @@ -1524,6 +1741,8 @@ int MyStringCompareNoCase(const char *s1, const char *s2) } */ +#if !defined(USE_UNICODE_FSTRING) || !defined(_UNICODE) + static inline UINT GetCurrentCodePage() { #if defined(UNDER_CE) || !defined(_WIN32) @@ -1533,6 +1752,8 @@ static inline UINT GetCurrentCodePage() #endif } +#endif + #ifdef USE_UNICODE_FSTRING #ifndef _UNICODE @@ -1542,18 +1763,28 @@ 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 +#endif // _UNICODE -#else +#else // USE_UNICODE_FSTRING + +UString fs2us(const FChar *s) +{ + return MultiByteToUnicodeString(s, GetCurrentCodePage()); +} UString fs2us(const FString &s) { - return MultiByteToUnicodeString((AString)s, GetCurrentCodePage()); + return MultiByteToUnicodeString(s, GetCurrentCodePage()); } FString us2fs(const wchar_t *s) @@ -1561,4 +1792,68 @@ FString us2fs(const wchar_t *s) return UnicodeStringToMultiByte(s, GetCurrentCodePage()); } -#endif +#endif // USE_UNICODE_FSTRING + + +bool CStringFinder::FindWord_In_LowCaseAsciiList_NoCase(const char *p, const wchar_t *str) +{ + _temp.Empty(); + for (;;) + { + const wchar_t c = *str++; + if (c == 0) + break; + if (c <= 0x20 || c > 0x7f) + return false; + _temp += (char)MyCharLower_Ascii((char)c); + } + + while (*p != 0) + { + const char *s2 = _temp.Ptr(); + char c, c2; + do + { + c = *p++; + c2 = *s2++; + } + while (c == c2); + + if (c == ' ') + { + if (c2 == 0) + return true; + continue; + } + + while (*p++ != ' '); + } + + return false; +} + + +void SplitString(const UString &srcString, UStringVector &destStrings) +{ + destStrings.Clear(); + unsigned len = srcString.Len(); + if (len == 0) + return; + UString s; + for (unsigned i = 0; i < len; i++) + { + const wchar_t c = srcString[i]; + if (c == ' ') + { + if (!s.IsEmpty()) + { + destStrings.Add(s); + s.Empty(); + } + } + else + s += c; + } + if (!s.IsEmpty()) + destStrings.Add(s); +} diff --git a/3rdparty/lzma/CPP/Common/MyString.h b/3rdparty/lzma/CPP/Common/MyString.h index 02308555a38..e5ce18ae385 100644 --- a/3rdparty/lzma/CPP/Common/MyString.h +++ b/3rdparty/lzma/CPP/Common/MyString.h @@ -1,7 +1,7 @@ -// Common/String.h +// Common/MyString.h -#ifndef __COMMON_STRING_H -#define __COMMON_STRING_H +#ifndef ZIP7_INC_COMMON_MY_STRING_H +#define ZIP7_INC_COMMON_MY_STRING_H #include <string.h> @@ -10,10 +10,42 @@ #include <wchar.h> #endif +#include "Common.h" #include "MyWindows.h" #include "MyTypes.h" #include "MyVector.h" + +/* if (DEBUG_FSTRING_INHERITS_ASTRING is defined), then + FString inherits from AString, so we can find bugs related to FString at compile time. + DON'T define DEBUG_FSTRING_INHERITS_ASTRING in release code */ + +// #define DEBUG_FSTRING_INHERITS_ASTRING + +#ifdef DEBUG_FSTRING_INHERITS_ASTRING +class FString; +#endif + + +#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 @@ -39,7 +71,7 @@ inline char *MyStpCpy(char *dest, const char *src) { for (;;) { - char c = *src; + const char c = *src; *dest = c; if (c == 0) return dest; @@ -48,6 +80,13 @@ inline char *MyStpCpy(char *dest, const char *src) } } +inline void MyStringCat(char *dest, const char *src) +{ + for (; *dest != 0; dest++); + while ((*dest++ = *src++) != 0); + // MyStringCopy(dest + MyStringLen(dest), src); +} + inline unsigned MyStringLen(const wchar_t *s) { unsigned i; @@ -60,12 +99,20 @@ inline void MyStringCopy(wchar_t *dest, const wchar_t *src) while ((*dest++ = *src++) != 0); } +inline void MyStringCat(wchar_t *dest, const wchar_t *src) +{ + for (; *dest != 0; dest++); + while ((*dest++ = *src++) != 0); + // MyStringCopy(dest + MyStringLen(dest), src); +} + + /* inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src) { for (;;) { - wchar_t c = *src; + const wchar_t c = *src; *dest = c; if (c == 0) return dest; @@ -88,13 +135,15 @@ int FindCharPosInString(const wchar_t *s, wchar_t c) throw(); #define STRING_UNICODE_THROW throw() #endif -/* + inline char MyCharUpper_Ascii(char c) { if (c >= 'a' && c <= 'z') - return (char)(c - 0x20); + return (char)((unsigned char)c - 0x20); return c; } + +/* inline wchar_t MyCharUpper_Ascii(wchar_t c) { if (c >= 'a' && c <= 'z') @@ -131,7 +180,7 @@ inline wchar_t MyCharUpper(wchar_t c) throw() return (wchar_t)MyCharUpper_WIN(c); #endif #else - return (wchar_t)towupper(c); + return (wchar_t)towupper((wint_t)c); #endif } @@ -158,6 +207,7 @@ inline wchar_t MyCharLower(wchar_t c) throw() // 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(); @@ -168,21 +218,53 @@ 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 char *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 char *u, const char *a) throw(); 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_) { 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; @@ -202,12 +284,12 @@ class AString void Grow_1(); void Grow(unsigned n); - // AString(unsigned num, const char *s); + 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+(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); @@ -215,35 +297,48 @@ class AString friend AString operator+(const char *s1, const AString &s2); // ---------- forbidden functions ---------- - AString &operator+=(wchar_t c); - AString &operator=(wchar_t c); - AString(wchar_t c); - void Find(wchar_t c) const; - void Find(wchar_t c, unsigned startIndex) const; - void ReverseFind(wchar_t c) const; - void InsertAtFront(wchar_t c); - void RemoveChar(wchar_t ch); - void Replace(wchar_t oldChar, wchar_t newChar); + + #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) + + #ifdef DEBUG_FSTRING_INHERITS_ASTRING + AString(const FString &s); + AString &operator=(const FString &s); + AString &operator+=(const FString &s); + #endif public: - AString(); - AString(char c); - AString(const char *s); + explicit AString(); + explicit AString(char c); + explicit AString(const char *s); AString(const AString &s); - ~AString() { MY_STRING_DELETE(_chars); } + ~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; } + char *Ptr_non_const() const { return _chars; } const char *Ptr() const { return _chars; } const char *Ptr(unsigned pos) const { return _chars + pos; } + const char *Ptr(int pos) const { return _chars + (unsigned)pos; } const char *RightPtr(unsigned num) const { return _chars + _len - num; } - char Back() const { return _chars[_len - 1]; } + char Back() const { return _chars[(size_t)_len - 1]; } void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; } + char *GetBuf() { return _chars; } /* 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 */ @@ -292,20 +387,29 @@ public: void Add_Space(); void Add_Space_if_NotEmpty(); + void Add_OptSpaced(const char *s); void Add_LF(); + void Add_Slash(); + void Add_Dot(); + void Add_Minus(); void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); } AString &operator+=(const char *s); AString &operator+=(const AString &s); - void AddAscii(const char *s) { operator+=(s); } + void Add_UInt32(UInt32 v); + void Add_UInt64(UInt64 v); + + void AddFrom(const char *s, unsigned len); // no check void SetFrom(const char *s, unsigned len); // no check + void SetFrom(const char* s, int len) // no check + { + SetFrom(s, (unsigned)len); // no check + } void SetFrom_CalcLen(const char *s, unsigned len); - // void SetFromAscii(const char *s) { operator+=(s); } 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); } @@ -332,9 +436,13 @@ public: int Find(char c) const { return FindCharPosInString(_chars, c); } int Find(char c, unsigned startIndex) const { - int pos = FindCharPosInString(_chars + startIndex, c); + const int pos = FindCharPosInString(_chars + startIndex, c); return pos < 0 ? -1 : (int)startIndex + pos; } + int Find(char c, int startIndex) const + { + return Find(c, (unsigned)startIndex); + } int ReverseFind(char c) const throw(); int ReverseFind_Dot() const throw() { return ReverseFind('.'); } @@ -373,8 +481,35 @@ public: _chars[index] = 0; } } + void DeleteFrom(int index) + { + DeleteFrom((unsigned)index); + } + + + void Wipe_and_Empty() + { + if (_chars) + { + memset(_chars, 0, (_limit + 1) * sizeof(*_chars)); + _len = 0; + } + } }; + +class AString_Wipe: public AString +{ + Z7_CLASS_NO_COPY(AString_Wipe) +public: + AString_Wipe(): AString() {} + // AString_Wipe(const AString &s): AString(s) {} + // AString_Wipe &operator=(const AString &s) { AString::operator=(s); return *this; } + // AString_Wipe &operator=(const char *s) { AString::operator=(s); return *this; } + ~AString_Wipe() { Wipe_and_Empty(); } +}; + + bool operator<(const AString &s1, const AString &s2); bool operator>(const AString &s1, const AString &s2); @@ -435,7 +570,7 @@ class UString 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+(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); @@ -444,44 +579,61 @@ class UString // ---------- forbidden functions ---------- - UString &operator+=(char c); - UString &operator+=(unsigned char c); - UString &operator=(char c); - UString &operator=(unsigned char c); - UString(char c); - UString(unsigned char c); - void Find(char c) const; - void Find(unsigned char c) const; - void Find(char c, unsigned startIndex) const; - void Find(unsigned char c, unsigned startIndex) const; - void ReverseFind(char c) const; - void ReverseFind(unsigned char c) const; - void InsertAtFront(char c); - void InsertAtFront(unsigned char c); - void RemoveChar(char ch); - void RemoveChar(unsigned char ch); - void Replace(char oldChar, char newChar); - void Replace(unsigned char oldChar, unsigned char newChar); + 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) + + #ifdef DEBUG_FSTRING_INHERITS_ASTRING + UString(const FString &s); + UString &operator=(const FString &s); + UString &operator+=(const FString &s); + #endif public: UString(); - UString(wchar_t c); + explicit UString(wchar_t c); + explicit UString(char c); + explicit UString(const char *s); + explicit UString(const AString &s); UString(const wchar_t *s); UString(const UString &s); - ~UString() { MY_STRING_DELETE(_chars); } + ~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; } + wchar_t *Ptr_non_const() const { return _chars; } const wchar_t *Ptr() const { return _chars; } + const wchar_t *Ptr(int pos) const { return _chars + (unsigned)pos; } 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[_len - 1]; } + 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_GetMaxAvail(unsigned &availBufLen) + { + availBufLen = _limit; + return _chars; + } + */ + wchar_t *GetBuf(unsigned minLen) { if (minLen > _limit) @@ -508,9 +660,13 @@ public: } 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 SetFromBstr(BSTR s); + void SetFrom(const wchar_t *s, unsigned len); // no check + void SetFromBstr(LPCOLESTR s); + UString &operator=(const char *s); + UString &operator=(const AString &s) { return operator=(s.Ptr()); } UString &operator+=(wchar_t c) { @@ -524,21 +680,25 @@ public: 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_Dot(); 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 SetFrom(const wchar_t *s, unsigned len); // no check - - void SetFromAscii(const char *s); - void AddAscii(const char *s); + void Add_UInt32(UInt32 v); + void Add_UInt64(UInt64 v); UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); } UString Left(unsigned count) const { return UString(count, *this); } + UString Left(int count) const { return Left((unsigned)count); } // void MakeUpper() { MyStringUpper(_chars); } // void MakeUpper() { MyStringUpper_Ascii(_chars); } @@ -588,7 +748,7 @@ public: } void InsertAtFront(wchar_t c); - // void Insert(unsigned index, wchar_t c); + // void Insert_wchar_t(unsigned index, wchar_t c); void Insert(unsigned index, const wchar_t *s); void Insert(unsigned index, const UString &s); @@ -597,10 +757,12 @@ public: void Replace(wchar_t oldChar, wchar_t newChar) throw(); void Replace(const UString &oldString, const UString &newString); + void Delete(int index) throw() { Delete((unsigned)index); } void Delete(unsigned index) throw(); void Delete(unsigned index, unsigned count) throw(); void DeleteFrontal(unsigned num) throw(); void DeleteBack() { _chars[--_len] = 0; } + void DeleteFrom(int index) { DeleteFrom((unsigned)index); } void DeleteFrom(unsigned index) { if (index < _len) @@ -609,8 +771,30 @@ public: _chars[index] = 0; } } + + void Wipe_and_Empty() + { + if (_chars) + { + memset(_chars, 0, (_limit + 1) * sizeof(*_chars)); + _len = 0; + } + } +}; + + +class UString_Wipe: public UString +{ + Z7_CLASS_NO_COPY(UString_Wipe) +public: + UString_Wipe(): UString() {} + // UString_Wipe(const UString &s): UString(s) {} + // UString_Wipe &operator=(const UString &s) { UString::operator=(s); return *this; } + // UString_Wipe &operator=(const wchar_t *s) { UString::operator=(s); return *this; } + ~UString_Wipe() { Wipe_and_Empty(); } }; + bool operator<(const UString &s1, const UString &s2); bool operator>(const UString &s1, const UString &s2); @@ -630,6 +814,12 @@ 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); @@ -662,18 +852,28 @@ class UString2 // ---------- forbidden functions ---------- - UString2 &operator=(char c); - UString2 &operator=(unsigned char c); + 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(char c); - UString2(unsigned char c); + + UString2(const AString &s); + UString2 &operator=(const AString &s); + UString2 &operator+=(const AString &s); + + #ifdef DEBUG_FSTRING_INHERITS_ASTRING + UString2(const FString &s); + UString2 &operator=(const FString &s); + UString2 &operator+=(const FString &s); + #endif public: UString2(): _chars(NULL), _len(0) {} - // UString2(wchar_t c); UString2(const wchar_t *s); UString2(const UString2 &s); - ~UString2() { if (_chars) MY_STRING_DELETE(_chars); } + ~UString2() { if (_chars) { MY_STRING_DELETE(_chars) } } unsigned Len() const { return _len; } bool IsEmpty() const { return _len == 0; } @@ -682,6 +882,8 @@ public: // 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) @@ -741,44 +943,122 @@ typedef CObjectVector<CSysString> CSysStringVector; // ---------- FString ---------- +#ifndef DEBUG_FSTRING_INHERITS_ASTRING #ifdef _WIN32 #define USE_UNICODE_FSTRING #endif +#endif #ifdef USE_UNICODE_FSTRING - #define __FTEXT(quote) L##quote + #define MY_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 +#else // USE_UNICODE_FSTRING - #define __FTEXT(quote) quote + #define MY_FTEXT(quote) quote typedef char FChar; + + #ifdef DEBUG_FSTRING_INHERITS_ASTRING + + class FString: public AString + { + // FString &operator=(const char *s); + FString &operator=(const AString &s); + // FString &operator+=(const AString &s); + public: + FString(const AString &s): AString(s.Ptr()) {} + FString(const FString &s): AString(s.Ptr()) {} + FString(const char *s): AString(s) {} + FString() {} + FString &operator=(const FString &s) { AString::operator=((const AString &)s); return *this; } + FString &operator=(char c) { AString::operator=(c); return *this; } + FString &operator+=(char c) { AString::operator+=(c); return *this; } + FString &operator+=(const FString &s) { AString::operator+=((const AString &)s); return *this; } + FString Left(unsigned count) const { return FString(AString::Left(count)); } + }; + void operator+(const AString &s1, const FString &s2); + void operator+(const FString &s1, const AString &s2); + + inline FString operator+(const FString &s1, const FString &s2) + { + AString s =(const AString &)s1 + (const AString &)s2; + return FString(s.Ptr()); + // return FString((const AString &)s1 + (const AString &)s2); + } + inline FString operator+(const FString &s1, const FChar *s2) + { + return s1 + (FString)s2; + } + /* + inline FString operator+(const FChar *s1, const FString &s2) + { + return (FString)s1 + s2; + } + */ + + inline FString fas2fs(const char *s) { return FString(s); } + + #else // DEBUG_FSTRING_INHERITS_ASTRING typedef AString FString; + #define fas2fs(_x_) (_x_) + #endif // DEBUG_FSTRING_INHERITS_ASTRING + 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 +#endif // USE_UNICODE_FSTRING -#define FTEXT(quote) __FTEXT(quote) +#define FTEXT(quote) MY_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("*") + +// #define FCHAR_ANY_MASK FTEXT('*') +// #define FSTRING_ANY_MASK FTEXT("*") + typedef const FChar *CFSTR; typedef CObjectVector<FString> FStringVector; + +class CStringFinder +{ + AString _temp; +public: + // list - is list of low case Ascii strings separated by space " ". + // the function returns true, if it can find exact word (str) in (list). + bool FindWord_In_LowCaseAsciiList_NoCase(const char *list, const wchar_t *str); +}; + +void SplitString(const UString &srcString, UStringVector &destStrings); + +#endif + + + +#if defined(_WIN32) + // #include <wchar.h> + // WCHAR_MAX is defined as ((wchar_t)-1) + #define Z7_WCHART_IS_16BIT 1 +#elif (defined(WCHAR_MAX) && (WCHAR_MAX <= 0xffff)) \ + || (defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ == 2)) + #define Z7_WCHART_IS_16BIT 1 +#endif + +#if WCHAR_PATH_SEPARATOR == L'\\' +// WSL scheme +#define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT ((wchar_t)((unsigned)(0xF000) + (unsigned)'\\')) +// #define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT '_' #endif diff --git a/3rdparty/lzma/CPP/Common/MyTypes.h b/3rdparty/lzma/CPP/Common/MyTypes.h index 75806f37dcf..8f44f672090 100644 --- a/3rdparty/lzma/CPP/Common/MyTypes.h +++ b/3rdparty/lzma/CPP/Common/MyTypes.h @@ -1,9 +1,10 @@ // Common/MyTypes.h -#ifndef __COMMON_MY_TYPES_H -#define __COMMON_MY_TYPES_H +#ifndef ZIP7_INC_COMMON_MY_TYPES_H +#define ZIP7_INC_COMMON_MY_TYPES_H #include "../../C/7zTypes.h" +#include "Common.h" typedef int HRes; @@ -25,11 +26,12 @@ struct CBoolPair Val = true; Def = true; } -}; -#define CLASS_NO_COPY(cls) \ - private: \ - cls(const cls &); \ - cls &operator=(const cls &); + void SetVal_as_Defined(bool val) + { + Val = val; + Def = true; + } +}; #endif diff --git a/3rdparty/lzma/CPP/Common/MyUnknown.h b/3rdparty/lzma/CPP/Common/MyUnknown.h index ff025cb538d..75ee96fa5a0 100644 --- a/3rdparty/lzma/CPP/Common/MyUnknown.h +++ b/3rdparty/lzma/CPP/Common/MyUnknown.h @@ -1,17 +1,8 @@ // MyUnknown.h -#ifndef __MY_UNKNOWN_H -#define __MY_UNKNOWN_H +#ifndef ZIP7_INC_MY_UNKNOWN_H +#define ZIP7_INC_MY_UNKNOWN_H #include "MyWindows.h" -/* -#ifdef _WIN32 -#include <basetyps.h> -#include <unknwn.h> -#else -#include "MyWindows.h" -#endif -*/ - #endif diff --git a/3rdparty/lzma/CPP/Common/MyVector.h b/3rdparty/lzma/CPP/Common/MyVector.h index 14f7b11a1a7..9ee71058ec6 100644 --- a/3rdparty/lzma/CPP/Common/MyVector.h +++ b/3rdparty/lzma/CPP/Common/MyVector.h @@ -1,10 +1,14 @@ // Common/MyVector.h -#ifndef __COMMON_MY_VECTOR_H -#define __COMMON_MY_VECTOR_H +#ifndef ZIP7_INC_COMMON_MY_VECTOR_H +#define ZIP7_INC_COMMON_MY_VECTOR_H #include <string.h> +#include "Common.h" + +const unsigned k_VectorSizeMax = ((unsigned)1 << 31) - 1; + template <class T> class CRecordVector { @@ -17,29 +21,41 @@ class CRecordVector memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T)); } - void ReserveOnePosition() + void ReAllocForNewCapacity(const unsigned newCapacity) { - if (_size == _capacity) - { - unsigned newCapacity = _capacity + (_capacity >> 2) + 1; - T *p = new T[newCapacity]; - if (_size != 0) - memcpy(p, _items, (size_t)_size * sizeof(T)); - delete []_items; - _items = p; - _capacity = newCapacity; - } + T *p; + Z7_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) {} + void ReserveOnePosition() + { + if (_size != _capacity) + return; + if (_capacity >= k_VectorSizeMax) + throw 2021; + const unsigned rem = k_VectorSizeMax - _capacity; + unsigned add = (_capacity >> 2) + 1; + if (add > rem) + add = rem; + ReAllocForNewCapacity(_capacity + add); + } + + CRecordVector(): _items(NULL), _size(0), _capacity(0) {} - CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0) + CRecordVector(const CRecordVector &v): _items(NULL), _size(0), _capacity(0) { - unsigned size = v.Size(); + const unsigned size = v.Size(); if (size != 0) { + // Z7_ARRAY_NEW(_items, T, size) _items = new T[size]; _size = size; _capacity = size; @@ -54,7 +70,8 @@ public: { if (size != 0) { - _items = new T[size]; + Z7_ARRAY_NEW(_items, T, size) + // _items = new T[size]; _capacity = size; } } @@ -63,24 +80,30 @@ public: { if (newCapacity > _capacity) { - T *p = new T[newCapacity]; - if (_size != 0) - memcpy(p, _items, (size_t)_size * sizeof(T)); - delete []_items; - _items = p; - _capacity = newCapacity; + if (newCapacity > k_VectorSizeMax) + throw 2021; + ReAllocForNewCapacity(newCapacity); } } + void ChangeSize_KeepData(unsigned newSize) + { + Reserve(newSize); + _size = newSize; + } + void ClearAndReserve(unsigned newCapacity) { Clear(); if (newCapacity > _capacity) { + if (newCapacity > k_VectorSizeMax) + throw 2021; delete []_items; _items = NULL; _capacity = 0; - _items = new T[newCapacity]; + Z7_ARRAY_NEW(_items, T, newCapacity) + // _items = new T[newCapacity]; _capacity = newCapacity; } } @@ -91,20 +114,6 @@ public: _size = newSize; } - void ChangeSize_KeepData(unsigned newSize) - { - if (newSize > _capacity) - { - T *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) @@ -112,6 +121,7 @@ public: T *p = NULL; if (_size != 0) { + // Z7_ARRAY_NEW(p, T, _size) p = new T[_size]; memcpy(p, _items, (size_t)_size * sizeof(T)); } @@ -170,7 +180,7 @@ public: { if (&v == this) return *this; - unsigned size = v.Size(); + const unsigned size = v.Size(); if (size > _capacity) { delete []_items; @@ -188,24 +198,45 @@ public: CRecordVector& operator+=(const CRecordVector &v) { - unsigned size = v.Size(); - Reserve(_size + size); + const unsigned size = v.Size(); if (size != 0) + { + if (_size >= k_VectorSizeMax || size > k_VectorSizeMax - _size) + throw 2021; + const unsigned newSize = _size + size; + Reserve(newSize); memcpy(_items + _size, v._items, (size_t)size * sizeof(T)); - _size += size; + _size = newSize; + } return *this; } unsigned Add(const T item) { ReserveOnePosition(); - _items[_size] = item; - return _size++; + const unsigned size = _size; + _size = size + 1; + _items[size] = item; + return size; } - void AddInReserved(const T item) + /* + unsigned Add2(const T &item) { - _items[_size++] = item; + ReserveOnePosition(); + const unsigned size = _size; + _size = size + 1; + _items[size] = item; + return size; + } + */ + + unsigned AddInReserved(const T item) + { + const unsigned size = _size; + _size = size + 1; + _items[size] = item; + return size; } void Insert(unsigned index, const T item) @@ -216,6 +247,13 @@ public: _size++; } + void InsertInReserved(unsigned index, const T item) + { + MoveItems(index + 1, index); + _items[index] = item; + _size++; + } + void MoveToFront(unsigned index) { if (index != 0) @@ -228,10 +266,12 @@ public: const T& operator[](unsigned index) const { return _items[index]; } T& operator[](unsigned index) { return _items[index]; } + const T& operator[](int index) const { return _items[(unsigned)index]; } + T& operator[](int index) { return _items[(unsigned)index]; } const T& Front() const { return _items[0]; } T& Front() { return _items[0]; } - const T& Back() const { return _items[_size - 1]; } - T& Back() { return _items[_size - 1]; } + const T& Back() const { return _items[(size_t)_size - 1]; } + T& Back() { return _items[(size_t)_size - 1]; } /* void Swap(unsigned i, unsigned j) @@ -246,10 +286,11 @@ public: { while (left != right) { - unsigned mid = (left + right) / 2; + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; const T midVal = (*this)[mid]; if (item == midVal) - return mid; + return (int)mid; if (item < midVal) right = mid; else @@ -262,11 +303,12 @@ public: { while (left != right) { - unsigned mid = (left + right) / 2; + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); + const int comp = item.Compare(midVal); if (comp == 0) - return mid; + return (int)mid; if (comp < 0) right = mid; else @@ -290,7 +332,8 @@ public: unsigned left = 0, right = _size; while (left != right) { - unsigned mid = (left + right) / 2; + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; const T midVal = (*this)[mid]; if (item == midVal) return mid; @@ -308,9 +351,10 @@ public: unsigned left = 0, right = _size; while (left != right) { - unsigned mid = (left + right) / 2; + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); + const int comp = item.Compare(midVal); if (comp == 0) return mid; if (comp < 0) @@ -370,7 +414,7 @@ public: unsigned s = (k << 1); if (s > size) break; - if (s < size && p[s + 1].Compare(p[s]) > 0) + if (s < size && p[(size_t)s + 1].Compare(p[s]) > 0) s++; if (temp.Compare(p[s]) >= 0) break; @@ -420,52 +464,83 @@ public: // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); } void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); } - CObjectVector() {}; + CObjectVector() {} CObjectVector(const CObjectVector &v) { - unsigned size = v.Size(); + const unsigned size = v.Size(); _v.ConstructReserve(size); for (unsigned i = 0; i < size; i++) - _v.AddInReserved(new T(v[i])); + AddInReserved(v[i]); } CObjectVector& operator=(const CObjectVector &v) { if (&v == this) return *this; Clear(); - unsigned size = v.Size(); + const unsigned size = v.Size(); _v.Reserve(size); for (unsigned i = 0; i < size; i++) - _v.AddInReserved(new T(v[i])); + AddInReserved(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])); + const unsigned addSize = v.Size(); + if (addSize != 0) + { + const unsigned size = Size(); + if (size >= k_VectorSizeMax || addSize > k_VectorSizeMax - size) + throw 2021; + _v.Reserve(size + addSize); + for (unsigned i = 0; i < addSize; i++) + AddInReserved(v[i]); + } return *this; } const T& operator[](unsigned index) const { return *((T *)_v[index]); } T& operator[](unsigned index) { return *((T *)_v[index]); } + const T& operator[](int index) const { return *((T *)_v[(unsigned)index]); } + T& operator[](int index) { return *((T *)_v[(unsigned)index]); } const T& Front() const { return operator[](0); } T& Front() { return operator[](0); } - const T& Back() const { return operator[](_v.Size() - 1); } - T& Back() { return operator[](_v.Size() - 1); } + 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)); } + unsigned Add(const T& item) + { + _v.ReserveOnePosition(); + return AddInReserved(item); + } + + unsigned AddInReserved(const T& item) + { + return _v.AddInReserved(new T(item)); + } + + void ReserveOnePosition() + { + _v.ReserveOnePosition(); + } + + unsigned AddInReserved_Ptr_of_new(T *ptr) + { + return _v.AddInReserved(ptr); + } + + #define VECTOR_ADD_NEW_OBJECT(v, a) \ + (v).ReserveOnePosition(); \ + (v).AddInReserved_Ptr_of_new(new a); - void AddInReserved(const T& item) { _v.AddInReserved(new T(item)); } T& AddNew() { + _v.ReserveOnePosition(); T *p = new T; - _v.Add(p); + _v.AddInReserved(p); return *p; } @@ -476,12 +551,17 @@ public: return *p; } - void Insert(unsigned index, const T& item) { _v.Insert(index, new T(item)); } + void Insert(unsigned index, const T& item) + { + _v.ReserveOnePosition(); + _v.InsertInReserved(index, new T(item)); + } T& InsertNew(unsigned index) { + _v.ReserveOnePosition(); T *p = new T; - _v.Insert(index, p); + _v.InsertInReserved(index, p); return *p; } @@ -506,7 +586,7 @@ public: void DeleteFrom(unsigned index) { - unsigned size = _v.Size(); + const unsigned size = _v.Size(); for (unsigned i = index; i < size; i++) delete (T *)_v[i]; _v.DeleteFrom(index); @@ -521,7 +601,7 @@ public: void DeleteBack() { - delete (T *)_v[_v.Size() - 1]; + delete (T *)_v.Back(); _v.DeleteBack(); } @@ -530,6 +610,7 @@ public: delete (T *)_v[index]; _v.Delete(index); } + // void Delete(int index) { Delete((unsigned)index); } /* void Delete(unsigned index, unsigned num) @@ -556,11 +637,12 @@ public: unsigned left = 0, right = Size(); while (left != right) { - unsigned mid = (left + right) / 2; + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); + const int comp = item.Compare(midVal); if (comp == 0) - return mid; + return (int)mid; if (comp < 0) right = mid; else @@ -574,9 +656,10 @@ public: unsigned left = 0, right = Size(); while (left != right) { - unsigned mid = (left + right) / 2; + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); + const int comp = item.Compare(midVal); if (comp == 0) return mid; if (comp < 0) @@ -594,9 +677,10 @@ public: unsigned left = 0, right = Size(); while (left != right) { - unsigned mid = (left + right) / 2; + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); + const int comp = item.Compare(midVal); if (comp == 0) { right = mid + 1; @@ -616,9 +700,9 @@ public: { _v.Sort(compare, param); } static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */) - { return (*(*((const T **)a1))).Compare(*(*((const T **)a2))); } + { return (*(*((const T *const *)a1))).Compare(*(*((const T *const *)a2))); } - void Sort() { _v.Sort(CompareObjectItems, 0); } + void Sort() { _v.Sort(CompareObjectItems, NULL); } }; #define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++) diff --git a/3rdparty/lzma/CPP/Common/MyWindows.cpp b/3rdparty/lzma/CPP/Common/MyWindows.cpp index 463c77c4a37..ae284ebcb4e 100644 --- a/3rdparty/lzma/CPP/Common/MyWindows.cpp +++ b/3rdparty/lzma/CPP/Common/MyWindows.cpp @@ -5,6 +5,10 @@ #ifndef _WIN32 #include <stdlib.h> +#include <time.h> +#ifdef __GNUC__ +#include <sys/time.h> +#endif #include "MyWindows.h" @@ -38,11 +42,11 @@ 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))) + if (len >= (k_BstrSize_Max - (UINT)sizeof(OLECHAR) - (UINT)sizeof(OLECHAR) - (UINT)sizeof(CBstrSizeType))) return NULL; - UINT size = (len + sizeof(OLECHAR) + sizeof(OLECHAR) - 1) & ~(sizeof(OLECHAR) - 1); - void *p = AllocateForBSTR(size + sizeof(CBstrSizeType)); + UINT size = (len + (UINT)sizeof(OLECHAR) + (UINT)sizeof(OLECHAR) - 1) & ~((UINT)sizeof(OLECHAR) - 1); + void *p = AllocateForBSTR(size + (UINT)sizeof(CBstrSizeType)); if (!p) return NULL; *(CBstrSizeType *)p = (CBstrSizeType)len; @@ -56,11 +60,11 @@ BSTR SysAllocStringByteLen(LPCSTR s, UINT len) BSTR SysAllocStringLen(const OLECHAR *s, UINT len) { - if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(CBstrSizeType)) / sizeof(OLECHAR)) + if (len >= (k_BstrSize_Max - (UINT)sizeof(OLECHAR) - (UINT)sizeof(CBstrSizeType)) / (UINT)sizeof(OLECHAR)) return NULL; - UINT size = len * sizeof(OLECHAR); - void *p = AllocateForBSTR(size + sizeof(CBstrSizeType) + sizeof(OLECHAR)); + UINT size = len * (UINT)sizeof(OLECHAR); + void *p = AllocateForBSTR(size + (UINT)sizeof(CBstrSizeType) + (UINT)sizeof(OLECHAR)); if (!p) return NULL; *(CBstrSizeType *)p = (CBstrSizeType)size; @@ -74,7 +78,7 @@ BSTR SysAllocStringLen(const OLECHAR *s, UINT len) BSTR SysAllocString(const OLECHAR *s) { if (!s) - return 0; + return NULL; const OLECHAR *s2 = s; while (*s2 != 0) s2++; @@ -98,7 +102,7 @@ UINT SysStringLen(BSTR bstr) { if (!bstr) return 0; - return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR); + return *((CBstrSizeType *)bstr - 1) / (UINT)sizeof(OLECHAR); } @@ -139,7 +143,150 @@ LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2) DWORD GetLastError() { - return 0; + return (DWORD)errno; +} + +void SetLastError(DWORD dw) +{ + errno = (int)dw; +} + + +static LONG TIME_GetBias() +{ + time_t utc = time(NULL); + struct tm *ptm = localtime(&utc); + int localdaylight = ptm->tm_isdst; /* daylight for local timezone */ + ptm = gmtime(&utc); + ptm->tm_isdst = localdaylight; /* use local daylight, not that of Greenwich */ + LONG bias = (int)(mktime(ptm)-utc); + return bias; +} + +#define TICKS_PER_SEC 10000000 +/* +#define SECS_PER_DAY (24 * 60 * 60) +#define SECS_1601_TO_1970 ((369 * 365 + 89) * (UInt64)SECS_PER_DAY) +#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKS_PER_SEC) +*/ + +#define GET_TIME_64(pft) ((pft)->dwLowDateTime | ((UInt64)(pft)->dwHighDateTime << 32)) + +#define SET_FILETIME(ft, v64) \ + (ft)->dwLowDateTime = (DWORD)v64; \ + (ft)->dwHighDateTime = (DWORD)(v64 >> 32); + + +BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *fileTime, FILETIME *localFileTime) +{ + UInt64 v = GET_TIME_64(fileTime); + v = (UInt64)((Int64)v - (Int64)TIME_GetBias() * TICKS_PER_SEC); + SET_FILETIME(localFileTime, v) + return TRUE; +} + +BOOL WINAPI LocalFileTimeToFileTime(const FILETIME *localFileTime, FILETIME *fileTime) +{ + UInt64 v = GET_TIME_64(localFileTime); + v = (UInt64)((Int64)v + (Int64)TIME_GetBias() * TICKS_PER_SEC); + SET_FILETIME(fileTime, v) + return TRUE; +} + +/* +VOID WINAPI GetSystemTimeAsFileTime(FILETIME *ft) +{ + UInt64 t = 0; + timeval tv; + if (gettimeofday(&tv, NULL) == 0) + { + t = tv.tv_sec * (UInt64)TICKS_PER_SEC + TICKS_1601_TO_1970; + t += tv.tv_usec * 10; + } + SET_FILETIME(ft, t) +} +*/ + +DWORD WINAPI GetTickCount(VOID) +{ + #ifndef _WIN32 + // gettimeofday() doesn't work in some MINGWs by unknown reason + timeval tv; + if (gettimeofday(&tv, NULL) == 0) + { + // tv_sec and tv_usec are (long) + return (DWORD)((UInt64)(Int64)tv.tv_sec * (UInt64)1000 + (UInt64)(Int64)tv.tv_usec / 1000); + } + #endif + return (DWORD)time(NULL) * 1000; +} + + +#define PERIOD_4 (4 * 365 + 1) +#define PERIOD_100 (PERIOD_4 * 25 - 1) +#define PERIOD_400 (PERIOD_100 * 4 + 1) + +BOOL WINAPI FileTimeToSystemTime(const FILETIME *ft, SYSTEMTIME *st) +{ + UInt32 v; + UInt64 v64 = GET_TIME_64(ft); + v64 /= 10000; + st->wMilliseconds = (WORD)(v64 % 1000); v64 /= 1000; + st->wSecond = (WORD)(v64 % 60); v64 /= 60; + st->wMinute = (WORD)(v64 % 60); v64 /= 60; + v = (UInt32)v64; + st->wHour = (WORD)(v % 24); v /= 24; + + // 1601-01-01 was Monday + st->wDayOfWeek = (WORD)((v + 1) % 7); + + UInt32 leaps, year, day, mon; + leaps = (3 * ((4 * v + (365 - 31 - 28) * 4 + 3) / PERIOD_400) + 3) / 4; + v += 28188 + leaps; + // leaps - the number of exceptions from PERIOD_4 rules starting from 1600-03-01 + // (1959 / 64) - converts day from 03-01 to month + year = (20 * v - 2442) / (5 * PERIOD_4); + day = v - (year * PERIOD_4) / 4; + mon = (64 * day) / 1959; + st->wDay = (WORD)(day - (1959 * mon) / 64); + mon -= 1; + year += 1524; + if (mon > 12) + { + mon -= 12; + year++; + } + st->wMonth = (WORD)mon; + st->wYear = (WORD)year; + + /* + unsigned year, mon; + unsigned char ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + unsigned t; + + year = (WORD)(1601 + v / PERIOD_400 * 400); + v %= PERIOD_400; + + t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100; + t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4; + t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365; + + st->wYear = (WORD)year; + + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ms[1] = 29; + for (mon = 0;; mon++) + { + unsigned d = ms[mon]; + if (v < d) + break; + v -= d; + } + st->wDay = (WORD)(v + 1); + st->wMonth = (WORD)(mon + 1); + */ + + return TRUE; } #endif diff --git a/3rdparty/lzma/CPP/Common/MyWindows.h b/3rdparty/lzma/CPP/Common/MyWindows.h index 139a4e8b976..a76e14b749f 100644 --- a/3rdparty/lzma/CPP/Common/MyWindows.h +++ b/3rdparty/lzma/CPP/Common/MyWindows.h @@ -1,24 +1,36 @@ // MyWindows.h -#ifndef __MY_WINDOWS_H -#define __MY_WINDOWS_H +#ifdef Z7_DEFINE_GUID +#undef Z7_DEFINE_GUID +#endif -#ifdef _WIN32 +#ifdef INITGUID + #define Z7_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + EXTERN_C const GUID name; \ + EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else + #define Z7_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + EXTERN_C const GUID name +#endif -#include <windows.h> -#ifdef UNDER_CE - #undef VARIANT_TRUE - #define VARIANT_TRUE ((VARIANT_BOOL)-1) -#endif +#ifndef ZIP7_INC_MY_WINDOWS_H +#define ZIP7_INC_MY_WINDOWS_H -#else +#ifdef _WIN32 + +#include "../../C/7zWindows.h" + +#else // _WIN32 #include <stddef.h> // for wchar_t #include <string.h> +// #include <stdint.h> // for uintptr_t +#include "../../C/7zTypes.h" #include "MyGuidDef.h" +// WINAPI is __stdcall in Windows-MSVC in windef.h #define WINAPI typedef char CHAR; @@ -34,15 +46,22 @@ typedef unsigned short USHORT; 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; +#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xffff)) +#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) + +// MS uses long for BOOL, but long is 32-bit in MS. So we use int. +// typedef long BOOL; +typedef int BOOL; + +#ifndef FALSE + #define FALSE 0 + #define TRUE 1 +#endif -#undef DWORD -typedef UINT32 DWORD; +// 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; @@ -66,53 +85,105 @@ typedef struct _FILETIME DWORD dwHighDateTime; } FILETIME; -#define HRESULT LONG -#define FAILED(Status) ((HRESULT)(Status)<0) +#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) +#define FAILED(hr) ((HRESULT)(hr) < 0) typedef ULONG PROPID; typedef LONG SCODE; + #define S_OK ((HRESULT)0x00000000L) #define S_FALSE ((HRESULT)0x00000001L) -#define E_NOTIMPL ((HRESULT)0x80004001L) +#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) +#define E_ABORT ((HRESULT)0x80004004L) +#define E_FAIL ((HRESULT)0x80004005L) +#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L) +#define CLASS_E_CLASSNOTAVAILABLE ((HRESULT)0x80040111L) + #ifdef _MSC_VER #define STDMETHODCALLTYPE __stdcall +#define STDAPICALLTYPE __stdcall #else +// do we need __export here? #define STDMETHODCALLTYPE +#define STDAPICALLTYPE +#endif + +#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE + +#ifndef DECLSPEC_NOTHROW +#define DECLSPEC_NOTHROW Z7_DECLSPEC_NOTHROW +#endif + +#ifndef DECLSPEC_NOVTABLE +#define DECLSPEC_NOVTABLE Z7_DECLSPEC_NOVTABLE +#endif + +#ifndef COM_DECLSPEC_NOTHROW +#ifdef COM_STDMETHOD_CAN_THROW + #define COM_DECLSPEC_NOTHROW +#else + #define COM_DECLSPEC_NOTHROW DECLSPEC_NOTHROW +#endif #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 DECLARE_INTERFACE(iface) struct DECLSPEC_NOVTABLE iface +#define DECLARE_INTERFACE_(iface, baseiface) struct DECLSPEC_NOVTABLE iface : public baseiface + +#define STDMETHOD_(t, f) virtual COM_DECLSPEC_NOTHROW t STDMETHODCALLTYPE f +#define STDMETHOD(f) STDMETHOD_(HRESULT, f) +#define STDMETHODIMP_(t) COM_DECLSPEC_NOTHROW t STDMETHODCALLTYPE +#define STDMETHODIMP STDMETHODIMP_(HRESULT) + #define PURE = 0 -#define MIDL_INTERFACE(x) struct +// #define MIDL_INTERFACE(x) struct + #ifdef __cplusplus +/* + p7zip and 7-Zip before v23 used virtual destructor in IUnknown, + if _WIN32 is not defined. + It used virtual destructor, because some compilers don't like virtual + interfaces without virtual destructor. + IUnknown in Windows (_WIN32) doesn't use virtual destructor in IUnknown. + We still can define Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN here, + if we want to be compatible with old plugin interface of p7zip and 7-Zip before v23. + +v23: + In new 7-Zip v23 we try to be more compatible with original IUnknown from _WIN32. + So we do not define Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN here, +*/ +// #define Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN + +#ifdef Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" +#endif +#endif + +Z7_PURE_INTERFACES_BEGIN + 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 + STDMETHOD(QueryInterface) (REFIID iid, void **outObject) =0; + STDMETHOD_(ULONG, AddRef)() =0; + STDMETHOD_(ULONG, Release)() =0; + #ifdef Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN virtual ~IUnknown() {} - #endif + #endif }; typedef IUnknown *LPUNKNOWN; -#endif +Z7_PURE_INTERFACES_END + +#endif // __cplusplus #define VARIANT_TRUE ((VARIANT_BOOL)-1) #define VARIANT_FALSE ((VARIANT_BOOL)0) @@ -134,6 +205,7 @@ enum VARENUM VT_VARIANT = 12, VT_UNKNOWN = 13, VT_DECIMAL = 14, + VT_I1 = 16, VT_UI1 = 17, VT_UI2 = 18, @@ -181,8 +253,8 @@ 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); +EXTERN_C HRESULT VariantClear(VARIANTARG *prop); +EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src); typedef struct tagSTATPROPSTG { @@ -191,15 +263,21 @@ typedef struct tagSTATPROPSTG 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); +EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len); +EXTERN_C BSTR SysAllocStringLen(const OLECHAR *sz, UINT len); +EXTERN_C BSTR SysAllocString(const OLECHAR *sz); +EXTERN_C void SysFreeString(BSTR bstr); +EXTERN_C UINT SysStringByteLen(BSTR bstr); +EXTERN_C UINT SysStringLen(BSTR bstr); + +EXTERN_C DWORD GetLastError(); +EXTERN_C void SetLastError(DWORD dwCode); +EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); + +EXTERN_C DWORD GetCurrentThreadId(); +EXTERN_C DWORD GetCurrentProcessId(); -MY_EXTERN_C DWORD GetLastError(); -MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); +#define MAX_PATH 1024 #define CP_ACP 0 #define CP_OEMCP 1 @@ -212,5 +290,35 @@ typedef enum tagSTREAM_SEEK STREAM_SEEK_END = 2 } STREAM_SEEK; -#endif + + +typedef struct _SYSTEMTIME +{ + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; +} SYSTEMTIME; + +BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *fileTime, FILETIME *localFileTime); +BOOL WINAPI LocalFileTimeToFileTime(const FILETIME *localFileTime, FILETIME *fileTime); +BOOL WINAPI FileTimeToSystemTime(const FILETIME *fileTime, SYSTEMTIME *systemTime); +// VOID WINAPI GetSystemTimeAsFileTime(FILETIME *systemTimeAsFileTime); + +DWORD GetTickCount(); + + +#define CREATE_NEW 1 +#define CREATE_ALWAYS 2 +#define OPEN_EXISTING 3 +#define OPEN_ALWAYS 4 +#define TRUNCATE_EXISTING 5 + + +#endif // _WIN32 + #endif diff --git a/3rdparty/lzma/CPP/Common/NewHandler.cpp b/3rdparty/lzma/CPP/Common/NewHandler.cpp index 522c2a75390..c95833e5f2e 100644 --- a/3rdparty/lzma/CPP/Common/NewHandler.cpp +++ b/3rdparty/lzma/CPP/Common/NewHandler.cpp @@ -10,21 +10,23 @@ #ifndef DEBUG_MEMORY_LEAK -#ifdef _WIN32 +#ifdef Z7_REDEFINE_OPERATOR_NEW /* void * my_new(size_t size) { // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + if (size == 0) + size = 1; void *p = ::malloc(size); - if (p == 0) + if (!p) throw CNewException(); return p; } void my_delete(void *p) throw() { - // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p); + // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p); ::free(p); } @@ -44,9 +46,21 @@ __cdecl #endif operator new(size_t size) { + /* by C++ specification: + if (size == 0), operator new(size) returns non_NULL pointer. + If (operator new(0) returns NULL), it's out of specification. + but some calling code can work correctly even in this case too. */ + // if (size == 0) return NULL; // for debug only. don't use it + + /* malloc(0) returns non_NULL in main compilers, as we need here. + But specification also allows malloc(0) to return NULL. + So we change (size=0) to (size=1) here to get real non_NULL pointer */ + if (size == 0) + size = 1; // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + // void *p = ::MyAlloc(size); // note: MyAlloc(0) returns NULL void *p = ::malloc(size); - if (p == 0) + if (!p) throw CNewException(); return p; } @@ -57,7 +71,8 @@ __cdecl #endif operator delete(void *p) throw() { - // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p); + // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p); + // MyFree(p); ::free(p); } @@ -69,8 +84,10 @@ __cdecl operator new[](size_t size) { // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + if (size == 0) + size = 1; void *p = ::malloc(size); - if (p == 0) + if (!p) throw CNewException(); return p; } @@ -81,7 +98,7 @@ __cdecl #endif operator delete[](void *p) throw() { - // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p); + // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p); ::free(p); } */ @@ -93,25 +110,10 @@ operator delete[](void *p) throw() #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; -} +static int g_index = 0; class CC { @@ -123,26 +125,159 @@ public: } ~CC() { + printf("\nDestructor: %d\n", numAllocs); for (int i = 0; i < kDebugSize; i++) if (a[i] != 0) return; } } g_CC; +*/ + +#ifdef _WIN32 +static bool wasInit = false; +static CRITICAL_SECTION cs; +#endif + +static int numAllocs = 0; + +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new(size_t size) +{ + #ifdef _WIN32 + if (!wasInit) + { + InitializeCriticalSection(&cs); + wasInit = true; + } + EnterCriticalSection(&cs); + numAllocs++; + int loc = numAllocs; + void *p = HeapAlloc(GetProcessHeap(), 0, size); + /* + if (g_index < kDebugSize) + { + a[g_index] = p; + g_index++; + } + */ + printf("Alloc %6d, size = %8u\n", loc, (unsigned)size); + LeaveCriticalSection(&cs); + if (!p) + throw CNewException(); + return p; + #else + numAllocs++; + int loc = numAllocs; + if (size == 0) + size = 1; + void *p = malloc(size); + /* + if (g_index < kDebugSize) + { + a[g_index] = p; + g_index++; + } + */ + printf("Alloc %6d, size = %8u\n", loc, (unsigned)size); + if (!p) + throw CNewException(); + return p; + #endif +} -void __cdecl operator delete(void *p) +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw() { - if (p == 0) + if (!p) return; + #ifdef _WIN32 + EnterCriticalSection(&cs); /* - for (int i = 0; i < index; i++) + for (int i = 0; i < g_index; i++) if (a[i] == p) a[i] = 0; */ HeapFree(GetProcessHeap(), 0, p); + if (numAllocs == 0) + numAllocs = numAllocs; // ERROR + numAllocs--; + if (numAllocs == 0) + numAllocs = numAllocs; // OK: all objects were deleted + printf("Free %d\n", numAllocs); + LeaveCriticalSection(&cs); + #else + free(p); numAllocs--; printf("Free %d\n", numAllocs); + #endif +} + +/* +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new[](size_t size) +{ + printf("operator_new[] : "); + return operator new(size); +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t sz) throw(); + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t sz) throw() +{ + if (!p) + return; + printf("operator_delete_size : size=%d : ", (unsigned)sz); + operator delete(p); +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p) throw() +{ + if (!p) + return; + printf("operator_delete[] : "); + operator delete(p); +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p, size_t sz) throw(); + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p, size_t sz) throw() +{ + if (!p) + return; + printf("operator_delete_size[] : size=%d : ", (unsigned)sz); + operator delete(p); } +*/ #endif diff --git a/3rdparty/lzma/CPP/Common/NewHandler.h b/3rdparty/lzma/CPP/Common/NewHandler.h index dcad56886db..50f6d0a8fc8 100644 --- a/3rdparty/lzma/CPP/Common/NewHandler.h +++ b/3rdparty/lzma/CPP/Common/NewHandler.h @@ -1,31 +1,42 @@ // Common/NewHandler.h -#ifndef __COMMON_NEW_HANDLER_H -#define __COMMON_NEW_HANDLER_H +#ifndef ZIP7_INC_COMMON_NEW_HANDLER_H +#define ZIP7_INC_COMMON_NEW_HANDLER_H /* -This file must be included before any code that uses operators "delete" or "new". -Also you must compile and link "NewHandler.cpp", if you use MSVC 6.0. -The operator "new" in MSVC 6.0 doesn't throw exception "bad_alloc". -So we define another version of operator "new" that throws "CNewException" on failure. +NewHandler.h and NewHandler.cpp allows to solve problem with compilers that +don't throw exception in operator new(). -If you use compiler that throws exception in "new" operator (GCC or new version of MSVC), -you can compile without "NewHandler.cpp". So standard exception "bad_alloc" will be used. +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. -It's still allowed to use redefined version of operator "new" from "NewHandler.cpp" -with any compiler. 7-Zip's code can work with "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" (that throws CNewException) is not -problem for your code. +DOCs: + Since ISO C++98, operator new throws std::bad_alloc when memory allocation fails. + MSVC 6.0 returned a null pointer on an allocation failure. + Beginning in VS2002, operator new conforms to the standard and throws on failure. + + By default, the compiler also generates defensive null checks to prevent + these older-style allocators from causing an immediate crash on failure. + The /Zc:throwingNew option tells the compiler to leave out these null checks, + on the assumption that all linked memory allocators conform to the standard. + +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. -Also we declare delete(void *p) throw() that creates smaller code. +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> -class CNewException {}; - -#ifdef WIN32 +#ifdef _WIN32 // We can compile my_new and my_delete with _fastcall /* void * my_new(size_t size); @@ -34,7 +45,19 @@ void my_delete(void *p) throw(); */ #endif -#ifdef _WIN32 + +#if defined(_MSC_VER) && (_MSC_VER < 1600) + // If you want to use default operator new(), you can disable the following line + #define Z7_REDEFINE_OPERATOR_NEW +#endif + + +#ifdef Z7_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 @@ -48,6 +71,12 @@ __cdecl #endif operator delete(void *p) throw(); +#else + +#include <new> + +#define CNewException std::bad_alloc + #endif /* diff --git a/3rdparty/lzma/CPP/Common/Sha256Prepare.cpp b/3rdparty/lzma/CPP/Common/Sha256Prepare.cpp new file mode 100644 index 00000000000..1ec242b5772 --- /dev/null +++ b/3rdparty/lzma/CPP/Common/Sha256Prepare.cpp @@ -0,0 +1,7 @@ +// Sha256Prepare.cpp + +#include "StdAfx.h" + +#include "../../C/Sha256.h" + +static struct CSha256Prepare { CSha256Prepare() { Sha256Prepare(); } } g_Sha256Prepare; diff --git a/3rdparty/lzma/CPP/Common/Sha256Reg.cpp b/3rdparty/lzma/CPP/Common/Sha256Reg.cpp index 66941699e61..b5689c42d49 100644 --- a/3rdparty/lzma/CPP/Common/Sha256Reg.cpp +++ b/3rdparty/lzma/CPP/Common/Sha256Reg.cpp @@ -4,37 +4,64 @@ #include "../../C/Sha256.h" +#include "../Common/MyBuffer2.h" #include "../Common/MyCom.h" #include "../7zip/Common/RegisterCodec.h" -class CSha256Hasher: - public IHasher, - public CMyUnknownImp -{ - CSha256 _sha; - Byte mtDummy[1 << 7]; - +Z7_CLASS_IMP_COM_2( + CSha256Hasher + , IHasher + , ICompressSetCoderProperties +) + CAlignedBuffer1 _buf; public: - CSha256Hasher() { Sha256_Init(&_sha); } + Byte _mtDummy[1 << 7]; - MY_UNKNOWN_IMP1(IHasher) - INTERFACE_IHasher(;) + CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_buf; } +public: + CSha256Hasher(): + _buf(sizeof(CSha256)) + { + Sha256_SetFunction(Sha(), 0); + Sha256_InitState(Sha()); + } }; -STDMETHODIMP_(void) CSha256Hasher::Init() throw() +Z7_COM7F_IMF2(void, CSha256Hasher::Init()) { - Sha256_Init(&_sha); + Sha256_InitState(Sha()); } -STDMETHODIMP_(void) CSha256Hasher::Update(const void *data, UInt32 size) throw() +Z7_COM7F_IMF2(void, CSha256Hasher::Update(const void *data, UInt32 size)) { - Sha256_Update(&_sha, (const Byte *)data, size); + Sha256_Update(Sha(), (const Byte *)data, size); } -STDMETHODIMP_(void) CSha256Hasher::Final(Byte *digest) throw() +Z7_COM7F_IMF2(void, CSha256Hasher::Final(Byte *digest)) +{ + Sha256_Final(Sha(), digest); +} + + +Z7_COM7F_IMF(CSha256Hasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) { - Sha256_Final(&_sha, digest); + unsigned algo = 0; + for (UInt32 i = 0; i < numProps; i++) + { + if (propIDs[i] == NCoderPropID::kDefaultProp) + { + const PROPVARIANT &prop = coderProps[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + if (prop.ulVal > 2) + return E_NOTIMPL; + algo = (unsigned)prop.ulVal; + } + } + if (!Sha256_SetFunction(Sha(), algo)) + return E_NOTIMPL; + return S_OK; } REGISTER_HASHER(CSha256Hasher, 0xA, "SHA256", SHA256_DIGEST_SIZE) diff --git a/3rdparty/lzma/CPP/Common/StdAfx.h b/3rdparty/lzma/CPP/Common/StdAfx.h index 420f5c3267f..a5228b0a669 100644 --- a/3rdparty/lzma/CPP/Common/StdAfx.h +++ b/3rdparty/lzma/CPP/Common/StdAfx.h @@ -1,7 +1,7 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H #include "Common.h" diff --git a/3rdparty/lzma/CPP/Common/StdInStream.cpp b/3rdparty/lzma/CPP/Common/StdInStream.cpp index c35747bbe69..7b209f1ca75 100644 --- a/3rdparty/lzma/CPP/Common/StdInStream.cpp +++ b/3rdparty/lzma/CPP/Common/StdInStream.cpp @@ -2,28 +2,34 @@ #include "StdAfx.h" +#ifdef _WIN32 #include <tchar.h> +#endif #include "StdInStream.h" #include "StringConvert.h" #include "UTFConvert.h" -static const char kNewLineChar = '\n'; +// #define kEOFMessage "Unexpected end of input stream" +// #define kReadErrorMessage "Error reading input stream" +// #define kIllegalCharMessage "Illegal zero character in input stream" -static const char *kEOFMessage = "Unexpected end of input stream"; -static const char *kReadErrorMessage ="Error reading input stream"; -static const char *kIllegalCharMessage = "Illegal character in input stream"; - -static LPCTSTR kFileOpenMode = TEXT("r"); - -extern int g_CodePage; CStdInStream g_StdIn(stdin); +/* +#define kFileOpenMode TEXT("r") + bool CStdInStream::Open(LPCTSTR fileName) throw() { Close(); - _stream = _tfopen(fileName, kFileOpenMode); + _stream = + #ifdef _WIN32 + _tfopen + #else + fopen + #endif + (fileName, kFileOpenMode); _streamIsOpen = (_stream != 0); return _streamIsOpen; } @@ -35,60 +41,58 @@ bool CStdInStream::Close() throw() _streamIsOpen = (fclose(_stream) != 0); return !_streamIsOpen; } +*/ -AString CStdInStream::ScanStringUntilNewLine(bool allowEOF) +bool CStdInStream::ScanAStringUntilNewLine(AString &s) { - AString s; + s.Empty(); for (;;) { int intChar = GetChar(); if (intChar == EOF) - { - if (allowEOF) - break; - throw kEOFMessage; - } + return true; char c = (char)intChar; if (c == 0) - throw kIllegalCharMessage; - if (c == kNewLineChar) - break; + return false; + if (c == '\n') + return true; s += c; } - return s; } -UString CStdInStream::ScanUStringUntilNewLine() +bool CStdInStream::ScanUStringUntilNewLine(UString &dest) { - AString s = ScanStringUntilNewLine(true); - int codePage = g_CodePage; + dest.Empty(); + AString s; + bool res = ScanAStringUntilNewLine(s); + int codePage = CodePage; if (codePage == -1) codePage = CP_OEMCP; - UString dest; if (codePage == CP_UTF8) ConvertUTF8ToUnicode(s, dest); else - dest = MultiByteToUnicodeString(s, (UINT)codePage); - return dest; + MultiByteToUnicodeString2(dest, s, (UINT)codePage); + return res; } -void CStdInStream::ReadToString(AString &resultString) +/* +bool CStdInStream::ReadToString(AString &resultString) { resultString.Empty(); - int c; - while ((c = GetChar()) != EOF) - resultString += (char)c; -} - -bool CStdInStream::Eof() throw() -{ - return (feof(_stream) != 0); + for (;;) + { + int intChar = GetChar(); + if (intChar == EOF) + return !Error(); + char c = (char)intChar; + if (c == 0) + return false; + resultString += c; + } } +*/ int CStdInStream::GetChar() { - int c = fgetc(_stream); // getc() doesn't work in BeOS? - if (c == EOF && !Eof()) - throw kReadErrorMessage; - return c; + return fgetc(_stream); // getc() doesn't work in BeOS? } diff --git a/3rdparty/lzma/CPP/Common/StdInStream.h b/3rdparty/lzma/CPP/Common/StdInStream.h index 6d9ed67040d..81ca3bf6f5d 100644 --- a/3rdparty/lzma/CPP/Common/StdInStream.h +++ b/3rdparty/lzma/CPP/Common/StdInStream.h @@ -1,7 +1,7 @@ // Common/StdInStream.h -#ifndef __COMMON_STD_IN_STREAM_H -#define __COMMON_STD_IN_STREAM_H +#ifndef ZIP7_INC_COMMON_STD_IN_STREAM_H +#define ZIP7_INC_COMMON_STD_IN_STREAM_H #include <stdio.h> @@ -11,20 +11,33 @@ class CStdInStream { FILE *_stream; - bool _streamIsOpen; + // bool _streamIsOpen; public: - CStdInStream(): _stream(0), _streamIsOpen(false) {}; - CStdInStream(FILE *stream): _stream(stream), _streamIsOpen(false) {}; + int CodePage; + + CStdInStream(FILE *stream = NULL): + _stream(stream), + // _streamIsOpen(false), + CodePage(-1) + {} + + /* ~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); - AString ScanStringUntilNewLine(bool allowEOF = false); - void ReadToString(AString &resultString); - UString ScanUStringUntilNewLine(); + bool Eof() const throw() { return (feof(_stream) != 0); } + bool Error() const throw() { return (ferror(_stream) != 0); } - bool Eof() throw(); int GetChar(); }; diff --git a/3rdparty/lzma/CPP/Common/StdOutStream.cpp b/3rdparty/lzma/CPP/Common/StdOutStream.cpp index 6aed31a3143..cfa5fdec678 100644 --- a/3rdparty/lzma/CPP/Common/StdOutStream.cpp +++ b/3rdparty/lzma/CPP/Common/StdOutStream.cpp @@ -2,22 +2,21 @@ #include "StdAfx.h" +#ifdef _WIN32 #include <tchar.h> +#endif #include "IntToString.h" #include "StdOutStream.h" #include "StringConvert.h" #include "UTFConvert.h" -static const char kNewLineChar = '\n'; - -static const char *kFileOpenMode = "wt"; - -extern int g_CodePage; - CStdOutStream g_StdOut(stdout); CStdOutStream g_StdErr(stderr); +/* +// #define kFileOpenMode "wt" + bool CStdOutStream::Open(const char *fileName) throw() { Close(); @@ -36,6 +35,7 @@ bool CStdOutStream::Close() throw() _streamIsOpen = false; return true; } +*/ bool CStdOutStream::Flush() throw() { @@ -44,39 +44,93 @@ bool CStdOutStream::Flush() throw() CStdOutStream & endl(CStdOutStream & outStream) throw() { - return outStream << kNewLineChar; + return outStream << '\n'; } CStdOutStream & CStdOutStream::operator<<(const wchar_t *s) { - int codePage = g_CodePage; + AString temp; + UString s2(s); + PrintUString(s2, temp); + return *this; +} + +void CStdOutStream::PrintUString(const UString &s, AString &temp) +{ + Convert_UString_to_AString(s, temp); + *this << (const char *)temp; +} + +void CStdOutStream::Convert_UString_to_AString(const UString &src, AString &dest) +{ + int codePage = CodePage; if (codePage == -1) codePage = CP_OEMCP; - AString dest; if (codePage == CP_UTF8) - ConvertUnicodeToUTF8(s, dest); + ConvertUnicodeToUTF8(src, dest); else - UnicodeStringToMultiByte2(dest, s, (UINT)codePage); - return operator<<((const char *)dest); + UnicodeStringToMultiByte2(dest, src, (UINT)codePage); } -void StdOut_Convert_UString_to_AString(const UString &s, AString &temp) + +static const wchar_t kReplaceChar = '_'; + +void CStdOutStream::Normalize_UString_LF_Allowed(UString &s) { - int codePage = g_CodePage; - if (codePage == -1) - codePage = CP_OEMCP; - if (codePage == CP_UTF8) - ConvertUnicodeToUTF8(s, temp); + 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 - UnicodeStringToMultiByte2(temp, s, (UINT)codePage); + for (unsigned i = 0; i < len; i++) + { + wchar_t c = d[i]; + if (c == '\n') + d[i] = kReplaceChar; + } } -void CStdOutStream::PrintUString(const UString &s, AString &temp) +void CStdOutStream::NormalizePrint_UString(const UString &s, UString &tempU, AString &tempA) { - StdOut_Convert_UString_to_AString(s, temp); - *this << (const char *)temp; + 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]; diff --git a/3rdparty/lzma/CPP/Common/StdOutStream.h b/3rdparty/lzma/CPP/Common/StdOutStream.h index 1837bfb0adc..bd15d7cb208 100644 --- a/3rdparty/lzma/CPP/Common/StdOutStream.h +++ b/3rdparty/lzma/CPP/Common/StdOutStream.h @@ -1,7 +1,7 @@ // Common/StdOutStream.h -#ifndef __COMMON_STD_OUT_STREAM_H -#define __COMMON_STD_OUT_STREAM_H +#ifndef ZIP7_INC_COMMON_STD_OUT_STREAM_H +#define ZIP7_INC_COMMON_STD_OUT_STREAM_H #include <stdio.h> @@ -11,18 +11,28 @@ class CStdOutStream { FILE *_stream; - bool _streamIsOpen; + // bool _streamIsOpen; public: - CStdOutStream(): _stream(0), _streamIsOpen(false) {}; - CStdOutStream(FILE *stream): _stream(stream), _streamIsOpen(false) {}; - ~CStdOutStream() { Close(); } + bool IsTerminalMode; + int CodePage; + + CStdOutStream(FILE *stream = NULL): + _stream(stream), + // _streamIsOpen(false), + IsTerminalMode(false), + CodePage(-1) + {} + + // ~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 &)) @@ -50,6 +60,14 @@ public: CStdOutStream & operator<<(const wchar_t *s); void PrintUString(const UString &s, AString &temp); + void Convert_UString_to_AString(const UString &src, AString &dest); + + 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(); @@ -57,6 +75,4 @@ 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/3rdparty/lzma/CPP/Common/StringConvert.cpp b/3rdparty/lzma/CPP/Common/StringConvert.cpp index 30d95aa7b56..f25396a6ab0 100644 --- a/3rdparty/lzma/CPP/Common/StringConvert.cpp +++ b/3rdparty/lzma/CPP/Common/StringConvert.cpp @@ -5,9 +5,18 @@ #include "StringConvert.h" #ifndef _WIN32 +// #include <stdio.h> #include <stdlib.h> #endif +#if !defined(_WIN32) || defined(ENV_HAVE_LOCALE) +#include "UTFConvert.h" +#endif + +#ifdef ENV_HAVE_LOCALE +#include <locale.h> +#endif + static const char k_DefultChar = '_'; #ifdef _WIN32 @@ -71,7 +80,7 @@ void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage) d[i] = 0; dest.ReleaseBuf_SetLen(i); */ - unsigned len = MultiByteToWideChar(codePage, 0, src, src.Len(), NULL, 0); + unsigned len = (unsigned)MultiByteToWideChar(codePage, 0, src, (int)src.Len(), NULL, 0); if (len == 0) { if (GetLastError() != 0) @@ -79,7 +88,7 @@ void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage) } else { - len = MultiByteToWideChar(codePage, 0, src, src.Len(), dest.GetBuf(len), len); + len = (unsigned)MultiByteToWideChar(codePage, 0, src, (int)src.Len(), dest.GetBuf(len), (int)len); if (len == 0) throw 282228; dest.ReleaseBuf_SetEnd(len); @@ -175,7 +184,7 @@ static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT co } */ - unsigned len = WideCharToMultiByte(codePage, 0, src, src.Len(), NULL, 0, NULL, NULL); + unsigned len = (unsigned)WideCharToMultiByte(codePage, 0, src, (int)src.Len(), NULL, 0, NULL, NULL); if (len == 0) { if (GetLastError() != 0) @@ -186,8 +195,8 @@ static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT co BOOL defUsed = FALSE; bool isUtf = (codePage == CP_UTF8 || codePage == CP_UTF7); // defaultChar = defaultChar; - len = WideCharToMultiByte(codePage, 0, src, src.Len(), - dest.GetBuf(len), len, + len = (unsigned)WideCharToMultiByte(codePage, 0, src, (int)src.Len(), + dest.GetBuf(len), (int)len, (isUtf ? NULL : &defaultChar), (isUtf ? NULL : &defUsed) ); @@ -213,23 +222,137 @@ AString SystemStringToOemString(const CSysString &src) #endif */ -#else +#else // _WIN32 + +// #include <stdio.h> +/* + if (wchar_t is 32-bit (#if WCHAR_MAX > 0xffff), + and utf-8 string contains big unicode character > 0xffff), + then we still use 16-bit surrogate pair in UString. + It simplifies another code where utf-16 encoding is used. + So we use surrogate-conversion code only in is file. +*/ + +/* + mbstowcs() returns error if there is error in utf-8 stream, + mbstowcs() returns error if there is single surrogates point (d800-dfff) in utf-8 stream +*/ + +/* +static void MultiByteToUnicodeString2_Native(UString &dest, const AString &src) +{ + dest.Empty(); + if (src.IsEmpty()) + return; + + const size_t limit = ((size_t)src.Len() + 1) * 2; + wchar_t *d = dest.GetBuf((unsigned)limit); + const size_t len = mbstowcs(d, src, limit); + if (len != (size_t)-1) + { + dest.ReleaseBuf_SetEnd((unsigned)len); + return; + } + dest.ReleaseBuf_SetEnd(0); +} +*/ + +bool g_ForceToUTF8 = true; // false; -void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT /* codePage */) +void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage) { dest.Empty(); if (src.IsEmpty()) return; - size_t limit = ((size_t)src.Len() + 1) * 2; + if (codePage == CP_UTF8 || g_ForceToUTF8) + { + ConvertUTF8ToUnicode(src, dest); + return; + } + + const size_t limit = ((size_t)src.Len() + 1) * 2; wchar_t *d = dest.GetBuf((unsigned)limit); - size_t len = mbstowcs(d, src, limit); + const size_t len = mbstowcs(d, src, limit); if (len != (size_t)-1) { dest.ReleaseBuf_SetEnd((unsigned)len); + + #if WCHAR_MAX > 0xffff + d = dest.GetBuf(); + for (size_t i = 0;; i++) + { + // wchar_t c = dest[i]; + wchar_t c = d[i]; + if (c == 0) + break; + if (c >= 0x10000 && c < 0x110000) + { + /* + c -= 0x10000; + unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF); + dest.ReplaceOneCharAtPos(i, c0); + i++; + c = 0xdc00 + (c & 0x3FF); + dest.Insert_wchar_t(i, c); + */ + UString temp = d + i; + + for (size_t t = 0;; t++) + { + wchar_t w = temp[t]; + if (w == 0) + break; + if (i == limit) + break; // unexpected error + if (w >= 0x10000 && w < 0x110000) + { + if (i + 1 == limit) + break; // unexpected error + w -= 0x10000; + d[i++] = (unsigned)0xd800 + (((unsigned)w >> 10) & 0x3FF); + w = 0xdc00 + (w & 0x3FF); + } + d[i++] = w; + } + dest.ReleaseBuf_SetEnd((unsigned)i); + } + } + + #endif + + /* + printf("\nMultiByteToUnicodeString2 (%d) %s\n", (int)src.Len(), src.Ptr()); + printf("char: "); + for (unsigned i = 0; i < src.Len(); i++) + printf (" %02x", (int)(Byte)src[i]); + printf("\n"); + printf("\n-> (%d) %ls\n", (int)dest.Len(), dest.Ptr()); + printf("wchar_t: "); + for (unsigned i = 0; i < dest.Len(); i++) + { + printf (" %02x", (int)dest[i]); + } + printf("\n"); + */ + return; } + + /* if there is mbstowcs() error, we have two ways: + + 1) change 0x80+ characters to some character: '_' + in that case we lose data, but we have correct UString() + and that scheme can show errors to user in early stages, + when file converted back to mbs() cannot be found + + 2) transfer bad characters in some UTF-16 range. + it can be non-original Unicode character. + but later we still can restore original character. + */ + + // printf("\nmbstowcs ERROR !!!!!! s=%s\n", src.Ptr()); { unsigned i; const char *s = (const char *)src; @@ -238,6 +361,8 @@ void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT /* codePa Byte c = (Byte)s[i]; if (c == 0) break; + // we can use ascii compatibilty character '_' + // if (c > 0x7F) c = '_'; // we replace "bad: character d[i++] = (wchar_t)c; } d[i] = 0; @@ -245,43 +370,131 @@ void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT /* codePa } } -static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT /* codePage */, char defaultChar, bool &defaultCharWasUsed) +static void UnicodeStringToMultiByte2_Native(AString &dest, const UString &src) { dest.Empty(); - defaultCharWasUsed = false; if (src.IsEmpty()) return; - size_t limit = ((size_t)src.Len() + 1) * 6; + const size_t limit = ((size_t)src.Len() + 1) * 6; char *d = dest.GetBuf((unsigned)limit); - size_t len = wcstombs(d, src, limit); + + const size_t len = wcstombs(d, src, limit); + if (len != (size_t)-1) { dest.ReleaseBuf_SetEnd((unsigned)len); return; } + dest.ReleaseBuf_SetEnd(0); +} + + +static void UnicodeStringToMultiByte2(AString &dest, const UString &src2, UINT codePage, char defaultChar, bool &defaultCharWasUsed) +{ + // if (codePage == 1234567) // for debug purposes + if (codePage == CP_UTF8 || g_ForceToUTF8) + { + defaultCharWasUsed = false; + ConvertUnicodeToUTF8(src2, dest); + return; + } + + UString src = src2; + #if WCHAR_MAX > 0xffff + { + src.Empty(); + for (unsigned i = 0; i < src2.Len();) + { + wchar_t c = src2[i]; + if (c >= 0xd800 && c < 0xdc00 && i + 1 != src2.Len()) + { + const wchar_t c2 = src2[i + 1]; + if (c2 >= 0xdc00 && c2 < 0x10000) + { + // printf("\nSurragate [%d]: %4x %4x -> ", i, (int)c, (int)c2); + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + // printf("%4x\n", (int)c); + i++; + } + } + src += c; + i++; + } + } + #endif + + dest.Empty(); + defaultCharWasUsed = false; + if (src.IsEmpty()) + return; + + const size_t len = wcstombs(NULL, src, 0); + + if (len != (size_t)-1) + { + const unsigned limit = ((unsigned)len); + if (limit == len) + { + char *d = dest.GetBuf(limit); + + /* + { + printf("\nwcstombs; len = %d %ls \n", (int)src.Len(), src.Ptr()); + for (unsigned i = 0; i < src.Len(); i++) + printf (" %02x", (int)src[i]); + printf("\n"); + printf("\ndest Limit = %d \n", limit); + } + */ + + const size_t len2 = wcstombs(d, src, len + 1); + + if (len2 != (size_t)-1 && len2 <= limit) + { + /* + printf("\nOK : destLen = %d : %s\n", (int)len, dest.Ptr()); + for (unsigned i = 0; i < len2; i++) + printf(" %02x", (int)(Byte)dest[i]); + printf("\n"); + */ + dest.ReleaseBuf_SetEnd((unsigned)len2); + return; + } + } + } { const wchar_t *s = (const wchar_t *)src; + char *d = dest.GetBuf(src.Len()); + unsigned i; for (i = 0;;) { wchar_t c = s[i]; if (c == 0) break; - if (c >= 0x100) + if (c >= + 0x100 + // 0x80 + ) { c = defaultChar; defaultCharWasUsed = true; } + d[i++] = (char)c; } d[i] = 0; dest.ReleaseBuf_SetLen(i); + /* + printf("\nUnicodeStringToMultiByte2; len = %d \n", (int)src.Len()); + printf("ERROR: %s\n", dest.Ptr()); + */ } } -#endif +#endif // _WIN32 UString MultiByteToUnicodeString(const AString &src, UINT codePage) @@ -291,6 +504,12 @@ UString MultiByteToUnicodeString(const AString &src, UINT 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; @@ -311,3 +530,227 @@ AString UnicodeStringToMultiByte(const UString &src, UINT codePage) UnicodeStringToMultiByte2(dest, src, codePage, k_DefultChar, defaultCharWasUsed); return dest; } + + + + +#if !defined(_WIN32) || defined(ENV_HAVE_LOCALE) + +#ifdef _WIN32 +#define U_to_A(a, b, c) UnicodeStringToMultiByte2 +// #define A_to_U(a, b, c) MultiByteToUnicodeString2 +#else +// void MultiByteToUnicodeString2_Native(UString &dest, const AString &src); +#define U_to_A(a, b, c) UnicodeStringToMultiByte2_Native(a, b) +// #define A_to_U(a, b, c) MultiByteToUnicodeString2_Native(a, b) +#endif + +bool IsNativeUTF8() +{ + UString u; + AString a, a2; + // for (unsigned c = 0x80; c < (UInt32)0x10000; c += (c >> 9) + 1) + for (unsigned c = 0x80; c < (UInt32)0xD000; c += (c >> 2) + 1) + { + u.Empty(); + u += (wchar_t)c; + /* + if (Unicode_Is_There_Utf16SurrogateError(u)) + continue; + #ifndef _WIN32 + if (Unicode_Is_There_BmpEscape(u)) + continue; + #endif + */ + ConvertUnicodeToUTF8(u, a); + U_to_A(a2, u, CP_OEMCP); + if (a != a2) + return false; + } + return true; +} + +#endif + + +#ifdef ENV_HAVE_LOCALE + +const char *GetLocale(void) +{ + #ifdef ENV_HAVE_LOCALE + // printf("\n\nsetlocale(LC_CTYPE, NULL) : return : "); + const char *s = setlocale(LC_CTYPE, NULL); + if (!s) + { + // printf("[NULL]\n"); + s = "C"; + } + else + { + // ubuntu returns "C" after program start + // printf("\"%s\"\n", s); + } + return s; + #elif defined(LOCALE_IS_UTF8) + return "utf8"; + #else + return "C"; + #endif +} + +#ifdef _WIN32 + static void Set_ForceToUTF8(bool) {} +#else + static void Set_ForceToUTF8(bool val) { g_ForceToUTF8 = val; } +#endif + +static bool Is_Default_Basic_Locale(const char *locale) +{ + const AString a (locale); + if (a.IsEqualTo_Ascii_NoCase("") + || a.IsEqualTo_Ascii_NoCase("C") + || a.IsEqualTo_Ascii_NoCase("POSIX")) + return true; + return false; +} + +static bool Is_Default_Basic_Locale() +{ + return Is_Default_Basic_Locale(GetLocale()); +} + + +void MY_SetLocale() +{ + #ifdef ENV_HAVE_LOCALE + /* + { + const char *s = GetLocale(); + printf("\nGetLocale() : returned : \"%s\"\n", s); + } + */ + + unsigned start = 0; + // unsigned lim = 0; + unsigned lim = 3; + + /* + #define MY_SET_LOCALE_FLAGS__FROM_ENV 1 + #define MY_SET_LOCALE_FLAGS__TRY_UTF8 2 + + unsigned flags = + MY_SET_LOCALE_FLAGS__FROM_ENV | + MY_SET_LOCALE_FLAGS__TRY_UTF8 + + if (flags != 0) + { + if (flags & MY_SET_LOCALE_FLAGS__FROM_ENV) + lim = (flags & MY_SET_LOCALE_FLAGS__TRY_UTF8) ? 3 : 1; + else + { + start = 1; + lim = 2; + } + } + */ + + for (unsigned i = start; i < lim; i++) + { + /* + man7: "If locale is an empty string, "", each part of the locale that + should be modified is set according to the environment variables. + for glibc: glibc, first from the user's environment variables: + 1) the environment variable LC_ALL, + 2) environment variable with the same name as the category (see the + 3) the environment variable LANG + The locale "C" or "POSIX" is a portable locale; it exists on all conforming systems. + + for WIN32 : MSDN : + Sets the locale to the default, which is the user-default + ANSI code page obtained from the operating system. + The locale name is set to the value returned by GetUserDefaultLocaleName. + The code page is set to the value returned by GetACP + */ + const char *newLocale = ""; + + #ifdef __APPLE__ + + /* look also CFLocale + there is no C.UTF-8 in macos + macos has UTF-8 locale only with some language like en_US.UTF-8 + what is best way to set UTF-8 locale in macos? */ + if (i == 1) + newLocale = "en_US.UTF-8"; + + /* file open with non-utf8 sequencies return + #define EILSEQ 92 // "Illegal byte sequence" + */ +#else + // newLocale = "C"; + if (i == 1) + { + newLocale = "C.UTF-8"; // main UTF-8 locale in ubuntu + // newLocale = ".utf8"; // supported in new Windows 10 build 17134 (April 2018 Update), the Universal C Runtime + // newLocale = "en_US.utf8"; // supported by ubuntu ? + // newLocale = "en_US.UTF-8"; + /* setlocale() in ubuntu allows locales with minor chracter changes in strings + "en_US.UTF-8" / "en_US.utf8" */ + } + +#endif + + // printf("\nsetlocale(LC_ALL, \"%s\") : returned: ", newLocale); + + // const char *s = + setlocale(LC_ALL, newLocale); + + /* + if (!s) + printf("NULL: can't set locale"); + else + printf("\"%s\"\n", s); + */ + + // request curent locale of program + const char *locale = GetLocale(); + if (locale) + { + AString a (locale); + a.MakeLower_Ascii(); + // if (a.Find("utf") >= 0) + { + if (IsNativeUTF8()) + { + Set_ForceToUTF8(true); + return; + } + } + if (!Is_Default_Basic_Locale(locale)) + { + // if there is some non-default and non-utf locale, we want to use it + break; // comment it for debug + } + } + } + + if (IsNativeUTF8()) + { + Set_ForceToUTF8(true); + return; + } + + if (Is_Default_Basic_Locale()) + { + Set_ForceToUTF8(true); + return; + } + + Set_ForceToUTF8(false); + + #elif defined(LOCALE_IS_UTF8) + // assume LC_CTYPE="utf8" + #else + // assume LC_CTYPE="C" + #endif +} +#endif diff --git a/3rdparty/lzma/CPP/Common/StringConvert.h b/3rdparty/lzma/CPP/Common/StringConvert.h index 924012450c6..2092a2da03b 100644 --- a/3rdparty/lzma/CPP/Common/StringConvert.h +++ b/3rdparty/lzma/CPP/Common/StringConvert.h @@ -1,77 +1,110 @@ // Common/StringConvert.h -#ifndef __COMMON_STRING_CONVERT_H -#define __COMMON_STRING_CONVERT_H +#ifndef ZIP7_INC_COMMON_STRING_CONVERT_H +#define ZIP7_INC_COMMON_STRING_CONVERT_H #include "MyString.h" #include "MyWindows.h" -UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP); +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 &srcString, UINT codePage = CP_ACP); +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 &srcString, UINT codePage); - -AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage, char defaultChar, bool &defaultCharWasUsed); -AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP); - -inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString) - { return unicodeString; } -inline const UString& GetUnicodeString(const UString &unicodeString) - { return unicodeString; } -inline UString GetUnicodeString(const AString &ansiString) - { return MultiByteToUnicodeString(ansiString); } -inline UString GetUnicodeString(const AString &multiByteString, UINT codePage) - { return MultiByteToUnicodeString(multiByteString, codePage); } -inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT) - { return unicodeString; } -inline const UString& GetUnicodeString(const UString &unicodeString, UINT) - { return unicodeString; } - -inline const char* GetAnsiString(const char* ansiString) - { return ansiString; } -inline const AString& GetAnsiString(const AString &ansiString) - { return ansiString; } -inline AString GetAnsiString(const UString &unicodeString) - { return UnicodeStringToMultiByte(unicodeString); } - -inline const char* GetOemString(const char* oemString) - { return oemString; } -inline const AString& GetOemString(const AString &oemString) - { return oemString; } -inline AString GetOemString(const UString &unicodeString) - { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); } +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* unicodeString) - { return unicodeString;} - inline const UString& GetSystemString(const UString &unicodeString) - { return unicodeString;} - inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT /* codePage */) - { return unicodeString;} - inline const UString& GetSystemString(const UString &unicodeString, UINT /* codePage */) - { return unicodeString;} - inline UString GetSystemString(const AString &multiByteString, UINT codePage) - { return MultiByteToUnicodeString(multiByteString, codePage);} - inline UString GetSystemString(const AString &multiByteString) - { return MultiByteToUnicodeString(multiByteString);} + 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 *ansiString) - { return ansiString; } - inline const AString& GetSystemString(const AString &multiByteString, UINT) - { return multiByteString; } - inline const char * GetSystemString(const char *multiByteString, UINT) - { return multiByteString; } - inline AString GetSystemString(const UString &unicodeString) - { return UnicodeStringToMultiByte(unicodeString); } - inline AString GetSystemString(const UString &unicodeString, UINT codePage) - { return UnicodeStringToMultiByte(unicodeString, codePage); } + 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 &srcString); +AString SystemStringToOemString(const CSysString &src); +#endif + + +#ifdef _WIN32 +/* we don't need locale functions in Windows + but we can define ENV_HAVE_LOCALE here for debug purposes */ +// #define ENV_HAVE_LOCALE +#else +#define ENV_HAVE_LOCALE +#endif + +#ifdef ENV_HAVE_LOCALE +void MY_SetLocale(); +const char *GetLocale(void); +#endif + +#if !defined(_WIN32) || defined(ENV_HAVE_LOCALE) +bool IsNativeUTF8(); +#endif + +#ifndef _WIN32 +extern bool g_ForceToUTF8; #endif #endif diff --git a/3rdparty/lzma/CPP/Common/StringToInt.cpp b/3rdparty/lzma/CPP/Common/StringToInt.cpp index dfa5cc3bff4..bc4926e5d1b 100644 --- a/3rdparty/lzma/CPP/Common/StringToInt.cpp +++ b/3rdparty/lzma/CPP/Common/StringToInt.cpp @@ -17,7 +17,7 @@ static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF); 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'); \ + unsigned v = (unsigned)(c - '0'); \ if (res > (k_ ## uintType ## _max) - v) return 0; \ res += v; }} @@ -26,6 +26,33 @@ 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 char *s, const char **end) throw() +{ + if (end) + *end = s; + const char *s2 = s; + if (*s == '-') + s2++; + if (*s2 == 0) + return 0; + const char *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; +} +*/ + Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw() { if (end) diff --git a/3rdparty/lzma/CPP/Common/StringToInt.h b/3rdparty/lzma/CPP/Common/StringToInt.h index 5c5d7d7fe75..c9dce7d1b75 100644 --- a/3rdparty/lzma/CPP/Common/StringToInt.h +++ b/3rdparty/lzma/CPP/Common/StringToInt.h @@ -1,7 +1,7 @@ // Common/StringToInt.h -#ifndef __COMMON_STRING_TO_INT_H -#define __COMMON_STRING_TO_INT_H +#ifndef ZIP7_INC_COMMON_STRING_TO_INT_H +#define ZIP7_INC_COMMON_STRING_TO_INT_H #include "MyTypes.h" @@ -10,6 +10,7 @@ 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 char *s, const char **end) throw(); Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw(); UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw(); diff --git a/3rdparty/lzma/CPP/Common/TextConfig.cpp b/3rdparty/lzma/CPP/Common/TextConfig.cpp index 9ae4074b690..d3e561c2d29 100644 --- a/3rdparty/lzma/CPP/Common/TextConfig.cpp +++ b/3rdparty/lzma/CPP/Common/TextConfig.cpp @@ -15,7 +15,7 @@ static AString GetIDString(const char *s, unsigned &finishPos) AString result; for (finishPos = 0; ; finishPos++) { - char c = s[finishPos]; + const char c = s[finishPos]; if (IsDelimitChar(c) || c == '=') break; result += c; @@ -35,7 +35,7 @@ static bool SkipSpaces(const AString &s, unsigned &pos) { for (; pos < s.Len(); pos++) { - char c = s[pos]; + const char c = s[pos]; if (!IsDelimitChar(c)) { if (c != ';') @@ -61,7 +61,7 @@ bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs) break; CTextConfigPair pair; unsigned finishPos; - AString temp = GetIDString(((const char *)s) + pos, finishPos); + const AString temp (GetIDString(((const char *)s) + pos, finishPos)); if (!ConvertUTF8ToUnicode(temp, pair.ID)) return false; if (finishPos == 0) @@ -107,17 +107,17 @@ bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs) return true; } -int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id) throw() +int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const char *id) throw() { FOR_VECTOR (i, pairs) - if (pairs[i].ID == id) - return i; + if (pairs[i].ID.IsEqualTo(id)) + return (int)i; return -1; } -UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id) +UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const char *id) { - int index = FindTextConfigItem(pairs, id); + const int index = FindTextConfigItem(pairs, id); if (index < 0) return UString(); return pairs[index].String; diff --git a/3rdparty/lzma/CPP/Common/TextConfig.h b/3rdparty/lzma/CPP/Common/TextConfig.h index 0129ad963a1..2263a442509 100644 --- a/3rdparty/lzma/CPP/Common/TextConfig.h +++ b/3rdparty/lzma/CPP/Common/TextConfig.h @@ -1,7 +1,7 @@ // Common/TextConfig.h -#ifndef __COMMON_TEXT_CONFIG_H -#define __COMMON_TEXT_CONFIG_H +#ifndef ZIP7_INC_COMMON_TEXT_CONFIG_H +#define ZIP7_INC_COMMON_TEXT_CONFIG_H #include "MyString.h" @@ -13,7 +13,7 @@ struct CTextConfigPair bool GetTextConfig(const AString &text, CObjectVector<CTextConfigPair> &pairs); -int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id) throw(); -UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id); +int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const char *id) throw(); +UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const char *id); #endif diff --git a/3rdparty/lzma/CPP/Common/UTFConvert.cpp b/3rdparty/lzma/CPP/Common/UTFConvert.cpp index b772164aab4..fb166b7f356 100644 --- a/3rdparty/lzma/CPP/Common/UTFConvert.cpp +++ b/3rdparty/lzma/CPP/Common/UTFConvert.cpp @@ -2,94 +2,354 @@ #include "StdAfx.h" +// #include <stdio.h> + #include "MyTypes.h" #include "UTFConvert.h" -#ifdef _WIN32 -#define _WCHART_IS_16BIT 1 + +#ifndef Z7_WCHART_IS_16BIT +#ifndef __APPLE__ + // we define it if the system supports files with non-utf8 symbols: + #define MY_UTF8_RAW_NON_UTF8_SUPPORTED +#endif #endif /* - _UTF8_START(n) - is a base value for start byte (head), if there are (n) additional bytes after start byte + MY_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 + n : MY_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 + 4 : 0xF8 : 26 : + 5 : 0xFC : 31 : UCS-4 : wcstombs() in ubuntu is limited to that value 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 MY_UTF8_START(n) (0x100 - (1 << (7 - (n)))) + +#define MY_UTF8_HEAD_PARSE2(n) \ + if (c < MY_UTF8_START((n) + 1)) \ + { numBytes = (n); val -= MY_UTF8_START(n); } + +#ifndef Z7_WCHART_IS_16BIT + +/* + if (wchar_t is 32-bit), we can support large points in long UTF-8 sequence, + when we convert wchar_t strings to UTF-8: + (_UTF8_NUM_TAIL_BYTES_MAX == 3) : (21-bits points) - Unicode + (_UTF8_NUM_TAIL_BYTES_MAX == 5) : (31-bits points) - UCS-4 + (_UTF8_NUM_TAIL_BYTES_MAX == 6) : (36-bit hack) +*/ + +#define MY_UTF8_NUM_TAIL_BYTES_MAX 5 +#endif + +/* +#define MY_UTF8_HEAD_PARSE \ + UInt32 val = c; \ + MY_UTF8_HEAD_PARSE2(1) \ + else MY_UTF8_HEAD_PARSE2(2) \ + else MY_UTF8_HEAD_PARSE2(3) \ + else MY_UTF8_HEAD_PARSE2(4) \ + else MY_UTF8_HEAD_PARSE2(5) \ + #if MY_UTF8_NUM_TAIL_BYTES_MAX >= 6 + else MY_UTF8_HEAD_PARSE2(6) + #endif +*/ + +#define MY_UTF8_HEAD_PARSE_MAX_3_BYTES \ + UInt32 val = c; \ + MY_UTF8_HEAD_PARSE2(1) \ + else MY_UTF8_HEAD_PARSE2(2) \ + else { numBytes = 3; val -= MY_UTF8_START(3); } + + +#define MY_UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6)) + + +#define START_POINT_FOR_SURROGATE 0x10000 + + +/* we use 128 bytes block in 16-bit BMP-PLANE to encode non-UTF-8 Escapes + Also we can use additional HIGH-PLANE (we use 21-bit points above 0x1f0000) + to simplify internal intermediate conversion in Linux: + RAW-UTF-8 <-> internal wchar_t utf-16 strings <-> RAW-UTF-UTF-8 +*/ + + +#if defined(Z7_WCHART_IS_16BIT) + +#define UTF_ESCAPE_PLANE 0 + +#else + +/* +we can place 128 ESCAPE chars to + ef 80 - ee be 80 (3-bytes utf-8) : similar to WSL + ef ff - ee bf bf + +1f ef 80 - f7 be be 80 (4-bytes utf-8) : last 4-bytes utf-8 plane (out of Unicode) +1f ef ff - f7 be bf bf (4-bytes utf-8) : last 4-bytes utf-8 plane (out of Unicode) +*/ + +// #define UTF_ESCAPE_PLANE_HIGH (0x1f << 16) +// #define UTF_ESCAPE_PLANE UTF_ESCAPE_PLANE_HIGH +#define UTF_ESCAPE_PLANE 0 + +/* + if (Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE is set) + { + if (UTF_ESCAPE_PLANE is UTF_ESCAPE_PLANE_HIGH) + { + we can restore any 8-bit Escape from ESCAPE-PLANE-21 plane. + But ESCAPE-PLANE-21 point cannot be stored to utf-16 (7z archive) + So we still need a way to extract 8-bit Escapes and BMP-Escapes-8 + from same BMP-Escapes-16 stored in 7z. + And if we want to restore any 8-bit from 7z archive, + we still must use Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT for (utf-8 -> utf-16) + Also we need additional Conversions to tranform from utf-16 to utf-16-With-Escapes-21 + } + else (UTF_ESCAPE_PLANE == 0) + { + we must convert original 3-bytes utf-8 BMP-Escape point to sequence + of 3 BMP-Escape-16 points with Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + so we can extract original RAW-UTF-8 from UTFD-16 later. + } + } +*/ + +#endif + + + +#define UTF_ESCAPE_BASE 0xef00 + + +#ifdef UTF_ESCAPE_BASE +#define IS_ESCAPE_POINT(v, plane) (((v) & (UInt32)0xffffff80) == (plane) + UTF_ESCAPE_BASE + 0x80) +#endif + +#define IS_SURROGATE_POINT(v) (((v) & (UInt32)0xfffff800) == 0xd800) +#define IS_LOW_SURROGATE_POINT(v) (((v) & (UInt32)0xfffffC00) == 0xdc00) + + +#define UTF_ERROR_UTF8_CHECK \ + { NonUtf = true; continue; } + +void CUtf8Check::Check_Buf(const char *src, size_t size) throw() +{ + Clear(); + // Byte maxByte = 0; + + for (;;) + { + if (size == 0) + break; + + const Byte c = (Byte)(*src++); + size--; + + if (c == 0) + { + ZeroChar = true; + continue; + } + + /* + if (c > maxByte) + maxByte = c; + */ + + if (c < 0x80) + continue; + + if (c < 0xc0 + 2) // it's limit for 0x140000 unicode codes : win32 compatibility + UTF_ERROR_UTF8_CHECK + + unsigned numBytes; + + UInt32 val = c; + MY_UTF8_HEAD_PARSE2(1) + else MY_UTF8_HEAD_PARSE2(2) + else MY_UTF8_HEAD_PARSE2(4) + else MY_UTF8_HEAD_PARSE2(5) + else + { + UTF_ERROR_UTF8_CHECK + } + + unsigned pos = 0; + do + { + if (pos == size) + break; + unsigned c2 = (Byte)src[pos]; + c2 -= 0x80; + if (c2 >= 0x40) + break; + val <<= 6; + val |= c2; + if (pos == 0) + if (val < (((unsigned)1 << 7) >> numBytes)) + break; + pos++; + } + while (--numBytes); + + if (numBytes != 0) + { + if (pos == size) + Truncated = true; + else + UTF_ERROR_UTF8_CHECK + } -#define _UTF8_HEAD_PARSE2(n) if (c < _UTF8_START((n) + 1)) { numBytes = (n); c -= _UTF8_START(n); } + #ifdef UTF_ESCAPE_BASE + if (IS_ESCAPE_POINT(val, 0)) + Escape = true; + #endif -#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) \ + if (MaxHighPoint < val) + MaxHighPoint = val; - // else _UTF8_HEAD_PARSE2(6) + if (IS_SURROGATE_POINT(val)) + SingleSurrogate = true; + + src += pos; + size -= pos; + } + // MaxByte = maxByte; +} + +bool Check_UTF8_Buf(const char *src, size_t size, bool allowReduced) throw() +{ + CUtf8Check check; + check.Check_Buf(src, size); + return check.IsOK(allowReduced); +} + +/* +bool CheckUTF8_chars(const char *src, bool allowReduced) throw() +{ + CUtf8Check check; + check.CheckBuf(src, strlen(src)); + return check.IsOK(allowReduced); +} +*/ + +bool CheckUTF8_AString(const AString &s) throw() +{ + CUtf8Check check; + check.Check_AString(s); + return check.IsOK(); +} + + +/* bool CheckUTF8(const char *src, bool allowReduced) throw() { + // return Check_UTF8_Buf(src, strlen(src), allowReduced); + for (;;) { - Byte c = *src++; + const Byte c = (Byte)(*src++); if (c == 0) return true; if (c < 0x80) continue; - if (c < 0xC0) // (c < 0xC0 + 2) // if we support only optimal encoding chars + if (c < 0xC0 + 2 || c >= 0xf5) return false; unsigned numBytes; - _UTF8_HEAD_PARSE + MY_UTF8_HEAD_PARSE else return false; - - UInt32 val = c; + unsigned pos = 0; + do { - Byte c2 = *src++; + Byte c2 = (Byte)(*src++); if (c2 < 0x80 || c2 >= 0xC0) return allowReduced && c2 == 0; val <<= 6; val |= (c2 - 0x80); + pos++; } while (--numBytes); - + + if (val < MY_UTF8_RANGE(pos - 1)) + return false; + if (val >= 0x110000) return false; } } +*/ + +// in case of UTF-8 error we have two ways: +// 21.01- : old : 0xfffd: REPLACEMENT CHARACTER : old version +// 21.02+ : new : 0xef00 + (c) : similar to WSL scheme for low symbols + +#define UTF_REPLACEMENT_CHAR 0xfffd + + + +#define UTF_ESCAPE(c) \ + ((flags & Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE) ? \ + UTF_ESCAPE_PLANE + UTF_ESCAPE_BASE + (c) : UTF_REPLACEMENT_CHAR) + +/* +#define UTF_HARD_ERROR_UTF8 + { if (dest) dest[destPos] = (wchar_t)UTF_ESCAPE(c); \ + destPos++; ok = false; continue; } +*/ + +// we ignore utf errors, and don't change (ok) variable! + +#define UTF_ERROR_UTF8 \ + { if (dest) dest[destPos] = (wchar_t)UTF_ESCAPE(c); \ + destPos++; continue; } +// we store UTF-16 in wchar_t strings. So we use surrogates for big unicode points: -#define _ERROR_UTF8 \ - { if (dest) dest[destPos] = (wchar_t)0xFFFD; destPos++; ok = false; continue; } +// for debug puposes only we can store UTF-32 in wchar_t: +// #define START_POINT_FOR_SURROGATE ((UInt32)0 - 1) -static bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, const char *srcLim) throw() + +/* + WIN32 MultiByteToWideChar(CP_UTF8) emits 0xfffd point, if utf-8 error was found. + Ant it can emit single 0xfffd from 2 src bytes. + It doesn't emit single 0xfffd from 3-4 src bytes. + We can + 1) emit Escape point for each incorrect byte. So we can data recover later + 2) emit 0xfffd for each incorrect byte. + That scheme is similar to Escape scheme, but we emit 0xfffd + instead of each Escape point. + 3) emit single 0xfffd from 1-2 incorrect bytes, as WIN32 MultiByteToWideChar scheme +*/ + +static bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, const char *srcLim, unsigned flags) throw() { size_t destPos = 0; bool ok = true; for (;;) { - Byte c; if (src == srcLim) { *destLen = destPos; return ok; } - c = *src++; + + const Byte c = (Byte)(*src++); if (c < 0x80) { @@ -98,113 +358,195 @@ static bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, const destPos++; continue; } - if (c < 0xC0) - _ERROR_UTF8 + + if (c < 0xc0 + 2 + || c >= 0xf5) // it's limit for 0x140000 unicode codes : win32 compatibility + { + UTF_ERROR_UTF8 + } unsigned numBytes; - _UTF8_HEAD_PARSE - else - _ERROR_UTF8 - - UInt32 val = c; + MY_UTF8_HEAD_PARSE_MAX_3_BYTES + + unsigned pos = 0; do { - Byte c2; - if (src == srcLim) + if (src + pos == srcLim) break; - c2 = *src; - if (c2 < 0x80 || c2 >= 0xC0) + unsigned c2 = (Byte)src[pos]; + c2 -= 0x80; + if (c2 >= 0x40) break; - src++; val <<= 6; - val |= (c2 - 0x80); + val |= c2; + pos++; + if (pos == 1) + { + if (val < (((unsigned)1 << 7) >> numBytes)) + break; + if (numBytes == 2) + { + if (flags & Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR) + if ((val & (0xF800 >> 6)) == (0xd800 >> 6)) + break; + } + else if (numBytes == 3 && val >= (0x110000 >> 12)) + break; + } } while (--numBytes); if (numBytes != 0) - _ERROR_UTF8 + { + if ((flags & Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE) == 0) + { + // the following code to emit the 0xfffd chars as win32 Utf8 function. + // disable the folling line, if you need 0xfffd for each incorrect byte as in Escape mode + src += pos; + } + UTF_ERROR_UTF8 + } + + /* + if (val < MY_UTF8_RANGE(pos - 1)) + UTF_ERROR_UTF8 + */ + + #ifdef UTF_ESCAPE_BASE + + if ((flags & Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT) + && IS_ESCAPE_POINT(val, 0)) + { + // We will emit 3 utf16-Escape-16-21 points from one Escape-16 point (3 bytes) + UTF_ERROR_UTF8 + } + + #endif - if (val < 0x10000) + /* + We don't expect virtual Escape-21 points in UTF-8 stream. + And we don't check for Escape-21. + So utf8-Escape-21 will be converted to another 3 utf16-Escape-21 points. + Maybe we could convert virtual utf8-Escape-21 to one utf16-Escape-21 point in some cases? + */ + + if (val < START_POINT_FOR_SURROGATE) { + /* + if ((flags & Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR) + && IS_SURROGATE_POINT(val)) + { + // We will emit 3 utf16-Escape-16-21 points from one Surrogate-16 point (3 bytes) + UTF_ERROR_UTF8 + } + */ if (dest) dest[destPos] = (wchar_t)val; destPos++; } else { - val -= 0x10000; - if (val >= 0x100000) - _ERROR_UTF8 + /* + if (val >= 0x110000) + { + // We will emit utf16-Escape-16-21 point from each source byte + UTF_ERROR_UTF8 + } + */ if (dest) { - dest[destPos + 0] = (wchar_t)(0xD800 + (val >> 10)); - dest[destPos + 1] = (wchar_t)(0xDC00 + (val & 0x3FF)); + dest[destPos + 0] = (wchar_t)(0xd800 - (0x10000 >> 10) + (val >> 10)); + dest[destPos + 1] = (wchar_t)(0xdc00 + (val & 0x3ff)); } destPos += 2; } + src += pos; } } -#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) +#define MY_UTF8_HEAD(n, val) ((char)(MY_UTF8_START(n) + (val >> (6 * (n))))) +#define MY_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, unsigned flags) { - size_t size = srcLim - src; + size_t size = (size_t)(srcLim - src); for (;;) { if (src == srcLim) return size; - UInt32 val = *src++; + UInt32 val = (UInt32)(*src++); if (val < 0x80) continue; - if (val < _UTF8_RANGE(1)) + if (val < MY_UTF8_RANGE(1)) { size++; continue; } - if (val >= 0xD800 && val < 0xDC00 && src != srcLim) + #ifdef UTF_ESCAPE_BASE + + #if UTF_ESCAPE_PLANE != 0 + if (flags & Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE) + if (IS_ESCAPE_POINT(val, UTF_ESCAPE_PLANE)) + continue; + #endif + + if (flags & Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE) + if (IS_ESCAPE_POINT(val, 0)) + continue; + + #endif + + if (IS_SURROGATE_POINT(val)) { - UInt32 c2 = *src; - if (c2 >= 0xDC00 && c2 < 0xE000) + // it's hack to UTF-8 encoding + + if (val < 0xdc00 && src != srcLim) { - src++; - size += 2; - continue; + const UInt32 c2 = (UInt32)*src; + if (c2 >= 0xdc00 && c2 < 0xe000) + src++; } + size += 2; + continue; } - #ifdef _WCHART_IS_16BIT + #ifdef Z7_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; + if (val < MY_UTF8_RANGE(2)) size += 2; + else if (val < MY_UTF8_RANGE(3)) size += 3; + else if (val < MY_UTF8_RANGE(4)) size += 4; + else if (val < MY_UTF8_RANGE(5)) size += 5; + else + #if MY_UTF8_NUM_TAIL_BYTES_MAX >= 6 + size += 6; + #else + size += 3; + #endif #endif } } -static char *Utf16_To_Utf8(char *dest, const wchar_t *src, const wchar_t *srcLim) + +static char *Utf16_To_Utf8(char *dest, const wchar_t *src, const wchar_t *srcLim, unsigned flags) { for (;;) { if (src == srcLim) return dest; - UInt32 val = *src++; + UInt32 val = (UInt32)*src++; if (val < 0x80) { @@ -212,51 +554,97 @@ static char *Utf16_To_Utf8(char *dest, const wchar_t *src, const wchar_t *srcLim continue; } - if (val < _UTF8_RANGE(1)) + if (val < MY_UTF8_RANGE(1)) { - dest[0] = _UTF8_HEAD(1, val); - dest[1] = _UTF8_CHAR(0, val); + dest[0] = MY_UTF8_HEAD(1, val); + dest[1] = MY_UTF8_CHAR(0, val); dest += 2; continue; } - if (val >= 0xD800 && val < 0xDC00 && src != srcLim) - { - UInt32 c2 = *src; - if (c2 >= 0xDC00 && c2 < 0xE000) + #ifdef UTF_ESCAPE_BASE + + #if UTF_ESCAPE_PLANE != 0 + /* + if (wchar_t is 32-bit) + && (Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE is set) + && (point is virtual escape plane) + we extract 8-bit byte from virtual HIGH-ESCAPE PLANE. + */ + if (flags & Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE) + if (IS_ESCAPE_POINT(val, UTF_ESCAPE_PLANE)) { - 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; + *dest++ = (char)(val); + continue; + } + #endif // UTF_ESCAPE_PLANE != 0 + + /* if (Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE is defined) + we extract 8-bit byte from BMP-ESCAPE PLANE. */ + + if (flags & Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE) + if (IS_ESCAPE_POINT(val, 0)) + { + *dest++ = (char)(val); continue; } - } - #ifndef _WCHART_IS_16BIT - if (val < _UTF8_RANGE(2)) + #endif // UTF_ESCAPE_BASE + + if (IS_SURROGATE_POINT(val)) + { + // it's hack to UTF-8 encoding + if (val < 0xdc00 && src != srcLim) + { + const UInt32 c2 = (UInt32)*src; + if (IS_LOW_SURROGATE_POINT(c2)) + { + src++; + val = (((val - 0xd800) << 10) | (c2 - 0xdc00)) + 0x10000; + dest[0] = MY_UTF8_HEAD(3, val); + dest[1] = MY_UTF8_CHAR(2, val); + dest[2] = MY_UTF8_CHAR(1, val); + dest[3] = MY_UTF8_CHAR(0, val); + dest += 4; + continue; + } + } + if (flags & Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR) + val = UTF_REPLACEMENT_CHAR; // WIN32 function does it + } + + #ifndef Z7_WCHART_IS_16BIT + if (val < MY_UTF8_RANGE(2)) #endif { - dest[0] = _UTF8_HEAD(2, val); - dest[1] = _UTF8_CHAR(1, val); - dest[2] = _UTF8_CHAR(0, val); + dest[0] = MY_UTF8_HEAD(2, val); + dest[1] = MY_UTF8_CHAR(1, val); + dest[2] = MY_UTF8_CHAR(0, val); dest += 3; continue; } - #ifndef _WCHART_IS_16BIT + #ifndef Z7_WCHART_IS_16BIT - UInt32 b; + // we don't expect this case. so we can throw exception + // throw 20210407; + + char 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; + if (val < MY_UTF8_RANGE(3)) { numBits = 6 * 3; b = MY_UTF8_HEAD(3, val); } + else if (val < MY_UTF8_RANGE(4)) { numBits = 6 * 4; b = MY_UTF8_HEAD(4, val); } + else if (val < MY_UTF8_RANGE(5)) { numBits = 6 * 5; b = MY_UTF8_HEAD(5, val); } + #if MY_UTF8_NUM_TAIL_BYTES_MAX >= 6 + else { numBits = 6 * 6; b = (char)MY_UTF8_START(6); } + #else + else + { + val = UTF_REPLACEMENT_CHAR; + { numBits = 6 * 3; b = MY_UTF8_HEAD(3, val); } + } + #endif + + *dest++ = b; do { @@ -269,20 +657,207 @@ static char *Utf16_To_Utf8(char *dest, const wchar_t *src, const wchar_t *srcLim } } -bool ConvertUTF8ToUnicode(const AString &src, UString &dest) +bool Convert_UTF8_Buf_To_Unicode(const char *src, size_t srcSize, UString &dest, unsigned flags) { 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())); + Utf8_To_Utf16(NULL, &destLen, src, src + srcSize, flags); + bool res = Utf8_To_Utf16(dest.GetBuf((unsigned)destLen), &destLen, src, src + srcSize, flags); dest.ReleaseBuf_SetEnd((unsigned)destLen); return res; } -void ConvertUnicodeToUTF8(const UString &src, AString &dest) +bool ConvertUTF8ToUnicode_Flags(const AString &src, UString &dest, unsigned flags) +{ + return Convert_UTF8_Buf_To_Unicode(src, src.Len(), dest, flags); +} + + +static +unsigned g_UTF8_To_Unicode_Flags = + Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + #ifndef Z7_WCHART_IS_16BIT + | Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + #ifdef MY_UTF8_RAW_NON_UTF8_SUPPORTED + | Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + #endif + #endif + ; + + +/* +bool ConvertUTF8ToUnicode_boolRes(const AString &src, UString &dest) +{ + return ConvertUTF8ToUnicode_Flags(src, dest, g_UTF8_To_Unicode_Flags); +} +*/ + +bool ConvertUTF8ToUnicode(const AString &src, UString &dest) +{ + return ConvertUTF8ToUnicode_Flags(src, dest, g_UTF8_To_Unicode_Flags); +} + +void Print_UString(const UString &a); + +void ConvertUnicodeToUTF8_Flags(const UString &src, AString &dest, unsigned flags) { + /* + if (src.Len()== 24) + throw "202104"; + */ 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())); + const size_t destLen = Utf16_To_Utf8_Calc(src, src.Ptr(src.Len()), flags); + char *destStart = dest.GetBuf((unsigned)destLen); + const char *destEnd = Utf16_To_Utf8(destStart, src, src.Ptr(src.Len()), flags); dest.ReleaseBuf_SetEnd((unsigned)destLen); + // printf("\nlen = %d\n", src.Len()); + if (destLen != (size_t)(destEnd - destStart)) + { + /* + // dest.ReleaseBuf_SetEnd((unsigned)(destEnd - destStart)); + printf("\nlen = %d\n", (unsigned)destLen); + printf("\n(destEnd - destStart) = %d\n", (unsigned)(destEnd - destStart)); + printf("\n"); + // Print_UString(src); + printf("\n"); + // printf("\nlen = %d\n", destLen); + */ + throw 20210406; + } +} + + + +unsigned g_Unicode_To_UTF8_Flags = + // Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE + 0 + #ifndef _WIN32 + #ifdef MY_UTF8_RAW_NON_UTF8_SUPPORTED + | Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE + #else + | Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR + #endif + #endif + ; + +void ConvertUnicodeToUTF8(const UString &src, AString &dest) +{ + ConvertUnicodeToUTF8_Flags(src, dest, g_Unicode_To_UTF8_Flags); } + +void Convert_Unicode_To_UTF8_Buf(const UString &src, CByteBuffer &dest) +{ + const unsigned flags = g_Unicode_To_UTF8_Flags; + dest.Free(); + const size_t destLen = Utf16_To_Utf8_Calc(src, src.Ptr(src.Len()), flags); + dest.Alloc(destLen); + const char *destEnd = Utf16_To_Utf8((char *)(void *)(Byte *)dest, src, src.Ptr(src.Len()), flags); + if (destLen != (size_t)(destEnd - (char *)(void *)(Byte *)dest)) + throw 202104; +} + +/* + +#ifndef _WIN32 +void Convert_UTF16_To_UTF32(const UString &src, UString &dest) +{ + dest.Empty(); + for (size_t i = 0; i < src.Len();) + { + wchar_t c = src[i++]; + if (c >= 0xd800 && c < 0xdc00 && i < src.Len()) + { + const wchar_t c2 = src[i]; + if (c2 >= 0xdc00 && c2 < 0x10000) + { + // printf("\nSurragate [%d]: %4x %4x -> ", i, (int)c, (int)c2); + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + // printf("%4x\n", (int)c); + i++; + } + } + dest += c; + } +} + +void Convert_UTF32_To_UTF16(const UString &src, UString &dest) +{ + dest.Empty(); + for (size_t i = 0; i < src.Len();) + { + wchar_t w = src[i++]; + if (w >= 0x10000 && w < 0x110000) + { + w -= 0x10000; + dest += (wchar_t)((unsigned)0xd800 + (((unsigned)w >> 10) & 0x3ff)); + w = 0xdc00 + (w & 0x3ff); + } + dest += w; + } +} + +bool UTF32_IsThere_BigPoint(const UString &src) +{ + for (size_t i = 0; i < src.Len();) + { + const UInt32 c = (UInt32)src[i++]; + if (c >= 0x110000) + return true; + } + return false; +} + +bool Unicode_IsThere_BmpEscape(const UString &src) +{ + for (size_t i = 0; i < src.Len();) + { + const UInt32 c = (UInt32)src[i++]; + if (IS_ESCAPE_POINT(c, 0)) + return true; + } + return false; +} + + +#endif + +bool Unicode_IsThere_Utf16SurrogateError(const UString &src) +{ + for (size_t i = 0; i < src.Len();) + { + const UInt32 val = (UInt32)src[i++]; + if (IS_SURROGATE_POINT(val)) + { + // it's hack to UTF-8 encoding + if (val >= 0xdc00 || i == src.Len()) + return true; + const UInt32 c2 = (UInt32)*src; + if (!IS_LOW_SURROGATE_POINT(c2)) + return true; + } + } + return false; +} +*/ + +#ifndef Z7_WCHART_IS_16BIT + +void Convert_UnicodeEsc16_To_UnicodeEscHigh +#if UTF_ESCAPE_PLANE == 0 + (UString &) {} +#else + (UString &s) +{ + const unsigned len = s.Len(); + for (unsigned i = 0; i < len; i++) + { + wchar_t c = s[i]; + if (IS_ESCAPE_POINT(c, 0)) + { + c += UTF_ESCAPE_PLANE; + s.ReplaceOneCharAtPos(i, c); + } + } +} +#endif +#endif diff --git a/3rdparty/lzma/CPP/Common/UTFConvert.h b/3rdparty/lzma/CPP/Common/UTFConvert.h index 827f3dcfe19..94a8024fbf7 100644 --- a/3rdparty/lzma/CPP/Common/UTFConvert.h +++ b/3rdparty/lzma/CPP/Common/UTFConvert.h @@ -1,12 +1,384 @@ // Common/UTFConvert.h -#ifndef __COMMON_UTF_CONVERT_H -#define __COMMON_UTF_CONVERT_H +#ifndef ZIP7_INC_COMMON_UTF_CONVERT_H +#define ZIP7_INC_COMMON_UTF_CONVERT_H +#include "MyBuffer.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); +struct CUtf8Check +{ + // Byte MaxByte; // in original src stream + bool NonUtf; + bool ZeroChar; + bool SingleSurrogate; + bool Escape; + bool Truncated; + UInt32 MaxHighPoint; // only for points >= 0x80 + + CUtf8Check() { Clear(); } + + void Clear() + { + // MaxByte = 0; + NonUtf = false; + ZeroChar = false; + SingleSurrogate = false; + Escape = false; + Truncated = false; + MaxHighPoint = 0; + } + + void Update(const CUtf8Check &c) + { + if (c.NonUtf) NonUtf = true; + if (c.ZeroChar) ZeroChar = true; + if (c.SingleSurrogate) SingleSurrogate = true; + if (c.Escape) Escape = true; + if (c.Truncated) Truncated = true; + if (MaxHighPoint < c.MaxHighPoint) MaxHighPoint = c.MaxHighPoint; + } + + void PrintStatus(AString &s) const + { + s.Empty(); + + // s.Add_OptSpaced("MaxByte="); + // s.Add_UInt32(MaxByte); + + if (NonUtf) s.Add_OptSpaced("non-UTF8"); + if (ZeroChar) s.Add_OptSpaced("ZeroChar"); + if (SingleSurrogate) s.Add_OptSpaced("SingleSurrogate"); + if (Escape) s.Add_OptSpaced("Escape"); + if (Truncated) s.Add_OptSpaced("Truncated"); + + if (MaxHighPoint != 0) + { + s.Add_OptSpaced("MaxUnicode="); + s.Add_UInt32(MaxHighPoint); + } + } + + + bool IsOK(bool allowReduced = false) const + { + if (NonUtf || SingleSurrogate || ZeroChar) + return false; + if (MaxHighPoint >= 0x110000) + return false; + if (Truncated && !allowReduced) + return false; + return true; + } + + // it checks full buffer as specified in (size) and it doesn't stop on zero char + void Check_Buf(const char *src, size_t size) throw(); + + void Check_AString(const AString &s) throw() + { + Check_Buf(s.Ptr(), s.Len()); + } +}; + +/* +if (allowReduced == false) - all UTF-8 character sequences must be finished. +if (allowReduced == true) - it allows truncated last character-Utf8-sequence +*/ + +bool Check_UTF8_Buf(const char *src, size_t size, bool allowReduced) throw(); +bool CheckUTF8_AString(const AString &s) throw(); + +#define Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR (1 << 0) +#define Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE (1 << 1) +#define Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT (1 << 2) + +/* +Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + + if (flag is NOT set) + { + it processes SINGLE-SURROGATE-8 as valid Unicode point. + it converts SINGLE-SURROGATE-8 to SINGLE-SURROGATE-16 + Note: some sequencies of two SINGLE-SURROGATE-8 points + will generate correct SURROGATE-16-PAIR, and + that SURROGATE-16-PAIR later will be converted to correct + UTF8-SURROGATE-21 point. So we don't restore original + STR-8 sequence in that case. + } + + if (flag is set) + { + if (Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE is defined) + it generates ESCAPE for SINGLE-SURROGATE-8, + if (Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE is not defined) + it generates U+fffd for SINGLE-SURROGATE-8, + } + + +Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + + if (flag is NOT set) + it generates (U+fffd) code for non-UTF-8 (invalid) characters + + if (flag is set) + { + It generates (ESCAPE) codes for NON-UTF-8 (invalid) characters. + And later we can restore original UTF-8-RAW characters from (ESCAPE-16-21) codes. + } + +Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + + if (flag is NOT set) + { + it process ESCAPE-8 points as another Unicode points. + In Linux: ESCAPE-16 will mean two different ESCAPE-8 seqences, + so we need HIGH-ESCAPE-PLANE-21 to restore UTF-8-RAW -> UTF-16 -> UTF-8-RAW + } + + if (flag is set) + { + it generates ESCAPE-16-21 for ESCAPE-8 points + so we can restore UTF-8-RAW -> UTF-16 -> UTF-8-RAW without HIGH-ESCAPE-PLANE-21. + } + + +Main USE CASES with UTF-8 <-> UTF-16 conversions: + + WIN32: UTF-16-RAW -> UTF-8 (Archive) -> UTF-16-RAW + { + set Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + Do NOT set Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + Do NOT set Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + + So we restore original SINGLE-SURROGATE-16 from single SINGLE-SURROGATE-8. + } + + Linux: UTF-8-RAW -> UTF-16 (Intermediate / Archive) -> UTF-8-RAW + { + we want restore original UTF-8-RAW sequence later from that ESCAPE-16. + Set the flags: + Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + } + + MacOS: UTF-8-RAW -> UTF-16 (Intermediate / Archive) -> UTF-8-RAW + { + we want to restore correct UTF-8 without any BMP processing: + Set the flags: + Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + } + +*/ + +// zero char is not allowed in (src) buf +bool Convert_UTF8_Buf_To_Unicode(const char *src, size_t srcSize, UString &dest, unsigned flags = 0); + +bool ConvertUTF8ToUnicode_Flags(const AString &src, UString &dest, unsigned flags = 0); +bool ConvertUTF8ToUnicode(const AString &src, UString &dest); + +#define Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR (1 << 8) +#define Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE (1 << 9) +// #define Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE (1 << 10) + +/* +Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR + + if (flag is NOT set) + { + we extract SINGLE-SURROGATE as normal UTF-8 + + In Windows : for UTF-16-RAW <-> UTF-8 (archive) <-> UTF-16-RAW in . + + In Linux : + use-case-1: UTF-8 -> UTF-16 -> UTF-8 doesn't generate UTF-16 SINGLE-SURROGATE, + if (Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR) is used. + use-case 2: UTF-16-7z (with SINGLE-SURROGATE from Windows) -> UTF-8 (Linux) + will generate SINGLE-SURROGATE-UTF-8 here. + } + + if (flag is set) + { + we generate UTF_REPLACEMENT_CHAR (0xfffd) for SINGLE_SURROGATE + it can be used for compatibility mode with WIN32 UTF function + or if we want UTF-8 stream without any errors + } + + +Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE + + if (flag is NOT set) it doesn't extract raw 8-bit symbol from Escape-Plane-16 + if (flag is set) it extracts raw 8-bit symbol from Escape-Plane-16 + + in Linux we need some way to extract NON-UTF8 RAW 8-bits from BMP (UTF-16 7z archive): + if (we use High-Escape-Plane), we can transfer BMP escapes to High-Escape-Plane. + if (we don't use High-Escape-Plane), we must use Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE. + + +Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE + // that flag affects the code only if (wchar_t is 32-bit) + // that mode with high-escape can be disabled now in UTFConvert.cpp + if (flag is NOT set) + it doesn't extract raw 8-bit symbol from High-Escape-Plane + if (flag is set) + it extracts raw 8-bit symbol from High-Escape-Plane + +Main use cases: + +WIN32 : UTF-16-RAW -> UTF-8 (archive) -> UTF-16-RAW + { + Do NOT set Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE. + Do NOT set Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR. + So we restore original UTF-16-RAW. + } + +Linix : UTF-8 with Escapes -> UTF-16 (7z archive) -> UTF-8 with Escapes + set Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE to extract non-UTF from 7z archive + set Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE for intermediate UTF-16. + Note: high esacape mode can be ignored now in UTFConvert.cpp + +macOS: + the system doesn't support incorrect UTF-8 in file names. + set Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR +*/ + +extern unsigned g_Unicode_To_UTF8_Flags; + +void ConvertUnicodeToUTF8_Flags(const UString &src, AString &dest, unsigned flags = 0); +void ConvertUnicodeToUTF8(const UString &src, AString &dest); + +void Convert_Unicode_To_UTF8_Buf(const UString &src, CByteBuffer &dest); + +/* +#ifndef _WIN32 +void Convert_UTF16_To_UTF32(const UString &src, UString &dest); +void Convert_UTF32_To_UTF16(const UString &src, UString &dest); +bool UTF32_IsThere_BigPoint(const UString &src); +bool Unicode_IsThere_BmpEscape(const UString &src); +#endif + +bool Unicode_IsThere_Utf16SurrogateError(const UString &src); +*/ + +#ifdef Z7_WCHART_IS_16BIT +#define Convert_UnicodeEsc16_To_UnicodeEscHigh(s) +#else +void Convert_UnicodeEsc16_To_UnicodeEscHigh(UString &s); +#endif + +/* +// #include "../../C/CpuArch.h" + +// ---------- Utf16 Little endian functions ---------- + +// We store 16-bit surrogates even in 32-bit WCHARs in Linux. +// So now we don't use the following code: + +#if WCHAR_MAX > 0xffff + +// void *p : pointer to src bytes stream +// size_t len : num Utf16 characters : it can include or not include NULL character + +inline size_t Utf16LE__Get_Num_WCHARs(const void *p, size_t len) +{ + #if WCHAR_MAX > 0xffff + size_t num_wchars = 0; + for (size_t i = 0; i < len; i++) + { + wchar_t c = GetUi16(p); + p = (const void *)((const Byte *)p + 2); + if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) + { + wchar_t c2 = GetUi16(p); + if (c2 >= 0xdc00 && c2 < 0xe000) + { + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + p = (const void *)((const Byte *)p + 2); + i++; + } + } + num_wchars++; + } + return num_wchars; + #else + UNUSED_VAR(p) + return len; + #endif +} + +// #include <stdio.h> + +inline wchar_t *Utf16LE__To_WCHARs_Sep(const void *p, size_t len, wchar_t *dest) +{ + for (size_t i = 0; i < len; i++) + { + wchar_t c = GetUi16(p); + p = (const void *)((const Byte *)p + 2); + + #if WCHAR_PATH_SEPARATOR != L'/' + if (c == L'/') + c = WCHAR_PATH_SEPARATOR; + #endif + + #if WCHAR_MAX > 0xffff + + if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) + { + wchar_t c2 = GetUi16(p); + if (c2 >= 0xdc00 && c2 < 0xe000) + { + // printf("\nSurragate : %4x %4x -> ", (int)c, (int)c2); + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + p = (const void *)((const Byte *)p + 2); + i++; + // printf("%4x\n", (int)c); + } + } + + #endif + + *dest++ = c; + } + return dest; +} + + +inline size_t Get_Num_Utf16_chars_from_wchar_string(const wchar_t *p) +{ + size_t num = 0; + for (;;) + { + wchar_t c = *p++; + if (c == 0) + return num; + num += ((c >= 0x10000 && c < 0x110000) ? 2 : 1); + } + return num; +} + +inline Byte *wchars_to_Utf16LE(const wchar_t *p, Byte *dest) +{ + for (;;) + { + wchar_t c = *p++; + if (c == 0) + return dest; + if (c >= 0x10000 && c < 0x110000) + { + SetUi16(dest , (UInt16)(0xd800 + ((c >> 10) & 0x3FF))); + SetUi16(dest + 2, (UInt16)(0xdc00 + ( c & 0x3FF))); + dest += 4; + } + else + { + SetUi16(dest, c); + dest += 2; + } + } +} + +#endif +*/ #endif diff --git a/3rdparty/lzma/CPP/Common/Wildcard.cpp b/3rdparty/lzma/CPP/Common/Wildcard.cpp index 5e6ddfc6e3f..798cbd957b4 100644 --- a/3rdparty/lzma/CPP/Common/Wildcard.cpp +++ b/3rdparty/lzma/CPP/Common/Wildcard.cpp @@ -4,9 +4,17 @@ #include "Wildcard.h" +extern +bool g_CaseSensitive; bool g_CaseSensitive = #ifdef _WIN32 false; + #elif defined (__APPLE__) + #ifdef TARGET_OS_IPHONE + true; + #else + false; + #endif #else true; #endif @@ -19,19 +27,92 @@ bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2) return IsString1PrefixedByString2_NoCase(s1, s2); } +// #include <stdio.h> + +/* +static int MyStringCompare_PathLinux(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + if (c1 == 0) return -1; + if (c2 == 0) return 1; + if (c1 == '/') c1 = 0; + if (c2 == '/') c2 = 0; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + continue; + } + if (c1 == 0) return 0; + } +} +*/ + +static int MyStringCompare_Path(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + if (c1 == 0) return -1; + if (c2 == 0) return 1; + if (IS_PATH_SEPAR(c1)) c1 = 0; + if (IS_PATH_SEPAR(c2)) c2 = 0; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + continue; + } + if (c1 == 0) return 0; + } +} + +static int MyStringCompareNoCase_Path(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + if (c1 == 0) return -1; + if (c2 == 0) return 1; + if (IS_PATH_SEPAR(c1)) c1 = 0; + if (IS_PATH_SEPAR(c2)) c2 = 0; + c1 = MyCharUpper(c1); + c2 = MyCharUpper(c2); + if (c1 < c2) return -1; + if (c1 > c2) return 1; + continue; + } + if (c1 == 0) return 0; + } +} + int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW { + /* + printf("\nCompareFileNames"); + printf("\n S1: %ls", s1); + printf("\n S2: %ls", s2); + printf("\n"); + */ + // 21.07 : we parse PATH_SEPARATOR so: 0 < PATH_SEPARATOR < 1 if (g_CaseSensitive) - return wcscmp(s1, s2); - return MyStringCompareNoCase(s1, s2); + return MyStringCompare_Path(s1, s2); + return MyStringCompareNoCase_Path(s1, s2); } #ifndef USE_UNICODE_FSTRING int CompareFileNames(const char *s1, const char *s2) { - if (g_CaseSensitive) - return wcscmp(fs2us(s1), fs2us(s2)); - return MyStringCompareNoCase(fs2us(s1), fs2us(s2)); + const UString u1 = fs2us(s1); + const UString u2 = fs2us(s2); + return CompareFileNames(u1, u2); } #endif @@ -44,8 +125,8 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name) { for (;;) { - wchar_t m = *mask; - wchar_t c = *name; + const wchar_t m = *mask; + const wchar_t c = *name; if (m == 0) return (c == 0); if (m == '*') @@ -120,24 +201,16 @@ void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &na name = p; } +/* UString ExtractDirPrefixFromPath(const UString &path) { - const wchar_t *start = path; - const wchar_t *p = start + path.Len(); - for (; p != start; p--) - if (IsPathSepar(*(p - 1))) - break; - return path.Left((unsigned)(p - start)); + return path.Left(path.ReverseFind_PathSepar() + 1)); } +*/ UString ExtractFileNameFromPath(const UString &path) { - const wchar_t *start = path; - const wchar_t *p = start + path.Len(); - for (; p != start; p--) - if (IsPathSepar(*(p - 1))) - break; - return p; + return UString(path.Ptr((unsigned)(path.ReverseFind_PathSepar() + 1))); } @@ -235,12 +308,12 @@ bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const { if (WildcardMatching) { - if (!DoesWildcardMatchName(PathParts[i], pathParts[i + d])) + if (!DoesWildcardMatchName(PathParts[i], pathParts[i + (unsigned)d])) break; } else { - if (CompareFileNames(PathParts[i], pathParts[i + d]) != 0) + if (CompareFileNames(PathParts[i], pathParts[i + (unsigned)d]) != 0) break; } } @@ -264,16 +337,14 @@ int CCensorNode::FindSubNode(const UString &name) const { FOR_VECTOR (i, SubNodes) if (CompareFileNames(SubNodes[i].Name, name) == 0) - return i; + return (int)i; return -1; } void CCensorNode::AddItemSimple(bool include, CItem &item) { - if (include) - IncludeItems.Add(item); - else - ExcludeItems.Add(item); + CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems; + items.Add(item); } void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex) @@ -288,6 +359,7 @@ void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex) AddItemSimple(include, item); return; } + const UString &front = item.PathParts.Front(); // WIN32 doesn't support wildcards in file names @@ -298,23 +370,23 @@ void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex) AddItemSimple(include, item); return; } - int index = FindSubNode(front); - if (index < 0) - index = SubNodes.Add(CCensorNode(front, this)); + CCensorNode &subNode = Find_SubNode_Or_Add_New(front); item.PathParts.Delete(0); - SubNodes[index].AddItem(include, item, ignoreWildcardIndex - 1); + subNode.AddItem(include, item, ignoreWildcardIndex - 1); } -void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching) +/* +void CCensorNode::AddItem(bool include, const UString &path, const CCensorPathProps &props) { CItem item; SplitPathToParts(path, item.PathParts); - item.Recursive = recursive; - item.ForFile = forFile; - item.ForDir = forDir; - item.WildcardMatching = wildcardMatching; + item.Recursive = props.Recursive; + item.ForFile = props.ForFile; + item.ForDir = props.ForDir; + item.WildcardMatching = props.WildcardMatching; AddItem(include, item); } +*/ bool CCensorNode::NeedCheckSubDirs() const { @@ -353,18 +425,19 @@ bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, boo 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) + if (pathParts.Size() > 1) { - UStringVector pathParts2 = pathParts; - pathParts2.Delete(0); - if (SubNodes[index].CheckPathVect(pathParts2, isFile, include)) - return true; + int index = FindSubNode(pathParts.Front()); + if (index >= 0) + { + UStringVector pathParts2 = pathParts; + pathParts2.Delete(0); + if (SubNodes[(unsigned)index].CheckPathVect(pathParts2, isFile, include)) + return true; + } } + bool finded = CheckPathCurrent(true, pathParts, isFile); + include = finded; // if (!finded), then (true) is allowed also return finded; } @@ -400,14 +473,26 @@ bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) } */ -bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const +bool CCensorNode::CheckPathToRoot_Change(bool include, UStringVector &pathParts, bool isFile) const { if (CheckPathCurrent(include, pathParts, isFile)) return true; - if (Parent == 0) + if (!Parent) return false; pathParts.Insert(0, Name); - return Parent->CheckPathToRoot(include, pathParts, isFile); + return Parent->CheckPathToRoot_Change(include, pathParts, isFile); +} + +bool CCensorNode::CheckPathToRoot(bool include, const UStringVector &pathParts, bool isFile) const +{ + if (CheckPathCurrent(include, pathParts, isFile)) + return true; + if (!Parent) + return false; + UStringVector pathParts2; + pathParts2.Add(Name); + pathParts2 += pathParts; + return Parent->CheckPathToRoot_Change(include, pathParts2, isFile); } /* @@ -419,39 +504,21 @@ bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool 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); + Find_SubNode_Or_Add_New(node.Name).ExtendExclude(node); } } -int CCensor::FindPrefix(const UString &prefix) const +int CCensor::FindPairForPrefix(const UString &prefix) const { FOR_VECTOR (i, Pairs) if (CompareFileNames(Pairs[i].Prefix, prefix) == 0) - return i; + return (int)i; return -1; } @@ -459,8 +526,10 @@ int CCensor::FindPrefix(const UString &prefix) const 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 c = s[0]; + c |= 0x20; + c -= 'a'; + return c <= (unsigned)('z' - 'a') && s[1] == ':' && s[2] == 0; } unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts) @@ -488,9 +557,12 @@ static unsigned GetNumPrefixParts(const UStringVector &pathParts) { if (pathParts.IsEmpty()) return 0; + + /* empty last part could be removed already from (pathParts), + if there was tail path separator (slash) in original full path string. */ #ifdef _WIN32 - + if (IsDriveColonName(pathParts[0])) return 1; if (!pathParts[0].IsEmpty()) @@ -531,7 +603,8 @@ static unsigned GetNumPrefixParts(const UStringVector &pathParts) #endif } -void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching) +void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, + const CCensorPathProps &props) { if (path.IsEmpty()) throw "Empty file path"; @@ -539,12 +612,26 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat UStringVector pathParts; SplitPathToParts(path, pathParts); + CCensorPathProps props2 = props; + bool forFile = true; - if (pathParts.Back().IsEmpty()) + bool forDir = true; + const UString &back = pathParts.Back(); + if (back.IsEmpty()) { + // we have tail path separator. So it's directory. + // we delete tail path separator here even for "\" and "c:\" forFile = false; pathParts.DeleteBack(); } + else + { + if (props.MarkMode == kMark_StrictFile + || (props.MarkMode == kMark_StrictFile_IfWildcard + && DoesNameContainWildcard(back))) + forDir = false; + } + UString prefix; @@ -561,6 +648,7 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat if (pathMode != k_AbsPath) { + // detection of the number of Skip Parts for prefix ignoreWildcardIndex = -1; const unsigned numPrefixParts = GetNumPrefixParts(pathParts); @@ -568,6 +656,7 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat if (pathMode != k_FullPath) { + // if absolute path, then all parts before last part will be in prefix if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts) numSkipParts = pathParts.Size() - 1; } @@ -577,22 +666,25 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat { const UString &part = pathParts[i]; if (part == L".." || part == L".") - dotsIndex = i; + dotsIndex = (int)i; } if (dotsIndex >= 0) + { if (dotsIndex == (int)pathParts.Size() - 1) numSkipParts = pathParts.Size(); else numSkipParts = pathParts.Size() - 1; + } } + // we split (pathParts) to (prefix) and (pathParts). for (unsigned i = 0; i < numSkipParts; i++) { { const UString &front = pathParts.Front(); // WIN32 doesn't support wildcards in file names - if (wildcardMatching) + if (props.WildcardMatching) if (i >= numPrefixParts && DoesNameContainWildcard(front)) break; prefix += front; @@ -602,30 +694,45 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat } } - int index = FindPrefix(prefix); + int index = FindPairForPrefix(prefix); if (index < 0) - index = Pairs.Add(CPair(prefix)); + { + index = (int)Pairs.Size(); + Pairs.AddNew().Prefix = prefix; + } if (pathMode != k_AbsPath) { - if (pathParts.IsEmpty() || pathParts.Size() == 1 && pathParts[0].IsEmpty()) + 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(L"*"); + pathParts.Add(UString("*")); forFile = true; - wildcardMatching = true; - recursive = false; + forDir = true; + props2.WildcardMatching = true; + props2.Recursive = false; } } + /* + // not possible now + if (!forDir && !forFile) + { + UString s ("file path was blocked for files and directories: "); + s += path; + throw s; + // return; // for debug : ignore item (don't create Item) + } + */ + CItem item; item.PathParts = pathParts; - item.ForDir = true; + item.ForDir = forDir; item.ForFile = forFile; - item.Recursive = recursive; - item.WildcardMatching = wildcardMatching; - Pairs[index].Head.AddItem(include, item, ignoreWildcardIndex); + item.Recursive = props2.Recursive; + item.WildcardMatching = props2.WildcardMatching; + Pairs[(unsigned)index].Head.AddItem(include, item, ignoreWildcardIndex); } /* @@ -665,18 +772,17 @@ void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode) FOR_VECTOR(i, CensorPaths) { const CCensorPath &cp = CensorPaths[i]; - AddItem(censorPathMode, cp.Include, cp.Path, cp.Recursive, cp.WildcardMatching); + AddItem(censorPathMode, cp.Include, cp.Path, cp.Props); } CensorPaths.Clear(); } -void CCensor::AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching) +void CCensor::AddPreItem(bool include, const UString &path, const CCensorPathProps &props) { CCensorPath &cp = CensorPaths.AddNew(); cp.Path = path; cp.Include = include; - cp.Recursive = recursive; - cp.WildcardMatching = wildcardMatching; + cp.Props = props; } } diff --git a/3rdparty/lzma/CPP/Common/Wildcard.h b/3rdparty/lzma/CPP/Common/Wildcard.h index 512687d1e67..4f81da923a0 100644 --- a/3rdparty/lzma/CPP/Common/Wildcard.h +++ b/3rdparty/lzma/CPP/Common/Wildcard.h @@ -1,7 +1,7 @@ // Common/Wildcard.h -#ifndef __COMMON_WILDCARD_H -#define __COMMON_WILDCARD_H +#ifndef ZIP7_INC_COMMON_WILDCARD_H +#define ZIP7_INC_COMMON_WILDCARD_H #include "MyString.h" @@ -51,50 +51,117 @@ struct CItem bool CheckPath(const UStringVector &pathParts, bool isFile) const; }; -class CCensorNode + + +const Byte kMark_FileOrDir = 0; +const Byte kMark_StrictFile = 1; +const Byte kMark_StrictFile_IfWildcard = 2; + +struct CCensorPathProps +{ + bool Recursive; + bool WildcardMatching; + Byte MarkMode; + + CCensorPathProps(): + Recursive(false), + WildcardMatching(true), + MarkMode(kMark_FileOrDir) + {} +}; + + +class CCensorNode MY_UNCOPYABLE { 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; + // bool ExcludeDirItems; + + CCensorNode(): + Parent(NULL) + // , ExcludeDirItems(false) + {} - CCensorNode(): Parent(0) { }; - CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { }; + CCensorNode(const UString &name, CCensorNode *parent): + Parent(parent) + // , ExcludeDirItems(false) + , Name(name) + {} UString Name; // WIN32 doesn't support wildcards in file names CObjectVector<CCensorNode> SubNodes; CObjectVector<CItem> IncludeItems; CObjectVector<CItem> ExcludeItems; + CCensorNode &Find_SubNode_Or_Add_New(const UString &name) + { + int i = FindSubNode(name); + if (i >= 0) + return SubNodes[(unsigned)i]; + // return SubNodes.Add(CCensorNode(name, this)); + CCensorNode &node = SubNodes.AddNew(); + node.Parent = this; + node.Name = name; + return node; + } + 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); + // void AddItem(bool include, const UString &path, const CCensorPathProps &props); + void Add_Wildcard() + { + CItem item; + item.PathParts.Add(L"*"); + item.Recursive = false; + item.ForFile = true; + item.ForDir = true; + item.WildcardMatching = true; + AddItem( + true // include + , item); + } + // NeedCheckSubDirs() returns true, if there are IncludeItems rules that affect items in subdirs bool NeedCheckSubDirs() const; bool AreThereIncludeItems() const; + /* + CheckPathVect() doesn't check path in Parent CCensorNode + so use CheckPathVect() for root CCensorNode + OUT: + returns (true) && (include = false) - file in exlude list + returns (true) && (include = true) - file in include list and is not in exlude list + returns (false) - file is not in (include/exlude) list + */ + bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) 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; + // CheckPathToRoot_Change() changes pathParts !!! + bool CheckPathToRoot_Change(bool include, UStringVector &pathParts, bool isFile) const; + bool CheckPathToRoot(bool include, const UStringVector &pathParts, bool isFile) const; + // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const; void ExtendExclude(const CCensorNode &fromNodes); }; -struct CPair + +struct CPair MY_UNCOPYABLE { UString Prefix; CCensorNode Head; - CPair(const UString &prefix): Prefix(prefix) { }; + // CPair(const UString &prefix): Prefix(prefix) { }; }; + enum ECensorPathMode { k_RelatPath, // absolute prefix as Prefix, remain path in Tree @@ -102,48 +169,63 @@ enum ECensorPathMode k_AbsPath // full path in Tree }; + struct CCensorPath { UString Path; bool Include; - bool Recursive; - bool WildcardMatching; + CCensorPathProps Props; CCensorPath(): - Include(true), - Recursive(false), - WildcardMatching(true) - {} + Include(true) + {} }; -class CCensor + +class CCensor MY_UNCOPYABLE { - int FindPrefix(const UString &prefix) const; + int FindPairForPrefix(const UString &prefix) const; public: CObjectVector<CPair> Pairs; + bool ExcludeDirItems; + bool ExcludeFileItems; + + CCensor(): + ExcludeDirItems(false), + ExcludeFileItems(false) + {} + 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); + void AddItem(ECensorPathMode pathMode, bool include, const UString &path, const CCensorPathProps &props); // 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) + void AddPreItem(bool include, const UString &path, const CCensorPathProps &props); + + void AddPreItem_NoWildcard(const UString &path) { - AddPreItem(true, path, false, false); + CCensorPathProps props; + props.WildcardMatching = false; + AddPreItem( + true, // include + path, props); } void AddPreItem_Wildcard() { - AddPreItem(true, L"*", false, true); + CCensorPathProps props; + // props.WildcardMatching = true; + AddPreItem( + true, // include + UString("*"), props); } }; - } #endif diff --git a/3rdparty/lzma/CPP/Common/XzCrc64Init.cpp b/3rdparty/lzma/CPP/Common/XzCrc64Init.cpp new file mode 100644 index 00000000000..5cb8e674489 --- /dev/null +++ b/3rdparty/lzma/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/3rdparty/lzma/CPP/Common/XzCrc64Reg.cpp b/3rdparty/lzma/CPP/Common/XzCrc64Reg.cpp index 33b524932c9..e9e67efcbfc 100644 --- a/3rdparty/lzma/CPP/Common/XzCrc64Reg.cpp +++ b/3rdparty/lzma/CPP/Common/XzCrc64Reg.cpp @@ -9,34 +9,31 @@ #include "../7zip/Common/RegisterCodec.h" -class CXzCrc64Hasher: - public IHasher, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CXzCrc64Hasher + , IHasher +) UInt64 _crc; - Byte mtDummy[1 << 7]; - public: - CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {} + Byte _mtDummy[1 << 7]; // it's public to eliminate clang warning: unused private field - MY_UNKNOWN_IMP1(IHasher) - INTERFACE_IHasher(;) + CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {} }; -STDMETHODIMP_(void) CXzCrc64Hasher::Init() throw() +Z7_COM7F_IMF2(void, CXzCrc64Hasher::Init()) { _crc = CRC64_INIT_VAL; } -STDMETHODIMP_(void) CXzCrc64Hasher::Update(const void *data, UInt32 size) throw() +Z7_COM7F_IMF2(void, CXzCrc64Hasher::Update(const void *data, UInt32 size)) { _crc = Crc64Update(_crc, data, size); } -STDMETHODIMP_(void) CXzCrc64Hasher::Final(Byte *digest) throw() +Z7_COM7F_IMF2(void, CXzCrc64Hasher::Final(Byte *digest)) { - UInt64 val = CRC64_GET_DIGEST(_crc); - SetUi64(digest, val); + const UInt64 val = CRC64_GET_DIGEST(_crc); + SetUi64(digest, val) } REGISTER_HASHER(CXzCrc64Hasher, 0x4, "CRC64", 8) |