diff options
author | Karsten Heimrich <karsten.heimrich@theqtcompany.com> | 2015-06-09 16:04:24 +0200 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@theqtcompany.com> | 2015-06-10 08:15:38 +0000 |
commit | 4677d362982a38c6e2aabb667e33aaa7f921f018 (patch) | |
tree | fe3b676288f05a87cdbb53a170e815427e3d9380 /src/libs/7zip/win/CPP/Common | |
parent | 22ec6aa53e44069c03c7baf94881949c7a4facff (diff) |
Update source tree with version 9.38.beta of LZMA SDK.
- Remove unused files.
- Split in .pri files.
- Add HEADERS section.
- Adjust lib7z_facade.
Change-Id: I31e7bafbfe1a9346364bd58c391601955f98ad3a
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
Diffstat (limited to 'src/libs/7zip/win/CPP/Common')
43 files changed, 3671 insertions, 1842 deletions
diff --git a/src/libs/7zip/win/CPP/Common/AutoPtr.h b/src/libs/7zip/win/CPP/Common/AutoPtr.h deleted file mode 100644 index 006d31551..000000000 --- a/src/libs/7zip/win/CPP/Common/AutoPtr.h +++ /dev/null @@ -1,35 +0,0 @@ -// Common/AutoPtr.h - -#ifndef __COMMON_AUTOPTR_H -#define __COMMON_AUTOPTR_H - -template<class T> class CMyAutoPtr -{ - T *_p; -public: - CMyAutoPtr(T *p = 0) : _p(p) {} - CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {} - CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p) - { - reset(p.release()); - return (*this); - } - ~CMyAutoPtr() { delete _p; } - T& operator*() const { return *_p; } - // T* operator->() const { return (&**this); } - T* get() const { return _p; } - T* release() - { - T *tmp = _p; - _p = 0; - return tmp; - } - void reset(T* p = 0) - { - if (p != _p) - delete _p; - _p = p; - } -}; - -#endif diff --git a/src/libs/7zip/win/CPP/Common/Buffer.h b/src/libs/7zip/win/CPP/Common/Buffer.h deleted file mode 100644 index 118fe11fc..000000000 --- a/src/libs/7zip/win/CPP/Common/Buffer.h +++ /dev/null @@ -1,77 +0,0 @@ -// Common/Buffer.h - -#ifndef __COMMON_BUFFER_H -#define __COMMON_BUFFER_H - -#include "Defs.h" - -template <class T> class CBuffer -{ -protected: - size_t _capacity; - T *_items; -public: - void Free() - { - delete []_items; - _items = 0; - _capacity = 0; - } - CBuffer(): _capacity(0), _items(0) {}; - CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; } - CBuffer(size_t size): _items(0), _capacity(0) { SetCapacity(size); } - virtual ~CBuffer() { delete []_items; } - operator T *() { return _items; }; - operator const T *() const { return _items; }; - size_t GetCapacity() const { return _capacity; } - void SetCapacity(size_t newCapacity) - { - if (newCapacity == _capacity) - return; - T *newBuffer; - if (newCapacity > 0) - { - newBuffer = new T[newCapacity]; - if (_capacity > 0) - memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T)); - } - else - newBuffer = 0; - delete []_items; - _items = newBuffer; - _capacity = newCapacity; - } - CBuffer& operator=(const CBuffer &buffer) - { - Free(); - if (buffer._capacity > 0) - { - SetCapacity(buffer._capacity); - memmove(_items, buffer._items, buffer._capacity * sizeof(T)); - } - return *this; - } -}; - -template <class T> -bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2) -{ - if (b1.GetCapacity() != b2.GetCapacity()) - return false; - for (size_t i = 0; i < b1.GetCapacity(); i++) - if (b1[i] != b2[i]) - return false; - return true; -} - -template <class T> -bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2) -{ - return !(b1 == b2); -} - -typedef CBuffer<char> CCharBuffer; -typedef CBuffer<wchar_t> CWCharBuffer; -typedef CBuffer<unsigned char> CByteBuffer; - -#endif diff --git a/src/libs/7zip/win/CPP/Common/CRC.cpp b/src/libs/7zip/win/CPP/Common/CRC.cpp deleted file mode 100644 index 9a9f81fb7..000000000 --- a/src/libs/7zip/win/CPP/Common/CRC.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// Common/CRC.cpp - -#include "StdAfx.h" - -#include "../../C/7zCrc.h" - -struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit; diff --git a/src/libs/7zip/win/CPP/Common/C_FileIO.cpp b/src/libs/7zip/win/CPP/Common/C_FileIO.cpp deleted file mode 100644 index b4893d658..000000000 --- a/src/libs/7zip/win/CPP/Common/C_FileIO.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// Common/C_FileIO.h - -#include "C_FileIO.h" - -#include <fcntl.h> -#include <unistd.h> - -namespace NC { -namespace NFile { -namespace NIO { - -bool CFileBase::OpenBinary(const char *name, int flags) -{ - #ifdef O_BINARY - flags |= O_BINARY; - #endif - Close(); - _handle = ::open(name, flags, 0666); - return _handle != -1; -} - -bool CFileBase::Close() -{ - if (_handle == -1) - return true; - if (close(_handle) != 0) - return false; - _handle = -1; - return true; -} - -bool CFileBase::GetLength(UInt64 &length) const -{ - off_t curPos = Seek(0, SEEK_CUR); - off_t lengthTemp = Seek(0, SEEK_END); - Seek(curPos, SEEK_SET); - length = (UInt64)lengthTemp; - return true; -} - -off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const -{ - return ::lseek(_handle, distanceToMove, moveMethod); -} - -///////////////////////// -// CInFile - -bool CInFile::Open(const char *name) -{ - return CFileBase::OpenBinary(name, O_RDONLY); -} - -bool CInFile::OpenShared(const char *name, bool) -{ - return Open(name); -} - -ssize_t CInFile::Read(void *data, size_t size) -{ - return read(_handle, data, size); -} - -///////////////////////// -// COutFile - -bool COutFile::Create(const char *name, bool createAlways) -{ - if (createAlways) - { - Close(); - _handle = ::creat(name, 0666); - return _handle != -1; - } - return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY); -} - -bool COutFile::Open(const char *name, DWORD creationDisposition) -{ - return Create(name, false); -} - -ssize_t COutFile::Write(const void *data, size_t size) -{ - return write(_handle, data, size); -} - -}}} diff --git a/src/libs/7zip/win/CPP/Common/C_FileIO.h b/src/libs/7zip/win/CPP/Common/C_FileIO.h deleted file mode 100644 index 27aa56869..000000000 --- a/src/libs/7zip/win/CPP/Common/C_FileIO.h +++ /dev/null @@ -1,47 +0,0 @@ -// Common/C_FileIO.h - -#ifndef __COMMON_C_FILEIO_H -#define __COMMON_C_FILEIO_H - -#include <stdio.h> -#include <sys/types.h> - -#include "Types.h" -#include "MyWindows.h" - -namespace NC { -namespace NFile { -namespace NIO { - -class CFileBase -{ -protected: - int _handle; - bool OpenBinary(const char *name, int flags); -public: - CFileBase(): _handle(-1) {}; - ~CFileBase() { Close(); } - bool Close(); - bool GetLength(UInt64 &length) const; - off_t Seek(off_t distanceToMove, int moveMethod) const; -}; - -class CInFile: public CFileBase -{ -public: - bool Open(const char *name); - bool OpenShared(const char *name, bool shareForWrite); - ssize_t Read(void *data, size_t size); -}; - -class COutFile: public CFileBase -{ -public: - bool Create(const char *name, bool createAlways); - bool Open(const char *name, DWORD creationDisposition); - ssize_t Write(const void *data, size_t size); -}; - -}}} - -#endif diff --git a/src/libs/7zip/win/CPP/Common/ComTry.h b/src/libs/7zip/win/CPP/Common/ComTry.h index fb4ef0459..c8aa4aedc 100644 --- a/src/libs/7zip/win/CPP/Common/ComTry.h +++ b/src/libs/7zip/win/CPP/Common/ComTry.h @@ -9,7 +9,7 @@ #define COM_TRY_BEGIN try { #define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; } - + // catch(const CNewException &) { return E_OUTOFMEMORY; } // catch(const CSystemException &e) { return e.ErrorCode; } // catch(...) { return E_FAIL; } diff --git a/src/libs/7zip/win/CPP/Common/CommandLineParser.cpp b/src/libs/7zip/win/CPP/Common/CommandLineParser.cpp index 80b467fcb..ac9ae1960 100644 --- a/src/libs/7zip/win/CPP/Common/CommandLineParser.cpp +++ b/src/libs/7zip/win/CPP/Common/CommandLineParser.cpp @@ -4,6 +4,20 @@ #include "CommandLineParser.h" +static bool IsString1PrefixedByString2_NoCase(const wchar_t *u, const char *a) +{ + for (;;) + { + char c = *a; + if (c == 0) + return true; + if (MyCharLower_Ascii(c) != MyCharLower_Ascii(*u)) + return false; + a++; + u++; + } +} + namespace NCommandLineParser { bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2) @@ -11,13 +25,13 @@ bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2) dest1.Empty(); dest2.Empty(); bool quoteMode = false; - int i; - for (i = 0; i < src.Length(); i++) + unsigned i; + for (i = 0; i < src.Len(); i++) { wchar_t c = src[i]; - if (c == L' ' && !quoteMode) + if ((c == L' ' || c == L'\t') && !quoteMode) { - dest2 = src.Mid(i + 1); + dest2 = src.Ptr(i + 1); return i != 0; } if (c == L'\"') @@ -45,21 +59,18 @@ void SplitCommandLine(const UString &s, UStringVector &parts) } -static const wchar_t kSwitchID1 = '-'; -// static const wchar_t kSwitchID2 = '/'; - -static const wchar_t kSwitchMinus = '-'; -static const wchar_t *kStopSwitchParsing = L"--"; +static const char *kStopSwitchParsing = "--"; -static bool IsItSwitchChar(wchar_t c) +static bool inline IsItSwitchChar(wchar_t c) { - return (c == kSwitchID1 /*|| c == kSwitchID2 */); + return (c == '-'); } -CParser::CParser(int numSwitches): - _numSwitches(numSwitches) +CParser::CParser(unsigned numSwitches): + _numSwitches(numSwitches), + _switches(0) { - _switches = new CSwitchResult[_numSwitches]; + _switches = new CSwitchResult[numSwitches]; } CParser::~CParser() @@ -67,163 +78,121 @@ CParser::~CParser() delete []_switches; } -void CParser::ParseStrings(const CSwitchForm *switchForms, - const UStringVector &commandStrings) + +// 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) { - int numCommandStrings = commandStrings.Size(); - bool stopSwitch = false; - for (int i = 0; i < numCommandStrings; i++) + if (s.IsEmpty() || !IsItSwitchChar(s[0])) + return false; + + unsigned pos = 1; + unsigned switchIndex = 0; + int maxLen = -1; + + for (unsigned i = 0; i < _numSwitches; i++) { - const UString &s = commandStrings[i]; - if (stopSwitch) - NonSwitchStrings.Add(s); - else - if (s == kStopSwitchParsing) - stopSwitch = true; - else - if (!ParseString(s, switchForms)) - NonSwitchStrings.Add(s); + const char *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)) + { + switchIndex = i; + maxLen = switchLen; + } } -} -// if string contains switch then function updates switch structures -// out: (string is a switch) -bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) -{ - int len = s.Length(); - if (len == 0) + if (maxLen < 0) + { + ErrorMessage = "Unknown switch:"; return false; - int pos = 0; - if (!IsItSwitchChar(s[pos])) + } + + pos += maxLen; + + CSwitchResult &sw = _switches[switchIndex]; + const CSwitchForm &form = switchForms[switchIndex]; + + if (!form.Multi && sw.ThereIs) + { + ErrorMessage = "Multiple instances for switch:"; return false; - while (pos < len) + } + + sw.ThereIs = true; + + int rem = s.Len() - pos; + if (rem < form.MinLen) { - if (IsItSwitchChar(s[pos])) - pos++; - const int kNoLen = -1; - int matchedSwitchIndex = 0; // GCC Warning - int maxLen = kNoLen; - for (int switchIndex = 0; switchIndex < _numSwitches; switchIndex++) - { - int switchLen = MyStringLen(switchForms[switchIndex].IDString); - if (switchLen <= maxLen || pos + switchLen > len) - continue; + ErrorMessage = "Too short switch:"; + return false; + } + + sw.WithMinus = false; + sw.PostCharIndex = -1; - UString temp = s + pos; - temp = temp.Left(switchLen); - if (temp.CompareNoCase(switchForms[switchIndex].IDString) == 0) - // if (_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0) + switch (form.Type) + { + case NSwitchType::kMinus: + if (rem != 0) { - matchedSwitchIndex = switchIndex; - maxLen = switchLen; + sw.WithMinus = (s[pos] == '-'); + if (sw.WithMinus) + pos++; } - } - if (maxLen == kNoLen) - throw "maxLen == kNoLen"; - CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex]; - const CSwitchForm &switchForm = switchForms[matchedSwitchIndex]; - if ((!switchForm.Multi) && matchedSwitch.ThereIs) - throw "switch must be single"; - matchedSwitch.ThereIs = true; - pos += maxLen; - int tailSize = len - pos; - NSwitchType::EEnum type = switchForm.Type; - switch(type) - { - case NSwitchType::kPostMinus: - { - if (tailSize == 0) - matchedSwitch.WithMinus = false; - else - { - matchedSwitch.WithMinus = (s[pos] == kSwitchMinus); - if (matchedSwitch.WithMinus) - pos++; - } - break; - } - case NSwitchType::kPostChar: - { - if (tailSize < switchForm.MinLen) - throw "switch is not full"; - UString set = switchForm.PostCharSet; - const int kEmptyCharValue = -1; - if (tailSize == 0) - matchedSwitch.PostCharIndex = kEmptyCharValue; - else - { - int index = set.Find(s[pos]); - if (index < 0) - matchedSwitch.PostCharIndex = kEmptyCharValue; - else - { - matchedSwitch.PostCharIndex = index; - pos++; - } - } - break; - } - case NSwitchType::kLimitedPostString: - case NSwitchType::kUnLimitedPostString: + break; + + case NSwitchType::kChar: + if (rem != 0) + { + wchar_t c = s[pos]; + if (c <= 0x7F) { - int minLen = switchForm.MinLen; - if (tailSize < minLen) - throw "switch is not full"; - if (type == NSwitchType::kUnLimitedPostString) - { - matchedSwitch.PostStrings.Add(s.Mid(pos)); - return true; - } - int maxLen = switchForm.MaxLen; - UString stringSwitch = s.Mid(pos, minLen); - pos += minLen; - for (int i = minLen; i < maxLen && pos < len; i++, pos++) - { - wchar_t c = s[pos]; - if (IsItSwitchChar(c)) - break; - stringSwitch += c; - } - matchedSwitch.PostStrings.Add(stringSwitch); - break; + sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c); + if (sw.PostCharIndex >= 0) + pos++; } - case NSwitchType::kSimple: - break; - } + } + break; + + case NSwitchType::kString: + sw.PostStrings.Add((const wchar_t *)s + pos); + return true; + } + if (pos != s.Len()) + { + ErrorMessage = "Too long switch:"; + return false; } return true; } -const CSwitchResult& CParser::operator[](size_t index) const -{ - return _switches[index]; -} - -///////////////////////////////// -// Command parsing procedures - -int ParseCommand(int numCommandForms, const CCommandForm *commandForms, - const UString &commandString, UString &postString) +bool CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings) { - for (int i = 0; i < numCommandForms; i++) + ErrorLine.Empty(); + bool stopSwitch = false; + FOR_VECTOR (i, commandStrings) { - const UString id = commandForms[i].IDString; - if (commandForms[i].PostStringMode) + const UString &s = commandStrings[i]; + if (!stopSwitch) { - if (commandString.Find(id) == 0) + if (s.IsEqualTo(kStopSwitchParsing)) { - postString = commandString.Mid(id.Length()); - return i; + stopSwitch = true; + continue; } - } - else - if (commandString == id) + if (!s.IsEmpty() && IsItSwitchChar(s[0])) { - postString.Empty(); - return i; + if (ParseString(s, switchForms)) + continue; + ErrorLine = s; + return false; } + } + NonSwitchStrings.Add(s); } - return -1; + return true; } - + } diff --git a/src/libs/7zip/win/CPP/Common/CommandLineParser.h b/src/libs/7zip/win/CPP/Common/CommandLineParser.h index 3d0b41dd4..e3e6e6b14 100644 --- a/src/libs/7zip/win/CPP/Common/CommandLineParser.h +++ b/src/libs/7zip/win/CPP/Common/CommandLineParser.h @@ -10,63 +10,54 @@ namespace NCommandLineParser { bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2); void SplitCommandLine(const UString &s, UStringVector &parts); -namespace NSwitchType { +namespace NSwitchType +{ enum EEnum { kSimple, - kPostMinus, - kLimitedPostString, - kUnLimitedPostString, - kPostChar + kMinus, + kString, + kChar }; } struct CSwitchForm { - const wchar_t *IDString; - NSwitchType::EEnum Type; + const char *Key; + Byte Type; bool Multi; - int MinLen; - int MaxLen; - const wchar_t *PostCharSet; + Byte MinLen; + // int MaxLen; + const char *PostCharSet; }; struct CSwitchResult { bool ThereIs; bool WithMinus; - UStringVector PostStrings; int PostCharIndex; + UStringVector PostStrings; + CSwitchResult(): ThereIs(false) {}; }; - + class CParser { - int _numSwitches; + unsigned _numSwitches; CSwitchResult *_switches; + bool ParseString(const UString &s, const CSwitchForm *switchForms); public: UStringVector NonSwitchStrings; - CParser(int numSwitches); - ~CParser(); - void ParseStrings(const CSwitchForm *switchForms, - const UStringVector &commandStrings); - const CSwitchResult& operator[](size_t index) const; -}; - -///////////////////////////////// -// Command parsing procedures + AString ErrorMessage; + UString ErrorLine; -struct CCommandForm -{ - const wchar_t *IDString; - bool PostStringMode; + CParser(unsigned numSwitches); + ~CParser(); + bool ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings); + const CSwitchResult& operator[](size_t index) const { return _switches[index]; } }; -// Returns: Index of form and postString; -1, if there is no match -int ParseCommand(int numCommandForms, const CCommandForm *commandForms, - const UString &commandString, UString &postString); - } #endif diff --git a/src/libs/7zip/win/CPP/Common/Common.h b/src/libs/7zip/win/CPP/Common/Common.h new file mode 100644 index 000000000..9dd30f4be --- /dev/null +++ b/src/libs/7zip/win/CPP/Common/Common.h @@ -0,0 +1,13 @@ +// Common.h + +#ifndef __COMMON_COMMON_H +#define __COMMON_COMMON_H + +#include "../../C/Compiler.h" + +#include "MyWindows.h" +#include "NewHandler.h" + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[1])) + +#endif diff --git a/src/libs/7zip/win/CPP/Common/Common.pri b/src/libs/7zip/win/CPP/Common/Common.pri new file mode 100644 index 000000000..ecc997d89 --- /dev/null +++ b/src/libs/7zip/win/CPP/Common/Common.pri @@ -0,0 +1,35 @@ +HEADERS += $$7ZIP_BASE/CPP/Common/CommandLineParser.h \ + $$7ZIP_BASE/CPP/Common/ComTry.h \ + $$7ZIP_BASE/CPP/Common/Common.h \ + $$7ZIP_BASE/CPP/Common/Defs.h \ + $$7ZIP_BASE/CPP/Common/IntToString.h \ + $$7ZIP_BASE/CPP/Common/ListFileUtils.h \ + $$7ZIP_BASE/CPP/Common/MyBuffer.h \ + $$7ZIP_BASE/CPP/Common/MyCom.h \ + $$7ZIP_BASE/CPP/Common/MyException.h \ + $$7ZIP_BASE/CPP/Common/MyGuidDef.h \ + $$7ZIP_BASE/CPP/Common/MyInitGuid.h \ + $$7ZIP_BASE/CPP/Common/MyString.h \ + $$7ZIP_BASE/CPP/Common/MyTypes.h \ + $$7ZIP_BASE/CPP/Common/MyUnknown.h \ + $$7ZIP_BASE/CPP/Common/MyVector.h \ + $$7ZIP_BASE/CPP/Common/MyWindows.h \ + $$7ZIP_BASE/CPP/Common/NewHandler.h \ + $$7ZIP_BASE/CPP/Common/StdAfx.h \ + $$7ZIP_BASE/CPP/Common/StdOutStream.h \ + $$7ZIP_BASE/CPP/Common/StringConvert.h \ + $$7ZIP_BASE/CPP/Common/StringToInt.h \ + $$7ZIP_BASE/CPP/Common/UTFConvert.h \ + $$7ZIP_BASE/CPP/Common/Wildcard.h + +SOURCES += $$7ZIP_BASE/CPP/Common/CommandLineParser.cpp \ + $$7ZIP_BASE/CPP/Common/IntToString.cpp \ + $$7ZIP_BASE/CPP/Common/ListFileUtils.cpp \ + $$7ZIP_BASE/CPP/Common/MyString.cpp \ + $$7ZIP_BASE/CPP/Common/MyWindows.cpp \ + $$7ZIP_BASE/CPP/Common/NewHandler.cpp \ + $$7ZIP_BASE/CPP/Common/StdOutStream.cpp \ + $$7ZIP_BASE/CPP/Common/StringConvert.cpp \ + $$7ZIP_BASE/CPP/Common/StringToInt.cpp \ + $$7ZIP_BASE/CPP/Common/UTFConvert.cpp \ + $$7ZIP_BASE/CPP/Common/Wildcard.cpp diff --git a/src/libs/7zip/win/CPP/Common/DynamicBuffer.h b/src/libs/7zip/win/CPP/Common/DynamicBuffer.h deleted file mode 100644 index eaac123e1..000000000 --- a/src/libs/7zip/win/CPP/Common/DynamicBuffer.h +++ /dev/null @@ -1,50 +0,0 @@ -// Common/DynamicBuffer.h - -#ifndef __COMMON_DYNAMIC_BUFFER_H -#define __COMMON_DYNAMIC_BUFFER_H - -#include "Buffer.h" - -template <class T> class CDynamicBuffer: public CBuffer<T> -{ - void GrowLength(size_t size) - { - size_t delta; - if (this->_capacity > 64) - delta = this->_capacity / 4; - else if (this->_capacity > 8) - delta = 16; - else - delta = 4; - delta = MyMax(delta, size); - size_t newCap = this->_capacity + delta; - if (newCap < delta) - newCap = this->_capacity + size; - this->SetCapacity(newCap); - } -public: - CDynamicBuffer(): CBuffer<T>() {}; - CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer<T>(buffer) {}; - CDynamicBuffer(size_t size): CBuffer<T>(size) {}; - CDynamicBuffer& operator=(const CDynamicBuffer &buffer) - { - this->Free(); - if (buffer._capacity > 0) - { - this->SetCapacity(buffer._capacity); - memmove(this->_items, buffer._items, buffer._capacity * sizeof(T)); - } - return *this; - } - void EnsureCapacity(size_t capacity) - { - if (this->_capacity < capacity) - GrowLength(capacity - this->_capacity); - } -}; - -typedef CDynamicBuffer<char> CCharDynamicBuffer; -typedef CDynamicBuffer<wchar_t> CWCharDynamicBuffer; -typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer; - -#endif diff --git a/src/libs/7zip/win/CPP/Common/IntToString.cpp b/src/libs/7zip/win/CPP/Common/IntToString.cpp index 013fee527..ed217c72c 100644 --- a/src/libs/7zip/win/CPP/Common/IntToString.cpp +++ b/src/libs/7zip/win/CPP/Common/IntToString.cpp @@ -4,74 +4,143 @@ #include "IntToString.h" -void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base) +#define CONVERT_INT_TO_STR(charType, tempSize) \ + unsigned char temp[tempSize]; unsigned i = 0; \ + while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \ + *s++ = (charType)('0' + (unsigned)val); \ + while (i != 0) { i--; *s++ = temp[i]; } \ + *s = 0; + +void ConvertUInt32ToString(UInt32 val, char *s) throw() { - if (base < 2 || base > 36) + CONVERT_INT_TO_STR(char, 16); +} + +void ConvertUInt64ToString(UInt64 val, char *s) throw() +{ + if (val <= (UInt32)0xFFFFFFFF) { - *s = '\0'; + ConvertUInt32ToString((UInt32)val, s); return; } - char temp[72]; - int pos = 0; - do + CONVERT_INT_TO_STR(char, 24); +} + +void ConvertUInt64ToOct(UInt64 val, char *s) throw() +{ + UInt64 v = val; + unsigned i; + for (i = 1;; i++) { - int delta = (int)(value % base); - temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10))); - value /= base; + v >>= 3; + if (v == 0) + break; } - while (value != 0); + s[i] = 0; do - *s++ = temp[--pos]; - while (pos > 0); - *s = '\0'; + { + unsigned t = (unsigned)(val & 0x7); + val >>= 3; + s[--i] = (char)('0' + t); + } + while (i); } -void ConvertUInt64ToString(UInt64 value, wchar_t *s) +void ConvertUInt32ToHex(UInt32 val, char *s) throw() { - wchar_t temp[32]; - int pos = 0; + UInt32 v = val; + unsigned i; + for (i = 1;; i++) + { + v >>= 4; + if (v == 0) + break; + } + s[i] = 0; do { - temp[pos++] = (wchar_t)(L'0' + (int)(value % 10)); - value /= 10; + unsigned t = (unsigned)((val & 0xF)); + val >>= 4; + s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); } - while (value != 0); + while (i); +} + +void ConvertUInt64ToHex(UInt64 val, char *s) throw() +{ + UInt64 v = val; + unsigned i; + for (i = 1;; i++) + { + v >>= 4; + if (v == 0) + break; + } + s[i] = 0; do - *s++ = temp[--pos]; - while (pos > 0); - *s = L'\0'; + { + unsigned t = (unsigned)((val & 0xF)); + val >>= 4; + s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + } + while (i); } -void ConvertUInt32ToString(UInt32 value, char *s) { ConvertUInt64ToString(value, s); } -void ConvertUInt32ToString(UInt32 value, wchar_t *s) { ConvertUInt64ToString(value, s); } +void ConvertUInt32ToHex8Digits(UInt32 val, char *s) throw() +{ + s[8] = 0; + for (int i = 7; i >= 0; i--) + { + unsigned t = val & 0xF; + val >>= 4; + s[i] = (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); + } +} -void ConvertInt64ToString(Int64 value, char *s) +/* +void ConvertUInt32ToHex8Digits(UInt32 val, wchar_t *s) { - if (value < 0) + s[8] = 0; + for (int i = 7; i >= 0; i--) { - *s++ = '-'; - value = -value; + unsigned t = val & 0xF; + val >>= 4; + s[i] = (wchar_t)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); + } +} +*/ + +void ConvertUInt32ToString(UInt32 val, wchar_t *s) throw() +{ + CONVERT_INT_TO_STR(wchar_t, 16); +} + +void ConvertUInt64ToString(UInt64 val, wchar_t *s) throw() +{ + if (val <= (UInt32)0xFFFFFFFF) + { + ConvertUInt32ToString((UInt32)val, s); + return; } - ConvertUInt64ToString(value, s); + CONVERT_INT_TO_STR(wchar_t, 24); } -void ConvertInt64ToString(Int64 value, wchar_t *s) +void ConvertInt64ToString(Int64 val, char *s) throw() { - if (value < 0) + if (val < 0) { - *s++ = L'-'; - value = -value; + *s++ = '-'; + val = -val; } - ConvertUInt64ToString(value, s); + ConvertUInt64ToString(val, s); } -void ConvertUInt32ToHexWithZeros(UInt32 value, char *s) +void ConvertInt64ToString(Int64 val, wchar_t *s) throw() { - for (int i = 0; i < 8; i++) + if (val < 0) { - int t = value & 0xF; - value >>= 4; - s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + *s++ = L'-'; + val = -val; } - s[8] = '\0'; + ConvertUInt64ToString(val, s); } diff --git a/src/libs/7zip/win/CPP/Common/IntToString.h b/src/libs/7zip/win/CPP/Common/IntToString.h index 782f930c5..69605ab76 100644 --- a/src/libs/7zip/win/CPP/Common/IntToString.h +++ b/src/libs/7zip/win/CPP/Common/IntToString.h @@ -3,17 +3,22 @@ #ifndef __COMMON_INT_TO_STRING_H #define __COMMON_INT_TO_STRING_H -#include <stddef.h> -#include "Types.h" +#include "MyTypes.h" -void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10); -void ConvertUInt64ToString(UInt64 value, wchar_t *s); -void ConvertInt64ToString(Int64 value, char *s); -void ConvertInt64ToString(Int64 value, wchar_t *s); +void ConvertUInt32ToString(UInt32 value, char *s) throw(); +void ConvertUInt64ToString(UInt64 value, char *s) throw(); -void ConvertUInt32ToString(UInt32 value, char *s); -void ConvertUInt32ToString(UInt32 value, wchar_t *s); +void ConvertUInt32ToString(UInt32 value, wchar_t *s) throw(); +void ConvertUInt64ToString(UInt64 value, wchar_t *s) throw(); -void ConvertUInt32ToHexWithZeros(UInt32 value, char *s); +void ConvertUInt64ToOct(UInt64 value, char *s) throw(); + +void ConvertUInt32ToHex(UInt32 value, char *s) throw(); +void ConvertUInt64ToHex(UInt64 value, char *s) throw(); +void ConvertUInt32ToHex8Digits(UInt32 value, char *s) throw(); +// void ConvertUInt32ToHex8Digits(UInt32 value, wchar_t *s) throw(); + +void ConvertInt64ToString(Int64 value, char *s) throw(); +void ConvertInt64ToString(Int64 value, wchar_t *s) throw(); #endif diff --git a/src/libs/7zip/win/CPP/Common/ListFileUtils.cpp b/src/libs/7zip/win/CPP/Common/ListFileUtils.cpp index c1c682a2c..4d7faeca3 100644 --- a/src/libs/7zip/win/CPP/Common/ListFileUtils.cpp +++ b/src/libs/7zip/win/CPP/Common/ListFileUtils.cpp @@ -2,74 +2,116 @@ #include "StdAfx.h" -#include "MyWindows.h" +#include "../../C/CpuArch.h" + #include "../Windows/FileIO.h" #include "ListFileUtils.h" +#include "MyBuffer.h" #include "StringConvert.h" #include "UTFConvert.h" -static const char kQuoteChar = '\"'; -static void RemoveQuote(UString &s) +static const char kQuoteChar = '\"'; + +static void AddName(UStringVector &strings, UString &s) { - if (s.Length() >= 2) - if (s[0] == kQuoteChar && s[s.Length() - 1] == kQuoteChar) - s = s.Mid(1, s.Length() - 2); + s.Trim(); + if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar) + { + s.DeleteBack(); + s.Delete(0); + } + if (!s.IsEmpty()) + strings.Add(s); } -bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &resultStrings, UINT codePage) +bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage) { NWindows::NFile::NIO::CInFile file; if (!file.Open(fileName)) return false; - UInt64 length; - if (!file.GetLength(length)) - return false; - if (length > ((UInt32)1 << 31)) + UInt64 fileSize; + if (!file.GetLength(fileSize)) return false; - AString s; - char *p = s.GetBuffer((int)length + 1); - UInt32 processed; - if (!file.Read(p, (UInt32)length, processed)) + if (fileSize >= ((UInt32)1 << 31) - 32) return false; - p[(UInt32)length] = 0; - s.ReleaseBuffer(); - file.Close(); - UString u; - #ifdef CP_UTF8 - if (codePage == CP_UTF8) + if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE) { - if (!ConvertUTF8ToUnicode(s, u)) + if ((fileSize & 1) != 0) + return false; + CByteArr buf((size_t)fileSize); + UInt32 processed; + if (!file.Read(buf, (UInt32)fileSize, processed)) return false; + if (processed != fileSize) + return false; + file.Close(); + unsigned num = (unsigned)fileSize / 2; + wchar_t *p = u.GetBuffer(num); + if (codePage == MY__CP_UTF16) + for (unsigned i = 0; i < num; i++) + { + wchar_t c = GetUi16(buf + i * 2); + if (c == 0) + return false; + p[i] = c; + } + else + for (unsigned i = 0; i < num; i++) + { + wchar_t c = (wchar_t)GetBe16(buf + i * 2); + if (c == 0) + return false; + p[i] = c; + } + u.ReleaseBuffer(num); } else - #endif - u = MultiByteToUnicodeString(s, codePage); - if (!u.IsEmpty()) { - if (u[0] == 0xFEFF) - u.Delete(0); + AString s; + char *p = s.GetBuffer((unsigned)fileSize); + UInt32 processed; + if (!file.Read(p, (UInt32)fileSize, processed)) + return false; + if (processed != fileSize) + return false; + file.Close(); + p[processed] = 0; + s.ReleaseBuffer(); + if (s.Len() != processed) + return false; + + // #ifdef CP_UTF8 + if (codePage == CP_UTF8) + { + if (!ConvertUTF8ToUnicode(s, u)) + return false; + } + else + // #endif + MultiByteToUnicodeString2(u, s, codePage); } - UString t; - for (int i = 0; i < u.Length(); i++) + const wchar_t kGoodBOM = 0xFEFF; + const wchar_t kBadBOM = 0xFFFE; + + UString s; + unsigned i = 0; + for (; i < u.Len() && u[i] == kGoodBOM; i++); + for (; i < u.Len(); i++) { wchar_t c = u[i]; + if (c == kGoodBOM || c == kBadBOM) + return false; if (c == L'\n' || c == 0xD) { - t.Trim(); - RemoveQuote(t); - if (!t.IsEmpty()) - resultStrings.Add(t); - t.Empty(); + AddName(strings, s); + s.Empty(); } else - t += c; + s += c; } - t.Trim(); - RemoveQuote(t); - if (!t.IsEmpty()) - resultStrings.Add(t); + AddName(strings, s); return true; } diff --git a/src/libs/7zip/win/CPP/Common/ListFileUtils.h b/src/libs/7zip/win/CPP/Common/ListFileUtils.h index c58a8bd42..e8d833fdb 100644 --- a/src/libs/7zip/win/CPP/Common/ListFileUtils.h +++ b/src/libs/7zip/win/CPP/Common/ListFileUtils.h @@ -1,11 +1,14 @@ // Common/ListFileUtils.h -#ifndef __COMMON_LISTFILEUTILS_H -#define __COMMON_LISTFILEUTILS_H +#ifndef __COMMON_LIST_FILE_UTILS_H +#define __COMMON_LIST_FILE_UTILS_H #include "MyString.h" -#include "Types.h" +#include "MyTypes.h" -bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP); +#define MY__CP_UTF16 1200 +#define MY__CP_UTF16BE 1201 + +bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP); #endif diff --git a/src/libs/7zip/win/CPP/Common/MyBuffer.h b/src/libs/7zip/win/CPP/Common/MyBuffer.h new file mode 100644 index 000000000..7bd79f6f4 --- /dev/null +++ b/src/libs/7zip/win/CPP/Common/MyBuffer.h @@ -0,0 +1,237 @@ +// Common/MyBuffer.h + +#ifndef __COMMON_MY_BUFFER_H +#define __COMMON_MY_BUFFER_H + +#include "Defs.h" + +template <class T> class CBuffer +{ + T *_items; + size_t _size; + + void CopyToEmpty(const CBuffer &buffer) + { + if (buffer._size > 0) + { + _items = new T[buffer._size]; + memcpy(_items, buffer._items, buffer._size * sizeof(T)); + _size = buffer._size; + } + } +public: + void Free() + { + if (_items) + { + delete []_items; + _items = 0; + } + _size = 0; + } + + CBuffer(): _items(0), _size(0) {}; + CBuffer(size_t size): _items(0), _size(0) { _items = new T[size]; _size = size; } + CBuffer(const CBuffer &buffer): _items(0), _size(0) { CopyToEmpty(buffer); } + ~CBuffer() { delete []_items; } + + operator T *() { return _items; }; + operator const T *() const { return _items; }; + size_t Size() const { return _size; } + + void Alloc(size_t size) + { + if (size != _size) + { + Free(); + if (size != 0) + { + _items = new T[size]; + _size = size; + } + } + } + + void AllocAtLeast(size_t size) + { + if (size > _size) + { + Free(); + _items = new T[size]; + _size = size; + } + } + + void CopyFrom(const T *data, size_t size) + { + Alloc(size); + memcpy(_items, data, size * sizeof(T)); + } + + void ChangeSize_KeepData(size_t newSize, size_t keepSize) + { + if (newSize == _size) + return; + T *newBuffer = NULL; + if (newSize > 0) + { + newBuffer = new T[newSize]; + if (_size > 0) + memcpy(newBuffer, _items, MyMin(MyMin(_size, keepSize), newSize) * sizeof(T)); + } + delete []_items; + _items = newBuffer; + _size = newSize; + } + + CBuffer& operator=(const CBuffer &buffer) + { + Free(); + CopyToEmpty(buffer); + return *this; + } +}; + +template <class T> +bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2) +{ + size_t size1 = b1.Size(); + if (size1 != b2.Size()) + return false; + return memcmp(b1, b2, size1 * sizeof(T)) == 0; +} + +template <class T> +bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2) +{ + size_t size1 = b1.Size(); + if (size1 == b2.Size()) + return false; + return memcmp(b1, b2, size1 * sizeof(T)) != 0; +} + + +typedef CBuffer<char> CCharBuffer; +typedef CBuffer<wchar_t> CWCharBuffer; +typedef CBuffer<unsigned char> CByteBuffer; + + +template <class T> class CObjArray +{ +protected: + T *_items; +private: + // we disable constructors + CObjArray(const CObjArray &buffer); + void operator=(const CObjArray &buffer); +public: + void Free() + { + delete []_items; + _items = 0; + } + CObjArray(size_t size): _items(0) { if (size != 0) _items = new T[size]; } + CObjArray(): _items(0) {}; + ~CObjArray() { delete []_items; } + + operator T *() { return _items; }; + operator const T *() const { return _items; }; + + void Alloc(size_t newSize) + { + delete []_items; + _items = 0; + _items = new T[newSize]; + } +}; + +typedef CObjArray<unsigned char> CByteArr; +typedef CObjArray<bool> CBoolArr; +typedef CObjArray<int> CIntArr; + +// #define CRecArray CObjArray + +template <class T> class CObjArray2 +{ +// protected: + T *_items; + unsigned _size; + + CObjArray2(const CObjArray2 &buffer); + void operator=(const CObjArray2 &buffer); +public: + + void Free() + { + delete []_items; + _items = 0; + _size = 0; + } + CObjArray2(): _items(0), _size(0) {}; + /* + CObjArray2(const CObjArray2 &buffer): _items(0), _size(0) + { + size_t newSize = buffer._size; + if (newSize > 0) + { + T *newBuffer = new T[newSize];; + _items = newBuffer; + _size = newSize; + const T *src = buffer; + for (size_t i = 0; i < newSize; i++) + newBuffer[i] = src[i]; + } + } + */ + /* + CObjArray2(size_t size): _items(0), _size(0) + { + if (size != 0) + { + _items = new T[size]; + _size = size; + } + } + */ + + ~CObjArray2() { delete []_items; } + + operator T *() { return _items; }; + operator const T *() const { return _items; }; + + unsigned Size() const { return (unsigned)_size; } + bool IsEmpty() const { return _size == 0; } + + // SetSize doesn't keep old items. It allocates new array if size is not equal + void SetSize(unsigned size) + { + if (size == _size) + return; + T *newBuffer = NULL; + if (size > 0) + newBuffer = new T[size]; + delete []_items; + _items = newBuffer; + _size = size; + } + + /* + CObjArray2& operator=(const CObjArray2 &buffer) + { + Free(); + size_t newSize = buffer._size; + if (newSize > 0) + { + T *newBuffer = new T[newSize];; + _items = newBuffer; + _size = newSize; + const T *src = buffer; + for (size_t i = 0; i < newSize; i++) + newBuffer[i] = src[i]; + } + return *this; + } + */ +}; + +#endif diff --git a/src/libs/7zip/win/CPP/Common/MyCom.h b/src/libs/7zip/win/CPP/Common/MyCom.h index 2f00c258f..466407cde 100644 --- a/src/libs/7zip/win/CPP/Common/MyCom.h +++ b/src/libs/7zip/win/CPP/Common/MyCom.h @@ -1,9 +1,10 @@ // MyCom.h -#ifndef __MYCOM_H -#define __MYCOM_H +#ifndef __MY_COM_H +#define __MY_COM_H #include "MyWindows.h" +#include "NewHandler.h" #ifndef RINOK #define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; } @@ -14,14 +15,9 @@ class CMyComPtr { T* _p; public: - // typedef T _PtrClass; - CMyComPtr() { _p = NULL;} - CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); } - CMyComPtr(const CMyComPtr<T>& lp) - { - if ((_p = lp._p) != NULL) - _p->AddRef(); - } + CMyComPtr(): _p(NULL) {} + CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); } + CMyComPtr(const CMyComPtr<T>& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); } ~CMyComPtr() { if (_p) _p->Release(); } void Release() { if (_p) { _p->Release(); _p = NULL; } } operator T*() const { return (T*)_p; } @@ -30,7 +26,7 @@ public: T* operator->() const { return _p; } T* operator=(T* p) { - if (p != 0) + if (p) p->AddRef(); if (_p) _p->Release(); @@ -40,7 +36,6 @@ public: T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); } bool operator!() const { return (_p == NULL); } // bool operator==(T* pT) const { return _p == pT; } - // Compare two objects for equivalence void Attach(T* p2) { Release(); @@ -70,7 +65,7 @@ public: } */ template <class Q> - HRESULT QueryInterface(REFGUID iid, Q** pp) const + HRESULT QueryInterface(REFGUID iid, Q** pp) const throw() { return _p->QueryInterface(iid, (void**)pp); } @@ -81,13 +76,14 @@ public: inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr) { *bstr = ::SysAllocString(src); - return (*bstr != 0) ? S_OK : E_OUTOFMEMORY; + return (*bstr != NULL) ? S_OK : E_OUTOFMEMORY; } class CMyComBSTR { -public: BSTR m_str; +public: + CMyComBSTR(): m_str(NULL) {} CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); } // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); } @@ -119,7 +115,7 @@ public: m_str = ::SysAllocString(src); return *this; } - unsigned int Length() const { return ::SysStringLen(m_str); } + // unsigned Len() const { return ::SysStringLen(m_str); } operator BSTR() const { return m_str; } BSTR* operator&() { return &m_str; } BSTR MyCopy() const @@ -143,7 +139,7 @@ public: ::SysFreeString(m_str); m_str = NULL; } - bool operator!() const { return (m_str == NULL); } + bool operator!() const { return (m_str == NULL); } }; ////////////////////////////////////////////////////////// @@ -156,22 +152,22 @@ public: }; #define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \ - (REFGUID iid, void **outObject) { +(REFGUID iid, void **outObject) throw() { *outObject = NULL; -#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \ - { *outObject = (void *)(i *)this; AddRef(); return S_OK; } +#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; AddRef(); return S_OK; } + { *outObject = (void *)(IUnknown *)(i *)this; } #define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ MY_QUERYINTERFACE_ENTRY(i) -#define MY_QUERYINTERFACE_END return E_NOINTERFACE; } +#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; AddRef(); return S_OK; } #define MY_ADDREF_RELEASE \ -STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \ +STDMETHOD_(ULONG, AddRef)() throw() { return ++__m_RefCount; } \ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ return __m_RefCount; delete this; return 0; } @@ -222,4 +218,25 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ MY_QUERYINTERFACE_ENTRY(i5) \ ) +#define MY_UNKNOWN_IMP6(i1, i2, i3, i4, i5, i6) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + MY_QUERYINTERFACE_ENTRY(i5) \ + MY_QUERYINTERFACE_ENTRY(i6) \ + ) + +#define MY_UNKNOWN_IMP7(i1, i2, i3, i4, i5, i6, i7) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + MY_QUERYINTERFACE_ENTRY(i5) \ + MY_QUERYINTERFACE_ENTRY(i6) \ + MY_QUERYINTERFACE_ENTRY(i7) \ + ) + #endif diff --git a/src/libs/7zip/win/CPP/Common/MyGuidDef.h b/src/libs/7zip/win/CPP/Common/MyGuidDef.h index 3c52cc07d..68745870e 100644 --- a/src/libs/7zip/win/CPP/Common/MyGuidDef.h +++ b/src/libs/7zip/win/CPP/Common/MyGuidDef.h @@ -3,7 +3,7 @@ #ifndef GUID_DEFINED #define GUID_DEFINED -#include "Types.h" +#include "MyTypes.h" typedef struct { UInt32 Data1; diff --git a/src/libs/7zip/win/CPP/Common/MyInitGuid.h b/src/libs/7zip/win/CPP/Common/MyInitGuid.h index d6a486980..279fba5d6 100644 --- a/src/libs/7zip/win/CPP/Common/MyInitGuid.h +++ b/src/libs/7zip/win/CPP/Common/MyInitGuid.h @@ -3,20 +3,43 @@ #ifndef __COMMON_MY_INITGUID_H #define __COMMON_MY_INITGUID_H +/* +This file must be included only to one C++ file in project before +declarations of COM interfaces with DEFINE_GUID macro. + +Each GUID must be initialized exactly once in project. +There are two different versions of the DEFINE_GUID macro in guiddef.h (MyGuidDef.h): + - if INITGUID is not defined: DEFINE_GUID declares an external reference to the symbol name. + - if INITGUID is defined: DEFINE_GUID initializes the symbol name to the value of the GUID. + +Also we need IID_IUnknown that is initialized in some file for linking: + MSVC: by default the linker uses some lib file that contains IID_IUnknown + MinGW: add -luuid switch for linker + WinCE: we define IID_IUnknown in this file + Other: we define IID_IUnknown in this file +*/ + #ifdef _WIN32 + #ifdef UNDER_CE #include <basetyps.h> #endif + #include <initguid.h> + #ifdef UNDER_CE DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); #endif + #else + #define INITGUID #include "MyGuidDef.h" DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); + #endif + #endif diff --git a/src/libs/7zip/win/CPP/Common/MyString.cpp b/src/libs/7zip/win/CPP/Common/MyString.cpp index 3d1ce2b84..6fbfa334b 100644 --- a/src/libs/7zip/win/CPP/Common/MyString.cpp +++ b/src/libs/7zip/win/CPP/Common/MyString.cpp @@ -2,32 +2,104 @@ #include "StdAfx.h" -#ifndef _WIN32 +#ifdef _WIN32 +#include <windows.h> +#include <wchar.h> +#else #include <ctype.h> #endif -#ifndef _UNICODE +#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING) #include "StringConvert.h" #endif #include "MyString.h" +#define MY_STRING_NEW(_T_, _size_) new _T_[_size_] +// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_))) + +/* +inline const char* MyStringGetNextCharPointer(const char *p) throw() +{ + #if defined(_WIN32) && !defined(UNDER_CE) + return CharNextA(p); + #else + return p + 1; + #endif +} +*/ + +int FindCharPosInString(const char *s, char c) throw() +{ + for (const char *p = s;; p++) + { + if (*p == c) + return (int)(p - s); + if (*p == 0) + return -1; + // MyStringGetNextCharPointer(p); + } +} + +int FindCharPosInString(const wchar_t *s, wchar_t c) throw() +{ + for (const wchar_t *p = s;; p++) + { + if (*p == c) + return (int)(p - s); + if (*p == 0) + return -1; + } +} + +/* +void MyStringUpper_Ascii(wchar_t *s) +{ + for (;;) + { + wchar_t c = *s; + if (c == 0) + return; + *s++ = MyCharUpper_Ascii(c); + } +} +*/ + +void MyStringLower_Ascii(wchar_t *s) throw() +{ + for (;;) + { + wchar_t c = *s; + if (c == 0) + return; + *s++ = MyCharLower_Ascii(c); + } +} #ifdef _WIN32 -#ifndef _UNICODE +#ifdef _UNICODE -wchar_t MyCharUpper(wchar_t c) +// wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); } +// wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); } +// for WinCE - FString - char +// const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; } + +#else + +// const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); } +// char * MyStringUpper(char *s) { return CharUpperA(s); } +// char * MyStringLower(char *s) { return CharLowerA(s); } + +wchar_t MyCharUpper_WIN(wchar_t c) throw() { - if (c == 0) - return 0; - wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); + wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return (wchar_t)(unsigned int)(UINT_PTR)res; - const int kBufferSize = 4; - char s[kBufferSize + 1]; - int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); - if (numChars == 0 || numChars > kBufferSize) + return (wchar_t)(unsigned)(UINT_PTR)res; + const int kBufSize = 4; + char s[kBufSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0); + if (numChars == 0 || numChars > kBufSize) return c; s[numChars] = 0; ::CharUpperA(s); @@ -35,24 +107,25 @@ wchar_t MyCharUpper(wchar_t c) return c; } -wchar_t MyCharLower(wchar_t c) +/* +wchar_t MyCharLower_WIN(wchar_t c) { - if (c == 0) - return 0; - wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); + wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return (wchar_t)(unsigned int)(UINT_PTR)res; - const int kBufferSize = 4; - char s[kBufferSize + 1]; - int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); - if (numChars == 0 || numChars > kBufferSize) + return (wchar_t)(unsigned)(UINT_PTR)res; + const int kBufSize = 4; + char s[kBufSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0); + if (numChars == 0 || numChars > kBufSize) return c; s[numChars] = 0; ::CharLowerA(s); ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); return c; } +*/ +/* wchar_t * MyStringUpper(wchar_t *s) { if (s == 0) @@ -62,9 +135,12 @@ wchar_t * MyStringUpper(wchar_t *s) return res; AString a = UnicodeStringToMultiByte(s); a.MakeUpper(); - return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); + MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); + return s; } +*/ +/* wchar_t * MyStringLower(wchar_t *s) { if (s == 0) @@ -74,110 +150,149 @@ wchar_t * MyStringLower(wchar_t *s) return res; AString a = UnicodeStringToMultiByte(s); a.MakeLower(); - return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); + MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); + return s; } +*/ #endif -/* -inline int ConvertCompareResult(int r) { return r - 2; } +#endif -int MyStringCollate(const wchar_t *s1, const wchar_t *s2) +bool IsString1PrefixedByString2(const char *s1, const char *s2) throw() { - int res = CompareStringW( - LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1); - #ifdef _UNICODE - return ConvertCompareResult(res); - #else - if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return ConvertCompareResult(res); - return MyStringCollate(UnicodeStringToMultiByte(s1), - UnicodeStringToMultiByte(s2)); - #endif + for (;;) + { + unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true; + unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false; + } } -#ifndef UNDER_CE -int MyStringCollate(const char *s1, const char *s2) +bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw() { - return ConvertCompareResult(CompareStringA( - LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false; + if (c1 == 0) return true; + } } -int MyStringCollateNoCase(const char *s1, const char *s2) +// ---------- ASCII ---------- + +bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() { - return ConvertCompareResult(CompareStringA( - LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); + const char *s1 = _chars; + for (;;) + { + char c2 = *s++; + if (c2 == 0) + return true; + char c1 = *s1++; + if (MyCharLower_Ascii(c1) != + MyCharLower_Ascii(c2)) + return false; + } } -#endif -int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) +bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() { - int res = CompareStringW( - LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1); - #ifdef _UNICODE - return ConvertCompareResult(res); - #else - if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return ConvertCompareResult(res); - return MyStringCollateNoCase(UnicodeStringToMultiByte(s1), - UnicodeStringToMultiByte(s2)); - #endif + const wchar_t *s1 = _chars; + for (;;) + { + char c2 = *s++; + if (c2 == 0) + return true; + wchar_t c1 = *s1++; + if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)) + return false; + } } -*/ -#else +bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw() +{ + for (;;) + { + unsigned char c = *a; + if (c != *u) + return false; + if (c == 0) + return true; + a++; + u++; + } +} -wchar_t MyCharUpper(wchar_t c) +bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw() { - return toupper(c); + for (;;) + { + char c1 = *s1++; + char c2 = *s2++; + if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) + return false; + if (c1 == 0) + return true; + } } -/* -int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) +bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw() { for (;;) { wchar_t c1 = *s1++; wchar_t c2 = *s2++; - wchar_t u1 = MyCharUpper(c1); - wchar_t u2 = MyCharUpper(c2); - - if (u1 < u2) return -1; - if (u1 > u2) return 1; - if (u1 == 0) return 0; + if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) + return false; + if (c1 == 0) + return true; } } -*/ -#endif +bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw() +{ + for (;;) + { + wchar_t c1 = *s1++; + char c2 = *s2++; + if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))) + return false; + if (c1 == 0) + return true; + } +} -int MyStringCompare(const char *s1, const char *s2) +bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw() { for (;;) { - unsigned char c1 = (unsigned char)*s1++; - unsigned char c2 = (unsigned char)*s2++; - if (c1 < c2) return -1; - if (c1 > c2) return 1; - if (c1 == 0) return 0; + wchar_t c2 = *s2++; if (c2 == 0) return true; + wchar_t c1 = *s1++; if (c1 != c2) return false; } } -int MyStringCompare(const wchar_t *s1, const wchar_t *s2) +// NTFS order: uses upper case +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw() { for (;;) { wchar_t c1 = *s1++; wchar_t c2 = *s2++; - if (c1 < c2) return -1; - if (c1 > c2) return 1; + if (c1 != c2) + { + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + if (u1 < u2) return -1; + if (u1 > u2) return 1; + } if (c1 == 0) return 0; } } -int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) +int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw() { - for (;;) + for (; num != 0; num--) { wchar_t c1 = *s1++; wchar_t c2 = *s2++; @@ -190,11 +305,911 @@ int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) } if (c1 == 0) return 0; } + return 0; +} + + +// ---------- AString ---------- + +void AString::InsertSpace(unsigned &index, unsigned size) +{ + Grow(size); + MoveItems(index + size, index); +} + +void AString::ReAlloc(unsigned newLimit) +{ + if (newLimit < _len || newLimit >= 0x20000000) throw 20130220; + // MY_STRING_REALLOC(_chars, char, newLimit + 1, _len + 1); + char *newBuf = MY_STRING_NEW(char, newLimit + 1); + memcpy(newBuf, _chars, (size_t)(_len + 1)); \ + MY_STRING_DELETE(_chars); + _chars = newBuf; + + _limit = newLimit; +} + +void AString::SetStartLen(unsigned len) +{ + _chars = 0; + _chars = MY_STRING_NEW(char, len + 1); + _len = len; + _limit = len; +} + +void AString::Grow_1() +{ + unsigned next = _len; + next += next / 2; + next += 16; + next &= ~(unsigned)15; + ReAlloc(next - 1); +} + +void AString::Grow(unsigned n) +{ + unsigned freeSize = _limit - _len; + if (n <= freeSize) + return; + + unsigned next = _len + n; + next += next / 2; + next += 16; + next &= ~(unsigned)15; + ReAlloc(next - 1); +} + +/* +AString::AString(unsigned num, const char *s) +{ + unsigned len = MyStringLen(s); + if (num > len) + num = len; + SetStartLen(num); + memcpy(_chars, s, num); + _chars[num] = 0; +} +*/ + +AString::AString(unsigned num, const AString &s) +{ + if (num > s._len) + num = s._len; + SetStartLen(num); + memcpy(_chars, s._chars, num); + _chars[num] = 0; +} + +AString::AString(const AString &s, char c) +{ + SetStartLen(s.Len() + 1); + char *chars = _chars; + unsigned len = s.Len(); + memcpy(chars, s, len); + chars[len] = c; + chars[len + 1] = 0; +} + +AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2) +{ + SetStartLen(num1 + num2); + char *chars = _chars; + memcpy(chars, s1, num1); + memcpy(chars + num1, s2, num2 + 1); +} + +AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); } +AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); } +AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); } + +AString::AString() +{ + _chars = 0; + _chars = MY_STRING_NEW(char, 4); + _len = 0; + _limit = 4 - 1; + _chars[0] = 0; +} + +AString::AString(char c) +{ + SetStartLen(1); + _chars[0] = c; + _chars[1] = 0; +} + +AString::AString(const char *s) +{ + SetStartLen(MyStringLen(s)); + MyStringCopy(_chars, s); +} + +AString::AString(const AString &s) +{ + SetStartLen(s._len); + MyStringCopy(_chars, s._chars); +} + +AString &AString::operator=(char c) +{ + if (1 > _limit) + { + char *newBuf = MY_STRING_NEW(char, 1 + 1); + MY_STRING_DELETE(_chars); + _chars = newBuf; + _limit = 1; + } + _len = 1; + _chars[0] = c; + _chars[1] = 0; + return *this; +} + +AString &AString::operator=(const char *s) +{ + unsigned len = MyStringLen(s); + if (len > _limit) + { + char *newBuf = MY_STRING_NEW(char, len + 1); + MY_STRING_DELETE(_chars); + _chars = newBuf; + _limit = len; + } + _len = len; + MyStringCopy(_chars, s); + return *this; +} + +AString &AString::operator=(const AString &s) +{ + if (&s == this) + return *this; + unsigned len = s._len; + if (len > _limit) + { + char *newBuf = MY_STRING_NEW(char, len + 1); + MY_STRING_DELETE(_chars); + _chars = newBuf; + _limit = len; + } + _len = len; + MyStringCopy(_chars, s._chars); + return *this; +} + +AString &AString::operator+=(const char *s) +{ + unsigned len = MyStringLen(s); + Grow(len); + MyStringCopy(_chars + _len, s); + _len += len; + return *this; +} + +AString &AString::operator+=(const AString &s) +{ + Grow(s._len); + MyStringCopy(_chars + _len, s._chars); + _len += s._len; + return *this; +} + +void AString::SetFrom(const char *s, unsigned len) // no check +{ + if (len > _limit) + { + char *newBuf = MY_STRING_NEW(char, len + 1); + MY_STRING_DELETE(_chars); + _chars = newBuf; + _limit = len; + } + memcpy(_chars, s, len); + _chars[len] = 0; + _len = len; +} + +int AString::Find(const AString &s, unsigned startIndex) const throw() +{ + if (s.IsEmpty()) + return startIndex; + for (; startIndex < _len; startIndex++) + { + unsigned j; + for (j = 0; j < s._len && startIndex + j < _len; j++) + if (_chars[startIndex + j] != s._chars[j]) + break; + if (j == s._len) + return (int)startIndex; + } + return -1; +} + +int AString::ReverseFind(char c) const throw() +{ + if (_len == 0) + return -1; + const char *p = _chars + _len - 1; + for (;;) + { + if (*p == c) + return (int)(p - _chars); + if (p == _chars) + return -1; + p--; // p = GetPrevCharPointer(_chars, p); + } +} + +void AString::TrimLeft() throw() +{ + const char *p = _chars; + for (;; p++) + { + char c = *p; + if (c != ' ' && c != '\n' && c != '\t') + break; + } + unsigned pos = (unsigned)(p - _chars); + if (pos != 0) + { + MoveItems(0, pos); + _len -= pos; + } +} + +void AString::TrimRight() throw() +{ + const char *p = _chars; + int i; + for (i = _len - 1; i >= 0; i--) + { + char c = p[i]; + if (c != ' ' && c != '\n' && c != '\t') + break; + } + i++; + if ((unsigned)i != _len) + { + _chars[i] = 0; + _len = i; + } +} + +void AString::InsertAtFront(char c) +{ + if (_limit == _len) + Grow_1(); + MoveItems(1, 0); + _chars[0] = c; + _len++; +} + +/* +void AString::Insert(unsigned index, char c) +{ + InsertSpace(index, 1); + _chars[index] = c; + _len++; +} +*/ + +void AString::Insert(unsigned index, const char *s) +{ + unsigned num = MyStringLen(s); + if (num != 0) + { + InsertSpace(index, num); + memcpy(_chars + index, s, num); + _len += num; + } +} + +void AString::Insert(unsigned index, const AString &s) +{ + unsigned num = s.Len(); + if (num != 0) + { + InsertSpace(index, num); + memcpy(_chars + index, s, num); + _len += num; + } +} + +void AString::RemoveChar(char ch) throw() +{ + int pos = Find(ch); + if (pos < 0) + return; + const char *src = _chars; + char *dest = _chars + pos; + pos++; + unsigned len = _len; + for (; (unsigned)pos < len; pos++) + { + char c = src[(unsigned)pos]; + if (c != ch) + *dest++ = c; + } + *dest = 0; + _len = (unsigned)(dest - _chars); +} + +// !!!!!!!!!!!!!!! test it if newChar = '\0' +void AString::Replace(char oldChar, char newChar) throw() +{ + if (oldChar == newChar) + return; // 0; + // unsigned number = 0; + int pos = 0; + while ((unsigned)pos < _len) + { + pos = Find(oldChar, pos); + if (pos < 0) + break; + _chars[pos] = newChar; + pos++; + // number++; + } + return; // number; +} + +void AString::Replace(const AString &oldString, const AString &newString) +{ + if (oldString.IsEmpty()) + return; // 0; + if (oldString == newString) + return; // 0; + unsigned oldLen = oldString.Len(); + unsigned newLen = newString.Len(); + // unsigned number = 0; + int pos = 0; + while ((unsigned)pos < _len) + { + pos = Find(oldString, pos); + if (pos < 0) + break; + Delete(pos, oldLen); + Insert(pos, newString); + pos += newLen; + // number++; + } + // return number; +} + +void AString::Delete(unsigned index) throw() +{ + MoveItems(index, index + 1); + _len--; +} + +void AString::Delete(unsigned index, unsigned count) throw() +{ + if (index + count > _len) + count = _len - index; + if (count > 0) + { + MoveItems(index, index + count); + _len -= count; + } +} + +void AString::DeleteFrontal(unsigned num) throw() +{ + if (num != 0) + { + MoveItems(0, num); + _len -= num; + } +} + +/* +AString operator+(const AString &s1, const AString &s2) +{ + AString result(s1); + result += s2; + return result; +} + +AString operator+(const AString &s, const char *chars) +{ + AString result(s); + result += chars; + return result; } +AString operator+(const char *chars, const AString &s) +{ + AString result(chars); + result += s; + return result; +} + +AString operator+(const AString &s, char c) +{ + AString result(s); + result += c; + return result; +} +*/ + +/* +AString operator+(char c, const AString &s) +{ + AString result(c); + result += s; + return result; +} +*/ + + + + +// ---------- UString ---------- + +void UString::InsertSpace(unsigned index, unsigned size) +{ + Grow(size); + MoveItems(index + size, index); +} + +void UString::ReAlloc(unsigned newLimit) +{ + if (newLimit < _len || newLimit >= 0x20000000) throw 20130221; + // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, _len + 1); + wchar_t *newBuf = MY_STRING_NEW(wchar_t, newLimit + 1); + wmemcpy(newBuf, _chars, _len + 1); + MY_STRING_DELETE(_chars); + _chars = newBuf; + + _limit = newLimit; +} + +void UString::SetStartLen(unsigned len) +{ + _chars = 0; + _chars = MY_STRING_NEW(wchar_t, len + 1); + _len = len; + _limit = len; +} + +void UString::Grow_1() +{ + unsigned next = _len; + next += next / 2; + next += 16; + next &= ~(unsigned)15; + ReAlloc(next - 1); +} + +void UString::Grow(unsigned n) +{ + unsigned freeSize = _limit - _len; + if (n <= freeSize) + return; + + unsigned next = _len + n; + next += next / 2; + next += 16; + next &= ~(unsigned)15; + ReAlloc(next - 1); +} + + +UString::UString(unsigned num, const wchar_t *s) +{ + unsigned len = MyStringLen(s); + if (num > len) + num = len; + SetStartLen(num); + wmemcpy(_chars, s, num); + _chars[num] = 0; +} + + +UString::UString(unsigned num, const UString &s) +{ + if (num > s._len) + num = s._len; + SetStartLen(num); + wmemcpy(_chars, s._chars, num); + _chars[num] = 0; +} + +UString::UString(const UString &s, wchar_t c) +{ + SetStartLen(s.Len() + 1); + wchar_t *chars = _chars; + unsigned len = s.Len(); + wmemcpy(chars, s, len); + chars[len] = c; + chars[len + 1] = 0; +} + +UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2) +{ + SetStartLen(num1 + num2); + wchar_t *chars = _chars; + wmemcpy(chars, s1, num1); + wmemcpy(chars + num1, s2, num2 + 1); +} + +UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); } +UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); } +UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); } + +UString::UString() +{ + _chars = 0; + _chars = MY_STRING_NEW(wchar_t, 4); + _len = 0; + _limit = 4 - 1; + _chars[0] = 0; +} + +UString::UString(wchar_t c) +{ + SetStartLen(1); + _chars[0] = c; + _chars[1] = 0; +} + +UString::UString(const wchar_t *s) +{ + SetStartLen(MyStringLen(s)); + MyStringCopy(_chars, s); +} + +UString::UString(const UString &s) +{ + SetStartLen(s._len); + MyStringCopy(_chars, s._chars); +} + +UString &UString::operator=(wchar_t c) +{ + if (1 > _limit) + { + wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1); + MY_STRING_DELETE(_chars); + _chars = newBuf; + _limit = 1; + } + _len = 1; + _chars[0] = c; + _chars[1] = 0; + return *this; +} + +UString &UString::operator=(const wchar_t *s) +{ + unsigned len = MyStringLen(s); + if (len > _limit) + { + wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); + MY_STRING_DELETE(_chars); + _chars = newBuf; + _limit = len; + } + _len = len; + MyStringCopy(_chars, s); + return *this; +} + +UString &UString::operator=(const UString &s) +{ + if (&s == this) + return *this; + unsigned len = s._len; + if (len > _limit) + { + wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); + MY_STRING_DELETE(_chars); + _chars = newBuf; + _limit = len; + } + _len = len; + MyStringCopy(_chars, s._chars); + return *this; +} + +UString &UString::operator+=(const wchar_t *s) +{ + unsigned len = MyStringLen(s); + Grow(len); + MyStringCopy(_chars + _len, s); + _len += len; + return *this; +} + +UString &UString::operator+=(const UString &s) +{ + Grow(s._len); + MyStringCopy(_chars + _len, s._chars); + _len += s._len; + 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; + } + 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] = s[i]; + chars[len] = 0; + _len = len; +} + +void UString::AddAsciiStr(const char *s) +{ + unsigned len = MyStringLen(s); + Grow(len); + wchar_t *chars = _chars + _len; + for (unsigned i = 0; i < len; i++) + chars[i] = s[i]; + chars[len] = 0; + _len += len; +} + + + +int UString::Find(const UString &s, unsigned startIndex) const throw() +{ + if (s.IsEmpty()) + return startIndex; + for (; startIndex < _len; startIndex++) + { + unsigned j; + for (j = 0; j < s._len && startIndex + j < _len; j++) + if (_chars[startIndex + j] != s._chars[j]) + break; + if (j == s._len) + return (int)startIndex; + } + return -1; +} + +int UString::ReverseFind(wchar_t c) const throw() +{ + if (_len == 0) + return -1; + const wchar_t *p = _chars + _len - 1; + for (;;) + { + if (*p == c) + return (int)(p - _chars); + if (p == _chars) + return -1; + p--; + } +} + +void UString::TrimLeft() throw() +{ + const wchar_t *p = _chars; + for (;; p++) + { + wchar_t c = *p; + if (c != ' ' && c != '\n' && c != '\t') + break; + } + unsigned pos = (unsigned)(p - _chars); + if (pos != 0) + { + MoveItems(0, pos); + _len -= pos; + } +} + +void UString::TrimRight() throw() +{ + const wchar_t *p = _chars; + int i; + for (i = _len - 1; i >= 0; i--) + { + wchar_t c = p[i]; + if (c != ' ' && c != '\n' && c != '\t') + break; + } + i++; + if ((unsigned)i != _len) + { + _chars[i] = 0; + _len = i; + } +} + +void UString::InsertAtFront(wchar_t c) +{ + if (_limit == _len) + Grow_1(); + MoveItems(1, 0); + _chars[0] = c; + _len++; +} + +/* +void UString::Insert(unsigned index, wchar_t c) +{ + InsertSpace(index, 1); + _chars[index] = c; + _len++; +} +*/ + +void UString::Insert(unsigned index, const wchar_t *s) +{ + unsigned num = MyStringLen(s); + if (num != 0) + { + InsertSpace(index, num); + wmemcpy(_chars + index, s, num); + _len += num; + } +} + +void UString::Insert(unsigned index, const UString &s) +{ + unsigned num = s.Len(); + if (num != 0) + { + InsertSpace(index, num); + wmemcpy(_chars + index, s, num); + _len += num; + } +} + +void UString::RemoveChar(wchar_t ch) throw() +{ + int pos = Find(ch); + if (pos < 0) + return; + const wchar_t *src = _chars; + wchar_t *dest = _chars + pos; + pos++; + unsigned len = _len; + for (; (unsigned)pos < len; pos++) + { + wchar_t c = src[(unsigned)pos]; + if (c != ch) + *dest++ = c; + } + *dest = 0; + _len = (unsigned)(dest - _chars); +} + +// !!!!!!!!!!!!!!! test it if newChar = '\0' +void UString::Replace(wchar_t oldChar, wchar_t newChar) throw() +{ + if (oldChar == newChar) + return; // 0; + // unsigned number = 0; + int pos = 0; + while ((unsigned)pos < _len) + { + pos = Find(oldChar, pos); + if (pos < 0) + break; + _chars[pos] = newChar; + pos++; + // number++; + } + return; // number; +} + +void UString::Replace(const UString &oldString, const UString &newString) +{ + if (oldString.IsEmpty()) + return; // 0; + if (oldString == newString) + return; // 0; + unsigned oldLen = oldString.Len(); + unsigned newLen = newString.Len(); + // unsigned number = 0; + int pos = 0; + while ((unsigned)pos < _len) + { + pos = Find(oldString, pos); + if (pos < 0) + break; + Delete(pos, oldLen); + Insert(pos, newString); + pos += newLen; + // number++; + } + // return number; +} + +void UString::Delete(unsigned index) throw() +{ + MoveItems(index, index + 1); + _len--; +} + +void UString::Delete(unsigned index, unsigned count) throw() +{ + if (index + count > _len) + count = _len - index; + if (count > 0) + { + MoveItems(index, index + count); + _len -= count; + } +} + +void UString::DeleteFrontal(unsigned num) throw() +{ + if (num != 0) + { + MoveItems(0, num); + _len -= num; + } +} + + +// ---------------------------------------- + /* int MyStringCompareNoCase(const char *s1, const char *s2) { return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); } */ + +static inline UINT GetCurrentCodePage() +{ + #if defined(UNDER_CE) || !defined(_WIN32) + return CP_ACP; + #else + return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; + #endif +} + +#ifdef USE_UNICODE_FSTRING + +#ifndef _UNICODE + +AString fs2fas(CFSTR s) +{ + return UnicodeStringToMultiByte(s, GetCurrentCodePage()); +} + +FString fas2fs(const AString &s) +{ + return MultiByteToUnicodeString(s, GetCurrentCodePage()); +} + +#endif + +#else + +UString fs2us(const FString &s) +{ + return MultiByteToUnicodeString((AString)s, GetCurrentCodePage()); +} + +FString us2fs(const wchar_t *s) +{ + return UnicodeStringToMultiByte(s, GetCurrentCodePage()); +} + +#endif diff --git a/src/libs/7zip/win/CPP/Common/MyString.h b/src/libs/7zip/win/CPP/Common/MyString.h index f483e39dc..8417815cf 100644 --- a/src/libs/7zip/win/CPP/Common/MyString.h +++ b/src/libs/7zip/win/CPP/Common/MyString.h @@ -5,623 +5,521 @@ #include <string.h> -#include "MyVector.h" +#ifndef _WIN32 +#include <wctype.h> +#include <wchar.h> +#endif -#include <windows.h> +#include "MyTypes.h" +#include "MyVector.h" -template <class T> -inline int MyStringLen(const T *s) +inline unsigned MyStringLen(const char *s) { - int i; - for (i = 0; s[i] != '\0'; i++); + unsigned i; + for (i = 0; s[i] != 0; i++); return i; } -template <class T> -inline T * MyStringCopy(T *dest, const T *src) +inline void MyStringCopy(char *dest, const char *src) { - T *destStart = dest; while ((*dest++ = *src++) != 0); - return destStart; } -inline wchar_t* MyStringGetNextCharPointer(wchar_t *p) - { return (p + 1); } -inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p) - { return (p + 1); } -inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p) - { return (p - 1); } -inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p) - { return (p - 1); } +inline char *MyStpCpy(char *dest, const char *src) +{ + for (;;) + { + char c = *src; + *dest = c; + if (c == 0) + return dest; + src++; + dest++; + } +} -#ifdef _WIN32 +inline unsigned MyStringLen(const wchar_t *s) +{ + unsigned i; + for (i = 0; s[i] != 0; i++); + return i; +} -inline const char* MyStringGetNextCharPointer(const char *p) +inline void MyStringCopy(wchar_t *dest, const wchar_t *src) { - #ifdef UNDER_CE - return p + 1; - #else - return CharNextA(p); - #endif + while ((*dest++ = *src++) != 0); } -inline const char* MyStringGetPrevCharPointer(const char *base, const char *p) - { return CharPrevA(base, p); } +int FindCharPosInString(const char *s, char c) throw(); +int FindCharPosInString(const wchar_t *s, wchar_t c) throw(); -inline char MyCharUpper(char c) - { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); } -#ifdef _UNICODE -inline wchar_t MyCharUpper(wchar_t c) - { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); } -#else -wchar_t MyCharUpper(wchar_t c); +#ifdef _WIN32 + #ifndef _UNICODE + #define STRING_UNICODE_THROW + #endif #endif -#ifdef _UNICODE -inline wchar_t MyCharLower(wchar_t c) - { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); } -#else -wchar_t MyCharLower(wchar_t c); +#ifndef STRING_UNICODE_THROW + #define STRING_UNICODE_THROW throw() #endif -inline char MyCharLower(char c) -#ifdef UNDER_CE - { return (char)MyCharLower((wchar_t)c); } -#else - { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); } -#endif +/* +inline char MyCharUpper_Ascii(char c) +{ + if (c >= 'a' && c <= 'z') + return (char)(c - 0x20); + return c; +} +inline wchar_t MyCharUpper_Ascii(wchar_t c) +{ + if (c >= 'a' && c <= 'z') + return (wchar_t)(c - 0x20); + return c; +} +*/ -inline char * MyStringUpper(char *s) { return CharUpperA(s); } -#ifdef _UNICODE -inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); } -#else -wchar_t * MyStringUpper(wchar_t *s); -#endif +inline char MyCharLower_Ascii(char c) +{ + if (c >= 'A' && c <= 'Z') + return (char)(c + 0x20); + return c; +} -inline char * MyStringLower(char *s) { return CharLowerA(s); } -#ifdef _UNICODE -inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); } -#else -wchar_t * MyStringLower(wchar_t *s); -#endif +inline wchar_t MyCharLower_Ascii(wchar_t c) +{ + if (c >= 'A' && c <= 'Z') + return (wchar_t)(c + 0x20); + return c; +} -#else // Standard-C -wchar_t MyCharUpper(wchar_t c); -#endif +wchar_t MyCharUpper_WIN(wchar_t c) throw(); -////////////////////////////////////// -// Compare +inline wchar_t MyCharUpper(wchar_t c) throw() +{ + if (c < 'a') return c; + if (c <= 'z') return (wchar_t)(c - 0x20); + if (c <= 0x7F) return c; + #ifdef _WIN32 + #ifdef _UNICODE + return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); + #else + return (wchar_t)MyCharUpper_WIN(c); + #endif + #else + return (wchar_t)towupper(c); + #endif +} /* -#ifndef UNDER_CE -int MyStringCollate(const char *s1, const char *s2); -int MyStringCollateNoCase(const char *s1, const char *s2); -#endif -int MyStringCollate(const wchar_t *s1, const wchar_t *s2); -int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2); +wchar_t MyCharLower_WIN(wchar_t c) throw(); + +inline wchar_t MyCharLower(wchar_t c) throw() +{ + if (c < 'A') return c; + if (c <= 'Z') return (wchar_t)(c + 0x20); + if (c <= 0x7F) return c; + #ifdef _WIN32 + #ifdef _UNICODE + return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); + #else + return (wchar_t)MyCharLower_WIN(c); + #endif + #else + return (wchar_t)tolower(c); + #endif +} */ -int MyStringCompare(const char *s1, const char *s2); -int MyStringCompare(const wchar_t *s1, const wchar_t *s2); +// char *MyStringUpper(char *s) throw(); +// char *MyStringLower(char *s) throw(); + +// void MyStringUpper_Ascii(wchar_t *s) throw(); +void MyStringLower_Ascii(wchar_t *s) throw(); +// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW; +// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW; + +bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw(); + +bool IsString1PrefixedByString2(const char *s1, const char *s2) throw(); +bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw(); -// int MyStringCompareNoCase(const char *s1, const char *s2); -int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *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(); -template <class T> -class CStringBase +// ---------- ASCII ---------- +// char values in ASCII strings must be less then 128 +bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw(); +bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw(); +bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw(); +bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw(); + +#define MY_STRING_DELETE(_p_) delete []_p_; +// #define MY_STRING_DELETE(_p_) my_delete(_p_); + +class AString { - void TrimLeftWithCharSet(const CStringBase &charSet) - { - const T *p = _chars; - while (charSet.Find(*p) >= 0 && (*p != 0)) - p = GetNextCharPointer(p); - Delete(0, (int)(p - _chars)); - } - void TrimRightWithCharSet(const CStringBase &charSet) - { - const T *p = _chars; - const T *pLast = NULL; - while (*p != 0) - { - if (charSet.Find(*p) >= 0) - { - if (pLast == NULL) - pLast = p; - } - else - pLast = NULL; - p = GetNextCharPointer(p); - } - if (pLast != NULL) - { - int i = (int)(pLast - _chars); - Delete(i, _length - i); - } + char *_chars; + unsigned _len; + unsigned _limit; - } - void MoveItems(int destIndex, int srcIndex) + void MoveItems(unsigned dest, unsigned src) { - memmove(_chars + destIndex, _chars + srcIndex, - sizeof(T) * (_length - srcIndex + 1)); - } - - void InsertSpace(int &index, int size) - { - CorrectIndex(index); - GrowLength(size); - MoveItems(index + size, index); + memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char)); } - static const T *GetNextCharPointer(const T *p) - { return MyStringGetNextCharPointer(p); } - static const T *GetPrevCharPointer(const T *base, const T *p) - { return MyStringGetPrevCharPointer(base, p); } -protected: - T *_chars; - int _length; - int _capacity; - - void SetCapacity(int newCapacity) - { - int realCapacity = newCapacity + 1; - if (realCapacity == _capacity) - return; - /* - const int kMaxStringSize = 0x20000000; - if (newCapacity > kMaxStringSize || newCapacity < _length) - throw 1052337; - */ - T *newBuffer = new T[realCapacity]; - if (_capacity > 0) - { - for (int i = 0; i < _length; i++) - newBuffer[i] = _chars[i]; - delete []_chars; - } - _chars = newBuffer; - _chars[_length] = 0; - _capacity = realCapacity; - } + void InsertSpace(unsigned &index, unsigned size); - void GrowLength(int n) - { - int freeSize = _capacity - _length - 1; - if (n <= freeSize) - return; - int delta; - if (_capacity > 64) - delta = _capacity / 2; - else if (_capacity > 8) - delta = 16; - else - delta = 4; - if (freeSize + delta < n) - delta = n - freeSize; - SetCapacity(_capacity + delta); - } + void ReAlloc(unsigned newLimit); + void SetStartLen(unsigned len); + void Grow_1(); + void Grow(unsigned n); - void CorrectIndex(int &index) const - { - if (index > _length) - index = _length; - } + // AString(unsigned num, const char *s); + AString(unsigned num, const AString &s); + AString(const AString &s, char c); // it's for String + char + AString(const char *s1, unsigned num1, const char *s2, unsigned num2); + + friend AString operator+(const AString &s, char c) { return AString(s, c); } ; + // friend AString operator+(char c, const AString &s); // is not supported + + friend AString operator+(const AString &s1, const AString &s2); + friend AString operator+(const AString &s1, const char *s2); + friend AString operator+(const char *s1, const AString &s2); public: - CStringBase(): _chars(0), _length(0), _capacity(0) { SetCapacity(3); } - CStringBase(T c): _chars(0), _length(0), _capacity(0) - { - SetCapacity(1); - _chars[0] = c; - _chars[1] = 0; - _length = 1; - } - CStringBase(const T *chars): _chars(0), _length(0), _capacity(0) - { - int length = MyStringLen(chars); - SetCapacity(length); - MyStringCopy(_chars, chars); // can be optimized by memove() - _length = length; - } - CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0) - { - SetCapacity(s._length); - MyStringCopy(_chars, s._chars); - _length = s._length; - } - ~CStringBase() { delete []_chars; } + AString(); + AString(char c); + AString(const char *s); + AString(const AString &s); + ~AString() { MY_STRING_DELETE(_chars); } - operator const T*() const { return _chars;} + unsigned Len() const { return _len; } + bool IsEmpty() const { return _len == 0; } + void Empty() { _len = 0; _chars[0] = 0; } - T Back() const { return _chars[_length - 1]; } + operator const char *() const { return _chars; } + const char *Ptr() const { return _chars; } + const char *Ptr(unsigned pos) const { return _chars + pos; } + const char *RightPtr(unsigned num) const { return _chars + _len - num; } + char Back() const { return _chars[_len - 1]; } + + void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; } // The minimum size of the character buffer in characters. // This value does not include space for a null terminator. - T* GetBuffer(int minBufLength) + char *GetBuffer(unsigned minBufLen) { - if (minBufLength >= _capacity) - SetCapacity(minBufLength); + if (minBufLen > _limit) + ReAlloc(minBufLen); return _chars; } void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } - void ReleaseBuffer(int newLength) - { - /* - if (newLength >= _capacity) - throw 282217; - */ - _chars[newLength] = 0; - _length = newLength; - } + void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } - CStringBase& operator=(T c) - { - Empty(); - SetCapacity(1); - _chars[0] = c; - _chars[1] = 0; - _length = 1; - return *this; - } - CStringBase& operator=(const T *chars) - { - Empty(); - int length = MyStringLen(chars); - SetCapacity(length); - MyStringCopy(_chars, chars); - _length = length; - return *this; - } - CStringBase& operator=(const CStringBase& s) - { - if (&s == this) - return *this; - Empty(); - SetCapacity(s._length); - MyStringCopy(_chars, s._chars); - _length = s._length; - return *this; - } - - CStringBase& operator+=(T c) - { - GrowLength(1); - _chars[_length] = c; - _chars[++_length] = 0; - return *this; - } - CStringBase& operator+=(const T *s) - { - int len = MyStringLen(s); - GrowLength(len); - MyStringCopy(_chars + _length, s); - _length += len; - return *this; - } - CStringBase& operator+=(const CStringBase &s) - { - GrowLength(s._length); - MyStringCopy(_chars + _length, s._chars); - _length += s._length; - return *this; - } - void Empty() - { - _length = 0; - _chars[0] = 0; - } - int Length() const { return _length; } - bool IsEmpty() const { return (_length == 0); } + AString &operator=(char c); + AString &operator=(const char *s); + AString &operator=(const AString &s); - CStringBase Mid(int startIndex) const - { return Mid(startIndex, _length - startIndex); } - CStringBase Mid(int startIndex, int count) const - { - if (startIndex + count > _length) - count = _length - startIndex; - - if (startIndex == 0 && startIndex + count == _length) - return *this; - - CStringBase<T> result; - result.SetCapacity(count); - // MyStringNCopy(result._chars, _chars + startIndex, count); - for (int i = 0; i < count; i++) - result._chars[i] = _chars[startIndex + i]; - result._chars[count] = 0; - result._length = count; - return result; - } - CStringBase Left(int count) const - { return Mid(0, count); } - CStringBase Right(int count) const + AString &operator+=(char c) { - if (count > _length) - count = _length; - return Mid(_length - count, count); + if (_limit == _len) + Grow_1(); + unsigned len = _len; + char *chars = _chars; + chars[len++] = c; + chars[len] = 0; + _len = len; + return *this; } - void MakeUpper() - { MyStringUpper(_chars); } - void MakeLower() - { MyStringLower(_chars); } + AString &operator+=(const char *s); + AString &operator+=(const AString &s); - int Compare(const CStringBase& s) const - { return MyStringCompare(_chars, s._chars); } + void SetFrom(const char *s, unsigned len); // no check + // AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); } + AString Left(unsigned count) const { return AString(count, *this); } - int Compare(const T *s) const - { return MyStringCompare(_chars, s); } + // void MakeUpper() { MyStringUpper(_chars); } + // void MakeLower() { MyStringLower(_chars); } - int CompareNoCase(const CStringBase& s) const - { return MyStringCompareNoCase(_chars, s._chars); } - int CompareNoCase(const T *s) const - { return MyStringCompareNoCase(_chars, s); } + // int Compare(const char *s) const { return MyStringCompare(_chars, s); } + // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); } + // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); } + // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); } + bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); } + bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); - /* - int Collate(const CStringBase& s) const - { return MyStringCollate(_chars, s._chars); } - int CollateNoCase(const CStringBase& s) const - { return MyStringCollateNoCase(_chars, s._chars); } - */ - - int Find(T c) const { return Find(c, 0); } - int Find(T c, int startIndex) const + int Find(char c) const { return FindCharPosInString(_chars, c); } + int Find(char c, unsigned startIndex) const { - const T *p = _chars + startIndex; - for (;;) - { - if (*p == c) - return (int)(p - _chars); - if (*p == 0) - return -1; - p = GetNextCharPointer(p); - } + int pos = FindCharPosInString(_chars + startIndex, c); + return pos < 0 ? -1 : (int)startIndex + pos; } - int Find(const CStringBase &s) const { return Find(s, 0); } - int Find(const CStringBase &s, int startIndex) const + int ReverseFind(char c) const throw(); + int Find(const AString &s) const { return Find(s, 0); } + int Find(const AString &s, unsigned startIndex) const throw(); + + void TrimLeft() throw(); + void TrimRight() throw(); + void Trim() { - if (s.IsEmpty()) - return startIndex; - for (; startIndex < _length; startIndex++) - { - int j; - for (j = 0; j < s._length && startIndex + j < _length; j++) - if (_chars[startIndex+j] != s._chars[j]) - break; - if (j == s._length) - return startIndex; - } - return -1; + TrimRight(); + TrimLeft(); } - int ReverseFind(T c) const + + void InsertAtFront(char c); + // void Insert(unsigned index, char c); + void Insert(unsigned index, const char *s); + void Insert(unsigned index, const AString &s); + + void RemoveChar(char ch) throw(); + void Replace(char oldChar, char newChar) throw(); + void Replace(const AString &oldString, const AString &newString); + + void Delete(unsigned index) throw(); + void Delete(unsigned index, unsigned count) throw(); + void DeleteFrontal(unsigned num) throw(); + void DeleteBack() { _chars[--_len] = 0; } + void DeleteFrom(unsigned index) { - if (_length == 0) - return -1; - const T *p = _chars + _length - 1; - for (;;) + if (index < _len) { - if (*p == c) - return (int)(p - _chars); - if (p == _chars) - return -1; - p = GetPrevCharPointer(_chars, p); + _len = index; + _chars[index] = 0; } } - int FindOneOf(const CStringBase &s) const - { - for (int i = 0; i < _length; i++) - if (s.Find(_chars[i]) >= 0) - return i; - return -1; - } +}; - void TrimLeft(T c) - { - const T *p = _chars; - while (c == *p) - p = GetNextCharPointer(p); - Delete(0, p - _chars); - } - private: - CStringBase GetTrimDefaultCharSet() +bool operator<(const AString &s1, const AString &s2); +bool operator>(const AString &s1, const AString &s2); + +/* +bool operator==(const AString &s1, const AString &s2); +bool operator==(const AString &s1, const char *s2); +bool operator==(const char *s1, const AString &s2); + +bool operator!=(const AString &s1, const AString &s2); +bool operator!=(const AString &s1, const char *s2); +bool operator!=(const char *s1, const AString &s2); +*/ + +inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; } +inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; } +inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; } + +inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; } +inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; } +inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; } + + + +class UString +{ + wchar_t *_chars; + unsigned _len; + unsigned _limit; + + void MoveItems(unsigned dest, unsigned src) { - CStringBase<T> charSet; - charSet += (T)' '; - charSet += (T)'\n'; - charSet += (T)'\t'; - return charSet; + memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t)); } - public: - void TrimLeft() + void InsertSpace(unsigned index, unsigned size); + + void ReAlloc(unsigned newLimit); + void SetStartLen(unsigned len); + void Grow_1(); + void Grow(unsigned n); + + UString(unsigned num, const wchar_t *s); // for Mid + UString(unsigned num, const UString &s); // for Left + UString(const UString &s, wchar_t c); // it's for String + char + UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2); + + friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ; + // friend UString operator+(wchar_t c, const UString &s); // is not supported + + friend UString operator+(const UString &s1, const UString &s2); + friend UString operator+(const UString &s1, const wchar_t *s2); + friend UString operator+(const wchar_t *s1, const UString &s2); + +public: + UString(); + UString(wchar_t c); + UString(const wchar_t *s); + UString(const UString &s); + ~UString() { MY_STRING_DELETE(_chars); } + + unsigned Len() const { return _len; } + bool IsEmpty() const { return _len == 0; } + void Empty() { _len = 0; _chars[0] = 0; } + + operator const wchar_t *() const { return _chars; } + const wchar_t *Ptr() const { return _chars; } + const wchar_t *Ptr(unsigned pos) const { return _chars + pos; } + const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; } + wchar_t Back() const { return _chars[_len - 1]; } + + void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; } + + // The minimum size of the character buffer in characters. + // This value does not include space for a null terminator. + wchar_t *GetBuffer(unsigned minBufLen) { - TrimLeftWithCharSet(GetTrimDefaultCharSet()); + if (minBufLen > _limit) + ReAlloc(minBufLen); + return _chars; } - void TrimRight() + void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } + void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } + + UString &operator=(wchar_t c); + UString &operator=(const wchar_t *s); + UString &operator=(const UString &s); + + UString &operator+=(wchar_t c) { - TrimRightWithCharSet(GetTrimDefaultCharSet()); + if (_limit == _len) + Grow_1(); + unsigned len = _len; + wchar_t *chars = _chars; + chars[len++] = c; + chars[len] = 0; + _len = len; + return *this; } - void TrimRight(T c) + + UString &operator+=(const wchar_t *s); + UString &operator+=(const UString &s); + + void SetFrom(const wchar_t *s, unsigned len); // no check + + void SetFromAscii(const char *s); + void AddAsciiStr(const char *s); + + UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); } + UString Left(unsigned count) const { return UString(count, *this); } + + // void MakeUpper() { MyStringUpper(_chars); } + // void MakeUpper() { MyStringUpper_Ascii(_chars); } + // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); } + void MakeLower_Ascii() { MyStringLower_Ascii(_chars); } + + bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); } + bool IsEqualToNoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); } + int Compare(const wchar_t *s) const { return wcscmp(_chars, s); } + // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); } + // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); } + // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); } + bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }; + bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); + + int Find(wchar_t c) const { return FindCharPosInString(_chars, c); } + int Find(wchar_t c, unsigned startIndex) const { - const T *p = _chars; - const T *pLast = NULL; - while (*p != 0) - { - if (*p == c) - { - if (pLast == NULL) - pLast = p; - } - else - pLast = NULL; - p = GetNextCharPointer(p); - } - if (pLast != NULL) - { - int i = pLast - _chars; - Delete(i, _length - i); - } + int pos = FindCharPosInString(_chars + startIndex, c); + return pos < 0 ? -1 : (int)startIndex + pos; } + int Find(const UString &s) const { return Find(s, 0); } + int Find(const UString &s, unsigned startIndex) const throw(); + int ReverseFind(wchar_t c) const throw(); + + void TrimLeft() throw(); + void TrimRight() throw(); void Trim() { TrimRight(); TrimLeft(); } - int Insert(int index, T c) - { - InsertSpace(index, 1); - _chars[index] = c; - _length++; - return _length; - } - int Insert(int index, const CStringBase &s) - { - CorrectIndex(index); - if (s.IsEmpty()) - return _length; - int numInsertChars = s.Length(); - InsertSpace(index, numInsertChars); - for (int i = 0; i < numInsertChars; i++) - _chars[index + i] = s[i]; - _length += numInsertChars; - return _length; - } + void InsertAtFront(wchar_t c); + // void Insert(unsigned index, wchar_t c); + void Insert(unsigned index, const wchar_t *s); + void Insert(unsigned index, const UString &s); - // !!!!!!!!!!!!!!! test it if newChar = '\0' - int Replace(T oldChar, T newChar) - { - if (oldChar == newChar) - return 0; - int number = 0; - int pos = 0; - while (pos < Length()) - { - pos = Find(oldChar, pos); - if (pos < 0) - break; - _chars[pos] = newChar; - pos++; - number++; - } - return number; - } - int Replace(const CStringBase &oldString, const CStringBase &newString) - { - if (oldString.IsEmpty()) - return 0; - if (oldString == newString) - return 0; - int oldStringLength = oldString.Length(); - int newStringLength = newString.Length(); - int number = 0; - int pos = 0; - while (pos < _length) - { - pos = Find(oldString, pos); - if (pos < 0) - break; - Delete(pos, oldStringLength); - Insert(pos, newString); - pos += newStringLength; - number++; - } - return number; - } - int Delete(int index, int count = 1) + void RemoveChar(wchar_t ch) throw(); + void Replace(wchar_t oldChar, wchar_t newChar) throw(); + void Replace(const UString &oldString, const UString &newString); + + void Delete(unsigned index) throw(); + void Delete(unsigned index, unsigned count) throw(); + void DeleteFrontal(unsigned num) throw(); + void DeleteBack() { _chars[--_len] = 0; } + void DeleteFrom(unsigned index) { - if (index + count > _length) - count = _length - index; - if (count > 0) + if (index < _len) { - MoveItems(index, index + count); - _length -= count; + _len = index; + _chars[index] = 0; } - return _length; } - void DeleteBack() { Delete(_length - 1); } }; -template <class T> -CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2) -{ - CStringBase<T> result(s1); - result += s2; - return result; -} +bool operator<(const UString &s1, const UString &s2); +bool operator>(const UString &s1, const UString &s2); -template <class T> -CStringBase<T> operator+(const CStringBase<T>& s, T c) -{ - CStringBase<T> result(s); - result += c; - return result; -} +inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; } +inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; } +inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; } -template <class T> -CStringBase<T> operator+(T c, const CStringBase<T>& s) -{ - CStringBase<T> result(c); - result += s; - return result; -} +inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; } +inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; } +inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; } -template <class T> -CStringBase<T> operator+(const CStringBase<T>& s, const T * chars) -{ - CStringBase<T> result(s); - result += chars; - return result; -} -template <class T> -CStringBase<T> operator+(const T * chars, const CStringBase<T>& s) -{ - CStringBase<T> result(chars); - result += s; - return result; -} +typedef CObjectVector<AString> AStringVector; +typedef CObjectVector<UString> UStringVector; -template <class T> -bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2) - { return (s1.Compare(s2) == 0); } +#ifdef _UNICODE + typedef UString CSysString; +#else + typedef AString CSysString; +#endif -template <class T> -bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2) - { return (s1.Compare(s2) < 0); } +typedef CObjectVector<CSysString> CSysStringVector; -template <class T> -bool operator==(const T *s1, const CStringBase<T>& s2) - { return (s2.Compare(s1) == 0); } -template <class T> -bool operator==(const CStringBase<T>& s1, const T *s2) - { return (s1.Compare(s2) == 0); } +// ---------- FString ---------- -template <class T> -bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2) - { return (s1.Compare(s2) != 0); } +#ifdef _WIN32 + #define USE_UNICODE_FSTRING +#endif -template <class T> -bool operator!=(const T *s1, const CStringBase<T>& s2) - { return (s2.Compare(s1) != 0); } +#ifdef USE_UNICODE_FSTRING -template <class T> -bool operator!=(const CStringBase<T>& s1, const T *s2) - { return (s1.Compare(s2) != 0); } + #define __FTEXT(quote) L##quote -typedef CStringBase<char> AString; -typedef CStringBase<wchar_t> UString; + typedef wchar_t FChar; + typedef UString FString; -typedef CObjectVector<AString> AStringVector; -typedef CObjectVector<UString> UStringVector; + #define fs2us(_x_) (_x_) + #define us2fs(_x_) (_x_) + FString fas2fs(const AString &s); + AString fs2fas(const FChar *s); -#ifdef _UNICODE - typedef UString CSysString; #else - typedef AString CSysString; + + #define __FTEXT(quote) quote + + typedef char FChar; + typedef AString FString; + + UString fs2us(const FString &s); + FString us2fs(const wchar_t *s); + #define fas2fs(_x_) (_x_) + #define fs2fas(_x_) (_x_) + #endif -typedef CObjectVector<CSysString> CSysStringVector; +#define FTEXT(quote) __FTEXT(quote) + +#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR) +#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR) +#define FCHAR_ANY_MASK FTEXT('*') +#define FSTRING_ANY_MASK FTEXT("*") +typedef const FChar *CFSTR; + +typedef CObjectVector<FString> FStringVector; #endif diff --git a/src/libs/7zip/win/CPP/Common/MyTypes.h b/src/libs/7zip/win/CPP/Common/MyTypes.h new file mode 100644 index 000000000..d81788816 --- /dev/null +++ b/src/libs/7zip/win/CPP/Common/MyTypes.h @@ -0,0 +1,30 @@ +// Common/MyTypes.h + +#ifndef __COMMON_MY_TYPES_H +#define __COMMON_MY_TYPES_H + +#include "../../C/7zTypes.h" + +typedef int HRes; + +struct CBoolPair +{ + bool Val; + bool Def; + + CBoolPair(): Val(false), Def(false) {} + + void Init() + { + Val = false; + Def = false; + } + + void SetTrueTrue() + { + Val = true; + Def = true; + } +}; + +#endif diff --git a/src/libs/7zip/win/CPP/Common/MyUnknown.h b/src/libs/7zip/win/CPP/Common/MyUnknown.h index e9e8666b9..8b95afd38 100644 --- a/src/libs/7zip/win/CPP/Common/MyUnknown.h +++ b/src/libs/7zip/win/CPP/Common/MyUnknown.h @@ -9,5 +9,5 @@ #else #include "MyWindows.h" #endif - + #endif diff --git a/src/libs/7zip/win/CPP/Common/MyVector.cpp b/src/libs/7zip/win/CPP/Common/MyVector.cpp deleted file mode 100644 index 3b5317688..000000000 --- a/src/libs/7zip/win/CPP/Common/MyVector.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Common/MyVector.cpp - -#include "StdAfx.h" - -#include <string.h> - -#include "MyVector.h" - -CBaseRecordVector::~CBaseRecordVector() { ClearAndFree(); } - -void CBaseRecordVector::ClearAndFree() -{ - Clear(); - delete []((unsigned char *)_items); - _capacity = 0; - _size = 0; - _items = 0; -} - -void CBaseRecordVector::Clear() { DeleteFrom(0); } -void CBaseRecordVector::DeleteBack() { Delete(_size - 1); } -void CBaseRecordVector::DeleteFrom(int index) { Delete(index, _size - index); } - -void CBaseRecordVector::ReserveOnePosition() -{ - if (_size != _capacity) - return; - unsigned delta = 1; - if (_capacity >= 64) - delta = (unsigned)_capacity / 4; - else if (_capacity >= 8) - delta = 8; - Reserve(_capacity + (int)delta); -} - -void CBaseRecordVector::Reserve(int newCapacity) -{ - // if (newCapacity <= _capacity) - if (newCapacity == _capacity) - return; - if ((unsigned)newCapacity >= ((unsigned)1 << (sizeof(unsigned) * 8 - 1))) - throw 1052353; - size_t newSize = (size_t)(unsigned)newCapacity * _itemSize; - if (newSize / _itemSize != (size_t)(unsigned)newCapacity) - throw 1052354; - unsigned char *p = NULL; - if (newSize > 0) - { - p = new unsigned char[newSize]; - if (p == 0) - throw 1052355; - int numRecordsToMove = (_size < newCapacity ? _size : newCapacity); - memcpy(p, _items, _itemSize * numRecordsToMove); - } - delete [](unsigned char *)_items; - _items = p; - _capacity = newCapacity; -} - -void CBaseRecordVector::ReserveDown() -{ - Reserve(_size); -} - -void CBaseRecordVector::MoveItems(int destIndex, int srcIndex) -{ - memmove(((unsigned char *)_items) + destIndex * _itemSize, - ((unsigned char *)_items) + srcIndex * _itemSize, - _itemSize * (_size - srcIndex)); -} - -void CBaseRecordVector::InsertOneItem(int index) -{ - ReserveOnePosition(); - MoveItems(index + 1, index); - _size++; -} - -void CBaseRecordVector::Delete(int index, int num) -{ - TestIndexAndCorrectNum(index, num); - if (num > 0) - { - MoveItems(index, index + num); - _size -= num; - } -} diff --git a/src/libs/7zip/win/CPP/Common/MyVector.h b/src/libs/7zip/win/CPP/Common/MyVector.h index 781b648bc..7e61dec31 100644 --- a/src/libs/7zip/win/CPP/Common/MyVector.h +++ b/src/libs/7zip/win/CPP/Common/MyVector.h @@ -1,92 +1,247 @@ -// Common/Vector.h +// Common/MyVector.h -#ifndef __COMMON_VECTOR_H -#define __COMMON_VECTOR_H - -#include "Defs.h" - -class CBaseRecordVector -{ - void MoveItems(int destIndex, int srcIndex); -protected: - int _capacity; - int _size; - void *_items; - size_t _itemSize; - - void ReserveOnePosition(); - void InsertOneItem(int index); - void TestIndexAndCorrectNum(int index, int &num) const - { if (index + num > _size) num = _size - index; } -public: - CBaseRecordVector(size_t itemSize): _capacity(0), _size(0), _items(0), _itemSize(itemSize) {} - virtual ~CBaseRecordVector(); - void ClearAndFree(); - int Size() const { return _size; } - bool IsEmpty() const { return (_size == 0); } - void Reserve(int newCapacity); - void ReserveDown(); - virtual void Delete(int index, int num = 1); - void Clear(); - void DeleteFrom(int index); - void DeleteBack(); -}; +#ifndef __COMMON_MY_VECTOR_H +#define __COMMON_MY_VECTOR_H template <class T> -class CRecordVector: public CBaseRecordVector +class CRecordVector { + T *_items; + unsigned _size; + unsigned _capacity; + + void MoveItems(unsigned destIndex, unsigned srcIndex) + { + memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * (size_t)sizeof(T)); + } + + void ReserveOnePosition() + { + if (_size == _capacity) + { + unsigned newCapacity = _capacity + (_capacity >> 2) + 1; + T *p = new T[newCapacity]; + memcpy(p, _items, (size_t)_size * (size_t)sizeof(T)); + delete []_items; + _items = p; + _capacity = newCapacity; + } + } + public: - CRecordVector(): CBaseRecordVector(sizeof(T)){}; - CRecordVector(const CRecordVector &v): CBaseRecordVector(sizeof(T)) { *this = v; } - CRecordVector& operator=(const CRecordVector &v) + + CRecordVector(): _items(0), _size(0), _capacity(0) {} + + CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0) + { + unsigned size = v.Size(); + if (size != 0) + { + _items = new T[size]; + _size = size; + _capacity = size; + memcpy(_items, v._items, (size_t)size * (size_t)sizeof(T)); + } + } + + unsigned Size() const { return _size; } + bool IsEmpty() const { return _size == 0; } + + void ConstructReserve(unsigned size) + { + if (size != 0) + { + _items = new T[size]; + _capacity = size; + } + } + + void Reserve(unsigned newCapacity) + { + if (newCapacity > _capacity) + { + T *p = new T[newCapacity]; + memcpy(p, _items, (size_t)_size * (size_t)sizeof(T)); + delete []_items; + _items = p; + _capacity = newCapacity; + } + } + + void ClearAndReserve(unsigned newCapacity) { Clear(); - return (*this += v); + if (newCapacity > _capacity) + { + delete []_items; + _items = NULL; + _capacity = 0; + _items = new T[newCapacity]; + _capacity = newCapacity; + } + } + + void ClearAndSetSize(unsigned newSize) + { + ClearAndReserve(newSize); + _size = newSize; } + + void ChangeSize_KeepData(unsigned newSize) + { + if (newSize > _capacity) + { + T *p = new T[newSize]; + memcpy(p, _items, (size_t)_size * (size_t)sizeof(T)); + delete []_items; + _items = p; + _capacity = newSize; + } + _size = newSize; + } + + void ReserveDown() + { + if (_size == _capacity) + return; + T *p = NULL; + if (_size != 0) + { + p = new T[_size]; + memcpy(p, _items, (size_t)_size * (size_t)sizeof(T)); + } + delete []_items; + _items = p; + _capacity = _size; + } + + ~CRecordVector() { delete []_items; } + + void ClearAndFree() + { + delete []_items; + _items = NULL; + _size = 0; + _capacity = 0; + } + + void Clear() { _size = 0; } + + void DeleteBack() { _size--; } + + void DeleteFrom(unsigned index) + { + // if (index <= _size) + _size = index; + } + + void DeleteFrontal(unsigned num) + { + if (num != 0) + { + MoveItems(0, num); + _size -= num; + } + } + + void Delete(unsigned index) + { + MoveItems(index, index + 1); + _size -= 1; + } + + /* + void Delete(unsigned index, unsigned num) + { + if (num > 0) + { + MoveItems(index, index + num); + _size -= num; + } + } + */ + + CRecordVector& operator=(const CRecordVector &v) + { + unsigned size = v.Size(); + if (size > _capacity) + { + delete []_items; + _capacity = 0; + _size = 0; + _items = NULL; + _items = new T[size]; + _capacity = size; + } + _size = size; + memcpy(_items, v._items, (size_t)size * (size_t)sizeof(T)); + return *this; + } + CRecordVector& operator+=(const CRecordVector &v) { - int size = v.Size(); - Reserve(Size() + size); - for (int i = 0; i < size; i++) - Add(v[i]); + unsigned size = v.Size(); + Reserve(_size + size); + memcpy(_items + _size, v._items, (size_t)size * (size_t)sizeof(T)); + _size += size; return *this; } - int Add(T item) + + unsigned Add(const T item) { ReserveOnePosition(); - ((T *)_items)[_size] = item; + _items[_size] = item; return _size++; } - void Insert(int index, T item) + + void AddInReserved(const T item) { - InsertOneItem(index); - ((T *)_items)[index] = item; + _items[_size++] = item; } - // T* GetPointer() const { return (T*)_items; } - // operator const T *() const { return _items; }; - const T& operator[](int index) const { return ((T *)_items)[index]; } - T& operator[](int index) { return ((T *)_items)[index]; } - const T& Front() const { return operator[](0); } - T& Front() { return operator[](0); } - const T& Back() const { return operator[](_size - 1); } - T& Back() { return operator[](_size - 1); } - void Swap(int i, int j) + void Insert(unsigned index, const T item) { - T temp = operator[](i); - operator[](i) = operator[](j); - operator[](j) = temp; + ReserveOnePosition(); + MoveItems(index + 1, index); + _items[index] = item; + _size++; } - int FindInSorted(const T& item, int left, int right) const + void MoveToFront(unsigned index) + { + if (index != 0) + { + T temp = _items[index]; + memmove(_items + 1, _items, (size_t)index * (size_t)sizeof(T)); + _items[0] = temp; + } + } + + const T& operator[](unsigned index) const { return _items[index]; } + T& operator[](unsigned index) { return _items[index]; } + const T& Front() const { return _items[0]; } + T& Front() { return _items[0]; } + const T& Back() const { return _items[_size - 1]; } + T& Back() { return _items[_size - 1]; } + + /* + void Swap(unsigned i, unsigned j) + { + T temp = _items[i]; + _items[i] = _items[j]; + _items[j] = temp; + } + */ + + int FindInSorted(const T item, unsigned left, unsigned right) const { while (left != right) { - int mid = (left + right) / 2; - const T& midValue = (*this)[mid]; - if (item == midValue) + unsigned mid = (left + right) / 2; + const T midVal = (*this)[mid]; + if (item == midVal) return mid; - if (item < midValue) + if (item < midVal) right = mid; else left = mid + 1; @@ -94,16 +249,16 @@ public: return -1; } - int FindInSorted(const T& item) const + int FindInSorted2(const T &item, unsigned left, unsigned right) const { - int left = 0, right = Size(); while (left != right) { - int mid = (left + right) / 2; - const T& midValue = (*this)[mid]; - if (item == midValue) + unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + int comp = item.Compare(midVal); + if (comp == 0) return mid; - if (item < midValue) + if (comp < 0) right = mid; else left = mid + 1; @@ -111,16 +266,26 @@ public: return -1; } - int AddToUniqueSorted(const T& item) + int FindInSorted(const T item) const + { + return FindInSorted(item, 0, _size); + } + + int FindInSorted2(const T &item) const + { + return FindInSorted2(item, 0, _size); + } + + unsigned AddToUniqueSorted(const T item) { - int left = 0, right = Size(); + unsigned left = 0, right = _size; while (left != right) { - int mid = (left + right) / 2; - const T& midValue = (*this)[mid]; - if (item == midValue) + unsigned mid = (left + right) / 2; + const T midVal = (*this)[mid]; + if (item == midVal) return mid; - if (item < midValue) + if (item < midVal) right = mid; else left = mid + 1; @@ -129,12 +294,31 @@ public: return right; } - static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param) + unsigned AddToUniqueSorted2(const T &item) + { + unsigned left = 0, right = _size; + while (left != right) + { + unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + int comp = item.Compare(midVal); + if (comp == 0) + return mid; + if (comp < 0) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param) { T temp = p[k]; for (;;) { - int s = (k << 1); + unsigned s = (k << 1); if (s > size) break; if (s < size && compare(p + s + 1, p + s, param) > 0) @@ -149,12 +333,12 @@ public: void Sort(int (*compare)(const T*, const T*, void *), void *param) { - int size = _size; + unsigned size = _size; if (size <= 1) return; T* p = (&Front()) - 1; { - int i = size / 2; + unsigned i = size >> 1; do SortRefDown(p, i, size, compare, param); while (--i != 0); @@ -168,6 +352,46 @@ public: } while (size > 1); } + + static void SortRefDown2(T* p, unsigned k, unsigned size) + { + T temp = p[k]; + for (;;) + { + unsigned s = (k << 1); + if (s > size) + break; + if (s < size && p[s + 1].Compare(p[s]) > 0) + s++; + if (temp.Compare(p[s]) >= 0) + break; + p[k] = p[s]; + k = s; + } + p[k] = temp; + } + + void Sort2() + { + unsigned size = _size; + if (size <= 1) + return; + T* p = (&Front()) - 1; + { + unsigned i = size >> 1; + do + SortRefDown2(p, i, size); + while (--i != 0); + } + do + { + T temp = p[size]; + p[size--] = p[1]; + p[1] = temp; + SortRefDown2(p, 1, size); + } + while (size > 1); + } }; typedef CRecordVector<int> CIntVector; @@ -177,76 +401,197 @@ typedef CRecordVector<unsigned char> CByteVector; typedef CRecordVector<void *> CPointerVector; template <class T> -class CObjectVector: public CPointerVector +class CObjectVector { + CPointerVector _v; public: + unsigned Size() const { return _v.Size(); } + bool IsEmpty() const { return _v.IsEmpty(); } + void ReserveDown() { _v.ReserveDown(); } + // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); } + void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); } + CObjectVector() {}; - ~CObjectVector() { Clear(); }; - CObjectVector(const CObjectVector &v): CPointerVector() { *this = v; } + CObjectVector(const CObjectVector &v) + { + unsigned size = v.Size(); + _v.ConstructReserve(size); + for (unsigned i = 0; i < size; i++) + _v.AddInReserved(new T(v[i])); + } CObjectVector& operator=(const CObjectVector &v) { Clear(); - return (*this += v); + unsigned size = v.Size(); + _v.Reserve(size); + for (unsigned i = 0; i < size; i++) + _v.AddInReserved(new T(v[i])); + return *this; } + CObjectVector& operator+=(const CObjectVector &v) { - int size = v.Size(); - Reserve(Size() + size); - for (int i = 0; i < size; i++) - Add(v[i]); + unsigned size = v.Size(); + _v.Reserve(Size() + size); + for (unsigned i = 0; i < size; i++) + _v.AddInReserved(new T(v[i])); return *this; } - const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); } - T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); } - T& Front() { return operator[](0); } + + const T& operator[](unsigned index) const { return *((T *)_v[index]); } + T& operator[](unsigned index) { return *((T *)_v[index]); } const T& Front() const { return operator[](0); } - T& Back() { return operator[](_size - 1); } - const T& Back() const { return operator[](_size - 1); } - int Add(const T& item) { return CPointerVector::Add(new T(item)); } - void Insert(int index, const T& item) { CPointerVector::Insert(index, new T(item)); } - virtual void Delete(int index, int num = 1) + T& Front() { return operator[](0); } + const T& Back() const { return operator[](_v.Size() - 1); } + T& Back() { return operator[](_v.Size() - 1); } + + void MoveToFront(unsigned index) { _v.MoveToFront(index); } + + unsigned Add(const T& item) { return _v.Add(new T(item)); } + + void AddInReserved(const T& item) { _v.AddInReserved(new T(item)); } + + T& AddNew() + { + T *p = new T; + _v.Add(p); + return *p; + } + + T& AddNewInReserved() + { + T *p = new T; + _v.AddInReserved(p); + return *p; + } + + void Insert(unsigned index, const T& item) { _v.Insert(index, new T(item)); } + + T& InsertNew(unsigned index) + { + T *p = new T; + _v.Insert(index, p); + return *p; + } + + ~CObjectVector() + { + for (unsigned i = _v.Size(); i != 0;) + delete (T *)_v[--i]; + } + + void ClearAndFree() + { + Clear(); + _v.ClearAndFree(); + } + + void Clear() + { + for (unsigned i = _v.Size(); i != 0;) + delete (T *)_v[--i]; + _v.Clear(); + } + + void DeleteFrom(unsigned index) + { + unsigned size = _v.Size(); + for (unsigned i = index; i < size; i++) + delete (T *)_v[i]; + _v.DeleteFrom(index); + } + + void DeleteFrontal(unsigned num) + { + for (unsigned i = 0; i < num; i++) + delete (T *)_v[i]; + _v.DeleteFrontal(num); + } + + void DeleteBack() { - TestIndexAndCorrectNum(index, num); - for (int i = 0; i < num; i++) - delete (T *)(((void **)_items)[index + i]); - CPointerVector::Delete(index, num); + delete (T *)_v[_v.Size() - 1]; + _v.DeleteBack(); } + + void Delete(unsigned index) + { + delete (T *)_v[index]; + _v.Delete(index); + } + + /* + void Delete(unsigned index, unsigned num) + { + for (unsigned i = 0; i < num; i++) + delete (T *)_v[index + i]; + _v.Delete(index, num); + } + */ + + /* int Find(const T& item) const { - for (int i = 0; i < Size(); i++) + unsigned size = Size(); + for (unsigned i = 0; i < size; i++) if (item == (*this)[i]) return i; return -1; } + */ + int FindInSorted(const T& item) const { - int left = 0, right = Size(); + unsigned left = 0, right = Size(); while (left != right) { - int mid = (left + right) / 2; - const T& midValue = (*this)[mid]; - if (item == midValue) + unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + int comp = item.Compare(midVal); + if (comp == 0) return mid; - if (item < midValue) + if (comp < 0) right = mid; else left = mid + 1; } return -1; } - int AddToSorted(const T& item) + + unsigned AddToUniqueSorted(const T& item) { - int left = 0, right = Size(); + unsigned left = 0, right = Size(); while (left != right) { - int mid = (left + right) / 2; - const T& midValue = (*this)[mid]; - if (item == midValue) + unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + int comp = item.Compare(midVal); + if (comp == 0) + return mid; + if (comp < 0) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + /* + unsigned AddToSorted(const T& item) + { + unsigned left = 0, right = Size(); + while (left != right) + { + unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + int comp = item.Compare(midVal); + if (comp == 0) { right = mid + 1; break; } - if (item < midValue) + if (comp < 0) right = mid; else left = mid + 1; @@ -254,13 +599,17 @@ public: Insert(right, item); return right; } + */ void Sort(int (*compare)(void *const *, void *const *, void *), void *param) - { CPointerVector::Sort(compare, param); } + { _v.Sort(compare, param); } static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */) - { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); } - void Sort() { CPointerVector::Sort(CompareObjectItems, 0); } + { return (*(*((const T **)a1))).Compare(*(*((const T **)a2))); } + + void Sort() { _v.Sort(CompareObjectItems, 0); } }; +#define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++) + #endif diff --git a/src/libs/7zip/win/CPP/Common/MyWindows.cpp b/src/libs/7zip/win/CPP/Common/MyWindows.cpp new file mode 100644 index 000000000..38c93fdb2 --- /dev/null +++ b/src/libs/7zip/win/CPP/Common/MyWindows.cpp @@ -0,0 +1,145 @@ +// MyWindows.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 + +#include <stdlib.h> + +#include "MyWindows.h" + +static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } +static inline void FreeForBSTR(void *pv) { ::free(pv);} + +/* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string. + We must select CBstrSizeType for another systems (not Win32): + + if (CBstrSizeType is UINT32), + then we support only strings smaller than 4 GB. + Win32 version always has that limitation. + + if (CBstrSizeType is UINT), + (UINT can be 16/32/64-bit) + We can support strings larger than 4 GB (if UINT is 64-bit), + but sizeof(UINT) can be different in parts compiled by + different compilers/settings, + and we can't send such BSTR strings between such parts. +*/ + +typedef UINT32 CBstrSizeType; +// typedef UINT CBstrSizeType; + +#define k_BstrSize_Max 0xFFFFFFFF +// #define k_BstrSize_Max UINT_MAX +// #define k_BstrSize_Max ((UINT)(INT)-1) + +BSTR SysAllocStringByteLen(LPCSTR s, UINT len) +{ + /* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end. + We provide also aligned null OLECHAR at the end. */ + + if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(OLECHAR) - sizeof(CBstrSizeType))) + return NULL; + + UINT size = (len + sizeof(OLECHAR) + sizeof(OLECHAR) - 1) & ~(sizeof(OLECHAR) - 1); + void *p = AllocateForBSTR(size + sizeof(CBstrSizeType)); + if (!p) + return NULL; + *(CBstrSizeType *)p = (CBstrSizeType)len; + BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); + if (s) + memcpy(bstr, s, len); + for (; len < size; len++) + ((Byte *)bstr)[len] = 0; + return bstr; +} + +BSTR SysAllocStringLen(const OLECHAR *s, UINT len) +{ + if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(CBstrSizeType)) / sizeof(OLECHAR)) + return NULL; + + UINT size = len * sizeof(OLECHAR); + void *p = AllocateForBSTR(size + sizeof(CBstrSizeType) + sizeof(OLECHAR)); + if (!p) + return NULL; + *(CBstrSizeType *)p = (CBstrSizeType)size; + BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); + if (s) + memcpy(bstr, s, size); + bstr[len] = 0; + return bstr; +} + +BSTR SysAllocString(const OLECHAR *s) +{ + if (!s) + return 0; + const OLECHAR *s2 = s; + while (*s2 != 0) + s2++; + return SysAllocStringLen(s, (UINT)(s2 - s)); +} + +void SysFreeString(BSTR bstr) +{ + if (bstr) + FreeForBSTR((CBstrSizeType *)bstr - 1); +} + +UINT SysStringByteLen(BSTR bstr) +{ + if (!bstr) + return 0; + return *((CBstrSizeType *)bstr - 1); +} + +UINT SysStringLen(BSTR bstr) +{ + if (!bstr) + return 0; + return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR); +} + + +HRESULT VariantClear(VARIANTARG *prop) +{ + if (prop->vt == VT_BSTR) + SysFreeString(prop->bstrVal); + prop->vt = VT_EMPTY; + return S_OK; +} + +HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src) +{ + HRESULT res = ::VariantClear(dest); + if (res != S_OK) + return res; + if (src->vt == VT_BSTR) + { + dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal, + SysStringByteLen(src->bstrVal)); + if (!dest->bstrVal) + return E_OUTOFMEMORY; + dest->vt = VT_BSTR; + } + else + *dest = *src; + return S_OK; +} + +LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2) +{ + if (ft1->dwHighDateTime < ft2->dwHighDateTime) return -1; + if (ft1->dwHighDateTime > ft2->dwHighDateTime) return 1; + if (ft1->dwLowDateTime < ft2->dwLowDateTime) return -1; + if (ft1->dwLowDateTime > ft2->dwLowDateTime) return 1; + return 0; +} + +DWORD GetLastError() +{ + return 0; +} + +#endif diff --git a/src/libs/7zip/win/CPP/Common/MyWindows.h b/src/libs/7zip/win/CPP/Common/MyWindows.h index 8b0e5c069..139a4e8b9 100644 --- a/src/libs/7zip/win/CPP/Common/MyWindows.h +++ b/src/libs/7zip/win/CPP/Common/MyWindows.h @@ -1,12 +1,17 @@ // MyWindows.h -#ifndef __MYWINDOWS_H -#define __MYWINDOWS_H +#ifndef __MY_WINDOWS_H +#define __MY_WINDOWS_H #ifdef _WIN32 #include <windows.h> +#ifdef UNDER_CE + #undef VARIANT_TRUE + #define VARIANT_TRUE ((VARIANT_BOOL)-1) +#endif + #else #include <stddef.h> // for wchar_t @@ -14,6 +19,8 @@ #include "MyGuidDef.h" +#define WINAPI + typedef char CHAR; typedef unsigned char UCHAR; @@ -40,8 +47,8 @@ typedef UINT32 DWORD; typedef Int64 LONGLONG; typedef UInt64 ULONGLONG; -typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER; -typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER; +typedef struct _LARGE_INTEGER { LONGLONG QuadPart; } LARGE_INTEGER; +typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart; } ULARGE_INTEGER; typedef const CHAR *LPCSTR; typedef CHAR TCHAR; @@ -57,7 +64,7 @@ typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; -}FILETIME; +} FILETIME; #define HRESULT LONG #define FAILED(Status) ((HRESULT)(Status)<0) @@ -145,8 +152,6 @@ typedef WORD PROPVAR_PAD1; typedef WORD PROPVAR_PAD2; typedef WORD PROPVAR_PAD3; -#ifdef __cplusplus - typedef struct tagPROPVARIANT { VARTYPE vt; @@ -177,11 +182,17 @@ typedef tagVARIANT VARIANT; typedef VARIANT VARIANTARG; MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop); -MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src); +MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src); -#endif +typedef struct tagSTATPROPSTG +{ + LPOLESTR lpwstrName; + PROPID propid; + VARTYPE vt; +} STATPROPSTG; MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len); +MY_EXTERN_C BSTR SysAllocStringLen(const OLECHAR *sz, UINT len); MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz); MY_EXTERN_C void SysFreeString(BSTR bstr); MY_EXTERN_C UINT SysStringByteLen(BSTR bstr); @@ -192,6 +203,7 @@ MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); #define CP_ACP 0 #define CP_OEMCP 1 +#define CP_UTF8 65001 typedef enum tagSTREAM_SEEK { diff --git a/src/libs/7zip/win/CPP/Common/NewHandler.cpp b/src/libs/7zip/win/CPP/Common/NewHandler.cpp index aad6e7d16..9072376df 100644 --- a/src/libs/7zip/win/CPP/Common/NewHandler.cpp +++ b/src/libs/7zip/win/CPP/Common/NewHandler.cpp @@ -1,5 +1,5 @@ // NewHandler.cpp - + #include "StdAfx.h" #include <stdlib.h> @@ -11,6 +11,32 @@ #ifndef DEBUG_MEMORY_LEAK #ifdef _WIN32 + +/* +void * my_new(size_t size) +{ + // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + void *p = ::malloc(size); + if (p == 0) + throw CNewException(); + return p; +} + +void my_delete(void *p) throw() +{ + // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p); + ::free(p); +} + +void * my_Realloc(void *p, size_t newSize, size_t oldSize) +{ + void *newBuf = my_new(newSize); + memcpy(newBuf, p, oldSize); + my_delete(p); + return newBuf; +} +*/ + void * #ifdef _MSC_VER __cdecl @@ -30,18 +56,42 @@ __cdecl #endif operator delete(void *p) throw() { - /* + // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p); + ::free(p); +} + +/* +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new[](size_t size) +{ + // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + void *p = ::malloc(size); if (p == 0) - return; - ::HeapFree(::GetProcessHeap(), 0, p); - */ + throw CNewException(); + return p; +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p) throw() +{ + // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p); ::free(p); } +*/ + #endif #else -#pragma init_seg(lib) +#include <stdio.h> + +// #pragma init_seg(lib) const int kDebugSize = 1000000; static void *a[kDebugSize]; static int index = 0; @@ -51,10 +101,6 @@ void * __cdecl operator new(size_t size) { numAllocs++; void *p = HeapAlloc(GetProcessHeap(), 0, size); - if (index == 40) - { - int t = 1; - } if (index < kDebugSize) { a[index] = p; diff --git a/src/libs/7zip/win/CPP/Common/NewHandler.h b/src/libs/7zip/win/CPP/Common/NewHandler.h index 215ba05f1..e3e7422c8 100644 --- a/src/libs/7zip/win/CPP/Common/NewHandler.h +++ b/src/libs/7zip/win/CPP/Common/NewHandler.h @@ -1,16 +1,68 @@ // Common/NewHandler.h -#ifndef __COMMON_NEWHANDLER_H -#define __COMMON_NEWHANDLER_H +#ifndef __COMMON_NEW_HANDLER_H +#define __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. + +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. + +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. + +Also we declare delete(void *p) throw() that creates smaller code. +*/ + class CNewException {}; +#ifdef WIN32 +// We can compile my_new and my_delete with _fastcall +/* +void * my_new(size_t size); +void my_delete(void *p) throw(); +// void * my_Realloc(void *p, size_t newSize, size_t oldSize); +*/ +#endif + #ifdef _WIN32 + +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new(size_t size); + void #ifdef _MSC_VER __cdecl #endif operator delete(void *p) throw(); + +#endif + +/* +#ifdef _WIN32 +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new[](size_t size); + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p) throw(); #endif +*/ #endif diff --git a/src/libs/7zip/win/CPP/Common/StdAfx.h b/src/libs/7zip/win/CPP/Common/StdAfx.h index b8ba1d5c4..420f5c326 100644 --- a/src/libs/7zip/win/CPP/Common/StdAfx.h +++ b/src/libs/7zip/win/CPP/Common/StdAfx.h @@ -3,7 +3,6 @@ #ifndef __STDAFX_H #define __STDAFX_H -// #include "MyWindows.h" -#include "NewHandler.h" +#include "Common.h" #endif diff --git a/src/libs/7zip/win/CPP/Common/StdInStream.cpp b/src/libs/7zip/win/CPP/Common/StdInStream.cpp deleted file mode 100644 index f3dcb85f5..000000000 --- a/src/libs/7zip/win/CPP/Common/StdInStream.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// Common/StdInStream.cpp - -#include "StdAfx.h" - -#include <tchar.h> - -#include "StdInStream.h" -#include "StringConvert.h" -#include "UTFConvert.h" - -#ifdef _MSC_VER -// "was declared deprecated" disabling -#pragma warning(disable : 4996 ) -#endif - -static const char kIllegalChar = '\0'; -static const char kNewLineChar = '\n'; - -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); - -bool CStdInStream::Open(LPCTSTR fileName) -{ - Close(); - _stream = _tfopen(fileName, kFileOpenMode); - _streamIsOpen = (_stream != 0); - return _streamIsOpen; -} - -bool CStdInStream::Close() -{ - if (!_streamIsOpen) - return true; - _streamIsOpen = (fclose(_stream) != 0); - return !_streamIsOpen; -} - -CStdInStream::~CStdInStream() -{ - Close(); -} - -AString CStdInStream::ScanStringUntilNewLine(bool allowEOF) -{ - AString s; - for (;;) - { - int intChar = GetChar(); - if (intChar == EOF) - { - if (allowEOF) - break; - throw kEOFMessage; - } - char c = char(intChar); - if (c == kIllegalChar) - throw kIllegalCharMessage; - if (c == kNewLineChar) - break; - s += c; - } - return s; -} - -UString CStdInStream::ScanUStringUntilNewLine() -{ - AString s = ScanStringUntilNewLine(true); - int codePage = g_CodePage; - if (codePage == -1) - codePage = CP_OEMCP; - UString dest; - if (codePage == CP_UTF8) - ConvertUTF8ToUnicode(s, dest); - else - dest = MultiByteToUnicodeString(s, (UINT)codePage); - return dest; -} - -void CStdInStream::ReadToString(AString &resultString) -{ - resultString.Empty(); - int c; - while ((c = GetChar()) != EOF) - resultString += char(c); -} - -bool CStdInStream::Eof() -{ - return (feof(_stream) != 0); -} - -int CStdInStream::GetChar() -{ - int c = fgetc(_stream); // getc() doesn't work in BeOS? - if (c == EOF && !Eof()) - throw kReadErrorMessage; - return c; -} - - diff --git a/src/libs/7zip/win/CPP/Common/StdInStream.h b/src/libs/7zip/win/CPP/Common/StdInStream.h deleted file mode 100644 index 0d182cc3c..000000000 --- a/src/libs/7zip/win/CPP/Common/StdInStream.h +++ /dev/null @@ -1,32 +0,0 @@ -// Common/StdInStream.h - -#ifndef __COMMON_STDINSTREAM_H -#define __COMMON_STDINSTREAM_H - -#include <stdio.h> - -#include "MyString.h" -#include "Types.h" - -class CStdInStream -{ - bool _streamIsOpen; - FILE *_stream; -public: - CStdInStream(): _streamIsOpen(false) {}; - CStdInStream(FILE *stream): _streamIsOpen(false), _stream(stream) {}; - ~CStdInStream(); - bool Open(LPCTSTR fileName); - bool Close(); - - AString ScanStringUntilNewLine(bool allowEOF = false); - void ReadToString(AString &resultString); - UString ScanUStringUntilNewLine(); - - bool Eof(); - int GetChar(); -}; - -extern CStdInStream g_StdIn; - -#endif diff --git a/src/libs/7zip/win/CPP/Common/StdOutStream.cpp b/src/libs/7zip/win/CPP/Common/StdOutStream.cpp index 061a76063..6aed31a31 100644 --- a/src/libs/7zip/win/CPP/Common/StdOutStream.cpp +++ b/src/libs/7zip/win/CPP/Common/StdOutStream.cpp @@ -9,21 +9,16 @@ #include "StringConvert.h" #include "UTFConvert.h" -#ifdef _MSC_VER -// "was declared deprecated" disabling -#pragma warning(disable : 4996 ) -#endif - static const char kNewLineChar = '\n'; static const char *kFileOpenMode = "wt"; extern int g_CodePage; -CStdOutStream g_StdOut(stdout); -CStdOutStream g_StdErr(stderr); +CStdOutStream g_StdOut(stdout); +CStdOutStream g_StdErr(stderr); -bool CStdOutStream::Open(const char *fileName) +bool CStdOutStream::Open(const char *fileName) throw() { Close(); _stream = fopen(fileName, kFileOpenMode); @@ -31,7 +26,7 @@ bool CStdOutStream::Open(const char *fileName) return _streamIsOpen; } -bool CStdOutStream::Close() +bool CStdOutStream::Close() throw() { if (!_streamIsOpen) return true; @@ -42,33 +37,16 @@ bool CStdOutStream::Close() return true; } -bool CStdOutStream::Flush() +bool CStdOutStream::Flush() throw() { return (fflush(_stream) == 0); } -CStdOutStream::~CStdOutStream () -{ - Close(); -} - -CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream &)) -{ - (*aFunction)(*this); - return *this; -} - -CStdOutStream & endl(CStdOutStream & outStream) +CStdOutStream & endl(CStdOutStream & outStream) throw() { return outStream << kNewLineChar; } -CStdOutStream & CStdOutStream::operator<<(const char *s) -{ - fputs(s, _stream); - return *this; -} - CStdOutStream & CStdOutStream::operator<<(const wchar_t *s) { int codePage = g_CodePage; @@ -78,27 +56,51 @@ CStdOutStream & CStdOutStream::operator<<(const wchar_t *s) if (codePage == CP_UTF8) ConvertUnicodeToUTF8(s, dest); else - dest = UnicodeStringToMultiByte(s, (UINT)codePage); - *this << (const char *)dest; - return *this; + UnicodeStringToMultiByte2(dest, s, (UINT)codePage); + return operator<<((const char *)dest); +} + +void StdOut_Convert_UString_to_AString(const UString &s, AString &temp) +{ + int codePage = g_CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if (codePage == CP_UTF8) + ConvertUnicodeToUTF8(s, temp); + else + UnicodeStringToMultiByte2(temp, s, (UINT)codePage); +} + +void CStdOutStream::PrintUString(const UString &s, AString &temp) +{ + StdOut_Convert_UString_to_AString(s, temp); + *this << (const char *)temp; +} + +CStdOutStream & CStdOutStream::operator<<(Int32 number) throw() +{ + char s[32]; + ConvertInt64ToString(number, s); + return operator<<(s); } -CStdOutStream & CStdOutStream::operator<<(char c) +CStdOutStream & CStdOutStream::operator<<(Int64 number) throw() { - fputc(c, _stream); - return *this; + char s[32]; + ConvertInt64ToString(number, s); + return operator<<(s); } -CStdOutStream & CStdOutStream::operator<<(int number) +CStdOutStream & CStdOutStream::operator<<(UInt32 number) throw() { - char textString[32]; - ConvertInt64ToString(number, textString); - return operator<<(textString); + char s[16]; + ConvertUInt32ToString(number, s); + return operator<<(s); } -CStdOutStream & CStdOutStream::operator<<(UInt64 number) +CStdOutStream & CStdOutStream::operator<<(UInt64 number) throw() { - char textString[32]; - ConvertUInt64ToString(number, textString); - return operator<<(textString); + char s[32]; + ConvertUInt64ToString(number, s); + return operator<<(s); } diff --git a/src/libs/7zip/win/CPP/Common/StdOutStream.h b/src/libs/7zip/win/CPP/Common/StdOutStream.h index b0b2c615c..0a8c0febb 100644 --- a/src/libs/7zip/win/CPP/Common/StdOutStream.h +++ b/src/libs/7zip/win/CPP/Common/StdOutStream.h @@ -1,35 +1,62 @@ // Common/StdOutStream.h -#ifndef __COMMON_STDOUTSTREAM_H -#define __COMMON_STDOUTSTREAM_H +#ifndef __COMMON_STD_OUT_STREAM_H +#define __COMMON_STD_OUT_STREAM_H #include <stdio.h> -#include "Types.h" +#include "MyString.h" +#include "MyTypes.h" class CStdOutStream { - bool _streamIsOpen; FILE *_stream; + bool _streamIsOpen; public: - CStdOutStream (): _streamIsOpen(false), _stream(0) {}; - CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {}; - ~CStdOutStream (); + CStdOutStream(): _stream(0), _streamIsOpen(false) {}; + CStdOutStream(FILE *stream): _stream(stream), _streamIsOpen(false) {}; + ~CStdOutStream() { Close(); } + + // void AttachStdStream(FILE *stream) { _stream = stream; _streamIsOpen = false; } + // bool IsDefined() const { return _stream != NULL; } + operator FILE *() { return _stream; } - bool Open(const char *fileName); - bool Close(); - bool Flush(); - CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream &)); - CStdOutStream & operator<<(const char *string); - CStdOutStream & operator<<(const wchar_t *string); - CStdOutStream & operator<<(char c); - CStdOutStream & operator<<(int number); - CStdOutStream & operator<<(UInt64 number); + bool Open(const char *fileName) throw(); + bool Close() throw(); + bool Flush() throw(); + + CStdOutStream & operator<<(CStdOutStream & (* func)(CStdOutStream &)) + { + (*func)(*this); + return *this; + } + + CStdOutStream & operator<<(const char *s) throw() + { + fputs(s, _stream); + return *this; + } + + CStdOutStream & operator<<(char c) throw() + { + fputc(c, _stream); + return *this; + } + + CStdOutStream & operator<<(Int32 number) throw(); + CStdOutStream & operator<<(Int64 number) throw(); + CStdOutStream & operator<<(UInt32 number) throw(); + CStdOutStream & operator<<(UInt64 number) throw(); + + CStdOutStream & operator<<(const wchar_t *s); + void PrintUString(const UString &s, AString &temp); }; -CStdOutStream & endl(CStdOutStream & outStream); +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/src/libs/7zip/win/CPP/Common/StringConvert.cpp b/src/libs/7zip/win/CPP/Common/StringConvert.cpp index 681895b71..0443a06ca 100644 --- a/src/libs/7zip/win/CPP/Common/StringConvert.cpp +++ b/src/libs/7zip/win/CPP/Common/StringConvert.cpp @@ -15,8 +15,8 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) if (!srcString.IsEmpty()) { int numChars = MultiByteToWideChar(codePage, 0, srcString, - srcString.Length(), resultString.GetBuffer(srcString.Length()), - srcString.Length() + 1); + srcString.Len(), resultString.GetBuffer(srcString.Len()), + srcString.Len() + 1); if (numChars == 0) throw 282228; resultString.ReleaseBuffer(numChars); @@ -24,15 +24,83 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) return resultString; } +void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage) +{ + dest.Empty(); + if (!srcString.IsEmpty()) + { + wchar_t *destBuf = dest.GetBuffer(srcString.Len()); + const char *sp = (const char *)srcString; + unsigned i; + for (i = 0;;) + { + char c = sp[i]; + if ((Byte)c >= 0x80 || c == 0) + break; + destBuf[i++] = (wchar_t)c; + } + + if (i != srcString.Len()) + { + unsigned numChars = MultiByteToWideChar(codePage, 0, sp + i, + srcString.Len() - i, destBuf + i, + srcString.Len() + 1 - i); + if (numChars == 0) + throw 282228; + i += numChars; + } + dest.ReleaseBuffer(i); + } +} + +void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed) +{ + dest.Empty(); + defaultCharWasUsed = false; + if (!s.IsEmpty()) + { + unsigned numRequiredBytes = s.Len() * 2; + char *destBuf = dest.GetBuffer(numRequiredBytes); + unsigned i; + const wchar_t *sp = (const wchar_t *)s; + for (i = 0;;) + { + wchar_t c = sp[i]; + if (c >= 0x80 || c == 0) + break; + destBuf[i++] = (char)c; + } + defaultCharWasUsed = false; + if (i != s.Len()) + { + BOOL defUsed; + unsigned numChars = WideCharToMultiByte(codePage, 0, sp + i, s.Len() - i, + destBuf + i, numRequiredBytes + 1 - i, + &defaultChar, &defUsed); + defaultCharWasUsed = (defUsed != FALSE); + if (numChars == 0) + throw 282229; + i += numChars; + } + dest.ReleaseBuffer(i); + } +} + +void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage) +{ + bool defaultCharWasUsed; + UnicodeStringToMultiByte2(dest, srcString, codePage, '_', defaultCharWasUsed); +} + AString UnicodeStringToMultiByte(const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed) { AString dest; defaultCharWasUsed = false; if (!s.IsEmpty()) { - int numRequiredBytes = s.Length() * 2; + unsigned numRequiredBytes = s.Len() * 2; BOOL defUsed; - int numChars = WideCharToMultiByte(codePage, 0, s, s.Length(), + int numChars = WideCharToMultiByte(codePage, 0, s, s.Len(), dest.GetBuffer(numRequiredBytes), numRequiredBytes + 1, &defaultChar, &defUsed); defaultCharWasUsed = (defUsed != FALSE); @@ -53,7 +121,7 @@ AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) AString SystemStringToOemString(const CSysString &srcString) { AString result; - CharToOem(srcString, result.GetBuffer(srcString.Length() * 2)); + CharToOem(srcString, result.GetBuffer(srcString.Len() * 2)); result.ReleaseBuffer(); return result; } @@ -64,12 +132,12 @@ AString SystemStringToOemString(const CSysString &srcString) UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) { UString resultString; - for (int i = 0; i < srcString.Length(); i++) - resultString += wchar_t(srcString[i]); + for (unsigned i = 0; i < srcString.Len(); i++) + resultString += (wchar_t)srcString[i]; /* if (!srcString.IsEmpty()) { - int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1); + int numChars = mbstowcs(resultString.GetBuffer(srcString.Len()), srcString, srcString.Len() + 1); if (numChars < 0) throw "Your environment does not support UNICODE"; resultString.ReleaseBuffer(numChars); } @@ -80,12 +148,12 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) { AString resultString; - for (int i = 0; i < srcString.Length(); i++) - resultString += char(srcString[i]); + for (unsigned i = 0; i < srcString.Len(); i++) + resultString += (char)srcString[i]; /* if (!srcString.IsEmpty()) { - int numRequiredBytes = srcString.Length() * 6 + 1; + int numRequiredBytes = srcString.Len() * 6 + 1; int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes); if (numChars < 0) throw "Your environment does not support UNICODE"; resultString.ReleaseBuffer(numChars); diff --git a/src/libs/7zip/win/CPP/Common/StringConvert.h b/src/libs/7zip/win/CPP/Common/StringConvert.h index cd737becb..8eea72ef2 100644 --- a/src/libs/7zip/win/CPP/Common/StringConvert.h +++ b/src/libs/7zip/win/CPP/Common/StringConvert.h @@ -3,15 +3,19 @@ #ifndef __COMMON_STRING_CONVERT_H #define __COMMON_STRING_CONVERT_H -#include "MyWindows.h" #include "MyString.h" -#include "Types.h" +#include "MyWindows.h" UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP); + +// optimized versions that work faster for ASCII strings +void MultiByteToUnicodeString2(UString &dest, const AString &srcString, 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) diff --git a/src/libs/7zip/win/CPP/Common/StringToInt.cpp b/src/libs/7zip/win/CPP/Common/StringToInt.cpp index 9473766bc..2023fcc2c 100644 --- a/src/libs/7zip/win/CPP/Common/StringToInt.cpp +++ b/src/libs/7zip/win/CPP/Common/StringToInt.cpp @@ -4,87 +4,141 @@ #include "StringToInt.h" -UInt64 ConvertStringToUInt64(const char *s, const char **end) +static const UInt32 k_UInt32_max = 0xFFFFFFFF; +static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF); +// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1; + +#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType) \ + uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \ + if (end) *end = s; \ + uintType res = 0; \ + for (;; s++) { \ + charType c = *s; \ + if (c < '0' || c > '9') { if (end) *end = s; return res; } \ + if (res > (k_ ## uintType ## _max) / 10) return 0; \ + res *= 10; \ + unsigned v = (c - '0'); \ + if (res > (k_ ## uintType ## _max) - v) return 0; \ + res += v; }} + +CONVERT_STRING_TO_UINT_FUNC(UInt32, char) +CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t) +CONVERT_STRING_TO_UINT_FUNC(UInt64, char) +CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t) + +Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw() +{ + if (end) + *end = s; + const wchar_t *s2 = s; + if (*s == '-') + s2++; + if (*s2 == 0) + return 0; + const wchar_t *end2; + UInt32 res = ConvertStringToUInt32(s2, &end2); + if (*s == '-') + { + if (res > ((UInt32)1 << (32 - 1))) + return 0; + } + else if ((res & ((UInt32)1 << (32 - 1))) != 0) + return 0; + if (end) + *end = end2; + if (*s == '-') + return -(Int32)res; + return (Int32)res; +} + +UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw() { - UInt64 result = 0; - for (;;) + if (end) + *end = s; + UInt32 res = 0; + for (;; s++) { char c = *s; - if (c < '0' || c > '9') + if (c < '0' || c > '7') { - if (end != NULL) + if (end) *end = s; - return result; + return res; } - result *= 10; - result += (c - '0'); - s++; + if ((res & (UInt32)7 << (32 - 3)) != 0) + return 0; + res <<= 3; + res |= (unsigned)(c - '0'); } } -UInt64 ConvertOctStringToUInt64(const char *s, const char **end) +UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw() { - UInt64 result = 0; - for (;;) + if (end) + *end = s; + UInt64 res = 0; + for (;; s++) { char c = *s; if (c < '0' || c > '7') { - if (end != NULL) + if (end) *end = s; - return result; + return res; } - result <<= 3; - result += (c - '0'); - s++; + if ((res & (UInt64)7 << (64 - 3)) != 0) + return 0; + res <<= 3; + res |= (unsigned)(c - '0'); } } -UInt64 ConvertHexStringToUInt64(const char *s, const char **end) +UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw() { - UInt64 result = 0; - for (;;) + if (end) + *end = s; + UInt32 res = 0; + for (;; s++) { char c = *s; - UInt32 v; + unsigned v; if (c >= '0' && c <= '9') v = (c - '0'); else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A'); else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a'); else { - if (end != NULL) + if (end) *end = s; - return result; + return res; } - result <<= 4; - result |= v; - s++; + if ((res & (UInt32)0xF << (32 - 4)) != 0) + return 0; + res <<= 4; + res |= v; } } - -UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) +UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw() { - UInt64 result = 0; - for (;;) + if (end) + *end = s; + UInt64 res = 0; + for (;; s++) { - wchar_t c = *s; - if (c < '0' || c > '9') + char c = *s; + unsigned v; + if (c >= '0' && c <= '9') v = (c - '0'); + else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A'); + else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a'); + else { - if (end != NULL) + if (end) *end = s; - return result; + return res; } - result *= 10; - result += (c - '0'); - s++; + if ((res & (UInt64)0xF << (64 - 4)) != 0) + return 0; + res <<= 4; + res |= v; } } - - -Int64 ConvertStringToInt64(const char *s, const char **end) -{ - if (*s == '-') - return -(Int64)ConvertStringToUInt64(s + 1, end); - return ConvertStringToUInt64(s, end); -} diff --git a/src/libs/7zip/win/CPP/Common/StringToInt.h b/src/libs/7zip/win/CPP/Common/StringToInt.h index c0d860eff..5c5d7d7fe 100644 --- a/src/libs/7zip/win/CPP/Common/StringToInt.h +++ b/src/libs/7zip/win/CPP/Common/StringToInt.h @@ -1,18 +1,21 @@ // Common/StringToInt.h -#ifndef __COMMON_STRINGTOINT_H -#define __COMMON_STRINGTOINT_H +#ifndef __COMMON_STRING_TO_INT_H +#define __COMMON_STRING_TO_INT_H -#include <string.h> -#include "Types.h" +#include "MyTypes.h" -UInt64 ConvertStringToUInt64(const char *s, const char **end); -UInt64 ConvertOctStringToUInt64(const char *s, const char **end); -UInt64 ConvertHexStringToUInt64(const char *s, const char **end); -UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end); +UInt32 ConvertStringToUInt32(const char *s, const char **end) throw(); +UInt64 ConvertStringToUInt64(const char *s, const char **end) throw(); +UInt32 ConvertStringToUInt32(const wchar_t *s, const wchar_t **end) throw(); +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) throw(); -Int64 ConvertStringToInt64(const char *s, const char **end); +Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw(); -#endif +UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw(); +UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw(); +UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw(); +UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw(); +#endif diff --git a/src/libs/7zip/win/CPP/Common/Types.h b/src/libs/7zip/win/CPP/Common/Types.h deleted file mode 100644 index 9365b327f..000000000 --- a/src/libs/7zip/win/CPP/Common/Types.h +++ /dev/null @@ -1,11 +0,0 @@ -// Common/Types.h - -#ifndef __COMMON_TYPES_H -#define __COMMON_TYPES_H - -#include "../../C/Types.h" - -typedef int HRes; - -#endif - diff --git a/src/libs/7zip/win/CPP/Common/UTFConvert.cpp b/src/libs/7zip/win/CPP/Common/UTFConvert.cpp index 95362430a..38bac3331 100644 --- a/src/libs/7zip/win/CPP/Common/UTFConvert.cpp +++ b/src/libs/7zip/win/CPP/Common/UTFConvert.cpp @@ -2,18 +2,53 @@ #include "StdAfx.h" +#include "MyTypes.h" #include "UTFConvert.h" -#include "Types.h" static const Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; -static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen) +bool CheckUTF8(const char *src) throw() +{ + for (;;) + { + Byte c; + unsigned numAdds; + c = *src++; + if (c == 0) + return true; + + if (c < 0x80) + continue; + if (c < 0xC0) + return false; + for (numAdds = 1; numAdds < 5; numAdds++) + if (c < kUtf8Limits[numAdds]) + break; + UInt32 value = (c - kUtf8Limits[numAdds - 1]); + + do + { + Byte c2 = *src++; + if (c2 < 0x80 || c2 >= 0xC0) + return false; + value <<= 6; + value |= (c2 - 0x80); + } + while (--numAdds); + + if (value >= 0x110000) + return false; + } +} + + +static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen) throw() { size_t destPos = 0, srcPos = 0; for (;;) { Byte c; - int numAdds; + unsigned numAdds; if (srcPos == srcLen) { *destLen = destPos; @@ -46,8 +81,8 @@ static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_ value <<= 6; value |= (c2 - 0x80); } - while (--numAdds != 0); - + while (--numAdds); + if (value < 0x10000) { if (dest) @@ -124,11 +159,9 @@ bool ConvertUTF8ToUnicode(const AString &src, UString &dest) { dest.Empty(); size_t destLen = 0; - Utf8_To_Utf16(NULL, &destLen, src, src.Length()); - wchar_t *p = dest.GetBuffer((int)destLen); - Bool res = Utf8_To_Utf16(p, &destLen, src, src.Length()); - p[destLen] = 0; - dest.ReleaseBuffer(); + Utf8_To_Utf16(NULL, &destLen, src, src.Len()); + Bool res = Utf8_To_Utf16(dest.GetBuffer((unsigned)destLen), &destLen, src, src.Len()); + dest.ReleaseBuffer((unsigned)destLen); return res ? true : false; } @@ -136,10 +169,8 @@ bool ConvertUnicodeToUTF8(const UString &src, AString &dest) { dest.Empty(); size_t destLen = 0; - Utf16_To_Utf8(NULL, &destLen, src, src.Length()); - char *p = dest.GetBuffer((int)destLen); - Bool res = Utf16_To_Utf8(p, &destLen, src, src.Length()); - p[destLen] = 0; - dest.ReleaseBuffer(); + Utf16_To_Utf8(NULL, &destLen, src, src.Len()); + Bool res = Utf16_To_Utf8(dest.GetBuffer((unsigned)destLen), &destLen, src, src.Len()); + dest.ReleaseBuffer((unsigned)destLen); return res ? true : false; } diff --git a/src/libs/7zip/win/CPP/Common/UTFConvert.h b/src/libs/7zip/win/CPP/Common/UTFConvert.h index 2a14600d9..16b02fe45 100644 --- a/src/libs/7zip/win/CPP/Common/UTFConvert.h +++ b/src/libs/7zip/win/CPP/Common/UTFConvert.h @@ -1,10 +1,11 @@ // Common/UTFConvert.h -#ifndef __COMMON_UTFCONVERT_H -#define __COMMON_UTFCONVERT_H +#ifndef __COMMON_UTF_CONVERT_H +#define __COMMON_UTF_CONVERT_H #include "MyString.h" +bool CheckUTF8(const char *src) throw(); bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString); bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString); diff --git a/src/libs/7zip/win/CPP/Common/Wildcard.cpp b/src/libs/7zip/win/CPP/Common/Wildcard.cpp index 476ddebde..e88a1cf1c 100644 --- a/src/libs/7zip/win/CPP/Common/Wildcard.cpp +++ b/src/libs/7zip/win/CPP/Common/Wildcard.cpp @@ -2,8 +2,6 @@ #include "StdAfx.h" -#include "../../C/Types.h" - #include "Wildcard.h" bool g_CaseSensitive = @@ -13,37 +11,43 @@ bool g_CaseSensitive = true; #endif -static const wchar_t kAnyCharsChar = L'*'; -static const wchar_t kAnyCharChar = L'?'; - -#ifdef _WIN32 -static const wchar_t kDirDelimiter1 = L'\\'; -#endif -static const wchar_t kDirDelimiter2 = L'/'; - -static const UString kWildCardCharSet = L"?*"; -static const UString kIllegalWildCardFileNameChars= - L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF" - L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" - L"\"/:<>\\|"; +bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2) +{ + if (g_CaseSensitive) + { + for (;;) + { + wchar_t c2 = *s2++; if (c2 == 0) return true; + wchar_t c1 = *s1++; + if (MyCharUpper(c1) != + MyCharUpper(c2)) + return false; + } + } + for (;;) + { + wchar_t c2 = *s2++; if (c2 == 0) return true; + wchar_t c1 = *s1++; if (c1 != c2) return false; + } +} -static inline bool IsCharDirLimiter(wchar_t c) +int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW { - return ( - #ifdef _WIN32 - c == kDirDelimiter1 || - #endif - c == kDirDelimiter2); + if (g_CaseSensitive) + return wcscmp(s1, s2); + return MyStringCompareNoCase(s1, s2); } -int CompareFileNames(const UString &s1, const UString &s2) +#ifndef USE_UNICODE_FSTRING +int CompareFileNames(const char *s1, const char *s2) { if (g_CaseSensitive) - return s1.Compare(s2); - return s1.CompareNoCase(s2); + return wcscmp(fs2us(s1), fs2us(s2)); + return MyStringCompareNoCase(fs2us(s1), fs2us(s2)); } +#endif // ----------------------------------------- // this function compares name with mask @@ -58,7 +62,7 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name) wchar_t c = *name; if (m == 0) return (c == 0); - if (m == kAnyCharsChar) + if (m == '*') { if (EnhancedMaskTest(mask + 1, name)) return true; @@ -67,7 +71,7 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name) } else { - if (m == kAnyCharChar) + if (m == '?') { if (c == 0) return false; @@ -87,61 +91,84 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name) void SplitPathToParts(const UString &path, UStringVector &pathParts) { pathParts.Clear(); - UString name; - int len = path.Length(); + unsigned len = path.Len(); if (len == 0) return; - for (int i = 0; i < len; i++) - { - wchar_t c = path[i]; - if (IsCharDirLimiter(c)) + UString name; + unsigned prev = 0; + for (unsigned i = 0; i < len; i++) + if (IsCharDirLimiter(path[i])) { + name.SetFrom(path.Ptr(prev), i - prev); pathParts.Add(name); - name.Empty(); + prev = i + 1; } - else - name += c; - } + name.SetFrom(path.Ptr(prev), len - prev); pathParts.Add(name); } -void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name) +void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name) { - int i; - for (i = path.Length() - 1; i >= 0; i--) - if (IsCharDirLimiter(path[i])) + const wchar_t *start = path; + const wchar_t *p = start + path.Len(); + for (; p != start; p--) + if (IsCharDirLimiter(*(p - 1))) break; - dirPrefix = path.Left(i + 1); - name = path.Mid(i + 1); + dirPrefix.SetFrom(path, (unsigned)(p - start)); + name = p; +} + +void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name) +{ + const wchar_t *start = path; + const wchar_t *p = start + path.Len(); + if (p != start) + { + if (IsCharDirLimiter(*(p - 1))) + p--; + for (; p != start; p--) + if (IsCharDirLimiter(*(p - 1))) + break; + } + dirPrefix.SetFrom(path, (unsigned)(p - start)); + name = p; } UString ExtractDirPrefixFromPath(const UString &path) { - int i; - for (i = path.Length() - 1; i >= 0; i--) - if (IsCharDirLimiter(path[i])) + const wchar_t *start = path; + const wchar_t *p = start + path.Len(); + for (; p != start; p--) + if (IsCharDirLimiter(*(p - 1))) break; - return path.Left(i + 1); + return path.Left((unsigned)(p - start)); } UString ExtractFileNameFromPath(const UString &path) { - int i; - for (i = path.Length() - 1; i >= 0; i--) - if (IsCharDirLimiter(path[i])) + const wchar_t *start = path; + const wchar_t *p = start + path.Len(); + for (; p != start; p--) + if (IsCharDirLimiter(*(p - 1))) break; - return path.Mid(i + 1); + return p; } -bool CompareWildCardWithName(const UString &mask, const UString &name) +bool DoesWildcardMatchName(const UString &mask, const UString &name) { return EnhancedMaskTest(mask, name); } -bool DoesNameContainWildCard(const UString &path) +bool DoesNameContainWildcard(const UString &path) { - return (path.FindOneOf(kWildCardCharSet) >= 0); + for (unsigned i = 0; i < path.Len(); i++) + { + wchar_t c = path[i]; + if (c == '*' || c == '?') + return true; + } + return false; } @@ -151,22 +178,36 @@ bool DoesNameContainWildCard(const UString &path) namespace NWildcard { +#ifdef _WIN32 +bool IsDriveColonName(const wchar_t *s) +{ + wchar_t c = s[0]; + return c != 0 && s[1] == ':' && s[2] == 0 && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'); +} +#endif + /* + M = MaskParts.Size(); N = TestNameParts.Size(); File Dir -ForFile req M<=N [N-M, N) - - nonreq M=N [0, M) - - -ForDir req M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File - nonreq [0, M) same as ForBoth-File +ForFile rec M<=N [N-M, N) - +!ForDir nonrec M=N [0, M) - -ForBoth req m<=N [0, M) ... [N-M, N) same as ForBoth-File - nonreq [0, M) same as ForBoth-File +ForDir rec M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File +!ForFile nonrec [0, M) same as ForBoth-File + +ForFile rec m<=N [0, M) ... [N-M, N) same as ForBoth-File +ForDir nonrec [0, M) same as ForBoth-File */ +bool CItem::AreAllAllowed() const +{ + return ForFile && ForDir && WildcardMatching && PathParts.Size() == 1 && PathParts.Front() == L"*"; +} + bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const { if (!isFile && !ForDir) @@ -176,36 +217,62 @@ bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const return false; int start = 0; int finish = 0; + if (isFile) { - if (!ForDir && !Recursive && delta !=0) - return false; + if (!ForDir) + { + if (Recursive) + start = delta; + else if (delta !=0) + return false; + } if (!ForFile && delta == 0) return false; - if (!ForDir && Recursive) - start = delta; } + if (Recursive) { finish = delta; if (isFile && !ForFile) finish = delta - 1; } + for (int d = start; d <= finish; d++) { - int i; + unsigned i; for (i = 0; i < PathParts.Size(); i++) - if (!CompareWildCardWithName(PathParts[i], pathParts[i + d])) - break; + { + if (WildcardMatching) + { + if (!DoesWildcardMatchName(PathParts[i], pathParts[i + d])) + break; + } + else + { + if (CompareFileNames(PathParts[i], pathParts[i + d]) != 0) + break; + } + } if (i == PathParts.Size()) return true; } return false; } +bool CCensorNode::AreAllAllowed() const +{ + if (!Name.IsEmpty() || + !SubNodes.IsEmpty() || + !ExcludeItems.IsEmpty() || + IncludeItems.Size() != 1) + return false; + return IncludeItems.Front().AreAllAllowed(); +} + int CCensorNode::FindSubNode(const UString &name) const { - for (int i = 0; i < SubNodes.Size(); i++) + FOR_VECTOR (i, SubNodes) if (CompareFileNames(SubNodes[i].Name, name) == 0) return i; return -1; @@ -223,11 +290,19 @@ void CCensorNode::AddItem(bool include, CItem &item) { if (item.PathParts.Size() <= 1) { + if (item.PathParts.Size() != 0 && item.WildcardMatching) + { + if (!DoesNameContainWildcard(item.PathParts.Front())) + item.WildcardMatching = false; + } AddItemSimple(include, item); return; } const UString &front = item.PathParts.Front(); - if (DoesNameContainWildCard(front)) + + // We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name + // if (item.Wildcard) + if (DoesNameContainWildcard(front)) { AddItemSimple(include, item); return; @@ -239,19 +314,20 @@ void CCensorNode::AddItem(bool include, CItem &item) SubNodes[index].AddItem(include, item); } -void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir) +void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching) { CItem item; SplitPathToParts(path, item.PathParts); item.Recursive = recursive; item.ForFile = forFile; item.ForDir = forDir; + item.WildcardMatching = wildcardMatching; AddItem(include, item); } bool CCensorNode::NeedCheckSubDirs() const { - for (int i = 0; i < IncludeItems.Size(); i++) + FOR_VECTOR (i, IncludeItems) { const CItem &item = IncludeItems[i]; if (item.Recursive || item.PathParts.Size() > 1) @@ -264,7 +340,7 @@ bool CCensorNode::AreThereIncludeItems() const { if (IncludeItems.Size() > 0) return true; - for (int i = 0; i < SubNodes.Size(); i++) + FOR_VECTOR (i, SubNodes) if (SubNodes[i].AreThereIncludeItems()) return true; return false; @@ -273,13 +349,13 @@ bool CCensorNode::AreThereIncludeItems() const bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const { const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems; - for (int i = 0; i < items.Size(); i++) + FOR_VECTOR (i, items) if (items[i].CheckPath(pathParts, isFile)) return true; return false; } -bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const +bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const { if (CheckPathCurrent(false, pathParts, isFile)) { @@ -288,30 +364,45 @@ bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include } include = true; bool finded = CheckPathCurrent(true, pathParts, isFile); - if (pathParts.Size() == 1) + if (pathParts.Size() <= 1) return finded; int index = FindSubNode(pathParts.Front()); if (index >= 0) { UStringVector pathParts2 = pathParts; pathParts2.Delete(0); - if (SubNodes[index].CheckPath(pathParts2, isFile, include)) + if (SubNodes[index].CheckPathVect(pathParts2, isFile, include)) return true; } return finded; } -bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const +bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const { UStringVector pathParts; SplitPathToParts(path, pathParts); - return CheckPath(pathParts, isFile, include); + if (CheckPathVect(pathParts, isFile, include)) + { + if (!include || !isAltStream) + return true; + } + if (isAltStream && !pathParts.IsEmpty()) + { + UString &back = pathParts.Back(); + int pos = back.Find(L':'); + if (pos > 0) + { + back.DeleteFrom(pos); + return CheckPathVect(pathParts, isFile, include); + } + } + return false; } -bool CCensorNode::CheckPath(const UString &path, bool isFile) const +bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) const { bool include; - if (CheckPath(path, isFile, include)) + if (CheckPath2(isAltStream, path, isFile, include)) return include; return false; } @@ -335,25 +426,25 @@ bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile } */ -void CCensorNode::AddItem2(bool include, const UString &path, bool recursive) +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 (IsCharDirLimiter(path[path.Length() - 1])) + if (IsCharDirLimiter(path.Back())) { - path2.Delete(path.Length() - 1); + path2.DeleteBack(); forFile = false; } - AddItem(include, path2, recursive, forFile, forFolder); + AddItem(include, path2, recursive, forFile, forFolder, wildcardMatching); } void CCensorNode::ExtendExclude(const CCensorNode &fromNodes) { ExcludeItems += fromNodes.ExcludeItems; - for (int i = 0; i < fromNodes.SubNodes.Size(); i++) + FOR_VECTOR (i, fromNodes.SubNodes) { const CCensorNode &node = fromNodes.SubNodes[i]; int subNodeIndex = FindSubNode(node.Name); @@ -365,13 +456,13 @@ void CCensorNode::ExtendExclude(const CCensorNode &fromNodes) int CCensor::FindPrefix(const UString &prefix) const { - for (int i = 0; i < Pairs.Size(); i++) + FOR_VECTOR (i, Pairs) if (CompareFileNames(Pairs[i].Prefix, prefix) == 0) return i; return -1; } -void CCensor::AddItem(bool include, const UString &path, bool recursive) +void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching) { UStringVector pathParts; if (path.IsEmpty()) @@ -383,40 +474,82 @@ void CCensor::AddItem(bool include, const UString &path, bool recursive) forFile = false; pathParts.DeleteBack(); } - const UString &front = pathParts.Front(); - bool isAbs = false; - if (front.IsEmpty()) - isAbs = true; - else if (front.Length() == 2 && front[1] == L':') - isAbs = true; - else + + UString prefix; + + if (pathMode != k_AbsPath) { - for (int i = 0; i < pathParts.Size(); i++) + const UString &front = pathParts.Front(); + bool isAbs = false; + + if (front.IsEmpty()) + isAbs = true; + else { - const UString &part = pathParts[i]; - if (part == L".." || part == L".") - { + #ifdef _WIN32 + + if (IsDriveColonName(front)) isAbs = true; - break; + else + + #endif + + FOR_VECTOR (i, pathParts) + { + const UString &part = pathParts[i]; + if (part == L".." || part == L".") + { + isAbs = true; + break; + } + } + } + + unsigned numAbsParts = 0; + if (isAbs) + if (pathParts.Size() > 1) + numAbsParts = pathParts.Size() - 1; + else + numAbsParts = 1; + + #ifdef _WIN32 + + // \\?\ case + if (numAbsParts >= 3) + { + if (pathParts[0].IsEmpty() && + pathParts[1].IsEmpty() && + pathParts[2] == L"?") + { + prefix = + WSTRING_PATH_SEPARATOR + WSTRING_PATH_SEPARATOR L"?" + WSTRING_PATH_SEPARATOR; + numAbsParts -= 3; + pathParts.DeleteFrontal(3); } } - } - int numAbsParts = 0; - if (isAbs) - if (pathParts.Size() > 1) - numAbsParts = pathParts.Size() - 1; - else + + #endif + + if (numAbsParts > 1 && pathMode == k_FullPath) numAbsParts = 1; - UString prefix; - for (int i = 0; i < numAbsParts; i++) - { - const UString &front = pathParts.Front(); - if (DoesNameContainWildCard(front)) - break; - prefix += front; - prefix += WCHAR_PATH_SEPARATOR; - pathParts.Delete(0); + + // We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name + // if (wildcardMatching) + for (unsigned i = 0; i < numAbsParts; i++) + { + { + const UString &front = pathParts.Front(); + if (DoesNameContainWildcard(front)) + break; + prefix += front; + prefix += WCHAR_PATH_SEPARATOR; + } + pathParts.Delete(0); + } } + int index = FindPrefix(prefix); if (index < 0) index = Pairs.Add(CPair(prefix)); @@ -426,16 +559,17 @@ void CCensor::AddItem(bool include, const UString &path, bool recursive) item.ForDir = true; item.ForFile = forFile; item.Recursive = recursive; + item.WildcardMatching = wildcardMatching; Pairs[index].Head.AddItem(include, item); } -bool CCensor::CheckPath(const UString &path, bool isFile) const +bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const { bool finded = false; - for (int i = 0; i < Pairs.Size(); i++) + FOR_VECTOR (i, Pairs) { bool include; - if (Pairs[i].Head.CheckPath(path, isFile, include)) + if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include)) { if (!include) return false; @@ -447,16 +581,35 @@ bool CCensor::CheckPath(const UString &path, bool isFile) const void CCensor::ExtendExclude() { - int i; + unsigned i; for (i = 0; i < Pairs.Size(); i++) if (Pairs[i].Prefix.IsEmpty()) break; if (i == Pairs.Size()) return; - int index = i; + unsigned index = i; for (i = 0; i < Pairs.Size(); i++) if (index != i) Pairs[i].Head.ExtendExclude(Pairs[index].Head); } +void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode) +{ + FOR_VECTOR(i, CensorPaths) + { + const CCensorPath &cp = CensorPaths[i]; + AddItem(censorPathMode, cp.Include, cp.Path, cp.Recursive, cp.WildcardMatching); + } + CensorPaths.Clear(); +} + +void CCensor::AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching) +{ + CCensorPath &cp = CensorPaths.AddNew(); + cp.Path = path; + cp.Include = include; + cp.Recursive = recursive; + cp.WildcardMatching = wildcardMatching; +} + } diff --git a/src/libs/7zip/win/CPP/Common/Wildcard.h b/src/libs/7zip/win/CPP/Common/Wildcard.h index 6d4cbcece..137d71ced 100644 --- a/src/libs/7zip/win/CPP/Common/Wildcard.h +++ b/src/libs/7zip/win/CPP/Common/Wildcard.h @@ -5,51 +5,90 @@ #include "MyString.h" -int CompareFileNames(const UString &s1, const UString &s2); +int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW; +#ifndef USE_UNICODE_FSTRING + int CompareFileNames(const char *s1, const char *s2); +#endif + +bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2); + +inline bool IsCharDirLimiter(wchar_t c) +{ + return c == WCHAR_PATH_SEPARATOR + #ifdef _WIN32 + || c == L'/' + #endif + ; +} void SplitPathToParts(const UString &path, UStringVector &pathParts); -void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name); +void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name); +void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name); // ignores dir delimiter at the end of (path) + UString ExtractDirPrefixFromPath(const UString &path); UString ExtractFileNameFromPath(const UString &path); -bool DoesNameContainWildCard(const UString &path); -bool CompareWildCardWithName(const UString &mask, const UString &name); + +bool DoesNameContainWildcard(const UString &path); +bool DoesWildcardMatchName(const UString &mask, const UString &name); namespace NWildcard { +#ifdef _WIN32 +// returns true, if name is like "a:", "c:", ... +bool IsDriveColonName(const wchar_t *s); +#endif + + struct CItem { UStringVector PathParts; bool Recursive; bool ForFile; bool ForDir; + bool WildcardMatching; + + #ifdef _WIN32 + bool IsDriveItem() const + { + return PathParts.Size() == 1 && !ForFile && ForDir && IsDriveColonName(PathParts[0]); + } + #endif + + // CItem(): WildcardMatching(true) {} + + bool AreAllAllowed() const; bool CheckPath(const UStringVector &pathParts, bool isFile) const; }; class CCensorNode { CCensorNode *Parent; + bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const; void AddItemSimple(bool include, CItem &item); - bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const; + bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const; public: CCensorNode(): Parent(0) { }; CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { }; - UString Name; + + UString Name; // wildcard is not allowed here CObjectVector<CCensorNode> SubNodes; CObjectVector<CItem> IncludeItems; CObjectVector<CItem> ExcludeItems; + bool AreAllAllowed() const; + int FindSubNode(const UString &path) const; void AddItem(bool include, CItem &item); - void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir); - void AddItem2(bool include, const UString &path, bool recursive); + void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching); + void AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching); bool NeedCheckSubDirs() const; bool AreThereIncludeItems() const; - bool CheckPath(const UString &path, bool isFile, bool &include) const; - bool CheckPath(const UString &path, bool isFile) const; + bool CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const; + bool CheckPath(bool isAltStream, const UString &path, bool isFile) const; bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const; // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const; @@ -60,21 +99,59 @@ struct CPair { UString Prefix; CCensorNode Head; + CPair(const UString &prefix): Prefix(prefix) { }; }; +enum ECensorPathMode +{ + k_RelatPath, // absolute prefix as Prefix, remain path in Tree + k_FullPath, // drive prefix as Prefix, remain path in Tree + k_AbsPath // full path in Tree +}; + +struct CCensorPath +{ + UString Path; + bool Include; + bool Recursive; + bool WildcardMatching; + + CCensorPath(): + Include(true), + Recursive(false), + WildcardMatching(true) + {} +}; + class CCensor { int FindPrefix(const UString &prefix) const; public: CObjectVector<CPair> Pairs; + + CObjectVector<NWildcard::CCensorPath> CensorPaths; + bool AllAreRelative() const { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); } - void AddItem(bool include, const UString &path, bool recursive); - bool CheckPath(const UString &path, bool isFile) const; + + void AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching); + bool CheckPath(bool isAltStream, const UString &path, bool isFile) const; void ExtendExclude(); + + void AddPathsToCensor(NWildcard::ECensorPathMode censorPathMode); + void AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching); + void AddPreItem(const UString &path) + { + AddPreItem(true, path, false, false); + } + void AddPreItem_Wildcard() + { + AddPreItem(true, L"*", false, true); + } }; + } #endif |