diff options
author | kh1 <karsten.heimrich@nokia.com> | 2012-03-15 14:53:47 +0100 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@nokia.com> | 2012-03-19 16:14:04 +0100 |
commit | be3b47d0d504a3409ce66bd77bb8c0acff87c4f5 (patch) | |
tree | 09dfb02d484a4f395991972b828da71400fb761a /src/libs/7zip/unix/CPP/Common | |
parent | 9fd62353cf7f973d78cd2093328ac15b5c4980b6 (diff) |
Reorganize the tree, have better ifw.pri. Shadow build support.
Change-Id: I01fb12537f863ed0744979973c7e4153889cc5cb
Reviewed-by: Tim Jenssen <tim.jenssen@nokia.com>
Diffstat (limited to 'src/libs/7zip/unix/CPP/Common')
47 files changed, 4725 insertions, 0 deletions
diff --git a/src/libs/7zip/unix/CPP/Common/AutoPtr.h b/src/libs/7zip/unix/CPP/Common/AutoPtr.h new file mode 100644 index 000000000..006d31551 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/AutoPtr.h @@ -0,0 +1,35 @@ +// Common/AutoPtr.h + +#ifndef __COMMON_AUTOPTR_H +#define __COMMON_AUTOPTR_H + +template<class T> class CMyAutoPtr +{ + T *_p; +public: + CMyAutoPtr(T *p = 0) : _p(p) {} + CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {} + CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p) + { + reset(p.release()); + return (*this); + } + ~CMyAutoPtr() { delete _p; } + T& operator*() const { return *_p; } + // T* operator->() const { return (&**this); } + T* get() const { return _p; } + T* release() + { + T *tmp = _p; + _p = 0; + return tmp; + } + void reset(T* p = 0) + { + if (p != _p) + delete _p; + _p = p; + } +}; + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/Buffer.h b/src/libs/7zip/unix/CPP/Common/Buffer.h new file mode 100644 index 000000000..118fe11fc --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/Buffer.h @@ -0,0 +1,77 @@ +// 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/unix/CPP/Common/CRC.cpp b/src/libs/7zip/unix/CPP/Common/CRC.cpp new file mode 100644 index 000000000..9a9f81fb7 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/CRC.cpp @@ -0,0 +1,7 @@ +// Common/CRC.cpp + +#include "StdAfx.h" + +#include "../../C/7zCrc.h" + +struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit; diff --git a/src/libs/7zip/unix/CPP/Common/C_FileIO.cpp b/src/libs/7zip/unix/CPP/Common/C_FileIO.cpp new file mode 100644 index 000000000..b4893d658 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/C_FileIO.cpp @@ -0,0 +1,88 @@ +// 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/unix/CPP/Common/C_FileIO.h b/src/libs/7zip/unix/CPP/Common/C_FileIO.h new file mode 100644 index 000000000..27aa56869 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/C_FileIO.h @@ -0,0 +1,47 @@ +// 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/unix/CPP/Common/ComTry.h b/src/libs/7zip/unix/CPP/Common/ComTry.h new file mode 100644 index 000000000..1f20e5d93 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/ComTry.h @@ -0,0 +1,18 @@ +// ComTry.h + +#ifndef __COM_TRY_H +#define __COM_TRY_H + +#include "MyWindows.h" +// #include "Exception.h" +// #include "NewHandler.h" + +#define COM_TRY_BEGIN try { +#define COM_TRY_END } catch(const char * s) { throw s ; } \ + catch(...) { return E_OUTOFMEMORY; } + + // catch(const CNewException &) { return E_OUTOFMEMORY; } + // catch(const CSystemException &e) { return e.ErrorCode; } + // catch(...) { return E_FAIL; } + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/CommandLineParser.cpp b/src/libs/7zip/unix/CPP/Common/CommandLineParser.cpp new file mode 100644 index 000000000..91fecc7af --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/CommandLineParser.cpp @@ -0,0 +1,230 @@ +// CommandLineParser.cpp + +#include "StdAfx.h" + +#include "CommandLineParser.h" + +namespace NCommandLineParser { + +#ifdef _WIN32 +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++) + { + wchar_t c = src[i]; + if (c == L' ' && !quoteMode) + { + dest2 = src.Mid(i + 1); + return i != 0; + } + if (c == L'\"') + quoteMode = !quoteMode; + else + dest1 += c; + } + return i != 0; +} + +void SplitCommandLine(const UString &s, UStringVector &parts) +{ + UString sTemp = s; + sTemp.Trim(); + parts.Clear(); + for (;;) + { + UString s1, s2; + if (SplitCommandLine(sTemp, s1, s2)) + parts.Add(s1); + if (s2.IsEmpty()) + break; + sTemp = s2; + } +} +#endif + +static const wchar_t kSwitchID1 = '-'; +// static const wchar_t kSwitchID2 = '/'; + +static const wchar_t kSwitchMinus = '-'; +static const wchar_t *kStopSwitchParsing = L"--"; + +static bool IsItSwitchChar(wchar_t c) +{ + return (c == kSwitchID1 /*|| c == kSwitchID2 */); +} + +CParser::CParser(int numSwitches): + _numSwitches(numSwitches) +{ + _switches = new CSwitchResult[_numSwitches]; +} + +CParser::~CParser() +{ + delete []_switches; +} + +void CParser::ParseStrings(const CSwitchForm *switchForms, + const UStringVector &commandStrings) +{ + int numCommandStrings = commandStrings.Size(); + bool stopSwitch = false; + for (int i = 0; i < numCommandStrings; 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); + } +} + +// 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) + return false; + int pos = 0; + if (!IsItSwitchChar(s[pos])) + return false; + while (pos < len) + { + 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; + + 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) + { + matchedSwitchIndex = switchIndex; + maxLen = switchLen; + } + } + 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: + { + 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; + } + case NSwitchType::kSimple: + break; + } + } + 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) +{ + for (int i = 0; i < numCommandForms; i++) + { + const UString id = commandForms[i].IDString; + if (commandForms[i].PostStringMode) + { + if (commandString.Find(id) == 0) + { + postString = commandString.Mid(id.Length()); + return i; + } + } + else + if (commandString == id) + { + postString.Empty(); + return i; + } + } + return -1; +} + +} diff --git a/src/libs/7zip/unix/CPP/Common/CommandLineParser.h b/src/libs/7zip/unix/CPP/Common/CommandLineParser.h new file mode 100644 index 000000000..3d0b41dd4 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/CommandLineParser.h @@ -0,0 +1,72 @@ +// Common/CommandLineParser.h + +#ifndef __COMMON_COMMAND_LINE_PARSER_H +#define __COMMON_COMMAND_LINE_PARSER_H + +#include "MyString.h" + +namespace NCommandLineParser { + +bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2); +void SplitCommandLine(const UString &s, UStringVector &parts); + +namespace NSwitchType { + enum EEnum + { + kSimple, + kPostMinus, + kLimitedPostString, + kUnLimitedPostString, + kPostChar + }; +} + +struct CSwitchForm +{ + const wchar_t *IDString; + NSwitchType::EEnum Type; + bool Multi; + int MinLen; + int MaxLen; + const wchar_t *PostCharSet; +}; + +struct CSwitchResult +{ + bool ThereIs; + bool WithMinus; + UStringVector PostStrings; + int PostCharIndex; + CSwitchResult(): ThereIs(false) {}; +}; + +class CParser +{ + int _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 + +struct CCommandForm +{ + const wchar_t *IDString; + bool PostStringMode; +}; + +// 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/unix/CPP/Common/Defs.h b/src/libs/7zip/unix/CPP/Common/Defs.h new file mode 100644 index 000000000..dad3ae8f1 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/Defs.h @@ -0,0 +1,20 @@ +// Common/Defs.h + +#ifndef __COMMON_DEFS_H +#define __COMMON_DEFS_H + +template <class T> inline T MyMin(T a, T b) + { return a < b ? a : b; } +template <class T> inline T MyMax(T a, T b) + { return a > b ? a : b; } + +template <class T> inline int MyCompare(T a, T b) + { return a < b ? -1 : (a == b ? 0 : 1); } + +inline int BoolToInt(bool value) + { return (value ? 1: 0); } + +inline bool IntToBool(int value) + { return (value != 0); } + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/DynamicBuffer.h b/src/libs/7zip/unix/CPP/Common/DynamicBuffer.h new file mode 100644 index 000000000..b5fd97823 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/DynamicBuffer.h @@ -0,0 +1,50 @@ +// 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) + { + 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/unix/CPP/Common/IntToString.cpp b/src/libs/7zip/unix/CPP/Common/IntToString.cpp new file mode 100644 index 000000000..013fee527 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/IntToString.cpp @@ -0,0 +1,77 @@ +// Common/IntToString.cpp + +#include "StdAfx.h" + +#include "IntToString.h" + +void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base) +{ + if (base < 2 || base > 36) + { + *s = '\0'; + return; + } + char temp[72]; + int pos = 0; + do + { + int delta = (int)(value % base); + temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10))); + value /= base; + } + while (value != 0); + do + *s++ = temp[--pos]; + while (pos > 0); + *s = '\0'; +} + +void ConvertUInt64ToString(UInt64 value, wchar_t *s) +{ + wchar_t temp[32]; + int pos = 0; + do + { + temp[pos++] = (wchar_t)(L'0' + (int)(value % 10)); + value /= 10; + } + while (value != 0); + do + *s++ = temp[--pos]; + while (pos > 0); + *s = L'\0'; +} + +void ConvertUInt32ToString(UInt32 value, char *s) { ConvertUInt64ToString(value, s); } +void ConvertUInt32ToString(UInt32 value, wchar_t *s) { ConvertUInt64ToString(value, s); } + +void ConvertInt64ToString(Int64 value, char *s) +{ + if (value < 0) + { + *s++ = '-'; + value = -value; + } + ConvertUInt64ToString(value, s); +} + +void ConvertInt64ToString(Int64 value, wchar_t *s) +{ + if (value < 0) + { + *s++ = L'-'; + value = -value; + } + ConvertUInt64ToString(value, s); +} + +void ConvertUInt32ToHexWithZeros(UInt32 value, char *s) +{ + for (int i = 0; i < 8; i++) + { + int t = value & 0xF; + value >>= 4; + s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + } + s[8] = '\0'; +} diff --git a/src/libs/7zip/unix/CPP/Common/IntToString.h b/src/libs/7zip/unix/CPP/Common/IntToString.h new file mode 100644 index 000000000..782f930c5 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/IntToString.h @@ -0,0 +1,19 @@ +// Common/IntToString.h + +#ifndef __COMMON_INT_TO_STRING_H +#define __COMMON_INT_TO_STRING_H + +#include <stddef.h> +#include "Types.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); +void ConvertUInt32ToString(UInt32 value, wchar_t *s); + +void ConvertUInt32ToHexWithZeros(UInt32 value, char *s); + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/Lang.cpp b/src/libs/7zip/unix/CPP/Common/Lang.cpp new file mode 100644 index 000000000..75dfed426 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/Lang.cpp @@ -0,0 +1,130 @@ +// Common/Lang.cpp + +#include "StdAfx.h" + +#include "Lang.h" +#include "TextConfig.h" + +#include "../Windows/FileIO.h" +#include "UTFConvert.h" +#include "Defs.h" + +static bool HexStringToNumber(const UString &s, UInt32 &value) +{ + value = 0; + if (s.IsEmpty()) + return false; + for (int i = 0; i < s.Length(); i++) + { + wchar_t c = s[i]; + int a; + if (c >= L'0' && c <= L'9') + a = c - L'0'; + else if (c >= L'A' && c <= L'F') + a = 10 + c - L'A'; + else if (c >= L'a' && c <= L'f') + a = 10 + c - L'a'; + else + return false; + value *= 0x10; + value += a; + } + return true; +} + + +static bool WaitNextLine(const AString &s, int &pos) +{ + for (; pos < s.Length(); pos++) + if (s[pos] == 0x0A) + return true; + return false; +} + +static int CompareLangItems(void *const *elem1, void *const *elem2, void *) +{ + const CLangPair &langPair1 = *(*((const CLangPair **)elem1)); + const CLangPair &langPair2 = *(*((const CLangPair **)elem2)); + return MyCompare(langPair1.Value, langPair2.Value); +} + +bool CLang::Open(LPCWSTR fileName) +{ + _langPairs.Clear(); + NWindows::NFile::NIO::CInFile file; + if (!file.Open(fileName)) + return false; + UInt64 length; + if (!file.GetLength(length)) + return false; + if (length > (1 << 20)) + return false; + AString s; + char *p = s.GetBuffer((int)length + 1); + UInt32 processed; + if (!file.Read(p, (UInt32)length, processed)) + return false; + p[(UInt32)length] = 0; + s.ReleaseBuffer(); + file.Close(); + int pos = 0; + if (s.Length() >= 3) + { + if (Byte(s[0]) == 0xEF && Byte(s[1]) == 0xBB && Byte(s[2]) == 0xBF) + pos += 3; + } + + ///////////////////// + // read header + + AString stringID = ";!@Lang@!UTF-8!"; + if (s.Mid(pos, stringID.Length()) != stringID) + return false; + pos += stringID.Length(); + + if (!WaitNextLine(s, pos)) + return false; + + CObjectVector<CTextConfigPair> pairs; + if (!GetTextConfig(s.Mid(pos), pairs)) + return false; + + _langPairs.Reserve(_langPairs.Size()); + for (int i = 0; i < pairs.Size(); i++) + { + CTextConfigPair textConfigPair = pairs[i]; + CLangPair langPair; + if (!HexStringToNumber(textConfigPair.ID, langPair.Value)) + return false; + langPair.String = textConfigPair.String; + _langPairs.Add(langPair); + } + _langPairs.Sort(CompareLangItems, NULL); + return true; +} + +int CLang::FindItem(UInt32 value) const +{ + int left = 0, right = _langPairs.Size(); + while (left != right) + { + UInt32 mid = (left + right) / 2; + UInt32 midValue = _langPairs[mid].Value; + if (value == midValue) + return mid; + if (value < midValue) + right = mid; + else + left = mid + 1; + } + return -1; +} + +bool CLang::GetMessage(UInt32 value, UString &message) const +{ + int index = FindItem(value); + if (index < 0) + return false; + message = _langPairs[index].String; + return true; +} diff --git a/src/libs/7zip/unix/CPP/Common/Lang.h b/src/libs/7zip/unix/CPP/Common/Lang.h new file mode 100644 index 000000000..cf978758e --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/Lang.h @@ -0,0 +1,28 @@ +// Common/Lang.h + +#ifndef __COMMON_LANG_H +#define __COMMON_LANG_H + +#include "MyVector.h" +#include "MyString.h" +#include "Types.h" + +struct CLangPair +{ + UInt32 Value; + UString String; +}; + +class CLang +{ + CObjectVector<CLangPair> _langPairs; +public: + bool Open(LPCWSTR fileName); + void Clear() { _langPairs.Clear(); } + int FindItem(UInt32 value) const; + bool GetMessage(UInt32 value, UString &message) const; +}; + +#endif + + diff --git a/src/libs/7zip/unix/CPP/Common/ListFileUtils.cpp b/src/libs/7zip/unix/CPP/Common/ListFileUtils.cpp new file mode 100644 index 000000000..8e409016e --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/ListFileUtils.cpp @@ -0,0 +1,75 @@ +// Common/ListFileUtils.cpp + +#include "StdAfx.h" + +#include "MyWindows.h" +#include "../Windows/FileIO.h" + +#include "ListFileUtils.h" +#include "StringConvert.h" +#include "UTFConvert.h" + +static const char kQuoteChar = '\"'; +static void RemoveQuote(UString &s) +{ + if (s.Length() >= 2) + if (s[0] == kQuoteChar && s[s.Length() - 1] == kQuoteChar) + s = s.Mid(1, s.Length() - 2); +} + +bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &resultStrings, UINT codePage) +{ + NWindows::NFile::NIO::CInFile file; + if (!file.Open(fileName,true)) /* follow the symbolic link */ + return false; + UInt64 length; + if (!file.GetLength(length)) + return false; + if (length > ((UInt32)1 << 31)) + return false; + AString s; + char *p = s.GetBuffer((int)length + 1); + UInt32 processed; + if (!file.Read(p, (UInt32)length, processed)) + return false; + p[(UInt32)length] = 0; + s.ReleaseBuffer(); + file.Close(); + + UString u; + #ifdef CP_UTF8 + if (codePage == CP_UTF8) + { + if (!ConvertUTF8ToUnicode(s, u)) + return false; + } + else + #endif + u = MultiByteToUnicodeString(s, codePage); + if (!u.IsEmpty()) + { + if (u[0] == 0xFEFF) + u.Delete(0); + } + + UString t; + for (int i = 0; i < u.Length(); i++) + { + wchar_t c = u[i]; + if (c == L'\n' || c == 0xD) + { + t.Trim(); + RemoveQuote(t); + if (!t.IsEmpty()) + resultStrings.Add(t); + t.Empty(); + } + else + t += c; + } + t.Trim(); + RemoveQuote(t); + if (!t.IsEmpty()) + resultStrings.Add(t); + return true; +} diff --git a/src/libs/7zip/unix/CPP/Common/ListFileUtils.h b/src/libs/7zip/unix/CPP/Common/ListFileUtils.h new file mode 100644 index 000000000..c58a8bd42 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/ListFileUtils.h @@ -0,0 +1,11 @@ +// Common/ListFileUtils.h + +#ifndef __COMMON_LISTFILEUTILS_H +#define __COMMON_LISTFILEUTILS_H + +#include "MyString.h" +#include "Types.h" + +bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP); + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyCom.h b/src/libs/7zip/unix/CPP/Common/MyCom.h new file mode 100644 index 000000000..2f00c258f --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyCom.h @@ -0,0 +1,225 @@ +// MyCom.h + +#ifndef __MYCOM_H +#define __MYCOM_H + +#include "MyWindows.h" + +#ifndef RINOK +#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; } +#endif + +template <class T> +class CMyComPtr +{ + T* _p; +public: + // 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() { if (_p) _p->Release(); } + void Release() { if (_p) { _p->Release(); _p = NULL; } } + operator T*() const { return (T*)_p; } + // T& operator*() const { return *_p; } + T** operator&() { return &_p; } + T* operator->() const { return _p; } + T* operator=(T* p) + { + if (p != 0) + p->AddRef(); + if (_p) + _p->Release(); + _p = p; + return p; + } + T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); } + bool operator!() const { return (_p == NULL); } + // bool operator==(T* pT) const { return _p == pT; } + // Compare two objects for equivalence + void Attach(T* p2) + { + Release(); + _p = p2; + } + T* Detach() + { + T* pt = _p; + _p = NULL; + return pt; + } + #ifdef _WIN32 + HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p); + } + #endif + /* + HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + CLSID clsid; + HRESULT hr = CLSIDFromProgID(szProgID, &clsid); + ATLASSERT(_p == NULL); + if (SUCCEEDED(hr)) + hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p); + return hr; + } + */ + template <class Q> + HRESULT QueryInterface(REFGUID iid, Q** pp) const + { + return _p->QueryInterface(iid, (void**)pp); + } +}; + +////////////////////////////////////////////////////////// + +inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr) +{ + *bstr = ::SysAllocString(src); + return (*bstr != 0) ? S_OK : E_OUTOFMEMORY; +} + +class CMyComBSTR +{ +public: + BSTR m_str; + CMyComBSTR(): m_str(NULL) {} + CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); } + // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); } + // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); } + CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); } + /* + CMyComBSTR(REFGUID src) + { + LPOLESTR szGuid; + StringFromCLSID(src, &szGuid); + m_str = ::SysAllocString(szGuid); + CoTaskMemFree(szGuid); + } + */ + ~CMyComBSTR() { ::SysFreeString(m_str); } + CMyComBSTR& operator=(const CMyComBSTR& src) + { + if (m_str != src.m_str) + { + if (m_str) + ::SysFreeString(m_str); + m_str = src.MyCopy(); + } + return *this; + } + CMyComBSTR& operator=(LPCOLESTR src) + { + ::SysFreeString(m_str); + m_str = ::SysAllocString(src); + return *this; + } + unsigned int Length() const { return ::SysStringLen(m_str); } + operator BSTR() const { return m_str; } + BSTR* operator&() { return &m_str; } + BSTR MyCopy() const + { + int byteLen = ::SysStringByteLen(m_str); + BSTR res = ::SysAllocStringByteLen(NULL, byteLen); + memcpy(res, m_str, byteLen); + return res; + } + /* + void Attach(BSTR src) { m_str = src; } + BSTR Detach() + { + BSTR s = m_str; + m_str = NULL; + return s; + } + */ + void Empty() + { + ::SysFreeString(m_str); + m_str = NULL; + } + bool operator!() const { return (m_str == NULL); } +}; + +////////////////////////////////////////////////////////// + +class CMyUnknownImp +{ +public: + ULONG __m_RefCount; + CMyUnknownImp(): __m_RefCount(0) {} +}; + +#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \ + (REFGUID iid, void **outObject) { + +#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \ + { *outObject = (void *)(i *)this; AddRef(); return S_OK; } + +#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \ + { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; } + +#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_ADDREF_RELEASE \ +STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \ +STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ + return __m_RefCount; delete this; return 0; } + +#define MY_UNKNOWN_IMP_SPEC(i) \ + MY_QUERYINTERFACE_BEGIN \ + i \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE + + +#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE + +#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ + MY_QUERYINTERFACE_ENTRY(i) \ + ) + +#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + ) + +#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + ) + +#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + ) + +#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + MY_QUERYINTERFACE_ENTRY(i5) \ + ) + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyException.h b/src/libs/7zip/unix/CPP/Common/MyException.h new file mode 100644 index 000000000..f0ad11158 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyException.h @@ -0,0 +1,14 @@ +// Common/Exception.h + +#ifndef __COMMON_EXCEPTION_H +#define __COMMON_EXCEPTION_H + +#include "MyWindows.h" + +struct CSystemException +{ + HRESULT ErrorCode; + CSystemException(HRESULT errorCode): ErrorCode(errorCode) {} +}; + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyGuidDef.h b/src/libs/7zip/unix/CPP/Common/MyGuidDef.h new file mode 100644 index 000000000..3c52cc07d --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyGuidDef.h @@ -0,0 +1,54 @@ +// Common/MyGuidDef.h + +#ifndef GUID_DEFINED +#define GUID_DEFINED + +#include "Types.h" + +typedef struct { + UInt32 Data1; + UInt16 Data2; + UInt16 Data3; + unsigned char Data4[8]; +} GUID; + +#ifdef __cplusplus +#define REFGUID const GUID & +#else +#define REFGUID const GUID * +#endif + +#define REFCLSID REFGUID +#define REFIID REFGUID + +#ifdef __cplusplus +inline int operator==(REFGUID g1, REFGUID g2) +{ + for (int i = 0; i < (int)sizeof(g1); i++) + if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i]) + return 0; + return 1; +} +inline int operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); } +#endif + +#ifdef __cplusplus + #define MY_EXTERN_C extern "C" +#else + #define MY_EXTERN_C extern +#endif + +#endif + + +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#endif + +#ifdef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + MY_EXTERN_C const GUID name +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyInitGuid.h b/src/libs/7zip/unix/CPP/Common/MyInitGuid.h new file mode 100644 index 000000000..d6a486980 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyInitGuid.h @@ -0,0 +1,22 @@ +// Common/MyInitGuid.h + +#ifndef __COMMON_MY_INITGUID_H +#define __COMMON_MY_INITGUID_H + +#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/unix/CPP/Common/MyMap.cpp b/src/libs/7zip/unix/CPP/Common/MyMap.cpp new file mode 100644 index 000000000..0ee11e8cd --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyMap.cpp @@ -0,0 +1,140 @@ +// MyMap.cpp + +#include "StdAfx.h" + +#include "MyMap.h" + +static const unsigned kNumBitsMax = sizeof(UInt32) * 8; + +static UInt32 GetSubBits(UInt32 value, unsigned startPos, unsigned numBits) +{ + if (startPos == sizeof(value) * 8) + return 0; + value >>= startPos; + if (numBits == sizeof(value) * 8) + return value; + return value & (((UInt32)1 << numBits) - 1); +} + +static inline unsigned GetSubBit(UInt32 v, unsigned n) { return (unsigned)(v >> n) & 1; } + +bool CMap32::Find(UInt32 key, UInt32 &valueRes) const +{ + valueRes = (UInt32)(Int32)-1; + if (Nodes.Size() == 0) + return false; + if (Nodes.Size() == 1) + { + const CNode &n = Nodes[0]; + if (n.Len == kNumBitsMax) + { + valueRes = n.Values[0]; + return (key == n.Key); + } + } + + int cur = 0; + unsigned bitPos = kNumBitsMax; + for (;;) + { + const CNode &n = Nodes[cur]; + bitPos -= n.Len; + if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len)) + return false; + unsigned bit = GetSubBit(key, --bitPos); + if (n.IsLeaf[bit]) + { + valueRes = n.Values[bit]; + return (key == n.Keys[bit]); + } + cur = (int)n.Keys[bit]; + } +} + +bool CMap32::Set(UInt32 key, UInt32 value) +{ + if (Nodes.Size() == 0) + { + CNode n; + n.Key = n.Keys[0] = n.Keys[1] = key; + n.Values[0] = n.Values[1] = value; + n.IsLeaf[0] = n.IsLeaf[1] = 1; + n.Len = kNumBitsMax; + Nodes.Add(n); + return false; + } + if (Nodes.Size() == 1) + { + CNode &n = Nodes[0]; + if (n.Len == kNumBitsMax) + { + if (key == n.Key) + { + n.Values[0] = n.Values[1] = value; + return true; + } + unsigned i = kNumBitsMax - 1; + for (;GetSubBit(key, i) == GetSubBit(n.Key, i); i--); + n.Len = (UInt16)(kNumBitsMax - (1 + i)); + unsigned newBit = GetSubBit(key, i); + n.Values[newBit] = value; + n.Keys[newBit] = key; + return false; + } + } + + int cur = 0; + unsigned bitPos = kNumBitsMax; + for (;;) + { + CNode &n = Nodes[cur]; + bitPos -= n.Len; + if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len)) + { + unsigned i = n.Len - 1; + for (; GetSubBit(key, bitPos + i) == GetSubBit(n.Key, bitPos + i); i--); + + CNode e2(n); + e2.Len = (UInt16)i; + + n.Len = (UInt16)(n.Len - (1 + i)); + unsigned newBit = GetSubBit(key, bitPos + i); + n.Values[newBit] = value; + n.IsLeaf[newBit] = 1; + n.IsLeaf[1 - newBit] = 0; + n.Keys[newBit] = key; + n.Keys[1 - newBit] = Nodes.Size(); + Nodes.Add(e2); + return false; + } + unsigned bit = GetSubBit(key, --bitPos); + + if (n.IsLeaf[bit]) + { + if (key == n.Keys[bit]) + { + n.Values[bit] = value; + return true; + } + unsigned i = bitPos - 1; + for (;GetSubBit(key, i) == GetSubBit(n.Keys[bit], i); i--); + + CNode e2; + + unsigned newBit = GetSubBit(key, i); + e2.Values[newBit] = value; + e2.Values[1 - newBit] = n.Values[bit]; + e2.IsLeaf[newBit] = e2.IsLeaf[1 - newBit] = 1; + e2.Keys[newBit] = key; + e2.Keys[1 - newBit] = e2.Key = n.Keys[bit]; + e2.Len = (UInt16)(bitPos - (1 + i)); + + n.IsLeaf[bit] = 0; + n.Keys[bit] = Nodes.Size(); + + Nodes.Add(e2); + return false; + } + cur = (int)n.Keys[bit]; + } +} diff --git a/src/libs/7zip/unix/CPP/Common/MyMap.h b/src/libs/7zip/unix/CPP/Common/MyMap.h new file mode 100644 index 000000000..d0dd43f53 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyMap.h @@ -0,0 +1,28 @@ +// MyMap.h + +#ifndef __COMMON_MYMAP_H +#define __COMMON_MYMAP_H + +#include "MyVector.h" +#include "Types.h" + +class CMap32 +{ + struct CNode + { + UInt32 Key; + UInt32 Keys[2]; + UInt32 Values[2]; + UInt16 Len; + Byte IsLeaf[2]; + }; + CRecordVector<CNode> Nodes; + +public: + + void Clear() { Nodes.Clear(); } + bool Find(UInt32 key, UInt32 &valueRes) const; + bool Set(UInt32 key, UInt32 value); // returns true, if there is such key already +}; + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyString.cpp b/src/libs/7zip/unix/CPP/Common/MyString.cpp new file mode 100644 index 000000000..697a35558 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyString.cpp @@ -0,0 +1,206 @@ +// Common/String.cpp + +#include "StdAfx.h" + +#include <ctype.h> +#ifdef ENV_HAVE_WCTYPE_H +#include <wctype.h> +#endif +#include "StringConvert.h" // FIXED + +#include "MyString.h" // FIXED to avoid confusion with <string.h> on some filesystems + +#include <stdio.h> +#include <stdlib.h> + +#ifdef ENV_HAVE_WCHAR__H +#include <wchar.h> +#endif + +#include <limits.h> +#ifndef MB_LEN_MAX +#define MB_LEN_MAX 1024 +#endif + +#include "myPrivate.h" + +LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr ) { // OK for MBS + while (*start && (start < ptr)) { + LPCSTR next = CharNextA( start ); + if (next >= ptr) + break; + start = next; + } + return (LPSTR)start; +} + +LPSTR WINAPI CharNextA( LPCSTR ptr ) { + if (!*ptr) + return (LPSTR)ptr; +// #ifdef ENV_HAVE_MBRTOWC +// if (global_use_utf16_conversion) +// { +// wchar_t wc; +// size_t len = mbrtowc(&wc,ptr,MB_LEN_MAX,0); // mbrtowc stales on some configurations. +// if (len >= 1) return (LPSTR)(ptr + len); +// printf("INTERNAL ERROR - CharNextA\n"); +// exit(EXIT_FAILURE); +// } else { +// return (LPSTR)(ptr + 1); +// } +//#else + return (LPSTR)(ptr + 1); // p7zip search only for ASCII characters like '/' so no need to worry about current locale +//#endif +} + +char MyCharLower(char c) +{ + int r = c & 0xFF; + + return tolower(r); +} + +wchar_t MyCharLower(wchar_t c) +{ +#ifdef ENV_HAVE_TOWUPPER + return towlower(c); +#else + int ret = c; + if ((ret >= 1) && (ret <256)) ret = tolower(ret); + return (wchar_t)ret; +#endif +} + +char * MyStringLower(char *s) +{ + if (s == 0) + return 0; + char *ret = s; + while (*s) + { + *s = MyCharLower(*s); + s++; + } + return ret; +} + +wchar_t * MyStringLower(wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *ret = s; + while (*s) + { + *s = MyCharLower(*s); + s++; + } + return ret; +} + +wchar_t MyCharUpper(wchar_t c) +{ +#ifdef ENV_HAVE_TOWUPPER + return towupper(c); +#else + int ret = c; + if ((ret >= 1) && (ret <256)) ret = toupper(ret); + return (wchar_t)ret; +#endif +} + +wchar_t * MyStringUpper(wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *ret = s; + while (*s) + { + *s = MyCharUpper(*s); + s++; + } + return ret; +} + +int MyStringCompare(const char *s1, const char *s2) +{ + while (true) + { + 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; + } +} + +int MyStringCompare(const wchar_t *s1, const wchar_t *s2) +{ + while (true) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} + +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) +{ + while (true) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + if (u1 < u2) return -1; + if (u1 > u2) return 1; + } + if (c1 == 0) return 0; + } +} + +int MyStringCompareNoCase(const char *s1, const char *s2) +{ + return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); +} + + +#ifndef ENV_HAVE_WCHAR__H + +EXTERN_C_BEGIN + +size_t wcslen(const wchar_t *s) +{ + register const wchar_t *p; + + for (p=s ; *p ; p++); + + return p - s; +} + +wchar_t *wcscpy(wchar_t * s1, const wchar_t * s2) +{ + register wchar_t *s = s1; + + while ( (*s++ = *s2++) != 0 ); + + return s1; +} + +wchar_t *wcscat(wchar_t * s1, const wchar_t * s2) +{ + register wchar_t *s = s1; + + while (*s++); + --s; + while ((*s++ = *s2++) != 0); + + return s1; +} + +EXTERN_C_END + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyString.h b/src/libs/7zip/unix/CPP/Common/MyString.h new file mode 100644 index 000000000..3daa137d0 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyString.h @@ -0,0 +1,601 @@ +// Common/String.h + +#ifndef __COMMON_STRING_H +#define __COMMON_STRING_H + +#include <string.h> +// #include <wchar.h> + +#include "MyVector.h" + +LPSTR WINAPI CharNextA( LPCSTR ptr ); +LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr ); + +template <class T> +inline int MyStringLen(const T *s) +{ + int i; + for (i = 0; s[i] != '\0'; i++); + return i; +} + +template <class T> +inline T * MyStringCopy(T *dest, const T *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); } + +wchar_t MyCharUpper(wchar_t c); +char * MyStringUpper(char *s); +wchar_t * MyStringUpper(wchar_t *s); + +char MyCharLower(char c); +char * MyStringLower(char *s); +wchar_t MyCharLower(wchar_t c); +wchar_t * MyStringLower(wchar_t *s); + + +inline char* MyStringGetPrevCharPointer(char *base, char *p) + { return CharPrevA(base, p); } +inline const char* MyStringGetPrevCharPointer(const char *base, const char *p) + { return CharPrevA(base, p); } +inline char* MyStringGetNextCharPointer(char *p) + { return CharNextA(p); } +inline const char* MyStringGetNextCharPointer(const char *p) + { return CharNextA(p); } + +////////////////////////////////////// +// Compare + +/* +#ifndef _WIN32_WCE +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); +*/ + +int MyStringCompare(const char *s1, const char *s2); +int MyStringCompare(const wchar_t *s1, const wchar_t *s2); + +// int MyStringCompareNoCase(const char *s1, const char *s2); +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2); + +template <class T> +class CStringBase +{ + 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); + } + + } + void MoveItems(int destIndex, int srcIndex) + { + memmove(_chars + destIndex, _chars + srcIndex, + sizeof(T) * (_length - srcIndex + 1)); + } + + void InsertSpace(int &index, int size) + { + CorrectIndex(index); + GrowLength(size); + MoveItems(index + size, index); + } + + static T *GetNextCharPointer(T *p) + { return MyStringGetNextCharPointer(p); } + static const T *GetNextCharPointer(const T *p) + { return MyStringGetNextCharPointer(p); } + static T *GetPrevCharPointer(T *base, T *p) + { return MyStringGetPrevCharPointer(base, 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; + #ifndef _WIN32_WCE + if (newCapacity > kMaxStringSize || newCapacity < _length) + throw 1052337; + #endif + */ + 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 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 CorrectIndex(int &index) const + { + if (index > _length) + index = _length; + } + +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; } + + operator const T*() const { return _chars;} + + T Back() const { return _chars[_length - 1]; } + + // The minimum size of the character buffer in characters. + // This value does not include space for a null terminator. + T* GetBuffer(int minBufLength) + { + if (minBufLength >= _capacity) + SetCapacity(minBufLength); + return _chars; + } + void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } + void ReleaseBuffer(int newLength) + { + /* + #ifndef _WIN32_WCE + if (newLength >= _capacity) + throw 282217; + #endif + */ + _chars[newLength] = 0; + _length = newLength; + } + + 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); } + + 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 + { + if (count > _length) + count = _length; + return Mid(_length - count, count); + } + + void MakeUpper() + { MyStringUpper(_chars); } + void MakeLower() + { MyStringLower(_chars); } + + int Compare(const CStringBase& s) const + { return MyStringCompare(_chars, s._chars); } + + int Compare(const T *s) const + { return MyStringCompare(_chars, s); } + + int CompareNoCase(const CStringBase& s) const + { return MyStringCompareNoCase(_chars, s._chars); } + + int CompareNoCase(const T *s) const + { return MyStringCompareNoCase(_chars, s); } + + /* + 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 + { + T *p = _chars + startIndex; + for (;;) + { + if (*p == c) + return (int)(p - _chars); + if (*p == 0) + return -1; + p = GetNextCharPointer(p); + } + } + int Find(const CStringBase &s) const { return Find(s, 0); } + int Find(const CStringBase &s, int startIndex) const + { + 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; + } + int ReverseFind(T c) const + { + if (_length == 0) + return -1; + T *p = _chars + _length - 1; + for (;;) + { + if (*p == c) + return (int)(p - _chars); + if (p == _chars) + return -1; + p = GetPrevCharPointer(_chars, p); + } + } + 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() + { + CStringBase<T> charSet; + charSet += (T)' '; + charSet += (T)'\n'; + charSet += (T)'\t'; + return charSet; + } + public: + + void TrimLeft() + { + TrimLeftWithCharSet(GetTrimDefaultCharSet()); + } + void TrimRight() + { + TrimRightWithCharSet(GetTrimDefaultCharSet()); + } + void TrimRight(T c) + { + 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); + } + } + 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; + } + + // !!!!!!!!!!!!!!! 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 ) + { + if (index + count > _length) + count = _length - index; + if (count > 0) + { + MoveItems(index, index + count); + _length -= count; + } + 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; +} + +template <class T> +CStringBase<T> operator+(const CStringBase<T>& s, T c) +{ + CStringBase<T> result(s); + result += c; + return result; +} + +template <class T> +CStringBase<T> operator+(T c, const CStringBase<T>& s) +{ + CStringBase<T> result(c); + result += s; + return result; +} + +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; +} + +template <class T> +bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2) + { return (s1.Compare(s2) == 0); } + +template <class T> +bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2) + { return (s1.Compare(s2) < 0); } + +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); } + +template <class T> +bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2) + { return (s1.Compare(s2) != 0); } + +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); } + +typedef CStringBase<char> AString; +typedef CStringBase<wchar_t> UString; + +typedef CObjectVector<AString> AStringVector; +typedef CObjectVector<UString> UStringVector; + +#ifdef _UNICODE + typedef UString CSysString; +#else + typedef AString CSysString; +#endif + +typedef CObjectVector<CSysString> CSysStringVector; + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyUnknown.h b/src/libs/7zip/unix/CPP/Common/MyUnknown.h new file mode 100644 index 000000000..e9e8666b9 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyUnknown.h @@ -0,0 +1,13 @@ +// MyUnknown.h + +#ifndef __MY_UNKNOWN_H +#define __MY_UNKNOWN_H + +#ifdef _WIN32 +#include <basetyps.h> +#include <unknwn.h> +#else +#include "MyWindows.h" +#endif + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyVector.cpp b/src/libs/7zip/unix/CPP/Common/MyVector.cpp new file mode 100644 index 000000000..3b5317688 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyVector.cpp @@ -0,0 +1,87 @@ +// 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/unix/CPP/Common/MyVector.h b/src/libs/7zip/unix/CPP/Common/MyVector.h new file mode 100644 index 000000000..781b648bc --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyVector.h @@ -0,0 +1,266 @@ +// Common/Vector.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(); +}; + +template <class T> +class CRecordVector: public CBaseRecordVector +{ +public: + CRecordVector(): CBaseRecordVector(sizeof(T)){}; + CRecordVector(const CRecordVector &v): CBaseRecordVector(sizeof(T)) { *this = v; } + CRecordVector& operator=(const CRecordVector &v) + { + Clear(); + return (*this += v); + } + CRecordVector& operator+=(const CRecordVector &v) + { + int size = v.Size(); + Reserve(Size() + size); + for (int i = 0; i < size; i++) + Add(v[i]); + return *this; + } + int Add(T item) + { + ReserveOnePosition(); + ((T *)_items)[_size] = item; + return _size++; + } + void Insert(int index, T item) + { + InsertOneItem(index); + ((T *)_items)[index] = 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) + { + T temp = operator[](i); + operator[](i) = operator[](j); + operator[](j) = temp; + } + + int FindInSorted(const T& item, int left, int right) const + { + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + return mid; + if (item < midValue) + right = mid; + else + left = mid + 1; + } + return -1; + } + + int FindInSorted(const T& item) const + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + return mid; + if (item < midValue) + right = mid; + else + left = mid + 1; + } + return -1; + } + + int AddToUniqueSorted(const T& item) + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + return mid; + if (item < midValue) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param) + { + T temp = p[k]; + for (;;) + { + int s = (k << 1); + if (s > size) + break; + if (s < size && compare(p + s + 1, p + s, param) > 0) + s++; + if (compare(&temp, p + s, param) >= 0) + break; + p[k] = p[s]; + k = s; + } + p[k] = temp; + } + + void Sort(int (*compare)(const T*, const T*, void *), void *param) + { + int size = _size; + if (size <= 1) + return; + T* p = (&Front()) - 1; + { + int i = size / 2; + do + SortRefDown(p, i, size, compare, param); + while (--i != 0); + } + do + { + T temp = p[size]; + p[size--] = p[1]; + p[1] = temp; + SortRefDown(p, 1, size, compare, param); + } + while (size > 1); + } +}; + +typedef CRecordVector<int> CIntVector; +typedef CRecordVector<unsigned int> CUIntVector; +typedef CRecordVector<bool> CBoolVector; +typedef CRecordVector<unsigned char> CByteVector; +typedef CRecordVector<void *> CPointerVector; + +template <class T> +class CObjectVector: public CPointerVector +{ +public: + CObjectVector() {}; + ~CObjectVector() { Clear(); }; + CObjectVector(const CObjectVector &v): CPointerVector() { *this = v; } + CObjectVector& operator=(const CObjectVector &v) + { + Clear(); + return (*this += v); + } + CObjectVector& operator+=(const CObjectVector &v) + { + int size = v.Size(); + Reserve(Size() + size); + for (int i = 0; i < size; i++) + Add(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& 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) + { + TestIndexAndCorrectNum(index, num); + for (int i = 0; i < num; i++) + delete (T *)(((void **)_items)[index + i]); + CPointerVector::Delete(index, num); + } + int Find(const T& item) const + { + for (int i = 0; i < Size(); i++) + if (item == (*this)[i]) + return i; + return -1; + } + int FindInSorted(const T& item) const + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + return mid; + if (item < midValue) + right = mid; + else + left = mid + 1; + } + return -1; + } + int AddToSorted(const T& item) + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + { + right = mid + 1; + break; + } + if (item < midValue) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + void Sort(int (*compare)(void *const *, void *const *, void *), void *param) + { CPointerVector::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); } +}; + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyWindows.cpp b/src/libs/7zip/unix/CPP/Common/MyWindows.cpp new file mode 100644 index 000000000..bee4acd47 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyWindows.cpp @@ -0,0 +1,111 @@ +// MyWindows.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 + +#include "MyWindows.h" +#include "Types.h" +#include <stdlib.h> /* FIXED <malloc.h> */ + +static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } +static inline void FreeForBSTR(void *pv) { ::free(pv);} + +static UINT MyStringLen(const wchar_t *s) +{ + UINT i; + for (i = 0; s[i] != '\0'; i++); + return i; +} + +BSTR SysAllocStringByteLen(LPCSTR psz, UINT len) +{ + // FIXED int realLen = len + sizeof(UINT) + 3; + const int LEN_ADDON = sizeof(wchar_t) - 1; + int realLen = len + sizeof(UINT) + sizeof(wchar_t) + LEN_ADDON; + void *p = AllocateForBSTR(realLen); + if (p == 0) + return 0; + *(UINT *)p = len; + // "void *" instead of "BSTR" to avoid unaligned copy of "wchar_t" because of optimizer on Solaris + void * bstr = (void *)((UINT *)p + 1); + if (psz) memmove(bstr, psz, len); // psz does not always have "wchar_t" alignment. + void *pb = (void *)(((Byte *)bstr) + len); + memset(pb,0,sizeof(wchar_t) + LEN_ADDON); + return (BSTR)bstr; +} + +BSTR SysAllocString(const OLECHAR *sz) +{ + if (sz == 0) + return 0; + UINT strLen = MyStringLen(sz); + UINT len = (strLen + 1) * sizeof(OLECHAR); + void *p = AllocateForBSTR(len + sizeof(UINT)); + if (p == 0) + return 0; + *(UINT *)p = strLen * sizeof(OLECHAR); // FIXED + void * bstr = (void *)((UINT *)p + 1); + memmove(bstr, sz, len); // sz does not always have "wchar_t" alignment. + return (BSTR)bstr; +} + +void SysFreeString(BSTR bstr) +{ + if (bstr != 0) + FreeForBSTR((UINT *)bstr - 1); +} + +UINT SysStringByteLen(BSTR bstr) +{ + if (bstr == 0) + return 0; + return *((UINT *)bstr - 1); + +} + +UINT SysStringLen(BSTR bstr) +{ + return SysStringByteLen(bstr) / 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, 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 == 0) + 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; +} + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyWindows.h b/src/libs/7zip/unix/CPP/Common/MyWindows.h new file mode 100644 index 000000000..d91f10f1b --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyWindows.h @@ -0,0 +1,218 @@ +// MyWindows.h + +#ifndef __MYWINDOWS_H +#define __MYWINDOWS_H + +#ifdef _WIN32 + +#include <windows.h> + +#else + +#include <stddef.h> // for wchar_t +#include <string.h> + +#include "MyGuidDef.h" + +typedef char CHAR; +typedef unsigned char UCHAR; + +#undef BYTE +typedef unsigned char BYTE; + +typedef short SHORT; +typedef unsigned short USHORT; + +#undef WORD +typedef unsigned short WORD; +typedef short VARIANT_BOOL; + +typedef int INT; +typedef Int32 INT32; +typedef unsigned int UINT; +typedef UInt32 UINT32; +typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit +typedef UINT32 ULONG; + +#undef DWORD +typedef UINT32 DWORD; + +typedef Int64 LONGLONG; +typedef UInt64 ULONGLONG; + +typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER; +typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER; + +typedef const CHAR *LPCSTR; + +typedef wchar_t WCHAR; + +#ifdef _UNICODE +typedef WCHAR TCHAR; +#define lstrcpy wcscpy +#define lstrcat wcscat +#define lstrlen wcslen +#else +typedef CHAR TCHAR; +#define lstrcpy strcpy +#define lstrcat strcat +#define lstrlen strlen +#endif +#define _wcsicmp(str1,str2) MyStringCompareNoCase(str1,str2) + +typedef const TCHAR *LPCTSTR; +typedef WCHAR OLECHAR; +typedef const WCHAR *LPCWSTR; +typedef OLECHAR *BSTR; +typedef const OLECHAR *LPCOLESTR; +typedef OLECHAR *LPOLESTR; + +typedef struct _FILETIME +{ + DWORD dwLowDateTime; + DWORD dwHighDateTime; +}FILETIME; + +#define HRESULT LONG +#define FAILED(Status) ((HRESULT)(Status)<0) +typedef ULONG PROPID; +typedef LONG SCODE; + +#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) +#define E_NOTIMPL ((HRESULT)0x80004001L) +#define E_NOINTERFACE ((HRESULT)0x80004002L) +#define E_ABORT ((HRESULT)0x80004004L) +#define E_FAIL ((HRESULT)0x80004005L) +#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L) +#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) +#define E_INVALIDARG ((HRESULT)0x80070057L) + +#ifdef _MSC_VER +#define STDMETHODCALLTYPE __stdcall +#else +#define STDMETHODCALLTYPE +#endif + +#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f +#define STDMETHOD(f) STDMETHOD_(HRESULT, f) +#define STDMETHODIMP_(type) type STDMETHODCALLTYPE +#define STDMETHODIMP STDMETHODIMP_(HRESULT) + +#define PURE = 0 + +#define MIDL_INTERFACE(x) struct + +#ifdef __cplusplus + +DEFINE_GUID(IID_IUnknown, +0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +struct IUnknown +{ + STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE; + STDMETHOD_(ULONG, AddRef)() PURE; + STDMETHOD_(ULONG, Release)() PURE; + #ifndef _WIN32 + virtual ~IUnknown() {} + #endif +}; + +typedef IUnknown *LPUNKNOWN; + +#endif + +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#define VARIANT_FALSE ((VARIANT_BOOL)0) + +enum VARENUM +{ + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_FILETIME = 64 +}; + +typedef unsigned short VARTYPE; +typedef WORD PROPVAR_PAD1; +typedef WORD PROPVAR_PAD2; +typedef WORD PROPVAR_PAD3; + +#ifdef __cplusplus + +typedef struct tagPROPVARIANT +{ + VARTYPE vt; + PROPVAR_PAD1 wReserved1; + PROPVAR_PAD2 wReserved2; + PROPVAR_PAD3 wReserved3; + union + { + CHAR cVal; + UCHAR bVal; + SHORT iVal; + USHORT uiVal; + LONG lVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + LARGE_INTEGER hVal; + ULARGE_INTEGER uhVal; + VARIANT_BOOL boolVal; + SCODE scode; + FILETIME filetime; + BSTR bstrVal; + }; +} PROPVARIANT; + +typedef PROPVARIANT tagVARIANT; +typedef tagVARIANT VARIANT; +typedef VARIANT VARIANTARG; + +MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop); +MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src); + +#endif + +MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len); +MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz); +MY_EXTERN_C void SysFreeString(BSTR bstr); +MY_EXTERN_C UINT SysStringByteLen(BSTR bstr); +MY_EXTERN_C UINT SysStringLen(BSTR bstr); + +/* MY_EXTERN_C DWORD GetLastError(); */ +MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); + +#define CP_ACP 0 +#define CP_OEMCP 1 + +typedef enum tagSTREAM_SEEK +{ + STREAM_SEEK_SET = 0, + STREAM_SEEK_CUR = 1, + STREAM_SEEK_END = 2 +} STREAM_SEEK; + +#endif +#endif diff --git a/src/libs/7zip/unix/CPP/Common/MyXml.cpp b/src/libs/7zip/unix/CPP/Common/MyXml.cpp new file mode 100644 index 000000000..8aa9ce8cd --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyXml.cpp @@ -0,0 +1,209 @@ +// MyXml.cpp + +#include "StdAfx.h" + +#include "MyXml.h" + +static bool IsValidChar(char c) +{ + return + c >= 'a' && c <= 'z' || + c >= 'A' && c <= 'Z' || + c >= '0' && c <= '9' || + c == '-'; +} + +static bool IsSpaceChar(char c) +{ + return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A); +} + +#define SKIP_SPACES(s, pos) while (IsSpaceChar(s[pos])) pos++; + +static bool ReadProperty(const AString &s, int &pos, CXmlProp &prop) +{ + prop.Name.Empty(); + prop.Value.Empty(); + for (; pos < s.Length(); pos++) + { + char c = s[pos]; + if (!IsValidChar(c)) + break; + prop.Name += c; + } + + if (prop.Name.IsEmpty()) + return false; + + SKIP_SPACES(s, pos); + if (s[pos++] != '=') + return false; + + SKIP_SPACES(s, pos); + if (s[pos++] != '\"') + return false; + + while (pos < s.Length()) + { + char c = s[pos++]; + if (c == '\"') + return true; + prop.Value += c; + } + return false; +} + +int CXmlItem::FindProperty(const AString &propName) const +{ + for (int i = 0; i < Props.Size(); i++) + if (Props[i].Name == propName) + return i; + return -1; +} + +AString CXmlItem::GetPropertyValue(const AString &propName) const +{ + int index = FindProperty(propName); + if (index >= 0) + return Props[index].Value; + return AString(); +} + +bool CXmlItem::IsTagged(const AString &tag) const +{ + return (IsTag && Name == tag); +} + +int CXmlItem::FindSubTag(const AString &tag) const +{ + for (int i = 0; i < SubItems.Size(); i++) + if (SubItems[i].IsTagged(tag)) + return i; + return -1; +} + +AString CXmlItem::GetSubString() const +{ + if (SubItems.Size() == 1) + { + const CXmlItem &item = SubItems[0]; + if (!item.IsTag) + return item.Name; + } + return AString(); +} + +AString CXmlItem::GetSubStringForTag(const AString &tag) const +{ + int index = FindSubTag(tag); + if (index >= 0) + return SubItems[index].GetSubString(); + return AString(); +} + +bool CXmlItem::ParseItems(const AString &s, int &pos, int numAllowedLevels) +{ + if (numAllowedLevels == 0) + return false; + SubItems.Clear(); + AString finishString = "</"; + for (;;) + { + SKIP_SPACES(s, pos); + + if (s.Mid(pos, finishString.Length()) == finishString) + return true; + + CXmlItem item; + if (!item.ParseItem(s, pos, numAllowedLevels - 1)) + return false; + SubItems.Add(item); + } +} + +bool CXmlItem::ParseItem(const AString &s, int &pos, int numAllowedLevels) +{ + SKIP_SPACES(s, pos); + + int pos2 = s.Find('<', pos); + if (pos2 < 0) + return false; + if (pos2 != pos) + { + IsTag = false; + Name += s.Mid(pos, pos2 - pos); + pos = pos2; + return true; + } + IsTag = true; + + pos++; + SKIP_SPACES(s, pos); + + for (; pos < s.Length(); pos++) + { + char c = s[pos]; + if (!IsValidChar(c)) + break; + Name += c; + } + if (Name.IsEmpty() || pos == s.Length()) + return false; + + int posTemp = pos; + for (;;) + { + SKIP_SPACES(s, pos); + if (s[pos] == '/') + { + pos++; + // SKIP_SPACES(s, pos); + return (s[pos++] == '>'); + } + if (s[pos] == '>') + { + if (!ParseItems(s, ++pos, numAllowedLevels)) + return false; + AString finishString = AString("</") + Name + AString(">"); + if (s.Mid(pos, finishString.Length()) != finishString) + return false; + pos += finishString.Length(); + return true; + } + if (posTemp == pos) + return false; + + CXmlProp prop; + if (!ReadProperty(s, pos, prop)) + return false; + Props.Add(prop); + posTemp = pos; + } +} + +static bool SkipHeader(const AString &s, int &pos, const AString &startString, const AString &endString) +{ + SKIP_SPACES(s, pos); + if (s.Mid(pos, startString.Length()) == startString) + { + pos = s.Find(endString, pos); + if (pos < 0) + return false; + pos += endString.Length(); + SKIP_SPACES(s, pos); + } + return true; +} + +bool CXml::Parse(const AString &s) +{ + int pos = 0; + if (!SkipHeader(s, pos, "<?xml", "?>")) + return false; + if (!SkipHeader(s, pos, "<!DOCTYPE", ">")) + return false; + if (!Root.ParseItem(s, pos, 1000)) + return false; + SKIP_SPACES(s, pos); + return (pos == s.Length() && Root.IsTag); +} diff --git a/src/libs/7zip/unix/CPP/Common/MyXml.h b/src/libs/7zip/unix/CPP/Common/MyXml.h new file mode 100644 index 000000000..c6e8829ad --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/MyXml.h @@ -0,0 +1,40 @@ +// MyXml.h + +#ifndef __MYXML_H +#define __MYXML_H + +#include "MyString.h" + +struct CXmlProp +{ + AString Name; + AString Value; +}; + +class CXmlItem +{ + bool ParseItems(const AString &s, int &pos, int numAllowedLevels); + +public: + AString Name; + bool IsTag; + CObjectVector<CXmlProp> Props; + CObjectVector<CXmlItem> SubItems; + + bool ParseItem(const AString &s, int &pos, int numAllowedLevels); + + bool IsTagged(const AString &tag) const; + int FindProperty(const AString &propName) const; + AString GetPropertyValue(const AString &propName) const; + AString GetSubString() const; + int FindSubTag(const AString &tag) const; + AString GetSubStringForTag(const AString &tag) const; +}; + +struct CXml +{ + CXmlItem Root; + bool Parse(const AString &s); +}; + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/NewHandler.h b/src/libs/7zip/unix/CPP/Common/NewHandler.h new file mode 100644 index 000000000..215ba05f1 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/NewHandler.h @@ -0,0 +1,16 @@ +// Common/NewHandler.h + +#ifndef __COMMON_NEWHANDLER_H +#define __COMMON_NEWHANDLER_H + +class CNewException {}; + +#ifdef _WIN32 +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw(); +#endif + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/StdInStream.cpp b/src/libs/7zip/unix/CPP/Common/StdInStream.cpp new file mode 100644 index 000000000..78897e5ef --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/StdInStream.cpp @@ -0,0 +1,100 @@ +// Common/StdInStream.cpp + +#include "StdAfx.h" + +#include <tchar.h> +#include "StdInStream.h" + +#ifdef _MSC_VER +// "was declared deprecated" disabling +#pragma warning(disable : 4996 ) +#endif + +#ifdef _UNICODE +#include "Common/StringConvert.h" +#define NEED_NAME_WINDOWS_TO_UNIX +#include "myPrivate.h" +#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 const char * kFileOpenMode = "r"; + +CStdInStream g_StdIn(stdin); + +bool CStdInStream::Open(LPCTSTR fileName) +{ + Close(); +#ifdef _UNICODE + AString aStr = UnicodeStringToMultiByte(fileName, CP_ACP); // FIXME + const char * name = nameWindowToUnix(aStr); +#else + const char * name = nameWindowToUnix(fileName); +#endif + _stream = fopen(name, 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; +} + +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/unix/CPP/Common/StdInStream.h b/src/libs/7zip/unix/CPP/Common/StdInStream.h new file mode 100644 index 000000000..0d182cc3c --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/StdInStream.h @@ -0,0 +1,32 @@ +// 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/unix/CPP/Common/StdOutStream.cpp b/src/libs/7zip/unix/CPP/Common/StdOutStream.cpp new file mode 100644 index 000000000..b93e255f9 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/StdOutStream.cpp @@ -0,0 +1,93 @@ +// Common/StdOutStream.cpp + +#include "StdAfx.h" + +#include <tchar.h> + +#include "StdOutStream.h" +#include "IntToString.h" +#include "StringConvert.h" + +#ifdef _MSC_VER +// "was declared deprecated" disabling +#pragma warning(disable : 4996 ) +#endif + +static const char kNewLineChar = '\n'; + +static const char *kFileOpenMode = "wt"; + +CStdOutStream g_StdOut(stdout); +CStdOutStream g_StdErr(stderr); + +bool CStdOutStream::Open(const char *fileName) +{ + Close(); + _stream = fopen(fileName, kFileOpenMode); + _streamIsOpen = (_stream != 0); + return _streamIsOpen; +} + +bool CStdOutStream::Close() +{ + if (!_streamIsOpen) + return true; + if (fclose(_stream) != 0) + return false; + _stream = 0; + _streamIsOpen = false; + return true; +} + +bool CStdOutStream::Flush() +{ + return (fflush(_stream) == 0); +} + +CStdOutStream::~CStdOutStream () +{ + Close(); +} + +CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream &)) +{ + (*aFunction)(*this); + return *this; +} + +CStdOutStream & endl(CStdOutStream & outStream) +{ + return outStream << kNewLineChar; +} + +CStdOutStream & CStdOutStream::operator<<(const char *string) +{ + fputs(string, _stream); + return *this; +} + +CStdOutStream & CStdOutStream::operator<<(const wchar_t *string) +{ + *this << (const char *)UnicodeStringToMultiByte(string, CP_OEMCP); + return *this; +} + +CStdOutStream & CStdOutStream::operator<<(char c) +{ + fputc(c, _stream); + return *this; +} + +CStdOutStream & CStdOutStream::operator<<(int number) +{ + char textString[32]; + ConvertInt64ToString(number, textString); + return operator<<(textString); +} + +CStdOutStream & CStdOutStream::operator<<(UInt64 number) +{ + char textString[32]; + ConvertUInt64ToString(number, textString); + return operator<<(textString); +} diff --git a/src/libs/7zip/unix/CPP/Common/StdOutStream.h b/src/libs/7zip/unix/CPP/Common/StdOutStream.h new file mode 100644 index 000000000..b0b2c615c --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/StdOutStream.h @@ -0,0 +1,35 @@ +// Common/StdOutStream.h + +#ifndef __COMMON_STDOUTSTREAM_H +#define __COMMON_STDOUTSTREAM_H + +#include <stdio.h> + +#include "Types.h" + +class CStdOutStream +{ + bool _streamIsOpen; + FILE *_stream; +public: + CStdOutStream (): _streamIsOpen(false), _stream(0) {}; + CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {}; + ~CStdOutStream (); + 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); +}; + +CStdOutStream & endl(CStdOutStream & outStream); + +extern CStdOutStream g_StdOut; +extern CStdOutStream g_StdErr; + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/StringConvert.cpp b/src/libs/7zip/unix/CPP/Common/StringConvert.cpp new file mode 100644 index 000000000..dc7dc2669 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/StringConvert.cpp @@ -0,0 +1,181 @@ +// Common/StringConvert.cpp + +#include "StdAfx.h" +#include <stdlib.h> + +#include "StringConvert.h" +extern "C" +{ +int global_use_utf16_conversion = 0; +} + + +#ifdef LOCALE_IS_UTF8 + +#ifdef __APPLE_CC__ +#define UInt32 macUIn32 +#include <CoreFoundation/CoreFoundation.h> +#undef UInt32 + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + if (!srcString.IsEmpty()) + { + UString resultString; + const char * path = &srcString[0]; + +// FIXME size_t n = strlen(path); + + CFStringRef cfpath = CFStringCreateWithCString(NULL,path,kCFStringEncodingUTF8); + + if (cfpath) + { + + CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpath); + CFRelease(cfpath); + CFStringNormalize(cfpath2,kCFStringNormalizationFormC); + + size_t n = CFStringGetLength(cfpath2); + for(size_t i = 0 ; i< n ;i++) { + resultString += CFStringGetCharacterAtIndex(cfpath2,i); + } + + CFRelease(cfpath2); + + return resultString; + } + } + + UString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += wchar_t(srcString[i] & 255); + + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + if (!srcString.IsEmpty()) + { + const wchar_t * wcs = &srcString[0]; + char utf8[4096]; + UniChar unipath[4096]; + + size_t n = wcslen(wcs); + + for(size_t i = 0 ; i<= n ;i++) { + unipath[i] = wcs[i]; + } + + CFStringRef cfpath = CFStringCreateWithCharacters(NULL,unipath,n); + + CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpath); + CFRelease(cfpath); + CFStringNormalize(cfpath2,kCFStringNormalizationFormD); + + CFStringGetCString(cfpath2,(char *)utf8,4096,kCFStringEncodingUTF8); + + CFRelease(cfpath2); + + return AString(utf8); + } + + AString resultString; + for (int i = 0; i < srcString.Length(); i++) + { + if (srcString[i] >= 256) resultString += '?'; + else resultString += char(srcString[i]); + } + return resultString; +} + +#else /* __APPLE_CC__ */ + + +#include "UTFConvert.h" + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) + { + UString resultString; + bool bret = ConvertUTF8ToUnicode(srcString,resultString); + if (bret) return resultString; + } + + UString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += wchar_t(srcString[i] & 255); + + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) + { + AString resultString; + bool bret = ConvertUnicodeToUTF8(srcString,resultString); + if (bret) return resultString; + } + + AString resultString; + for (int i = 0; i < srcString.Length(); i++) + { + if (srcString[i] >= 256) resultString += '?'; + else resultString += char(srcString[i]); + } + return resultString; +} + +#endif /* __APPLE_CC__ */ + +#else /* LOCALE_IS_UTF8 */ + +UString MultiByteToUnicodeString(const AString &srcString, UINT /* codePage */ ) +{ +#ifdef ENV_HAVE_MBSTOWCS + if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) + { + UString resultString; + int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()),srcString,srcString.Length()+1); + if (numChars >= 0) { + resultString.ReleaseBuffer(numChars); + return resultString; + } + } +#endif + + UString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += wchar_t(srcString[i] & 255); + + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT /* codePage */ ) +{ +#ifdef ENV_HAVE_WCSTOMBS + if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) + { + AString resultString; + int numRequiredBytes = srcString.Length() * 6+1; + int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes),srcString,numRequiredBytes); + if (numChars >= 0) { + resultString.ReleaseBuffer(numChars); + return resultString; + } + } +#endif + + AString resultString; + for (int i = 0; i < srcString.Length(); i++) + { + if (srcString[i] >= 256) resultString += '?'; + else resultString += char(srcString[i]); + } + return resultString; +} + +#endif /* LOCALE_IS_UTF8 */ + diff --git a/src/libs/7zip/unix/CPP/Common/StringConvert.h b/src/libs/7zip/unix/CPP/Common/StringConvert.h new file mode 100644 index 000000000..cd737becb --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/StringConvert.h @@ -0,0 +1,73 @@ +// Common/StringConvert.h + +#ifndef __COMMON_STRING_CONVERT_H +#define __COMMON_STRING_CONVERT_H + +#include "MyWindows.h" +#include "MyString.h" +#include "Types.h" + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP); +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage, char defaultChar, bool &defaultCharWasUsed); +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP); + + +inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString) + { return unicodeString; } +inline const UString& GetUnicodeString(const UString &unicodeString) + { return unicodeString; } +inline UString GetUnicodeString(const AString &ansiString) + { return MultiByteToUnicodeString(ansiString); } +inline UString GetUnicodeString(const AString &multiByteString, UINT codePage) + { return MultiByteToUnicodeString(multiByteString, codePage); } +inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT) + { return unicodeString; } +inline const UString& GetUnicodeString(const UString &unicodeString, UINT) + { return unicodeString; } + +inline const char* GetAnsiString(const char* ansiString) + { return ansiString; } +inline const AString& GetAnsiString(const AString &ansiString) + { return ansiString; } +inline AString GetAnsiString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + +inline const char* GetOemString(const char* oemString) + { return oemString; } +inline const AString& GetOemString(const AString &oemString) + { return oemString; } +inline AString GetOemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); } + + +#ifdef _UNICODE + inline const wchar_t* GetSystemString(const wchar_t* unicodeString) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString) + { return unicodeString;} + inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT /* codePage */) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString, UINT /* codePage */) + { return unicodeString;} + inline UString GetSystemString(const AString &multiByteString, UINT codePage) + { return MultiByteToUnicodeString(multiByteString, codePage);} + inline UString GetSystemString(const AString &multiByteString) + { return MultiByteToUnicodeString(multiByteString);} +#else + inline const char* GetSystemString(const char *ansiString) + { return ansiString; } + inline const AString& GetSystemString(const AString &multiByteString, UINT) + { return multiByteString; } + inline const char * GetSystemString(const char *multiByteString, UINT) + { return multiByteString; } + inline AString GetSystemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + inline AString GetSystemString(const UString &unicodeString, UINT codePage) + { return UnicodeStringToMultiByte(unicodeString, codePage); } +#endif + +#ifndef UNDER_CE +AString SystemStringToOemString(const CSysString &srcString); +#endif + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/StringToInt.cpp b/src/libs/7zip/unix/CPP/Common/StringToInt.cpp new file mode 100644 index 000000000..9473766bc --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/StringToInt.cpp @@ -0,0 +1,90 @@ +// Common/StringToInt.cpp + +#include "StdAfx.h" + +#include "StringToInt.h" + +UInt64 ConvertStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + for (;;) + { + char c = *s; + if (c < '0' || c > '9') + { + if (end != NULL) + *end = s; + return result; + } + result *= 10; + result += (c - '0'); + s++; + } +} + +UInt64 ConvertOctStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + for (;;) + { + char c = *s; + if (c < '0' || c > '7') + { + if (end != NULL) + *end = s; + return result; + } + result <<= 3; + result += (c - '0'); + s++; + } +} + +UInt64 ConvertHexStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + for (;;) + { + char c = *s; + UInt32 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) + *end = s; + return result; + } + result <<= 4; + result |= v; + s++; + } +} + + +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) +{ + UInt64 result = 0; + for (;;) + { + wchar_t c = *s; + if (c < '0' || c > '9') + { + if (end != NULL) + *end = s; + return result; + } + result *= 10; + result += (c - '0'); + s++; + } +} + + +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/unix/CPP/Common/StringToInt.h b/src/libs/7zip/unix/CPP/Common/StringToInt.h new file mode 100644 index 000000000..c0d860eff --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/StringToInt.h @@ -0,0 +1,18 @@ +// Common/StringToInt.h + +#ifndef __COMMON_STRINGTOINT_H +#define __COMMON_STRINGTOINT_H + +#include <string.h> +#include "Types.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); + +Int64 ConvertStringToInt64(const char *s, const char **end); + +#endif + + diff --git a/src/libs/7zip/unix/CPP/Common/TextConfig.cpp b/src/libs/7zip/unix/CPP/Common/TextConfig.cpp new file mode 100644 index 000000000..6a55012c3 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/TextConfig.cpp @@ -0,0 +1,138 @@ +// Common/TextConfig.cpp + +#include "StdAfx.h" + +#include "TextConfig.h" + +#include "Defs.h" +#include "UTFConvert.h" + +static bool IsDelimitChar(char c) +{ + return (c == ' ' || c == 0x0A || c == 0x0D || + c == '\0' || c == '\t'); +} + +static AString GetIDString(const char *string, int &finishPos) +{ + AString result; + for (finishPos = 0; ; finishPos++) + { + char c = string[finishPos]; + if (IsDelimitChar(c) || c == '=') + break; + result += c; + } + return result; +} + +static bool WaitNextLine(const AString &string, int &pos) +{ + for (;pos < string.Length(); pos++) + if (string[pos] == 0x0A) + return true; + return false; +} + +static bool SkipSpaces(const AString &string, int &pos) +{ + for (;pos < string.Length(); pos++) + { + char c = string[pos]; + if (!IsDelimitChar(c)) + { + if (c != ';') + return true; + if (!WaitNextLine(string, pos)) + return false; + } + } + return false; +} + +bool GetTextConfig(const AString &string, CObjectVector<CTextConfigPair> &pairs) +{ + pairs.Clear(); + int pos = 0; + + ///////////////////// + // read strings + + for (;;) + { + if (!SkipSpaces(string, pos)) + break; + CTextConfigPair pair; + int finishPos; + AString temp = GetIDString(((const char *)string) + pos, finishPos); + if (!ConvertUTF8ToUnicode(temp, pair.ID)) + return false; + if (finishPos == 0) + return false; + pos += finishPos; + if (!SkipSpaces(string, pos)) + return false; + if (string[pos] != '=') + return false; + pos++; + if (!SkipSpaces(string, pos)) + return false; + if (string[pos] != '\"') + return false; + pos++; + AString message; + for (;;) + { + if (pos >= string.Length()) + return false; + char c = string[pos++]; + if (c == '\"') + break; + if (c == '\\') // FIXME ? + { + char c = string[pos++]; + switch(c) + { + case 'n': + message += '\n'; + break; + case 't': + message += '\t'; + break; + case '\\': // FIXME ? + message += '\\'; + break; + case '\"': + message += '\"'; + break; + default: + message += '\\'; // FIXME ? + message += c; + break; + } + } + else + message += c; + } + if (!ConvertUTF8ToUnicode(message, pair.String)) + return false; + pairs.Add(pair); + } + return true; +} + +int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id) +{ + for (int i = 0; i < pairs.Size(); i++) + if (pairs[i].ID.Compare(id) == 0) + return i; + return -1; +} + +UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id) +{ + int index = FindTextConfigItem(pairs, id); + if (index < 0) + return UString(); + return pairs[index].String; +} diff --git a/src/libs/7zip/unix/CPP/Common/TextConfig.h b/src/libs/7zip/unix/CPP/Common/TextConfig.h new file mode 100644 index 000000000..a25142a70 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/TextConfig.h @@ -0,0 +1,22 @@ +// Common/TextConfig.h + +#ifndef __COMMON_TEXTCONFIG_H +#define __COMMON_TEXTCONFIG_H + +#include "MyVector.h" +#include "MyString.h" + +struct CTextConfigPair +{ + UString ID; + UString String; +}; + +bool GetTextConfig(const AString &text, CObjectVector<CTextConfigPair> &pairs); + +int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id); +UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id); + +#endif + + diff --git a/src/libs/7zip/unix/CPP/Common/Types.h b/src/libs/7zip/unix/CPP/Common/Types.h new file mode 100644 index 000000000..9365b327f --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/Types.h @@ -0,0 +1,11 @@ +// 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/unix/CPP/Common/UTFConvert.cpp b/src/libs/7zip/unix/CPP/Common/UTFConvert.cpp new file mode 100644 index 000000000..95362430a --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/UTFConvert.cpp @@ -0,0 +1,145 @@ +// UTFConvert.cpp + +#include "StdAfx.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) +{ + size_t destPos = 0, srcPos = 0; + for (;;) + { + Byte c; + int numAdds; + if (srcPos == srcLen) + { + *destLen = destPos; + return True; + } + c = (Byte)src[srcPos++]; + + if (c < 0x80) + { + if (dest) + dest[destPos] = (wchar_t)c; + destPos++; + continue; + } + if (c < 0xC0) + break; + for (numAdds = 1; numAdds < 5; numAdds++) + if (c < kUtf8Limits[numAdds]) + break; + UInt32 value = (c - kUtf8Limits[numAdds - 1]); + + do + { + Byte c2; + if (srcPos == srcLen) + break; + c2 = (Byte)src[srcPos++]; + if (c2 < 0x80 || c2 >= 0xC0) + break; + value <<= 6; + value |= (c2 - 0x80); + } + while (--numAdds != 0); + + if (value < 0x10000) + { + if (dest) + dest[destPos] = (wchar_t)value; + destPos++; + } + else + { + value -= 0x10000; + if (value >= 0x100000) + break; + if (dest) + { + dest[destPos + 0] = (wchar_t)(0xD800 + (value >> 10)); + dest[destPos + 1] = (wchar_t)(0xDC00 + (value & 0x3FF)); + } + destPos += 2; + } + } + *destLen = destPos; + return False; +} + +static Bool Utf16_To_Utf8(char *dest, size_t *destLen, const wchar_t *src, size_t srcLen) +{ + size_t destPos = 0, srcPos = 0; + for (;;) + { + unsigned numAdds; + UInt32 value; + if (srcPos == srcLen) + { + *destLen = destPos; + return True; + } + value = src[srcPos++]; + if (value < 0x80) + { + if (dest) + dest[destPos] = (char)value; + destPos++; + continue; + } + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2; + if (value >= 0xDC00 || srcPos == srcLen) + break; + c2 = src[srcPos++]; + if (c2 < 0xDC00 || c2 >= 0xE000) + break; + value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; + } + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + if (dest) + dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + destPos++; + do + { + numAdds--; + if (dest) + dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + destPos++; + } + while (numAdds != 0); + } + *destLen = destPos; + return False; +} + +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(); + return res ? true : false; +} + +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(); + return res ? true : false; +} diff --git a/src/libs/7zip/unix/CPP/Common/UTFConvert.h b/src/libs/7zip/unix/CPP/Common/UTFConvert.h new file mode 100644 index 000000000..2a14600d9 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/UTFConvert.h @@ -0,0 +1,11 @@ +// Common/UTFConvert.h + +#ifndef __COMMON_UTFCONVERT_H +#define __COMMON_UTFCONVERT_H + +#include "MyString.h" + +bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString); +bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString); + +#endif diff --git a/src/libs/7zip/unix/CPP/Common/Wildcard.cpp b/src/libs/7zip/unix/CPP/Common/Wildcard.cpp new file mode 100644 index 000000000..476ddebde --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/Wildcard.cpp @@ -0,0 +1,462 @@ +// Common/Wildcard.cpp + +#include "StdAfx.h" + +#include "../../C/Types.h" + +#include "Wildcard.h" + +bool g_CaseSensitive = + #ifdef _WIN32 + false; + #else + 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"\"/:<>\\|"; + + +static inline bool IsCharDirLimiter(wchar_t c) +{ + return ( + #ifdef _WIN32 + c == kDirDelimiter1 || + #endif + c == kDirDelimiter2); +} + +int CompareFileNames(const UString &s1, const UString &s2) +{ + if (g_CaseSensitive) + return s1.Compare(s2); + return s1.CompareNoCase(s2); +} + +// ----------------------------------------- +// this function compares name with mask +// ? - any char +// * - any char or empty + +static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name) +{ + for (;;) + { + wchar_t m = *mask; + wchar_t c = *name; + if (m == 0) + return (c == 0); + if (m == kAnyCharsChar) + { + if (EnhancedMaskTest(mask + 1, name)) + return true; + if (c == 0) + return false; + } + else + { + if (m == kAnyCharChar) + { + if (c == 0) + return false; + } + else if (m != c) + if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c)) + return false; + mask++; + } + name++; + } +} + +// -------------------------------------------------- +// Splits path to strings + +void SplitPathToParts(const UString &path, UStringVector &pathParts) +{ + pathParts.Clear(); + UString name; + int len = path.Length(); + if (len == 0) + return; + for (int i = 0; i < len; i++) + { + wchar_t c = path[i]; + if (IsCharDirLimiter(c)) + { + pathParts.Add(name); + name.Empty(); + } + else + name += c; + } + pathParts.Add(name); +} + +void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name) +{ + int i; + for (i = path.Length() - 1; i >= 0; i--) + if (IsCharDirLimiter(path[i])) + break; + dirPrefix = path.Left(i + 1); + name = path.Mid(i + 1); +} + +UString ExtractDirPrefixFromPath(const UString &path) +{ + int i; + for (i = path.Length() - 1; i >= 0; i--) + if (IsCharDirLimiter(path[i])) + break; + return path.Left(i + 1); +} + +UString ExtractFileNameFromPath(const UString &path) +{ + int i; + for (i = path.Length() - 1; i >= 0; i--) + if (IsCharDirLimiter(path[i])) + break; + return path.Mid(i + 1); +} + + +bool CompareWildCardWithName(const UString &mask, const UString &name) +{ + return EnhancedMaskTest(mask, name); +} + +bool DoesNameContainWildCard(const UString &path) +{ + return (path.FindOneOf(kWildCardCharSet) >= 0); +} + + +// ----------------------------------------------------------' +// NWildcard + +namespace NWildcard { + + +/* +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 + +ForBoth req m<=N [0, M) ... [N-M, N) same as ForBoth-File + nonreq [0, M) same as ForBoth-File + +*/ + +bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const +{ + if (!isFile && !ForDir) + return false; + int delta = (int)pathParts.Size() - (int)PathParts.Size(); + if (delta < 0) + return false; + int start = 0; + int finish = 0; + if (isFile) + { + if (!ForDir && !Recursive && 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; + for (i = 0; i < PathParts.Size(); i++) + if (!CompareWildCardWithName(PathParts[i], pathParts[i + d])) + break; + if (i == PathParts.Size()) + return true; + } + return false; +} + +int CCensorNode::FindSubNode(const UString &name) const +{ + for (int i = 0; i < SubNodes.Size(); i++) + if (CompareFileNames(SubNodes[i].Name, name) == 0) + return i; + return -1; +} + +void CCensorNode::AddItemSimple(bool include, CItem &item) +{ + if (include) + IncludeItems.Add(item); + else + ExcludeItems.Add(item); +} + +void CCensorNode::AddItem(bool include, CItem &item) +{ + if (item.PathParts.Size() <= 1) + { + AddItemSimple(include, item); + return; + } + const UString &front = item.PathParts.Front(); + if (DoesNameContainWildCard(front)) + { + AddItemSimple(include, item); + return; + } + int index = FindSubNode(front); + if (index < 0) + index = SubNodes.Add(CCensorNode(front, this)); + item.PathParts.Delete(0); + SubNodes[index].AddItem(include, item); +} + +void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir) +{ + CItem item; + SplitPathToParts(path, item.PathParts); + item.Recursive = recursive; + item.ForFile = forFile; + item.ForDir = forDir; + AddItem(include, item); +} + +bool CCensorNode::NeedCheckSubDirs() const +{ + for (int i = 0; i < IncludeItems.Size(); i++) + { + const CItem &item = IncludeItems[i]; + if (item.Recursive || item.PathParts.Size() > 1) + return true; + } + return false; +} + +bool CCensorNode::AreThereIncludeItems() const +{ + if (IncludeItems.Size() > 0) + return true; + for (int i = 0; i < SubNodes.Size(); i++) + if (SubNodes[i].AreThereIncludeItems()) + return true; + return false; +} + +bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const +{ + const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems; + for (int i = 0; i < items.Size(); i++) + if (items[i].CheckPath(pathParts, isFile)) + return true; + return false; +} + +bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const +{ + if (CheckPathCurrent(false, pathParts, isFile)) + { + include = false; + return true; + } + include = true; + bool finded = CheckPathCurrent(true, pathParts, isFile); + if (pathParts.Size() == 1) + return finded; + int index = FindSubNode(pathParts.Front()); + if (index >= 0) + { + UStringVector pathParts2 = pathParts; + pathParts2.Delete(0); + if (SubNodes[index].CheckPath(pathParts2, isFile, include)) + return true; + } + return finded; +} + +bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + return CheckPath(pathParts, isFile, include); +} + +bool CCensorNode::CheckPath(const UString &path, bool isFile) const +{ + bool include; + if (CheckPath(path, isFile, include)) + return include; + return false; +} + +bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const +{ + if (CheckPathCurrent(include, pathParts, isFile)) + return true; + if (Parent == 0) + return false; + pathParts.Insert(0, Name); + return Parent->CheckPathToRoot(include, pathParts, isFile); +} + +/* +bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + return CheckPathToRoot(include, pathParts, isFile); +} +*/ + +void CCensorNode::AddItem2(bool include, const UString &path, bool recursive) +{ + if (path.IsEmpty()) + return; + bool forFile = true; + bool forFolder = true; + UString path2 = path; + if (IsCharDirLimiter(path[path.Length() - 1])) + { + path2.Delete(path.Length() - 1); + forFile = false; + } + AddItem(include, path2, recursive, forFile, forFolder); +} + +void CCensorNode::ExtendExclude(const CCensorNode &fromNodes) +{ + ExcludeItems += fromNodes.ExcludeItems; + for (int i = 0; i < fromNodes.SubNodes.Size(); i++) + { + const CCensorNode &node = fromNodes.SubNodes[i]; + int subNodeIndex = FindSubNode(node.Name); + if (subNodeIndex < 0) + subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this)); + SubNodes[subNodeIndex].ExtendExclude(node); + } +} + +int CCensor::FindPrefix(const UString &prefix) const +{ + for (int i = 0; i < Pairs.Size(); i++) + if (CompareFileNames(Pairs[i].Prefix, prefix) == 0) + return i; + return -1; +} + +void CCensor::AddItem(bool include, const UString &path, bool recursive) +{ + UStringVector pathParts; + if (path.IsEmpty()) + throw "Empty file path"; + SplitPathToParts(path, pathParts); + bool forFile = true; + if (pathParts.Back().IsEmpty()) + { + 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 + { + for (int i = 0; i < pathParts.Size(); i++) + { + const UString &part = pathParts[i]; + if (part == L".." || part == L".") + { + isAbs = true; + break; + } + } + } + int numAbsParts = 0; + if (isAbs) + if (pathParts.Size() > 1) + numAbsParts = pathParts.Size() - 1; + else + 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); + } + int index = FindPrefix(prefix); + if (index < 0) + index = Pairs.Add(CPair(prefix)); + + CItem item; + item.PathParts = pathParts; + item.ForDir = true; + item.ForFile = forFile; + item.Recursive = recursive; + Pairs[index].Head.AddItem(include, item); +} + +bool CCensor::CheckPath(const UString &path, bool isFile) const +{ + bool finded = false; + for (int i = 0; i < Pairs.Size(); i++) + { + bool include; + if (Pairs[i].Head.CheckPath(path, isFile, include)) + { + if (!include) + return false; + finded = true; + } + } + return finded; +} + +void CCensor::ExtendExclude() +{ + int i; + for (i = 0; i < Pairs.Size(); i++) + if (Pairs[i].Prefix.IsEmpty()) + break; + if (i == Pairs.Size()) + return; + int index = i; + for (i = 0; i < Pairs.Size(); i++) + if (index != i) + Pairs[i].Head.ExtendExclude(Pairs[index].Head); +} + +} diff --git a/src/libs/7zip/unix/CPP/Common/Wildcard.h b/src/libs/7zip/unix/CPP/Common/Wildcard.h new file mode 100644 index 000000000..6d4cbcece --- /dev/null +++ b/src/libs/7zip/unix/CPP/Common/Wildcard.h @@ -0,0 +1,80 @@ +// Common/Wildcard.h + +#ifndef __COMMON_WILDCARD_H +#define __COMMON_WILDCARD_H + +#include "MyString.h" + +int CompareFileNames(const UString &s1, const UString &s2); + +void SplitPathToParts(const UString &path, UStringVector &pathParts); +void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name); +UString ExtractDirPrefixFromPath(const UString &path); +UString ExtractFileNameFromPath(const UString &path); +bool DoesNameContainWildCard(const UString &path); +bool CompareWildCardWithName(const UString &mask, const UString &name); + +namespace NWildcard { + +struct CItem +{ + UStringVector PathParts; + bool Recursive; + bool ForFile; + bool ForDir; + 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; +public: + CCensorNode(): Parent(0) { }; + CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { }; + UString Name; + CObjectVector<CCensorNode> SubNodes; + CObjectVector<CItem> IncludeItems; + CObjectVector<CItem> ExcludeItems; + + 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); + + 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 CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const; + // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const; + void ExtendExclude(const CCensorNode &fromNodes); +}; + +struct CPair +{ + UString Prefix; + CCensorNode Head; + CPair(const UString &prefix): Prefix(prefix) { }; +}; + +class CCensor +{ + int FindPrefix(const UString &prefix) const; +public: + CObjectVector<CPair> Pairs; + 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 ExtendExclude(); +}; + +} + +#endif |