Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2014-11-23 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:51 +0300
commitf08f4dcc3c02464c17753b3feafcfe5243b9e236 (patch)
treeb0e1b15bc5368d92dff422e8ec0818564a2b00b8 /CPP/Common
parent83f8ddcc5b2161e1e3c49666265257fca8aeb12c (diff)
9.349.34
Diffstat (limited to 'CPP/Common')
-rw-r--r--[-rwxr-xr-x]CPP/Common/AutoPtr.h0
-rwxr-xr-xCPP/Common/Buffer.h77
-rw-r--r--[-rwxr-xr-x]CPP/Common/CRC.cpp0
-rw-r--r--[-rwxr-xr-x]CPP/Common/C_FileIO.cpp0
-rw-r--r--[-rwxr-xr-x]CPP/Common/C_FileIO.h2
-rw-r--r--[-rwxr-xr-x]CPP/Common/ComTry.h0
-rw-r--r--[-rwxr-xr-x]CPP/Common/CommandLineParser.cpp267
-rw-r--r--[-rwxr-xr-x]CPP/Common/CommandLineParser.h49
-rw-r--r--CPP/Common/Common.h13
-rw-r--r--CPP/Common/CrcReg.cpp111
-rw-r--r--[-rwxr-xr-x]CPP/Common/Defs.h0
-rw-r--r--CPP/Common/DynLimBuf.cpp100
-rw-r--r--CPP/Common/DynLimBuf.h36
-rw-r--r--[-rwxr-xr-x]CPP/Common/DynamicBuffer.h72
-rw-r--r--[-rwxr-xr-x]CPP/Common/IntToString.cpp149
-rw-r--r--[-rwxr-xr-x]CPP/Common/IntToString.h23
-rw-r--r--[-rwxr-xr-x]CPP/Common/Lang.cpp204
-rw-r--r--[-rwxr-xr-x]CPP/Common/Lang.h24
-rw-r--r--[-rwxr-xr-x]CPP/Common/ListFileUtils.cpp117
-rw-r--r--[-rwxr-xr-x]CPP/Common/ListFileUtils.h5
-rw-r--r--CPP/Common/MyBuffer.h237
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyCom.h63
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyException.h0
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyGuidDef.h2
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyInitGuid.h0
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyMap.cpp14
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyMap.h4
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyString.cpp1110
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyString.h842
-rw-r--r--CPP/Common/MyTypes.h30
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyUnknown.h0
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyVector.cpp84
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyVector.h575
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyWindows.cpp24
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyWindows.h15
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyXml.cpp265
-rw-r--r--[-rwxr-xr-x]CPP/Common/MyXml.h23
-rw-r--r--[-rwxr-xr-x]CPP/Common/NewHandler.cpp64
-rw-r--r--[-rwxr-xr-x]CPP/Common/NewHandler.h56
-rw-r--r--[-rwxr-xr-x]CPP/Common/Random.cpp0
-rw-r--r--[-rwxr-xr-x]CPP/Common/Random.h0
-rw-r--r--CPP/Common/Sha256Reg.cpp52
-rw-r--r--[-rwxr-xr-x]CPP/Common/StdAfx.h3
-rw-r--r--[-rwxr-xr-x]CPP/Common/StdInStream.cpp19
-rw-r--r--[-rwxr-xr-x]CPP/Common/StdInStream.h21
-rw-r--r--[-rwxr-xr-x]CPP/Common/StdOutStream.cpp58
-rw-r--r--[-rwxr-xr-x]CPP/Common/StdOutStream.h41
-rw-r--r--[-rwxr-xr-x]CPP/Common/StringConvert.cpp90
-rw-r--r--[-rwxr-xr-x]CPP/Common/StringConvert.h10
-rw-r--r--[-rwxr-xr-x]CPP/Common/StringToInt.cpp148
-rw-r--r--[-rwxr-xr-x]CPP/Common/StringToInt.h19
-rw-r--r--[-rwxr-xr-x]CPP/Common/TextConfig.cpp74
-rw-r--r--[-rwxr-xr-x]CPP/Common/TextConfig.h7
-rwxr-xr-xCPP/Common/Types.h11
-rw-r--r--[-rwxr-xr-x]CPP/Common/UTFConvert.cpp59
-rw-r--r--[-rwxr-xr-x]CPP/Common/UTFConvert.h5
-rw-r--r--[-rwxr-xr-x]CPP/Common/Wildcard.cpp385
-rw-r--r--[-rwxr-xr-x]CPP/Common/Wildcard.h101
-rw-r--r--CPP/Common/XzCrc64Reg.cpp54
59 files changed, 4085 insertions, 1729 deletions
diff --git a/CPP/Common/AutoPtr.h b/CPP/Common/AutoPtr.h
index 006d3155..006d3155 100755..100644
--- a/CPP/Common/AutoPtr.h
+++ b/CPP/Common/AutoPtr.h
diff --git a/CPP/Common/Buffer.h b/CPP/Common/Buffer.h
deleted file mode 100755
index 118fe11f..00000000
--- a/CPP/Common/Buffer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Common/Buffer.h
-
-#ifndef __COMMON_BUFFER_H
-#define __COMMON_BUFFER_H
-
-#include "Defs.h"
-
-template <class T> class CBuffer
-{
-protected:
- size_t _capacity;
- T *_items;
-public:
- void Free()
- {
- delete []_items;
- _items = 0;
- _capacity = 0;
- }
- CBuffer(): _capacity(0), _items(0) {};
- CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; }
- CBuffer(size_t size): _items(0), _capacity(0) { SetCapacity(size); }
- virtual ~CBuffer() { delete []_items; }
- operator T *() { return _items; };
- operator const T *() const { return _items; };
- size_t GetCapacity() const { return _capacity; }
- void SetCapacity(size_t newCapacity)
- {
- if (newCapacity == _capacity)
- return;
- T *newBuffer;
- if (newCapacity > 0)
- {
- newBuffer = new T[newCapacity];
- if (_capacity > 0)
- memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T));
- }
- else
- newBuffer = 0;
- delete []_items;
- _items = newBuffer;
- _capacity = newCapacity;
- }
- CBuffer& operator=(const CBuffer &buffer)
- {
- Free();
- if (buffer._capacity > 0)
- {
- SetCapacity(buffer._capacity);
- memmove(_items, buffer._items, buffer._capacity * sizeof(T));
- }
- return *this;
- }
-};
-
-template <class T>
-bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
-{
- if (b1.GetCapacity() != b2.GetCapacity())
- return false;
- for (size_t i = 0; i < b1.GetCapacity(); i++)
- if (b1[i] != b2[i])
- return false;
- return true;
-}
-
-template <class T>
-bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
-{
- return !(b1 == b2);
-}
-
-typedef CBuffer<char> CCharBuffer;
-typedef CBuffer<wchar_t> CWCharBuffer;
-typedef CBuffer<unsigned char> CByteBuffer;
-
-#endif
diff --git a/CPP/Common/CRC.cpp b/CPP/Common/CRC.cpp
index 9a9f81fb..9a9f81fb 100755..100644
--- a/CPP/Common/CRC.cpp
+++ b/CPP/Common/CRC.cpp
diff --git a/CPP/Common/C_FileIO.cpp b/CPP/Common/C_FileIO.cpp
index 7c629390..7c629390 100755..100644
--- a/CPP/Common/C_FileIO.cpp
+++ b/CPP/Common/C_FileIO.cpp
diff --git a/CPP/Common/C_FileIO.h b/CPP/Common/C_FileIO.h
index ff7a1a11..cb043311 100755..100644
--- a/CPP/Common/C_FileIO.h
+++ b/CPP/Common/C_FileIO.h
@@ -6,7 +6,7 @@
#include <stdio.h>
#include <sys/types.h>
-#include "Types.h"
+#include "MyTypes.h"
#include "MyWindows.h"
#ifdef _WIN32
diff --git a/CPP/Common/ComTry.h b/CPP/Common/ComTry.h
index fb4ef045..fb4ef045 100755..100644
--- a/CPP/Common/ComTry.h
+++ b/CPP/Common/ComTry.h
diff --git a/CPP/Common/CommandLineParser.cpp b/CPP/Common/CommandLineParser.cpp
index 80b467fc..1bf41736 100755..100644
--- a/CPP/Common/CommandLineParser.cpp
+++ b/CPP/Common/CommandLineParser.cpp
@@ -4,6 +4,20 @@
#include "CommandLineParser.h"
+static bool IsString1PrefixedByString2_NoCase(const wchar_t *u, const char *a)
+{
+ for (;;)
+ {
+ char c = *a;
+ if (c == 0)
+ return true;
+ if (MyCharLower_Ascii(c) != MyCharLower_Ascii(*u))
+ return false;
+ a++;
+ u++;
+ }
+}
+
namespace NCommandLineParser {
bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
@@ -11,13 +25,13 @@ bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
dest1.Empty();
dest2.Empty();
bool quoteMode = false;
- int i;
- for (i = 0; i < src.Length(); i++)
+ unsigned i;
+ for (i = 0; i < src.Len(); i++)
{
wchar_t c = src[i];
- if (c == L' ' && !quoteMode)
+ if ((c == L' ' || c == L'\t') && !quoteMode)
{
- dest2 = src.Mid(i + 1);
+ dest2 = src.Ptr(i + 1);
return i != 0;
}
if (c == L'\"')
@@ -45,21 +59,18 @@ void SplitCommandLine(const UString &s, UStringVector &parts)
}
-static const wchar_t kSwitchID1 = '-';
-// static const wchar_t kSwitchID2 = '/';
+static const char *kStopSwitchParsing = "--";
-static const wchar_t kSwitchMinus = '-';
-static const wchar_t *kStopSwitchParsing = L"--";
-
-static bool IsItSwitchChar(wchar_t c)
+static bool inline IsItSwitchChar(wchar_t c)
{
- return (c == kSwitchID1 /*|| c == kSwitchID2 */);
+ return (c == '-');
}
-CParser::CParser(int numSwitches):
- _numSwitches(numSwitches)
+CParser::CParser(unsigned numSwitches):
+ _numSwitches(numSwitches),
+ _switches(0)
{
- _switches = new CSwitchResult[_numSwitches];
+ _switches = new CSwitchResult[numSwitches];
}
CParser::~CParser()
@@ -67,163 +78,121 @@ CParser::~CParser()
delete []_switches;
}
-void CParser::ParseStrings(const CSwitchForm *switchForms,
- const UStringVector &commandStrings)
-{
- 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)
+// if (s) contains switch then function updates switch structures
+// out: true, if (s) is a switch
bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
{
- int len = s.Length();
- if (len == 0)
+ if (s.IsEmpty() || !IsItSwitchChar(s[0]))
return false;
- int pos = 0;
- if (!IsItSwitchChar(s[pos]))
- return false;
- while (pos < len)
+
+ unsigned pos = 1;
+ unsigned switchIndex = 0;
+ int maxLen = -1;
+
+ for (unsigned i = 0; i < _numSwitches; i++)
{
- if (IsItSwitchChar(s[pos]))
- pos++;
- const int kNoLen = -1;
- int matchedSwitchIndex = 0; // GCC Warning
- int maxLen = kNoLen;
- for (int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
+ const char *key = switchForms[i].Key;
+ unsigned switchLen = MyStringLen(key);
+ if ((int)switchLen <= maxLen || pos + switchLen > s.Len())
+ continue;
+ if (IsString1PrefixedByString2_NoCase((const wchar_t *)s + pos, key))
{
- int switchLen = MyStringLen(switchForms[switchIndex].IDString);
- if (switchLen <= maxLen || pos + switchLen > len)
- continue;
+ switchIndex = i;
+ maxLen = switchLen;
+ }
+ }
- 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)
+ if (maxLen < 0)
+ {
+ ErrorMessage = "Unknown switch:";
+ return false;
+ }
+
+ pos += maxLen;
+
+ CSwitchResult &sw = _switches[switchIndex];
+ const CSwitchForm &form = switchForms[switchIndex];
+
+ if (!form.Multi && sw.ThereIs)
+ {
+ ErrorMessage = "Multiple instances for switch:";
+ return false;
+ }
+
+ sw.ThereIs = true;
+
+ int rem = s.Len() - pos;
+ if (rem < form.MinLen)
+ {
+ ErrorMessage = "Too short switch:";
+ return false;
+ }
+
+ sw.WithMinus = false;
+ sw.PostCharIndex = -1;
+
+ switch (form.Type)
+ {
+ case NSwitchType::kMinus:
+ if (rem != 0)
{
- matchedSwitchIndex = switchIndex;
- maxLen = switchLen;
+ sw.WithMinus = (s[pos] == '-');
+ if (sw.WithMinus)
+ pos++;
}
- }
- if (maxLen == kNoLen)
- throw "maxLen == kNoLen";
- CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
- const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
- if ((!switchForm.Multi) && matchedSwitch.ThereIs)
- throw "switch must be single";
- matchedSwitch.ThereIs = true;
- pos += maxLen;
- int tailSize = len - pos;
- NSwitchType::EEnum type = switchForm.Type;
- switch(type)
- {
- case NSwitchType::kPostMinus:
- {
- if (tailSize == 0)
- matchedSwitch.WithMinus = false;
- else
- {
- matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
- if (matchedSwitch.WithMinus)
- pos++;
- }
- break;
- }
- case NSwitchType::kPostChar:
- {
- if (tailSize < switchForm.MinLen)
- throw "switch is not full";
- UString set = switchForm.PostCharSet;
- const int kEmptyCharValue = -1;
- if (tailSize == 0)
- matchedSwitch.PostCharIndex = kEmptyCharValue;
- else
- {
- int index = set.Find(s[pos]);
- if (index < 0)
- matchedSwitch.PostCharIndex = kEmptyCharValue;
- else
- {
- matchedSwitch.PostCharIndex = index;
- pos++;
- }
- }
- break;
- }
- case NSwitchType::kLimitedPostString:
- case NSwitchType::kUnLimitedPostString:
+ break;
+
+ case NSwitchType::kChar:
+ if (rem != 0)
+ {
+ wchar_t c = s[pos];
+ if (c <= 0x7F)
{
- int minLen = switchForm.MinLen;
- if (tailSize < minLen)
- throw "switch is not full";
- if (type == NSwitchType::kUnLimitedPostString)
- {
- matchedSwitch.PostStrings.Add(s.Mid(pos));
- return true;
- }
- int maxLen = switchForm.MaxLen;
- UString stringSwitch = s.Mid(pos, minLen);
- pos += minLen;
- for (int i = minLen; i < maxLen && pos < len; i++, pos++)
- {
- wchar_t c = s[pos];
- if (IsItSwitchChar(c))
- break;
- stringSwitch += c;
- }
- matchedSwitch.PostStrings.Add(stringSwitch);
- break;
+ sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);
+ if (sw.PostCharIndex >= 0)
+ pos++;
}
- case NSwitchType::kSimple:
- break;
- }
+ }
+ break;
+
+ case NSwitchType::kString:
+ sw.PostStrings.Add((const wchar_t *)s + pos);
+ return true;
+ }
+ if (pos != s.Len())
+ {
+ ErrorMessage = "Too long switch:";
+ return false;
}
return true;
}
-const CSwitchResult& CParser::operator[](size_t index) const
-{
- return _switches[index];
-}
-
-/////////////////////////////////
-// Command parsing procedures
-
-int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
- const UString &commandString, UString &postString)
+bool CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings)
{
- for (int i = 0; i < numCommandForms; i++)
+ ErrorLine.Empty();
+ bool stopSwitch = false;
+ FOR_VECTOR (i, commandStrings)
{
- const UString id = commandForms[i].IDString;
- if (commandForms[i].PostStringMode)
+ const UString &s = commandStrings[i];
+ if (!stopSwitch)
{
- if (commandString.Find(id) == 0)
+ if (s.IsEqualTo(kStopSwitchParsing))
{
- postString = commandString.Mid(id.Length());
- return i;
+ stopSwitch = true;
+ continue;
}
- }
- else
- if (commandString == id)
+ if (!s.IsEmpty() && IsItSwitchChar(s[0]))
{
- postString.Empty();
- return i;
+ if (ParseString(s, switchForms))
+ continue;
+ ErrorLine = s;
+ return false;
}
+ }
+ NonSwitchStrings.Add(s);
}
- return -1;
+ return true;
}
-
+
}
diff --git a/CPP/Common/CommandLineParser.h b/CPP/Common/CommandLineParser.h
index 3d0b41dd..c9fd2956 100755..100644
--- a/CPP/Common/CommandLineParser.h
+++ b/CPP/Common/CommandLineParser.h
@@ -10,63 +10,54 @@ namespace NCommandLineParser {
bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
void SplitCommandLine(const UString &s, UStringVector &parts);
-namespace NSwitchType {
+namespace NSwitchType
+{
enum EEnum
{
kSimple,
- kPostMinus,
- kLimitedPostString,
- kUnLimitedPostString,
- kPostChar
+ kMinus,
+ kString,
+ kChar
};
}
struct CSwitchForm
{
- const wchar_t *IDString;
- NSwitchType::EEnum Type;
+ const char *Key;
+ Byte Type;
bool Multi;
- int MinLen;
- int MaxLen;
- const wchar_t *PostCharSet;
+ Byte MinLen;
+ // int MaxLen;
+ const char *PostCharSet;
};
struct CSwitchResult
{
bool ThereIs;
bool WithMinus;
- UStringVector PostStrings;
int PostCharIndex;
+ UStringVector PostStrings;
+
CSwitchResult(): ThereIs(false) {};
};
class CParser
{
- int _numSwitches;
+ unsigned _numSwitches;
CSwitchResult *_switches;
+
bool ParseString(const UString &s, const CSwitchForm *switchForms);
public:
UStringVector NonSwitchStrings;
- CParser(int numSwitches);
+ AString ErrorMessage;
+ UString ErrorLine;
+
+ CParser(unsigned numSwitches);
~CParser();
- void ParseStrings(const CSwitchForm *switchForms,
- const UStringVector &commandStrings);
- const CSwitchResult& operator[](size_t index) const;
+ bool ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings);
+ const CSwitchResult& operator[](size_t index) const { return _switches[index]; }
};
-/////////////////////////////////
-// 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/CPP/Common/Common.h b/CPP/Common/Common.h
new file mode 100644
index 00000000..9dd30f4b
--- /dev/null
+++ b/CPP/Common/Common.h
@@ -0,0 +1,13 @@
+// Common.h
+
+#ifndef __COMMON_COMMON_H
+#define __COMMON_COMMON_H
+
+#include "../../C/Compiler.h"
+
+#include "MyWindows.h"
+#include "NewHandler.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[1]))
+
+#endif
diff --git a/CPP/Common/CrcReg.cpp b/CPP/Common/CrcReg.cpp
new file mode 100644
index 00000000..6f4de495
--- /dev/null
+++ b/CPP/Common/CrcReg.cpp
@@ -0,0 +1,111 @@
+// CrcReg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/7zCrc.h"
+#include "../../C/CpuArch.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/ICoder.h"
+#include "../7zip/Common/RegisterCodec.h"
+
+EXTERN_C_BEGIN
+
+typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
+
+extern CRC_FUNC g_CrcUpdate;
+
+#ifdef MY_CPU_X86_OR_AMD64
+ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
+#endif
+
+#ifndef MY_CPU_BE
+ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
+#endif
+
+EXTERN_C_END
+
+class CCrcHasher:
+ public IHasher,
+ public ICompressSetCoderProperties,
+ public CMyUnknownImp
+{
+ UInt32 _crc;
+ CRC_FUNC _updateFunc;
+ bool SetFunctions(UInt32 tSize);
+public:
+ CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); }
+
+ MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
+
+ STDMETHOD_(void, Init)();
+ STDMETHOD_(void, Update)(const void *data, UInt32 size);
+ STDMETHOD_(void, Final)(Byte *digest);
+ STDMETHOD_(UInt32, GetDigestSize)();
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+};
+
+STDMETHODIMP_(void) CCrcHasher::Init()
+{
+ _crc = CRC_INIT_VAL;
+}
+
+STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size)
+{
+ _crc = _updateFunc(_crc, data, size, g_CrcTable);
+}
+
+STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest)
+{
+ UInt32 val = CRC_GET_DIGEST(_crc);
+ SetUi32(digest, val);
+}
+
+STDMETHODIMP_(UInt32) CCrcHasher::GetDigestSize()
+{
+ return 4;
+}
+
+bool CCrcHasher::SetFunctions(UInt32 tSize)
+{
+ _updateFunc = g_CrcUpdate;
+ if (tSize == 4)
+ {
+ #ifndef MY_CPU_BE
+ _updateFunc = CrcUpdateT4;
+ #endif
+ }
+ else if (tSize == 8)
+ {
+ #ifdef MY_CPU_X86_OR_AMD64
+ _updateFunc = CrcUpdateT8;
+ #else
+ return false;
+ #endif
+ }
+ return true;
+}
+
+STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ if (propIDs[i] == NCoderPropID::kDefaultProp)
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ if (!SetFunctions(prop.ulVal))
+ return E_NOTIMPL;
+ }
+ }
+ return S_OK;
+}
+
+static IHasher *CreateHasher() { return new CCrcHasher(); }
+
+static CHasherInfo g_HasherInfo = { CreateHasher, 0x1, L"CRC32", 4 };
+
+REGISTER_HASHER(Crc32)
diff --git a/CPP/Common/Defs.h b/CPP/Common/Defs.h
index dad3ae8f..dad3ae8f 100755..100644
--- a/CPP/Common/Defs.h
+++ b/CPP/Common/Defs.h
diff --git a/CPP/Common/DynLimBuf.cpp b/CPP/Common/DynLimBuf.cpp
new file mode 100644
index 00000000..ad4ab128
--- /dev/null
+++ b/CPP/Common/DynLimBuf.cpp
@@ -0,0 +1,100 @@
+// Common/DynLimBuf.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#include <wchar.h>
+#else
+#include <ctype.h>
+#endif
+
+#include "DynLimBuf.h"
+#include "MyString.h"
+
+CDynLimBuf::CDynLimBuf(size_t limit)
+{
+ _chars = 0;
+ _pos = 0;
+ _size = 0;
+ _sizeLimit = limit;
+ _error = true;
+ unsigned size = 1 << 4;
+ if (size > limit)
+ size = (unsigned)limit;
+ _chars = (Byte *)MyAlloc(size);
+ if (_chars)
+ {
+ _size = size;
+ _error = false;
+ }
+}
+
+CDynLimBuf & CDynLimBuf::operator+=(char c)
+{
+ if (_error)
+ return *this;
+ if (_size == _pos)
+ {
+ size_t n = _sizeLimit - _size;
+ if (n == 0)
+ {
+ _error = true;
+ return *this;
+ }
+ if (n > _size)
+ n = _size;
+
+ n += _pos;
+
+ Byte *newBuf = (Byte *)MyAlloc(n);
+ if (!newBuf)
+ {
+ _error = true;
+ return *this;
+ }
+ memcpy(newBuf, _chars, _pos);
+ MyFree(_chars);
+ _chars = newBuf;
+ _size = n;
+ }
+ _chars[_pos++] = c;
+ return *this;
+}
+
+CDynLimBuf &CDynLimBuf::operator+=(const char *s)
+{
+ if (_error)
+ return *this;
+ unsigned len = MyStringLen(s);
+ size_t rem = _sizeLimit - _pos;
+ if (rem < len)
+ {
+ len = (unsigned)rem;
+ _error = true;
+ }
+ if (_size - _pos < len)
+ {
+ size_t n = _pos + len;
+ if (n - _size < _size)
+ {
+ size_t n = _sizeLimit;
+ if (n - _size > _size)
+ n = _size * 2;
+ }
+
+ Byte *newBuf = (Byte *)MyAlloc(n);
+ if (!newBuf)
+ {
+ _error = true;
+ return *this;
+ }
+ memcpy(newBuf, _chars, _pos);
+ MyFree(_chars);
+ _chars = newBuf;
+ _size = n;
+ }
+ memcpy(_chars + _pos, s, len);
+ _pos += len;
+ return *this;
+}
diff --git a/CPP/Common/DynLimBuf.h b/CPP/Common/DynLimBuf.h
new file mode 100644
index 00000000..035fc272
--- /dev/null
+++ b/CPP/Common/DynLimBuf.h
@@ -0,0 +1,36 @@
+// Common/DynLimBuf.h
+
+#ifndef __COMMON_DYN_LIM_BUF_H
+#define __COMMON_DYN_LIM_BUF_H
+
+#include <string.h>
+
+#include "../../C/Alloc.h"
+
+#include "MyString.h"
+
+class CDynLimBuf
+{
+ Byte *_chars;
+ size_t _pos;
+ size_t _size;
+ size_t _sizeLimit;
+ bool _error;
+
+ CDynLimBuf(const CDynLimBuf &s);
+public:
+ CDynLimBuf(size_t limit) throw();
+ ~CDynLimBuf() { MyFree(_chars); }
+
+ size_t Len() const { return _pos; }
+ void Empty() { _pos = 0; }
+
+ operator const Byte *() const { return _chars; }
+ // const char *Ptr() const { return _chars; }
+
+ CDynLimBuf &operator+=(char c) throw();
+ CDynLimBuf &operator+=(const char *s) throw();
+};
+
+
+#endif
diff --git a/CPP/Common/DynamicBuffer.h b/CPP/Common/DynamicBuffer.h
index bf52a742..cd23ad73 100755..100644
--- a/CPP/Common/DynamicBuffer.h
+++ b/CPP/Common/DynamicBuffer.h
@@ -3,48 +3,56 @@
#ifndef __COMMON_DYNAMIC_BUFFER_H
#define __COMMON_DYNAMIC_BUFFER_H
-#include "Buffer.h"
-
-template <class T> class CDynamicBuffer: public CBuffer<T>
+template <class T> class CDynamicBuffer
{
- void GrowLength(size_t size)
+ T *_items;
+ size_t _size;
+ size_t _pos;
+
+ CDynamicBuffer(const CDynamicBuffer &buffer);
+ void operator=(const CDynamicBuffer &buffer);
+
+ void Grow(size_t size)
{
- size_t delta;
- 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;
+ size_t delta = _size >= 64 ? _size : 64;
+ if (delta < size)
+ delta = size;
+ size_t newCap = _size + delta;
if (newCap < delta)
- newCap = this->_capacity + size;
- 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));
+ newCap = _size + size;
+ if (newCap < size)
+ throw 20120116;
}
- return *this;
+
+ T *newBuffer = new T[newCap];
+ memcpy(newBuffer, _items, _pos * sizeof(T));
+ delete []_items;
+ _items = newBuffer;
+ _size = newCap;
}
- void EnsureCapacity(size_t capacity)
+
+public:
+ CDynamicBuffer(): _items(0), _size(0), _pos(0) {}
+ // operator T *() { return _items; };
+ operator const T *() const { return _items; };
+ ~CDynamicBuffer() { delete []_items; }
+
+ T *GetCurPtrAndGrow(size_t addSize)
{
- if (this->_capacity < capacity)
- GrowLength(capacity - this->_capacity);
+ size_t rem = _size - _pos;
+ if (rem < addSize)
+ Grow(addSize - rem);
+ T *res = _items + _pos;
+ _pos += addSize;
+ return res;
}
+
+ const size_t GetPos() const { return _pos; }
+
+ // void Empty() { _pos = 0; }
};
-typedef CDynamicBuffer<char> CCharDynamicBuffer;
-typedef CDynamicBuffer<wchar_t> CWCharDynamicBuffer;
typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;
#endif
diff --git a/CPP/Common/IntToString.cpp b/CPP/Common/IntToString.cpp
index 013fee52..09156e16 100755..100644
--- a/CPP/Common/IntToString.cpp
+++ b/CPP/Common/IntToString.cpp
@@ -4,74 +4,143 @@
#include "IntToString.h"
-void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base)
+#define CONVERT_INT_TO_STR(charType, tempSize) \
+ unsigned char temp[tempSize]; unsigned i = 0; \
+ while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
+ *s++ = (charType)('0' + (unsigned)val); \
+ while (i != 0) { i--; *s++ = temp[i]; } \
+ *s = 0;
+
+void ConvertUInt32ToString(UInt32 val, char *s)
{
- if (base < 2 || base > 36)
+ CONVERT_INT_TO_STR(char, 16);
+}
+
+void ConvertUInt64ToString(UInt64 val, char *s)
+{
+ if (val <= (UInt32)0xFFFFFFFF)
{
- *s = '\0';
+ ConvertUInt32ToString((UInt32)val, s);
return;
}
- char temp[72];
- int pos = 0;
- do
+ CONVERT_INT_TO_STR(char, 24);
+}
+
+void ConvertUInt64ToOct(UInt64 val, char *s)
+{
+ UInt64 v = val;
+ unsigned i;
+ for (i = 1;; i++)
{
- int delta = (int)(value % base);
- temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10)));
- value /= base;
+ v >>= 3;
+ if (v == 0)
+ break;
}
- while (value != 0);
+ s[i] = 0;
do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = '\0';
+ {
+ unsigned t = (unsigned)(val & 0x7);
+ val >>= 3;
+ s[--i] = (char)('0' + t);
+ }
+ while (i);
}
-void ConvertUInt64ToString(UInt64 value, wchar_t *s)
+void ConvertUInt32ToHex(UInt32 val, char *s)
{
- wchar_t temp[32];
- int pos = 0;
+ UInt32 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 4;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
do
{
- temp[pos++] = (wchar_t)(L'0' + (int)(value % 10));
- value /= 10;
+ unsigned t = (unsigned)((val & 0xF));
+ val >>= 4;
+ s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
- while (value != 0);
+ while (i);
+}
+
+void ConvertUInt64ToHex(UInt64 val, char *s)
+{
+ UInt64 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 4;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = L'\0';
+ {
+ unsigned t = (unsigned)((val & 0xF));
+ val >>= 4;
+ s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+ while (i);
}
-void ConvertUInt32ToString(UInt32 value, char *s) { ConvertUInt64ToString(value, s); }
-void ConvertUInt32ToString(UInt32 value, wchar_t *s) { ConvertUInt64ToString(value, s); }
+void ConvertUInt32ToHex8Digits(UInt32 val, char *s)
+{
+ s[8] = 0;
+ for (int i = 7; i >= 0; i--)
+ {
+ unsigned t = val & 0xF;
+ val >>= 4;
+ s[i] = (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))));
+ }
+}
-void ConvertInt64ToString(Int64 value, char *s)
+/*
+void ConvertUInt32ToHex8Digits(UInt32 val, wchar_t *s)
{
- if (value < 0)
+ s[8] = 0;
+ for (int i = 7; i >= 0; i--)
{
- *s++ = '-';
- value = -value;
+ unsigned t = val & 0xF;
+ val >>= 4;
+ s[i] = (wchar_t)(((t < 10) ? ('0' + t) : ('A' + (t - 10))));
+ }
+}
+*/
+
+void ConvertUInt32ToString(UInt32 val, wchar_t *s)
+{
+ CONVERT_INT_TO_STR(wchar_t, 16);
+}
+
+void ConvertUInt64ToString(UInt64 val, wchar_t *s)
+{
+ if (val <= (UInt32)0xFFFFFFFF)
+ {
+ ConvertUInt32ToString((UInt32)val, s);
+ return;
}
- ConvertUInt64ToString(value, s);
+ CONVERT_INT_TO_STR(wchar_t, 24);
}
-void ConvertInt64ToString(Int64 value, wchar_t *s)
+void ConvertInt64ToString(Int64 val, char *s)
{
- if (value < 0)
+ if (val < 0)
{
- *s++ = L'-';
- value = -value;
+ *s++ = '-';
+ val = -val;
}
- ConvertUInt64ToString(value, s);
+ ConvertUInt64ToString(val, s);
}
-void ConvertUInt32ToHexWithZeros(UInt32 value, char *s)
+void ConvertInt64ToString(Int64 val, wchar_t *s)
{
- for (int i = 0; i < 8; i++)
+ if (val < 0)
{
- int t = value & 0xF;
- value >>= 4;
- s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ *s++ = L'-';
+ val = -val;
}
- s[8] = '\0';
+ ConvertUInt64ToString(val, s);
}
diff --git a/CPP/Common/IntToString.h b/CPP/Common/IntToString.h
index 782f930c..69605ab7 100755..100644
--- a/CPP/Common/IntToString.h
+++ b/CPP/Common/IntToString.h
@@ -3,17 +3,22 @@
#ifndef __COMMON_INT_TO_STRING_H
#define __COMMON_INT_TO_STRING_H
-#include <stddef.h>
-#include "Types.h"
+#include "MyTypes.h"
-void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10);
-void ConvertUInt64ToString(UInt64 value, wchar_t *s);
-void ConvertInt64ToString(Int64 value, char *s);
-void ConvertInt64ToString(Int64 value, wchar_t *s);
+void ConvertUInt32ToString(UInt32 value, char *s) throw();
+void ConvertUInt64ToString(UInt64 value, char *s) throw();
-void ConvertUInt32ToString(UInt32 value, char *s);
-void ConvertUInt32ToString(UInt32 value, wchar_t *s);
+void ConvertUInt32ToString(UInt32 value, wchar_t *s) throw();
+void ConvertUInt64ToString(UInt64 value, wchar_t *s) throw();
-void ConvertUInt32ToHexWithZeros(UInt32 value, char *s);
+void ConvertUInt64ToOct(UInt64 value, char *s) throw();
+
+void ConvertUInt32ToHex(UInt32 value, char *s) throw();
+void ConvertUInt64ToHex(UInt64 value, char *s) throw();
+void ConvertUInt32ToHex8Digits(UInt32 value, char *s) throw();
+// void ConvertUInt32ToHex8Digits(UInt32 value, wchar_t *s) throw();
+
+void ConvertInt64ToString(Int64 value, char *s) throw();
+void ConvertInt64ToString(Int64 value, wchar_t *s) throw();
#endif
diff --git a/CPP/Common/Lang.cpp b/CPP/Common/Lang.cpp
index 2339d120..c1638ba0 100755..100644
--- a/CPP/Common/Lang.cpp
+++ b/CPP/Common/Lang.cpp
@@ -3,54 +3,115 @@
#include "StdAfx.h"
#include "Lang.h"
-#include "TextConfig.h"
+#include "StringToInt.h"
+#include "UTFConvert.h"
#include "../Windows/FileIO.h"
-#include "UTFConvert.h"
-#include "Defs.h"
-static bool HexStringToNumber(const UString &s, UInt32 &value)
+void CLang::Clear()
+{
+ delete []_text;
+ _text = 0;
+ _ids.Clear();
+ _offsets.Clear();
+}
+
+static const wchar_t *kLangSignature = L";!@Lang2@!UTF-8!";
+
+bool CLang::OpenFromString(const AString &s2)
{
- value = 0;
+ UString s;
+ if (!ConvertUTF8ToUnicode(s2, s))
+ return false;
+ unsigned i = 0;
if (s.IsEmpty())
return false;
- for (int i = 0; i < s.Length(); i++)
+ if (s[0] == 0xFEFF)
+ i++;
+
+ for (const wchar_t *p = kLangSignature;; 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
+ wchar_t c = *p++;
+ if (c == 0)
+ break;
+ if (s[i] != c)
return false;
- value *= 0x10;
- value += a;
}
- return true;
-}
+ _text = new wchar_t[s.Len() - i + 1];
+ wchar_t *text = _text;
-static bool WaitNextLine(const AString &s, int &pos)
-{
- for (; pos < s.Length(); pos++)
- if (s[pos] == 0x0A)
- return true;
- return false;
-}
+ Int32 id = -100;
+ UInt32 pos = 0;
-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);
+ while (i < s.Len())
+ {
+ unsigned start = pos;
+ do
+ {
+ wchar_t c = s[i++];
+ if (c == '\n')
+ break;
+ if (c == '\\')
+ {
+ if (i == s.Len())
+ return false;
+ c = s[i++];
+ switch (c)
+ {
+ case '\n': return false;
+ case 'n': c = '\n'; break;
+ case 't': c = '\t'; break;
+ case '\\': c = '\\'; break;
+ default: text[pos++] = L'\\'; break;
+ }
+ }
+ text[pos++] = c;
+ }
+ while (i < s.Len());
+
+ {
+ unsigned j = start;
+ for (; j < pos; j++)
+ if (text[j] != ' ')
+ break;
+ if (j == pos)
+ {
+ id++;
+ continue;
+ }
+ }
+ if (text[start] == ';')
+ {
+ pos = start;
+ id++;
+ continue;
+ }
+
+ text[pos++] = 0;
+ const wchar_t *end;
+ UInt32 id32 = ConvertStringToUInt32(text + start, &end);
+ if (*end == 0)
+ {
+ if (id32 > ((UInt32)1 << 30) || (Int32)id32 < id)
+ return false;
+ id = (Int32)id32;
+ pos = start;
+ continue;
+ }
+
+ if (id < 0)
+ return false;
+ _ids.Add((UInt32)id++);
+ _offsets.Add(start);
+ }
+
+ return true;
}
-bool CLang::Open(CFSTR fileName)
+bool CLang::Open(CFSTR fileName, const wchar_t *id)
{
- _langPairs.Clear();
+ Clear();
NWindows::NFile::NIO::CInFile file;
if (!file.Open(fileName))
return false;
@@ -60,71 +121,38 @@ bool CLang::Open(CFSTR fileName)
if (length > (1 << 20))
return false;
AString s;
- char *p = s.GetBuffer((int)length + 1);
+ unsigned len = (unsigned)length;
+ char *p = s.GetBuffer(len);
UInt32 processed;
- if (!file.Read(p, (UInt32)length, processed))
+ if (!file.Read(p, len, 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))
+ if (len != processed)
return false;
-
- CObjectVector<CTextConfigPair> pairs;
- if (!GetTextConfig(s.Mid(pos), pairs))
- return false;
-
- _langPairs.Reserve(pairs.Size());
- for (int i = 0; i < pairs.Size(); i++)
+ char *p2 = p;
+ for (unsigned i = 0; i < len; i++)
{
- CTextConfigPair textConfigPair = pairs[i];
- CLangPair langPair;
- if (!HexStringToNumber(textConfigPair.ID, langPair.Value))
- return false;
- langPair.String = textConfigPair.String;
- _langPairs.Add(langPair);
+ char c = p[i];
+ if (c == 0)
+ break;
+ if (c != 0x0D)
+ *p2++ = c;
}
- _langPairs.Sort(CompareLangItems, NULL);
- return true;
-}
-
-int CLang::FindItem(UInt32 value) const
-{
- int left = 0, right = _langPairs.Size();
- while (left != right)
+ s.ReleaseBuffer((unsigned)(p2 - p));
+ if (OpenFromString(s))
{
- UInt32 mid = (left + right) / 2;
- UInt32 midValue = _langPairs[mid].Value;
- if (value == midValue)
- return mid;
- if (value < midValue)
- right = mid;
- else
- left = mid + 1;
+ const wchar_t *s = Get(0);
+ if (s && wcscmp(s, id) == 0)
+ return true;
}
- return -1;
+ Clear();
+ return false;
}
-bool CLang::GetMessage(UInt32 value, UString &message) const
+const wchar_t *CLang::Get(UInt32 id) const
{
- int index = FindItem(value);
+ int index = _ids.FindInSorted(id);
if (index < 0)
- return false;
- message = _langPairs[index].String;
- return true;
+ return NULL;
+ return _text + (size_t)_offsets[index];
}
diff --git a/CPP/Common/Lang.h b/CPP/Common/Lang.h
index 2ce53a0d..2ca2a850 100755..100644
--- a/CPP/Common/Lang.h
+++ b/CPP/Common/Lang.h
@@ -4,24 +4,20 @@
#define __COMMON_LANG_H
#include "MyString.h"
-#include "Types.h"
-
-struct CLangPair
-{
- UInt32 Value;
- UString String;
-};
class CLang
{
- CObjectVector<CLangPair> _langPairs;
+ wchar_t *_text;
+ CRecordVector<UInt32> _ids;
+ CRecordVector<UInt32> _offsets;
+
+ bool OpenFromString(const AString &s);
public:
- bool Open(CFSTR fileName);
- void Clear() { _langPairs.Clear(); }
- int FindItem(UInt32 value) const;
- bool GetMessage(UInt32 value, UString &message) const;
+ CLang(): _text(0) {}
+ ~CLang() { Clear(); };
+ bool Open(CFSTR fileName, const wchar_t *id);
+ void Clear() throw();
+ const wchar_t *Get(UInt32 id) const throw();
};
#endif
-
-
diff --git a/CPP/Common/ListFileUtils.cpp b/CPP/Common/ListFileUtils.cpp
index f9bd18ed..313532ef 100755..100644
--- a/CPP/Common/ListFileUtils.cpp
+++ b/CPP/Common/ListFileUtils.cpp
@@ -2,75 +2,116 @@
#include "StdAfx.h"
-#include "MyWindows.h"
+#include "../../C/CpuArch.h"
+
#include "../Windows/FileIO.h"
#include "ListFileUtils.h"
+#include "MyBuffer.h"
#include "StringConvert.h"
#include "UTFConvert.h"
static const char kQuoteChar = '\"';
-static void RemoveQuote(UString &s)
+static void AddName(UStringVector &strings, UString &s)
{
- if (s.Length() >= 2)
- if (s[0] == kQuoteChar && s.Back() == kQuoteChar)
- s = s.Mid(1, s.Length() - 2);
+ s.Trim();
+ if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
+ {
+ s.DeleteBack();
+ s.Delete(0);
+ }
+ if (!s.IsEmpty())
+ strings.Add(s);
}
-bool ReadNamesFromListFile(CFSTR fileName, UStringVector &resultStrings, UINT codePage)
+bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage)
{
NWindows::NFile::NIO::CInFile file;
if (!file.Open(fileName))
return false;
- UInt64 length;
- if (!file.GetLength(length))
- return false;
- if (length > ((UInt32)1 << 31))
+ UInt64 fileSize;
+ if (!file.GetLength(fileSize))
return false;
- AString s;
- char *p = s.GetBuffer((int)length + 1);
- UInt32 processed;
- if (!file.Read(p, (UInt32)length, processed))
+ if (fileSize >= ((UInt32)1 << 31) - 32)
return false;
- p[(UInt32)length] = 0;
- s.ReleaseBuffer();
- file.Close();
-
UString u;
- #ifdef CP_UTF8
- if (codePage == CP_UTF8)
+ if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE)
{
- if (!ConvertUTF8ToUnicode(s, u))
+ if ((fileSize & 1) != 0)
+ return false;
+ CByteArr buf((size_t)fileSize);
+ UInt32 processed;
+ if (!file.Read(buf, (UInt32)fileSize, processed))
return false;
+ if (processed != fileSize)
+ return false;
+ file.Close();
+ unsigned num = (unsigned)fileSize / 2;
+ wchar_t *p = u.GetBuffer(num);
+ if (codePage == MY__CP_UTF16)
+ for (unsigned i = 0; i < num; i++)
+ {
+ wchar_t c = GetUi16(buf + i * 2);
+ if (c == 0)
+ return false;
+ p[i] = c;
+ }
+ else
+ for (unsigned i = 0; i < num; i++)
+ {
+ wchar_t c = (wchar_t)GetBe16(buf + i * 2);
+ if (c == 0)
+ return false;
+ p[i] = c;
+ }
+ u.ReleaseBuffer(num);
}
else
- #endif
- u = MultiByteToUnicodeString(s, codePage);
- if (!u.IsEmpty())
{
- if (u[0] == 0xFEFF)
- u.Delete(0);
+ AString s;
+ char *p = s.GetBuffer((unsigned)fileSize);
+ UInt32 processed;
+ if (!file.Read(p, (UInt32)fileSize, processed))
+ return false;
+ if (processed != fileSize)
+ return false;
+ file.Close();
+ p[processed] = 0;
+ s.ReleaseBuffer();
+ if (s.Len() != processed)
+ return false;
+
+ // #ifdef CP_UTF8
+ if (codePage == CP_UTF8)
+ {
+ if (!ConvertUTF8ToUnicode(s, u))
+ return false;
+ }
+ else
+ // #endif
+ MultiByteToUnicodeString2(u, s, codePage);
}
- UString t;
- for (int i = 0; i < u.Length(); i++)
+ const wchar_t kGoodBOM = 0xFEFF;
+ const wchar_t kBadBOM = 0xFFFE;
+
+ UString s;
+ unsigned i = 0;
+ for (; i < u.Len() && u[i] == kGoodBOM; i++);
+ for (; i < u.Len(); i++)
{
wchar_t c = u[i];
+ if (c == kGoodBOM || c == kBadBOM)
+ return false;
if (c == L'\n' || c == 0xD)
{
- t.Trim();
- RemoveQuote(t);
- if (!t.IsEmpty())
- resultStrings.Add(t);
- t.Empty();
+ AddName(strings, s);
+ s.Empty();
}
else
- t += c;
+ s += c;
}
- t.Trim();
- RemoveQuote(t);
- if (!t.IsEmpty())
- resultStrings.Add(t);
+ AddName(strings, s);
return true;
}
diff --git a/CPP/Common/ListFileUtils.h b/CPP/Common/ListFileUtils.h
index d43bfdfc..e8d833fd 100755..100644
--- a/CPP/Common/ListFileUtils.h
+++ b/CPP/Common/ListFileUtils.h
@@ -4,7 +4,10 @@
#define __COMMON_LIST_FILE_UTILS_H
#include "MyString.h"
-#include "Types.h"
+#include "MyTypes.h"
+
+#define MY__CP_UTF16 1200
+#define MY__CP_UTF16BE 1201
bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
diff --git a/CPP/Common/MyBuffer.h b/CPP/Common/MyBuffer.h
new file mode 100644
index 00000000..27c188c7
--- /dev/null
+++ b/CPP/Common/MyBuffer.h
@@ -0,0 +1,237 @@
+// Common/MyBuffer.h
+
+#ifndef __COMMON_MY_BUFFER_H
+#define __COMMON_MY_BUFFER_H
+
+#include "Defs.h"
+
+template <class T> class CBuffer
+{
+ T *_items;
+ size_t _size;
+
+ void CopyToEmpty(const CBuffer &buffer)
+ {
+ if (buffer._size > 0)
+ {
+ _items = new T[buffer._size];
+ memcpy(_items, buffer._items, buffer._size * sizeof(T));
+ _size = buffer._size;
+ }
+ }
+public:
+ void Free()
+ {
+ if (_items)
+ {
+ delete []_items;
+ _items = 0;
+ }
+ _size = 0;
+ }
+
+ CBuffer(): _items(0), _size(0) {};
+ CBuffer(size_t size): _items(0), _size(0) { _items = new T[size]; _size = size; }
+ CBuffer(const CBuffer &buffer): _items(0), _size(0) { CopyToEmpty(buffer); }
+ ~CBuffer() { delete []_items; }
+
+ operator T *() { return _items; };
+ operator const T *() const { return _items; };
+ size_t Size() const { return _size; }
+
+ void Alloc(size_t size)
+ {
+ if (size != _size)
+ {
+ Free();
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ }
+ }
+ }
+
+ void AllocAtLeast(size_t size)
+ {
+ if (size > _size)
+ {
+ Free();
+ _items = new T[size];
+ _size = size;
+ }
+ }
+
+ void CopyFrom(const T *data, size_t size)
+ {
+ Alloc(size);
+ memcpy(_items, data, size * sizeof(T));
+ }
+
+ void ChangeSize_KeepData(size_t newSize, size_t keepSize)
+ {
+ if (newSize == _size)
+ return;
+ T *newBuffer = NULL;
+ if (newSize > 0)
+ {
+ newBuffer = new T[newSize];
+ if (_size > 0)
+ memcpy(newBuffer, _items, MyMin(MyMin(_size, keepSize), newSize) * sizeof(T));
+ }
+ delete []_items;
+ _items = newBuffer;
+ _size = newSize;
+ }
+
+ CBuffer& operator=(const CBuffer &buffer)
+ {
+ Free();
+ CopyToEmpty(buffer);
+ return *this;
+ }
+};
+
+template <class T>
+bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ size_t size1 = b1.Size();
+ if (size1 != b2.Size())
+ return false;
+ return memcmp(b1, b2, size1 * sizeof(T)) == 0;
+}
+
+template <class T>
+bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ size_t size1 = b1.Size();
+ if (size1 == b2.Size())
+ return false;
+ return memcmp(b1, b2, size1 * sizeof(T)) != 0;
+}
+
+
+typedef CBuffer<char> CCharBuffer;
+typedef CBuffer<wchar_t> CWCharBuffer;
+typedef CBuffer<unsigned char> CByteBuffer;
+
+
+template <class T> class CObjArray
+{
+protected:
+ T *_items;
+private:
+ // we disable constructors
+ CObjArray(const CObjArray &buffer);
+ void operator=(const CObjArray &buffer);
+public:
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ }
+ CObjArray(size_t size): _items(0) { if (size != 0) _items = new T[size]; }
+ CObjArray(): _items(0) {};
+ ~CObjArray() { delete []_items; }
+
+ operator T *() { return _items; };
+ operator const T *() const { return _items; };
+
+ void Alloc(size_t newSize)
+ {
+ delete []_items;
+ _items = 0;
+ _items = new T[newSize];
+ }
+};
+
+typedef CObjArray<unsigned char> CByteArr;
+typedef CObjArray<bool> CBoolArr;
+typedef CObjArray<int> CIntArr;
+
+// #define CRecArray CObjArray
+
+template <class T> class CObjArray2
+{
+// protected:
+ T *_items;
+ unsigned _size;
+
+ CObjArray2(const CObjArray2 &buffer);
+ void operator=(const CObjArray2 &buffer);
+public:
+
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ _size = 0;
+ }
+ CObjArray2(): _items(0), _size(0) {};
+ /*
+ CObjArray2(const CObjArray2 &buffer): _items(0), _size(0)
+ {
+ size_t newSize = buffer._size;
+ if (newSize > 0)
+ {
+ T *newBuffer = new T[newSize];;
+ _items = newBuffer;
+ _size = newSize;
+ const T *src = buffer;
+ for (size_t i = 0; i < newSize; i++)
+ newBuffer[i] = src[i];
+ }
+ }
+ */
+ /*
+ CObjArray2(size_t size): _items(0), _size(0)
+ {
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ }
+ }
+ */
+
+ ~CObjArray2() { delete []_items; }
+
+ operator T *() { return _items; };
+ operator const T *() const { return _items; };
+
+ unsigned Size() const { return (unsigned)_size; }
+ bool IsEmpty() const { return _size == 0; }
+
+ // SetSize doesn't keep old items. It allocates new array if size is not equal
+ void SetSize(unsigned size)
+ {
+ if (size == _size)
+ return;
+ T *newBuffer = NULL;
+ if (size > 0)
+ newBuffer = new T[size];
+ delete []_items;
+ _items = newBuffer;
+ _size = size;
+ }
+
+ /*
+ CObjArray2& operator=(const CObjArray2 &buffer)
+ {
+ Free();
+ size_t newSize = buffer._size;
+ if (newSize > 0)
+ {
+ T *newBuffer = new T[newSize];;
+ _items = newBuffer;
+ _size = newSize;
+ const T *src = buffer;
+ for (size_t i = 0; i < newSize; i++)
+ newBuffer[i] = src[i];
+ }
+ return *this;
+ }
+ */
+};
+
+#endif
diff --git a/CPP/Common/MyCom.h b/CPP/Common/MyCom.h
index 2f00c258..9e2576e3 100755..100644
--- a/CPP/Common/MyCom.h
+++ b/CPP/Common/MyCom.h
@@ -1,9 +1,10 @@
// MyCom.h
-#ifndef __MYCOM_H
-#define __MYCOM_H
+#ifndef __MY_COM_H
+#define __MY_COM_H
#include "MyWindows.h"
+#include "NewHandler.h"
#ifndef RINOK
#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }
@@ -14,14 +15,9 @@ class CMyComPtr
{
T* _p;
public:
- // typedef T _PtrClass;
- CMyComPtr() { _p = NULL;}
- CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
- CMyComPtr(const CMyComPtr<T>& lp)
- {
- if ((_p = lp._p) != NULL)
- _p->AddRef();
- }
+ CMyComPtr(): _p(NULL) {}
+ CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); }
+ CMyComPtr(const CMyComPtr<T>& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); }
~CMyComPtr() { if (_p) _p->Release(); }
void Release() { if (_p) { _p->Release(); _p = NULL; } }
operator T*() const { return (T*)_p; }
@@ -30,7 +26,7 @@ public:
T* operator->() const { return _p; }
T* operator=(T* p)
{
- if (p != 0)
+ if (p)
p->AddRef();
if (_p)
_p->Release();
@@ -40,7 +36,6 @@ public:
T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
bool operator!() const { return (_p == NULL); }
// bool operator==(T* pT) const { return _p == pT; }
- // Compare two objects for equivalence
void Attach(T* p2)
{
Release();
@@ -70,7 +65,7 @@ public:
}
*/
template <class Q>
- HRESULT QueryInterface(REFGUID iid, Q** pp) const
+ HRESULT QueryInterface(REFGUID iid, Q** pp) const throw()
{
return _p->QueryInterface(iid, (void**)pp);
}
@@ -81,13 +76,14 @@ public:
inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)
{
*bstr = ::SysAllocString(src);
- return (*bstr != 0) ? S_OK : E_OUTOFMEMORY;
+ return (*bstr != NULL) ? S_OK : E_OUTOFMEMORY;
}
class CMyComBSTR
{
-public:
BSTR m_str;
+public:
+
CMyComBSTR(): m_str(NULL) {}
CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
@@ -119,7 +115,7 @@ public:
m_str = ::SysAllocString(src);
return *this;
}
- unsigned int Length() const { return ::SysStringLen(m_str); }
+ // unsigned Len() const { return ::SysStringLen(m_str); }
operator BSTR() const { return m_str; }
BSTR* operator&() { return &m_str; }
BSTR MyCopy() const
@@ -143,7 +139,7 @@ public:
::SysFreeString(m_str);
m_str = NULL;
}
- bool operator!() const { return (m_str == NULL); }
+ bool operator!() const { return (m_str == NULL); }
};
//////////////////////////////////////////////////////////
@@ -156,22 +152,22 @@ public:
};
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
- (REFGUID iid, void **outObject) {
+(REFGUID iid, void **outObject) throw() { *outObject = NULL;
-#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
- { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+#define MY_QUERYINTERFACE_ENTRY(i) else if (iid == IID_ ## i) \
+ { *outObject = (void *)(i *)this; }
#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
- { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; }
+ { *outObject = (void *)(IUnknown *)(i *)this; }
#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
MY_QUERYINTERFACE_ENTRY(i)
-#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; AddRef(); return S_OK; }
#define MY_ADDREF_RELEASE \
-STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, AddRef)() throw() { return ++__m_RefCount; } \
STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
return __m_RefCount; delete this; return 0; }
@@ -222,4 +218,25 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
MY_QUERYINTERFACE_ENTRY(i5) \
)
+#define MY_UNKNOWN_IMP6(i1, i2, i3, i4, i5, i6) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ MY_QUERYINTERFACE_ENTRY(i6) \
+ )
+
+#define MY_UNKNOWN_IMP7(i1, i2, i3, i4, i5, i6, i7) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ MY_QUERYINTERFACE_ENTRY(i6) \
+ MY_QUERYINTERFACE_ENTRY(i7) \
+ )
+
#endif
diff --git a/CPP/Common/MyException.h b/CPP/Common/MyException.h
index f0ad1115..f0ad1115 100755..100644
--- a/CPP/Common/MyException.h
+++ b/CPP/Common/MyException.h
diff --git a/CPP/Common/MyGuidDef.h b/CPP/Common/MyGuidDef.h
index 3c52cc07..68745870 100755..100644
--- a/CPP/Common/MyGuidDef.h
+++ b/CPP/Common/MyGuidDef.h
@@ -3,7 +3,7 @@
#ifndef GUID_DEFINED
#define GUID_DEFINED
-#include "Types.h"
+#include "MyTypes.h"
typedef struct {
UInt32 Data1;
diff --git a/CPP/Common/MyInitGuid.h b/CPP/Common/MyInitGuid.h
index d6a48698..d6a48698 100755..100644
--- a/CPP/Common/MyInitGuid.h
+++ b/CPP/Common/MyInitGuid.h
diff --git a/CPP/Common/MyMap.cpp b/CPP/Common/MyMap.cpp
index 0ee11e8c..db95169e 100755..100644
--- a/CPP/Common/MyMap.cpp
+++ b/CPP/Common/MyMap.cpp
@@ -6,7 +6,7 @@
static const unsigned kNumBitsMax = sizeof(UInt32) * 8;
-static UInt32 GetSubBits(UInt32 value, unsigned startPos, unsigned numBits)
+static UInt32 GetSubBits(UInt32 value, unsigned startPos, unsigned numBits) throw()
{
if (startPos == sizeof(value) * 8)
return 0;
@@ -33,7 +33,7 @@ bool CMap32::Find(UInt32 key, UInt32 &valueRes) const
}
}
- int cur = 0;
+ unsigned cur = 0;
unsigned bitPos = kNumBitsMax;
for (;;)
{
@@ -47,7 +47,7 @@ bool CMap32::Find(UInt32 key, UInt32 &valueRes) const
valueRes = n.Values[bit];
return (key == n.Keys[bit]);
}
- cur = (int)n.Keys[bit];
+ cur = (unsigned)n.Keys[bit];
}
}
@@ -74,7 +74,7 @@ bool CMap32::Set(UInt32 key, UInt32 value)
return true;
}
unsigned i = kNumBitsMax - 1;
- for (;GetSubBit(key, i) == GetSubBit(n.Key, i); i--);
+ for (; GetSubBit(key, i) == GetSubBit(n.Key, i); i--);
n.Len = (UInt16)(kNumBitsMax - (1 + i));
unsigned newBit = GetSubBit(key, i);
n.Values[newBit] = value;
@@ -83,7 +83,7 @@ bool CMap32::Set(UInt32 key, UInt32 value)
}
}
- int cur = 0;
+ unsigned cur = 0;
unsigned bitPos = kNumBitsMax;
for (;;)
{
@@ -117,7 +117,7 @@ bool CMap32::Set(UInt32 key, UInt32 value)
return true;
}
unsigned i = bitPos - 1;
- for (;GetSubBit(key, i) == GetSubBit(n.Keys[bit], i); i--);
+ for (; GetSubBit(key, i) == GetSubBit(n.Keys[bit], i); i--);
CNode e2;
@@ -135,6 +135,6 @@ bool CMap32::Set(UInt32 key, UInt32 value)
Nodes.Add(e2);
return false;
}
- cur = (int)n.Keys[bit];
+ cur = (unsigned)n.Keys[bit];
}
}
diff --git a/CPP/Common/MyMap.h b/CPP/Common/MyMap.h
index d0dd43f5..cbcbadd6 100755..100644
--- a/CPP/Common/MyMap.h
+++ b/CPP/Common/MyMap.h
@@ -3,8 +3,8 @@
#ifndef __COMMON_MYMAP_H
#define __COMMON_MYMAP_H
+#include "MyTypes.h"
#include "MyVector.h"
-#include "Types.h"
class CMap32
{
@@ -21,7 +21,7 @@ class CMap32
public:
void Clear() { Nodes.Clear(); }
- bool Find(UInt32 key, UInt32 &valueRes) const;
+ bool Find(UInt32 key, UInt32 &valueRes) const throw();
bool Set(UInt32 key, UInt32 value); // returns true, if there is such key already
};
diff --git a/CPP/Common/MyString.cpp b/CPP/Common/MyString.cpp
index dc254eaf..ac407e87 100755..100644
--- a/CPP/Common/MyString.cpp
+++ b/CPP/Common/MyString.cpp
@@ -4,17 +4,22 @@
#ifdef _WIN32
#include <windows.h>
+#include <wchar.h>
#else
#include <ctype.h>
#endif
-#ifndef _UNICODE
+#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING)
#include "StringConvert.h"
#endif
#include "MyString.h"
-const char* MyStringGetNextCharPointer(const char *p)
+#define MY_STRING_NEW(_T_, _size_) new _T_[_size_]
+// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_)))
+
+/*
+inline const char* MyStringGetNextCharPointer(const char *p) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
return CharNextA(p);
@@ -22,16 +27,17 @@ const char* MyStringGetNextCharPointer(const char *p)
return p + 1;
#endif
}
+*/
int FindCharPosInString(const char *s, char c)
{
- for (const char *p = s;;)
+ for (const char *p = s;; p++)
{
if (*p == c)
return (int)(p - s);
if (*p == 0)
return -1;
- p = MyStringGetNextCharPointer(p);
+ // MyStringGetNextCharPointer(p);
}
}
@@ -46,55 +52,54 @@ int FindCharPosInString(const wchar_t *s, wchar_t c)
}
}
-#ifdef _WIN32
-
-#ifdef _UNICODE
-
-wchar_t MyCharUpper(wchar_t c)
+/*
+void MyStringUpper_Ascii(wchar_t *s)
{
- return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharUpper_Ascii(c);
+ }
}
+*/
-/*
-wchar_t MyCharLower(wchar_t c)
+void MyStringLower_Ascii(wchar_t *s)
{
- return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharLower_Ascii(c);
+ }
}
-char MyCharLower(char c)
-#ifdef UNDER_CE
- { return (char)MyCharLower((wchar_t)c); }
-#else
- { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
-#endif
-*/
+#ifdef _WIN32
-wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
-wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
+#ifdef _UNICODE
+// wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
+// wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
// for WinCE - FString - char
-const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p)
-{
- return p - 1;
-}
+// const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; }
#else
-const char * MyStringGetPrevCharPointer(const char *base, const char *p) { return CharPrevA(base, p); }
-char * MyStringUpper(char *s) { return CharUpperA(s); }
-char * MyStringLower(char *s) { return CharLowerA(s); }
+// const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); }
+// char * MyStringUpper(char *s) { return CharUpperA(s); }
+// char * MyStringLower(char *s) { return CharLowerA(s); }
-wchar_t MyCharUpper(wchar_t c)
+wchar_t MyCharUpper_WIN(wchar_t c)
{
- if (c == 0)
- return 0;
- wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return (wchar_t)(unsigned int)(UINT_PTR)res;
- const int kBufferSize = 4;
- char s[kBufferSize + 1];
- int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
- if (numChars == 0 || numChars > kBufferSize)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
return c;
s[numChars] = 0;
::CharUpperA(s);
@@ -102,24 +107,25 @@ wchar_t MyCharUpper(wchar_t c)
return c;
}
-wchar_t MyCharLower(wchar_t c)
+/*
+wchar_t MyCharLower_WIN(wchar_t c)
{
- if (c == 0)
- return 0;
- wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return (wchar_t)(unsigned int)(UINT_PTR)res;
- const int kBufferSize = 4;
- char s[kBufferSize + 1];
- int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
- if (numChars == 0 || numChars > kBufferSize)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
return c;
s[numChars] = 0;
::CharLowerA(s);
::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
return c;
}
+*/
+/*
wchar_t * MyStringUpper(wchar_t *s)
{
if (s == 0)
@@ -132,7 +138,9 @@ wchar_t * MyStringUpper(wchar_t *s)
MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
return s;
}
+*/
+/*
wchar_t * MyStringLower(wchar_t *s)
{
if (s == 0)
@@ -145,68 +153,127 @@ wchar_t * MyStringLower(wchar_t *s)
MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
return s;
}
+*/
#endif
-#else
+#endif
-wchar_t MyCharUpper(wchar_t c)
+bool IsString1PrefixedByString2(const char *s1, const char *s2)
{
- return toupper(c);
+ for (;;)
+ {
+ unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true;
+ unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false;
+ }
}
-wchar_t * MyStringUpper(wchar_t *s)
+bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2)
{
- if (s == 0)
- return 0;
- for (wchar_t *p = s; *p != 0; p++)
- *p = MyCharUpper(*p);
- return s;
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false;
+ if (c1 == 0) return true;
+ }
}
-/*
-int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+// ---------- ASCII ----------
+
+bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const
{
+ const char *s1 = _chars;
for (;;)
{
- wchar_t c1 = *s1++;
- wchar_t c2 = *s2++;
- wchar_t u1 = MyCharUpper(c1);
- wchar_t u2 = MyCharUpper(c2);
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ char c1 = *s1++;
+ if (MyCharLower_Ascii(c1) !=
+ MyCharLower_Ascii(c2))
+ return false;
+ }
+}
- if (u1 < u2) return -1;
- if (u1 > u2) return 1;
- if (u1 == 0) return 0;
+bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const
+{
+ const wchar_t *s1 = _chars;
+ for (;;)
+ {
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ wchar_t c1 = *s1++;
+ if (MyCharLower_Ascii(c1) !=
+ MyCharLower_Ascii(c2))
+ return false;
}
}
-*/
-#endif
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a)
+{
+ for (;;)
+ {
+ unsigned char c = *a;
+ if (c != *u)
+ return false;
+ if (c == 0)
+ return true;
+ a++;
+ u++;
+ }
+}
-int MyStringCompare(const char *s1, const char *s2)
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2)
{
for (;;)
{
- unsigned char c1 = (unsigned char)*s1++;
- unsigned char c2 = (unsigned char)*s2++;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
- if (c1 == 0) return 0;
+ char c1 = *s1++;
+ char c2 = *s2++;
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
}
}
-int MyStringCompare(const wchar_t *s1, const wchar_t *s2)
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2)
{
for (;;)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
- if (c1 == 0) return 0;
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
+}
+
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2)
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ char c2 = *s2++;
+ if (c1 != c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)))
+ return false;
+ if (c1 == 0)
+ return true;
}
}
+bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2)
+{
+ for (;;)
+ {
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++; if (c1 != c2) return false;
+ }
+}
+
+// NTFS order: uses upper case
int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
{
for (;;)
@@ -224,17 +291,894 @@ int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
}
}
-UString MultiByteToUnicodeString(const AString &srcString, UINT codePage);
-AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage);
+int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num)
+{
+ for (; num != 0; num--)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2)
+ {
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ }
+ if (c1 == 0) return 0;
+ }
+ return 0;
+}
+
+
+// ---------- AString ----------
+
+void AString::InsertSpace(unsigned &index, unsigned size)
+{
+ Grow(size);
+ MoveItems(index + size, index);
+}
+
+void AString::ReAlloc(unsigned newLimit)
+{
+ if (newLimit < _len || newLimit >= 0x20000000) throw 20130220;
+ // MY_STRING_REALLOC(_chars, char, newLimit + 1, _len + 1);
+ char *newBuf = MY_STRING_NEW(char, newLimit + 1);
+ memcpy(newBuf, _chars, (size_t)(_len + 1)); \
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+
+ _limit = newLimit;
+}
+
+void AString::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(char, len + 1);
+ _len = len;
+ _limit = len;
+}
+
+void AString::Grow_1()
+{
+ unsigned next = _len;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+void AString::Grow(unsigned n)
+{
+ unsigned freeSize = _limit - _len;
+ if (n <= freeSize)
+ return;
+
+ unsigned next = _len + n;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+/*
+AString::AString(unsigned num, const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (num > len)
+ num = len;
+ SetStartLen(num);
+ memcpy(_chars, s, num);
+ _chars[num] = 0;
+}
+*/
+
+AString::AString(unsigned num, const AString &s)
+{
+ if (num > s._len)
+ num = s._len;
+ SetStartLen(num);
+ memcpy(_chars, s._chars, num);
+ _chars[num] = 0;
+}
+
+AString::AString(const AString &s, char c)
+{
+ SetStartLen(s.Len() + 1);
+ char *chars = _chars;
+ unsigned len = s.Len();
+ memcpy(chars, s, len);
+ chars[len] = c;
+ chars[len + 1] = 0;
+}
+
+AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2)
+{
+ SetStartLen(num1 + num2);
+ char *chars = _chars;
+ memcpy(chars, s1, num1);
+ memcpy(chars + num1, s2, num2 + 1);
+}
+
+AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); }
+AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); }
+AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); }
+
+AString::AString()
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(char, 4);
+ _len = 0;
+ _limit = 4 - 1;
+ _chars[0] = 0;
+}
+
+AString::AString(char c)
+{
+ SetStartLen(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+}
+
+AString::AString(const char *s)
+{
+ SetStartLen(MyStringLen(s));
+ MyStringCopy(_chars, s);
+}
+
+AString::AString(const AString &s)
+{
+ SetStartLen(s._len);
+ MyStringCopy(_chars, s._chars);
+}
+
+AString &AString::operator=(char c)
+{
+ if (1 > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, 1 + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = 1;
+ }
+ _len = 1;
+ _chars[0] = c;
+ _chars[1] = 0;
+ return *this;
+}
+
+AString &AString::operator=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s);
+ return *this;
+}
+
+AString &AString::operator=(const AString &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s._chars);
+ return *this;
+}
+
+AString &AString::operator+=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ MyStringCopy(_chars + _len, s);
+ _len += len;
+ return *this;
+}
+
+AString &AString::operator+=(const AString &s)
+{
+ Grow(s._len);
+ MyStringCopy(_chars + _len, s._chars);
+ _len += s._len;
+ return *this;
+}
+void AString::SetFrom(const char *s, unsigned len) // no check
+{
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ memcpy(_chars, s, len);
+ _chars[len] = 0;
+ _len = len;
+}
+
+int AString::Find(const AString &s, unsigned startIndex) const
+{
+ if (s.IsEmpty())
+ return startIndex;
+ for (; startIndex < _len; startIndex++)
+ {
+ unsigned j;
+ for (j = 0; j < s._len && startIndex + j < _len; j++)
+ if (_chars[startIndex + j] != s._chars[j])
+ break;
+ if (j == s._len)
+ return (int)startIndex;
+ }
+ return -1;
+}
+
+int AString::ReverseFind(char c) const
+{
+ if (_len == 0)
+ return -1;
+ const char *p = _chars + _len - 1;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--; // p = GetPrevCharPointer(_chars, p);
+ }
+}
+
+void AString::TrimLeft()
+{
+ const char *p = _chars;
+ for (;; p++)
+ {
+ char c = *p;
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ unsigned pos = (unsigned)(p - _chars);
+ if (pos != 0)
+ {
+ MoveItems(0, pos);
+ _len -= pos;
+ }
+}
+
+void AString::TrimRight()
+{
+ const char *p = _chars;
+ int i;
+ for (i = _len - 1; i >= 0; i--)
+ {
+ char c = p[i];
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ i++;
+ if ((unsigned)i != _len)
+ {
+ _chars[i] = 0;
+ _len = i;
+ }
+}
+
+void AString::InsertAtFront(char c)
+{
+ if (_limit == _len)
+ Grow_1();
+ MoveItems(1, 0);
+ _chars[0] = c;
+ _len++;
+}
+
+/*
+void AString::Insert(unsigned index, char c)
+{
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _len++;
+}
+*/
+
+void AString::Insert(unsigned index, const char *s)
+{
+ unsigned num = MyStringLen(s);
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ memcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void AString::Insert(unsigned index, const AString &s)
+{
+ unsigned num = s.Len();
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ memcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void AString::RemoveChar(char ch)
+{
+ int pos = Find(ch);
+ if (pos < 0)
+ return;
+ const char *src = _chars;
+ char *dest = _chars + pos;
+ pos++;
+ unsigned len = _len;
+ for (; (unsigned)pos < len; pos++)
+ {
+ char c = src[(unsigned)pos];
+ if (c != ch)
+ *dest++ = c;
+ }
+ *dest = 0;
+ _len = (unsigned)(dest - _chars);
+}
+
+// !!!!!!!!!!!!!!! test it if newChar = '\0'
+void AString::Replace(char oldChar, char newChar)
+{
+ if (oldChar == newChar)
+ return; // 0;
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ _chars[pos] = newChar;
+ pos++;
+ // number++;
+ }
+ return; // number;
+}
+
+void AString::Replace(const AString &oldString, const AString &newString)
+{
+ if (oldString.IsEmpty())
+ return; // 0;
+ if (oldString == newString)
+ return; // 0;
+ unsigned oldLen = oldString.Len();
+ unsigned newLen = newString.Len();
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldLen);
+ Insert(pos, newString);
+ pos += newLen;
+ // number++;
+ }
+ // return number;
+}
+
+void AString::Delete(unsigned index)
+{
+ MoveItems(index, index + 1);
+ _len--;
+}
+
+void AString::Delete(unsigned index, unsigned count)
+{
+ if (index + count > _len)
+ count = _len - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _len -= count;
+ }
+}
+
+void AString::DeleteFrontal(unsigned num)
+{
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _len -= num;
+ }
+}
+
+/*
+AString operator+(const AString &s1, const AString &s2)
+{
+ AString result(s1);
+ result += s2;
+ return result;
+}
+
+AString operator+(const AString &s, const char *chars)
+{
+ AString result(s);
+ result += chars;
+ return result;
+}
+
+AString operator+(const char *chars, const AString &s)
+{
+ AString result(chars);
+ result += s;
+ return result;
+}
+
+AString operator+(const AString &s, char c)
+{
+ AString result(s);
+ result += c;
+ return result;
+}
+*/
+
+/*
+AString operator+(char c, const AString &s)
+{
+ AString result(c);
+ result += s;
+ return result;
+}
+*/
+
+
+
+
+// ---------- UString ----------
+
+void UString::InsertSpace(unsigned index, unsigned size)
+{
+ Grow(size);
+ MoveItems(index + size, index);
+}
+
+void UString::ReAlloc(unsigned newLimit)
+{
+ if (newLimit < _len || newLimit >= 0x20000000) throw 20130221;
+ // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, _len + 1);
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, newLimit + 1);
+ wmemcpy(newBuf, _chars, _len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+
+ _limit = newLimit;
+}
+
+void UString::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(wchar_t, len + 1);
+ _len = len;
+ _limit = len;
+}
+
+void UString::Grow_1()
+{
+ unsigned next = _len;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+void UString::Grow(unsigned n)
+{
+ unsigned freeSize = _limit - _len;
+ if (n <= freeSize)
+ return;
+
+ unsigned next = _len + n;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+
+UString::UString(unsigned num, const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (num > len)
+ num = len;
+ SetStartLen(num);
+ wmemcpy(_chars, s, num);
+ _chars[num] = 0;
+}
+
+
+UString::UString(unsigned num, const UString &s)
+{
+ if (num > s._len)
+ num = s._len;
+ SetStartLen(num);
+ wmemcpy(_chars, s._chars, num);
+ _chars[num] = 0;
+}
+
+UString::UString(const UString &s, wchar_t c)
+{
+ SetStartLen(s.Len() + 1);
+ wchar_t *chars = _chars;
+ unsigned len = s.Len();
+ wmemcpy(chars, s, len);
+ chars[len] = c;
+ chars[len + 1] = 0;
+}
+
+UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2)
+{
+ SetStartLen(num1 + num2);
+ wchar_t *chars = _chars;
+ wmemcpy(chars, s1, num1);
+ wmemcpy(chars + num1, s2, num2 + 1);
+}
+
+UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); }
+UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); }
+UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); }
+
+UString::UString()
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(wchar_t, 4);
+ _len = 0;
+ _limit = 4 - 1;
+ _chars[0] = 0;
+}
+
+UString::UString(wchar_t c)
+{
+ SetStartLen(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+}
+
+UString::UString(const wchar_t *s)
+{
+ SetStartLen(MyStringLen(s));
+ MyStringCopy(_chars, s);
+}
+
+UString::UString(const UString &s)
+{
+ SetStartLen(s._len);
+ MyStringCopy(_chars, s._chars);
+}
+
+UString &UString::operator=(wchar_t c)
+{
+ if (1 > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = 1;
+ }
+ _len = 1;
+ _chars[0] = c;
+ _chars[1] = 0;
+ return *this;
+}
+
+UString &UString::operator=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s);
+ return *this;
+}
+
+UString &UString::operator=(const UString &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s._chars);
+ return *this;
+}
+
+UString &UString::operator+=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ MyStringCopy(_chars + _len, s);
+ _len += len;
+ return *this;
+}
+
+UString &UString::operator+=(const UString &s)
+{
+ Grow(s._len);
+ MyStringCopy(_chars + _len, s._chars);
+ _len += s._len;
+ return *this;
+}
+
+void UString::SetFrom(const wchar_t *s, unsigned len) // no check
+{
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ wmemcpy(_chars, s, len);
+ _chars[len] = 0;
+ _len = len;
+}
+
+void UString::SetFromAscii(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ wchar_t *chars = _chars;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = s[i];
+ chars[len] = 0;
+ _len = len;
+}
+
+void UString::AddAsciiStr(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ wchar_t *chars = _chars + _len;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = s[i];
+ chars[len] = 0;
+ _len += len;
+}
+
+
+
+int UString::Find(const UString &s, unsigned startIndex) const
+{
+ if (s.IsEmpty())
+ return startIndex;
+ for (; startIndex < _len; startIndex++)
+ {
+ unsigned j;
+ for (j = 0; j < s._len && startIndex + j < _len; j++)
+ if (_chars[startIndex + j] != s._chars[j])
+ break;
+ if (j == s._len)
+ return (int)startIndex;
+ }
+ return -1;
+}
+
+int UString::ReverseFind(wchar_t c) const
+{
+ if (_len == 0)
+ return -1;
+ const wchar_t *p = _chars + _len - 1;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--;
+ }
+}
+
+void UString::TrimLeft()
+{
+ const wchar_t *p = _chars;
+ for (;; p++)
+ {
+ wchar_t c = *p;
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ unsigned pos = (unsigned)(p - _chars);
+ if (pos != 0)
+ {
+ MoveItems(0, pos);
+ _len -= pos;
+ }
+}
+
+void UString::TrimRight()
+{
+ const wchar_t *p = _chars;
+ int i;
+ for (i = _len - 1; i >= 0; i--)
+ {
+ wchar_t c = p[i];
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ i++;
+ if ((unsigned)i != _len)
+ {
+ _chars[i] = 0;
+ _len = i;
+ }
+}
+
+void UString::InsertAtFront(wchar_t c)
+{
+ if (_limit == _len)
+ Grow_1();
+ MoveItems(1, 0);
+ _chars[0] = c;
+ _len++;
+}
+
+/*
+void UString::Insert(unsigned index, wchar_t c)
+{
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _len++;
+}
+*/
+
+void UString::Insert(unsigned index, const wchar_t *s)
+{
+ unsigned num = MyStringLen(s);
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ wmemcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void UString::Insert(unsigned index, const UString &s)
+{
+ unsigned num = s.Len();
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ wmemcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void UString::RemoveChar(wchar_t ch)
+{
+ int pos = Find(ch);
+ if (pos < 0)
+ return;
+ const wchar_t *src = _chars;
+ wchar_t *dest = _chars + pos;
+ pos++;
+ unsigned len = _len;
+ for (; (unsigned)pos < len; pos++)
+ {
+ wchar_t c = src[(unsigned)pos];
+ if (c != ch)
+ *dest++ = c;
+ }
+ *dest = 0;
+ _len = (unsigned)(dest - _chars);
+}
+
+// !!!!!!!!!!!!!!! test it if newChar = '\0'
+void UString::Replace(wchar_t oldChar, wchar_t newChar)
+{
+ if (oldChar == newChar)
+ return; // 0;
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ _chars[pos] = newChar;
+ pos++;
+ // number++;
+ }
+ return; // number;
+}
+
+void UString::Replace(const UString &oldString, const UString &newString)
+{
+ if (oldString.IsEmpty())
+ return; // 0;
+ if (oldString == newString)
+ return; // 0;
+ unsigned oldLen = oldString.Len();
+ unsigned newLen = newString.Len();
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldLen);
+ Insert(pos, newString);
+ pos += newLen;
+ // number++;
+ }
+ // return number;
+}
+
+void UString::Delete(unsigned index)
+{
+ MoveItems(index, index + 1);
+ _len--;
+}
+
+void UString::Delete(unsigned index, unsigned count)
+{
+ if (index + count > _len)
+ count = _len - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _len -= count;
+ }
+}
+
+void UString::DeleteFrontal(unsigned num)
+{
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _len -= num;
+ }
+}
+
+
+// ----------------------------------------
+
+/*
int MyStringCompareNoCase(const char *s1, const char *s2)
{
- return MyStringCompareNoCase(MultiByteToUnicodeString(s1, CP_ACP), MultiByteToUnicodeString(s2, CP_ACP));
+ return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
}
+*/
static inline UINT GetCurrentCodePage()
{
- #if defined(UNDER_CE) || !defined(defined)
+ #if defined(UNDER_CE) || !defined(_WIN32)
return CP_ACP;
#else
return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
@@ -243,6 +1187,8 @@ static inline UINT GetCurrentCodePage()
#ifdef USE_UNICODE_FSTRING
+#ifndef _UNICODE
+
AString fs2fas(CFSTR s)
{
return UnicodeStringToMultiByte(s, GetCurrentCodePage());
@@ -253,6 +1199,8 @@ FString fas2fs(const AString &s)
return MultiByteToUnicodeString(s, GetCurrentCodePage());
}
+#endif
+
#else
UString fs2us(const FString &s)
diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h
index 0312bac6..b70e9a54 100755..100644
--- a/CPP/Common/MyString.h
+++ b/CPP/Common/MyString.h
@@ -5,552 +5,468 @@
#include <string.h>
-#include "Types.h"
+#ifndef _WIN32
+#include <wctype.h>
+#include <wchar.h>
+#endif
+
+#include "MyTypes.h"
#include "MyVector.h"
-template <class T>
-inline int MyStringLen(const T *s)
+inline unsigned MyStringLen(const char *s)
+{
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
+ return i;
+}
+
+inline void MyStringCopy(char *dest, const char *src)
+{
+ while ((*dest++ = *src++) != 0);
+}
+
+inline char *MyStpCpy(char *dest, const char *src)
+{
+ for (;;)
+ {
+ Byte c = *src;
+ *dest = c;
+ if (c == 0)
+ return dest;
+ src++;
+ dest++;
+ }
+}
+
+inline unsigned MyStringLen(const wchar_t *s)
{
- int i;
- for (i = 0; s[i] != '\0'; i++);
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
return i;
}
-template <class T>
-inline void MyStringCopy(T *dest, const T *src)
+inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
{
while ((*dest++ = *src++) != 0);
}
-int FindCharPosInString(const char *s, char c);
-int FindCharPosInString(const wchar_t *s, wchar_t c);
+int FindCharPosInString(const char *s, char c) throw();
+int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
-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); }
+#ifdef _WIN32
+ #ifndef _UNICODE
+ #define STRING_UNICODE_THROW
+ #endif
+#endif
-wchar_t MyCharUpper(wchar_t c);
-// wchar_t MyCharLower(wchar_t c);
+#ifndef STRING_UNICODE_THROW
+ #define STRING_UNICODE_THROW throw()
+#endif
-char *MyStringUpper(char *s);
-char *MyStringLower(char *s);
+/*
+inline char MyCharUpper_Ascii(char c)
+{
+ if (c >= 'a' && c <= 'z')
+ return (char)(c - 0x20);
+ return c;
+}
+inline wchar_t MyCharUpper_Ascii(wchar_t c)
+{
+ if (c >= 'a' && c <= 'z')
+ return (wchar_t)(c - 0x20);
+ return c;
+}
+*/
-wchar_t *MyStringUpper(wchar_t *s);
-wchar_t *MyStringLower(wchar_t *s);
+inline char MyCharLower_Ascii(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return (char)(c + 0x20);
+ return c;
+}
-const char* MyStringGetNextCharPointer(const char *p);
-const char* MyStringGetPrevCharPointer(const char *base, const char *p);
+inline wchar_t MyCharLower_Ascii(wchar_t c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return (wchar_t)(c + 0x20);
+ return c;
+}
-//////////////////////////////////////
-// Compare
+wchar_t MyCharUpper_WIN(wchar_t c) throw();
-int MyStringCompare(const char *s1, const char *s2);
-int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
+inline wchar_t MyCharUpper(wchar_t c) throw()
+{
+ if (c < 'a') return c;
+ if (c <= 'z') return (wchar_t)(c - 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharUpper_WIN(c);
+ #endif
+ #else
+ return (wchar_t)towupper(c);
+ #endif
+}
-int MyStringCompareNoCase(const char *s1, const char *s2);
-int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
+/*
+wchar_t MyCharLower_WIN(wchar_t c) throw();
-template <class T>
-class CStringBase
+inline wchar_t MyCharLower(wchar_t c) throw()
{
- 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);
- }
+ if (c < 'A') return c;
+ if (c <= 'Z') return (wchar_t)(c + 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharLower_WIN(c);
+ #endif
+ #else
+ return (wchar_t)tolower(c);
+ #endif
+}
+*/
- }
- void MoveItems(int destIndex, int srcIndex)
+// char *MyStringUpper(char *s) throw();
+// char *MyStringLower(char *s) throw();
+
+// void MyStringUpper_Ascii(wchar_t *s) throw();
+void MyStringLower_Ascii(wchar_t *s) throw();
+// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW;
+// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW;
+
+bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw();
+
+bool IsString1PrefixedByString2(const char *s1, const char *s2) throw();
+bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw();
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
+int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
+
+// ---------- ASCII ----------
+// char values in ASCII strings must be less then 128
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw();
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw();
+
+#define MY_STRING_DELETE(_p_) delete []_p_;
+// #define MY_STRING_DELETE(_p_) my_delete(_p_);
+
+class AString
+{
+ char *_chars;
+ unsigned _len;
+ unsigned _limit;
+
+ void MoveItems(unsigned dest, unsigned src)
{
- memmove(_chars + destIndex, _chars + srcIndex,
- sizeof(T) * (_length - srcIndex + 1));
+ memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char));
}
- void InsertSpace(int &index, int size)
- {
- CorrectIndex(index);
- GrowLength(size);
- MoveItems(index + size, index);
- }
-
- static const T *GetNextCharPointer(const T *p)
- { return MyStringGetNextCharPointer(p); }
- static const T *GetPrevCharPointer(const T *base, const T *p)
- { return MyStringGetPrevCharPointer(base, p); }
-protected:
- T *_chars;
- int _length;
- int _capacity;
+ void InsertSpace(unsigned &index, unsigned size);
- void SetCapacity(int newCapacity)
- {
- int realCapacity = newCapacity + 1;
- if (realCapacity == _capacity)
- return;
- /*
- const int kMaxStringSize = 0x20000000;
- if (newCapacity > kMaxStringSize || newCapacity < _length)
- throw 1052337;
- */
- T *newBuffer = new T[realCapacity];
- if (_capacity > 0)
- {
- for (int i = 0; i < _length; i++)
- newBuffer[i] = _chars[i];
- delete []_chars;
- }
- _chars = newBuffer;
- _chars[_length] = 0;
- _capacity = realCapacity;
- }
+ void ReAlloc(unsigned newLimit);
+ void SetStartLen(unsigned len);
+ void Grow_1();
+ void Grow(unsigned n);
- 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);
- }
+ // AString(unsigned num, const char *s);
+ AString(unsigned num, const AString &s);
+ AString(const AString &s, char c); // it's for String + char
+ AString(const char *s1, unsigned num1, const char *s2, unsigned num2);
- void CorrectIndex(int &index) const
- {
- if (index > _length)
- index = _length;
- }
+ friend AString operator+(const AString &s, char c) { return AString(s, c); } ;
+ // friend AString operator+(char c, const AString &s); // is not supported
+
+ friend AString operator+(const AString &s1, const AString &s2);
+ friend AString operator+(const AString &s1, const char *s2);
+ friend AString operator+(const char *s1, const AString &s2);
public:
- CStringBase(): _chars(0), _length(0), _capacity(0) { SetCapacity(3); }
- CStringBase(T c): _chars(0), _length(0), _capacity(0)
- {
- SetCapacity(1);
- _chars[0] = c;
- _chars[1] = 0;
- _length = 1;
- }
- CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
- {
- int length = MyStringLen(chars);
- SetCapacity(length);
- MyStringCopy(_chars, chars); // can be optimized by memove()
- _length = length;
- }
- CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0)
- {
- SetCapacity(s._length);
- MyStringCopy(_chars, s._chars);
- _length = s._length;
- }
- ~CStringBase() { delete []_chars; }
+ AString();
+ AString(char c);
+ AString(const char *s);
+ AString(const AString &s);
+ ~AString() { MY_STRING_DELETE(_chars); }
- operator const T*() const { return _chars;}
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ void Empty() { _len = 0; _chars[0] = 0; }
- T Back() const { return _chars[_length - 1]; }
+ operator const char *() const { return _chars; }
+ const char *Ptr() const { return _chars; }
+ const char *Ptr(unsigned pos) const { return _chars + pos; }
+ const char *RightPtr(unsigned num) const { return _chars + _len - num; }
+ char Back() const { return _chars[_len - 1]; }
+
+ void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
// The minimum size of the character buffer in characters.
// This value does not include space for a null terminator.
- T* GetBuffer(int minBufLength)
+ char *GetBuffer(unsigned minBufLen)
{
- if (minBufLength >= _capacity)
- SetCapacity(minBufLength);
+ if (minBufLen > _limit)
+ ReAlloc(minBufLen);
return _chars;
}
void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
- void ReleaseBuffer(int newLength)
- {
- /*
- if (newLength >= _capacity)
- throw 282217;
- */
- _chars[newLength] = 0;
- _length = newLength;
- }
+ void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
+
+ AString &operator=(char c);
+ AString &operator=(const char *s);
+ AString &operator=(const AString &s);
- CStringBase& operator=(T c)
+ AString &operator+=(char c)
{
- Empty();
- SetCapacity(1);
- _chars[0] = c;
- _chars[1] = 0;
- _length = 1;
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ char *chars = _chars;
+ chars[len++] = c;
+ chars[len] = 0;
+ _len = len;
return *this;
}
- CStringBase& operator=(const T *chars)
+
+ AString &operator+=(const char *s);
+ AString &operator+=(const AString &s);
+
+ void SetFrom(const char *s, unsigned len); // no check
+ // AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
+ AString Left(unsigned count) const { return AString(count, *this); }
+
+ // void MakeUpper() { MyStringUpper(_chars); }
+ // void MakeLower() { MyStringLower(_chars); }
+
+
+ // int Compare(const char *s) const { return MyStringCompare(_chars, s); }
+ // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
+ // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
+ // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
+ bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
+ bool IsPrefixedBy_Ascii_NoCase(const char *s) const;
+
+ int Find(char c) const { return FindCharPosInString(_chars, c); }
+ int Find(char c, unsigned startIndex) const
{
- Empty();
- int length = MyStringLen(chars);
- SetCapacity(length);
- MyStringCopy(_chars, chars);
- _length = length;
- return *this;
+ int pos = FindCharPosInString(_chars + startIndex, c);
+ return pos < 0 ? -1 : (int)startIndex + pos;
}
- CStringBase& operator=(const CStringBase& s)
+ int ReverseFind(char c) const throw();
+ int Find(const AString &s) const { return Find(s, 0); }
+ int Find(const AString &s, unsigned startIndex) const throw();
+
+ void TrimLeft() throw();
+ void TrimRight() throw();
+ void Trim()
{
- if (&s == this)
- return *this;
- Empty();
- SetCapacity(s._length);
- MyStringCopy(_chars, s._chars);
- _length = s._length;
- return *this;
+ TrimRight();
+ TrimLeft();
}
+
+ void InsertAtFront(char c);
+ // void Insert(unsigned index, char c);
+ void Insert(unsigned index, const char *s);
+ void Insert(unsigned index, const AString &s);
+
+ void RemoveChar(char ch) throw();
+ void Replace(char oldChar, char newChar) throw();
+ void Replace(const AString &oldString, const AString &newString);
- 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)
+ void Delete(unsigned index) throw();
+ void Delete(unsigned index, unsigned count) throw();
+ void DeleteFrontal(unsigned num) throw();
+ void DeleteBack() { _chars[--_len] = 0; }
+ void DeleteFrom(unsigned index)
{
- GrowLength(s._length);
- MyStringCopy(_chars + _length, s._chars);
- _length += s._length;
- return *this;
- }
- void Empty()
- {
- _length = 0;
- _chars[0] = 0;
+ if (index < _len)
+ {
+ _len = index;
+ _chars[index] = 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);
- }
+bool operator<(const AString &s1, const AString &s2);
+bool operator>(const AString &s1, const AString &s2);
- void MakeUpper() { MyStringUpper(_chars); }
- void MakeLower() { MyStringLower(_chars); }
+/*
+bool operator==(const AString &s1, const AString &s2);
+bool operator==(const AString &s1, const char *s2);
+bool operator==(const char *s1, const AString &s2);
- int Compare(const CStringBase& s) const
- { return MyStringCompare(_chars, s._chars); }
+bool operator!=(const AString &s1, const AString &s2);
+bool operator!=(const AString &s1, const char *s2);
+bool operator!=(const char *s1, const AString &s2);
+*/
- int Compare(const T *s) const
- { return MyStringCompare(_chars, s); }
+inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
+inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; }
+inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
- int CompareNoCase(const CStringBase& s) const
- { return MyStringCompareNoCase(_chars, s._chars); }
+inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
+inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; }
+inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
- 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 FindCharPosInString(_chars, c); }
- int Find(T c, int startIndex) const
- {
- int pos = FindCharPosInString(_chars + startIndex, c);
- return pos < 0 ? -1 : pos + startIndex;
- }
- 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;
- const 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;
- }
+class UString
+{
+ wchar_t *_chars;
+ unsigned _len;
+ unsigned _limit;
- void TrimLeft(T c)
- {
- const T *p = _chars;
- while (c == *p)
- p = GetNextCharPointer(p);
- Delete(0, p - _chars);
- }
- private:
- CStringBase GetTrimDefaultCharSet()
+ void MoveItems(unsigned dest, unsigned src)
{
- CStringBase<T> charSet;
- charSet += (T)' ';
- charSet += (T)'\n';
- charSet += (T)'\t';
- return charSet;
+ memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t));
}
- public:
+
+ void InsertSpace(unsigned index, unsigned size);
+
+ void ReAlloc(unsigned newLimit);
+ void SetStartLen(unsigned len);
+ void Grow_1();
+ void Grow(unsigned n);
+
+ UString(unsigned num, const wchar_t *s); // for Mid
+ UString(unsigned num, const UString &s); // for Left
+ UString(const UString &s, wchar_t c); // it's for String + char
+ UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2);
+
+ friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ;
+ // friend UString operator+(wchar_t c, const UString &s); // is not supported
+
+ friend UString operator+(const UString &s1, const UString &s2);
+ friend UString operator+(const UString &s1, const wchar_t *s2);
+ friend UString operator+(const wchar_t *s1, const UString &s2);
+
+public:
+ UString();
+ UString(wchar_t c);
+ UString(const wchar_t *s);
+ UString(const UString &s);
+ ~UString() { MY_STRING_DELETE(_chars); }
- void TrimLeft()
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ void Empty() { _len = 0; _chars[0] = 0; }
+
+ operator const wchar_t *() const { return _chars; }
+ const wchar_t *Ptr() const { return _chars; }
+ const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
+ const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
+ wchar_t Back() const { return _chars[_len - 1]; }
+
+ void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
+
+ // The minimum size of the character buffer in characters.
+ // This value does not include space for a null terminator.
+ wchar_t *GetBuffer(unsigned minBufLen)
{
- TrimLeftWithCharSet(GetTrimDefaultCharSet());
+ if (minBufLen > _limit)
+ ReAlloc(minBufLen);
+ return _chars;
}
- void TrimRight()
+ void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
+ void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
+
+ UString &operator=(wchar_t c);
+ UString &operator=(const wchar_t *s);
+ UString &operator=(const UString &s);
+
+ UString &operator+=(wchar_t c)
{
- TrimRightWithCharSet(GetTrimDefaultCharSet());
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ wchar_t *chars = _chars;
+ chars[len++] = c;
+ chars[len] = 0;
+ _len = len;
+ return *this;
}
- void TrimRight(T c)
+
+ UString &operator+=(const wchar_t *s);
+ UString &operator+=(const UString &s);
+
+ void SetFrom(const wchar_t *s, unsigned len); // no check
+
+ void SetFromAscii(const char *s);
+ void AddAsciiStr(const char *s);
+
+ UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
+ UString Left(unsigned count) const { return UString(count, *this); }
+
+ // void MakeUpper() { MyStringUpper(_chars); }
+ // void MakeUpper() { MyStringUpper_Ascii(_chars); }
+ // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); }
+ void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
+
+ bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
+ bool IsEqualToNoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
+ int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
+ // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); }
+ // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); }
+ // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
+ bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); };
+ bool IsPrefixedBy_Ascii_NoCase(const char *s) const;
+
+ int Find(wchar_t c) const { return FindCharPosInString(_chars, c); }
+ int Find(wchar_t c, unsigned startIndex) const
{
- const T *p = _chars;
- const T *pLast = NULL;
- while (*p != 0)
- {
- if (*p == c)
- {
- if (pLast == NULL)
- pLast = p;
- }
- else
- pLast = NULL;
- p = GetNextCharPointer(p);
- }
- if (pLast != NULL)
- {
- int i = pLast - _chars;
- Delete(i, _length - i);
- }
+ int pos = FindCharPosInString(_chars + startIndex, c);
+ return pos < 0 ? -1 : (int)startIndex + pos;
}
+ int Find(const UString &s) const { return Find(s, 0); }
+ int Find(const UString &s, unsigned startIndex) const throw();
+ int ReverseFind(wchar_t c) const throw();
+
+ void TrimLeft() throw();
+ void TrimRight() throw();
void Trim()
{
TrimRight();
TrimLeft();
}
- int Insert(int index, T c)
- {
- InsertSpace(index, 1);
- _chars[index] = c;
- _length++;
- return _length;
- }
- int Insert(int index, const CStringBase &s)
- {
- CorrectIndex(index);
- if (s.IsEmpty())
- return _length;
- int numInsertChars = s.Length();
- InsertSpace(index, numInsertChars);
- for (int i = 0; i < numInsertChars; i++)
- _chars[index + i] = s[i];
- _length += numInsertChars;
- return _length;
- }
+ void InsertAtFront(wchar_t c);
+ // void Insert(unsigned index, wchar_t c);
+ void Insert(unsigned index, const wchar_t *s);
+ void Insert(unsigned index, const UString &s);
- // !!!!!!!!!!!!!!! test it if newChar = '\0'
- int Replace(T oldChar, T newChar)
- {
- if (oldChar == newChar)
- return 0;
- int number = 0;
- int pos = 0;
- while (pos < Length())
- {
- pos = Find(oldChar, pos);
- if (pos < 0)
- break;
- _chars[pos] = newChar;
- pos++;
- number++;
- }
- return number;
- }
- int Replace(const CStringBase &oldString, const CStringBase &newString)
- {
- if (oldString.IsEmpty())
- return 0;
- if (oldString == newString)
- return 0;
- int oldStringLength = oldString.Length();
- int newStringLength = newString.Length();
- int number = 0;
- int pos = 0;
- while (pos < _length)
- {
- pos = Find(oldString, pos);
- if (pos < 0)
- break;
- Delete(pos, oldStringLength);
- Insert(pos, newString);
- pos += newStringLength;
- number++;
- }
- return number;
- }
- int Delete(int index, int count = 1)
+ void RemoveChar(wchar_t ch) throw();
+ void Replace(wchar_t oldChar, wchar_t newChar) throw();
+ void Replace(const UString &oldString, const UString &newString);
+
+ void Delete(unsigned index) throw();
+ void Delete(unsigned index, unsigned count) throw();
+ void DeleteFrontal(unsigned num) throw();
+ void DeleteBack() { _chars[--_len] = 0; }
+ void DeleteFrom(unsigned index)
{
- if (index + count > _length)
- count = _length - index;
- if (count > 0)
+ if (index < _len)
{
- MoveItems(index, index + count);
- _length -= count;
+ _len = index;
+ _chars[index] = 0;
}
- return _length;
}
- void DeleteBack() { Delete(_length - 1); }
};
-template <class T>
-CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
-{
- CStringBase<T> result(s1);
- result += s2;
- return result;
-}
-
-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); }
+bool operator<(const UString &s1, const UString &s2);
+bool operator>(const UString &s1, const UString &s2);
-template <class T>
-bool operator!=(const T *s1, const CStringBase<T>& s2)
- { return (s2.Compare(s1) != 0); }
+inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
+inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
+inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
-template <class T>
-bool operator!=(const CStringBase<T>& s1, const T *s2)
- { return (s1.Compare(s2) != 0); }
+inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
+inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
+inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
-typedef CStringBase<char> AString;
-typedef CStringBase<wchar_t> UString;
typedef CObjectVector<AString> AStringVector;
typedef CObjectVector<UString> UStringVector;
diff --git a/CPP/Common/MyTypes.h b/CPP/Common/MyTypes.h
new file mode 100644
index 00000000..4f52a01d
--- /dev/null
+++ b/CPP/Common/MyTypes.h
@@ -0,0 +1,30 @@
+// Common/MyTypes.h
+
+#ifndef __COMMON_MY_TYPES_H
+#define __COMMON_MY_TYPES_H
+
+#include "../../C/7zTypes.h"
+
+typedef int HRes;
+
+struct CBoolPair
+{
+ bool Val;
+ bool Def;
+
+ CBoolPair(): Val(false), Def(false) {}
+
+ void Init()
+ {
+ Val = false;
+ Def = false;
+ }
+
+ void SetTrueTrue()
+ {
+ Val = true;
+ Def = true;
+ }
+};
+
+#endif
diff --git a/CPP/Common/MyUnknown.h b/CPP/Common/MyUnknown.h
index e9e8666b..e9e8666b 100755..100644
--- a/CPP/Common/MyUnknown.h
+++ b/CPP/Common/MyUnknown.h
diff --git a/CPP/Common/MyVector.cpp b/CPP/Common/MyVector.cpp
index 3b531768..0b1baf45 100755..100644
--- a/CPP/Common/MyVector.cpp
+++ b/CPP/Common/MyVector.cpp
@@ -1,87 +1,3 @@
// 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/CPP/Common/MyVector.h b/CPP/Common/MyVector.h
index 781b648b..0d060a93 100755..100644
--- a/CPP/Common/MyVector.h
+++ b/CPP/Common/MyVector.h
@@ -1,92 +1,247 @@
-// Common/Vector.h
+// Common/MyVector.h
-#ifndef __COMMON_VECTOR_H
-#define __COMMON_VECTOR_H
+#ifndef __COMMON_MY_VECTOR_H
+#define __COMMON_MY_VECTOR_H
-#include "Defs.h"
-
-class CBaseRecordVector
+template <class T>
+class CRecordVector
{
- void MoveItems(int destIndex, int srcIndex);
-protected:
- int _capacity;
- int _size;
- void *_items;
- size_t _itemSize;
+ T *_items;
+ unsigned _size;
+ unsigned _capacity;
- 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();
-};
+ void MoveItems(unsigned destIndex, unsigned srcIndex)
+ {
+ memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * (size_t)sizeof(T));
+ }
+
+ void ReserveOnePosition()
+ {
+ if (_size == _capacity)
+ {
+ unsigned newCapacity = _capacity + (_capacity >> 2) + 1;
+ T *p = new T[newCapacity];
+ memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
+ }
+ }
-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)
+
+ CRecordVector(): _items(0), _size(0), _capacity(0) {}
+
+ CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0)
+ {
+ unsigned size = v.Size();
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ _capacity = size;
+ memcpy(_items, v._items, (size_t)size * (size_t)sizeof(T));
+ }
+ }
+
+ unsigned Size() const { return _size; }
+ bool IsEmpty() const { return _size == 0; }
+
+ void ConstructReserve(unsigned size)
+ {
+ if (size != 0)
+ {
+ _items = new T[size];
+ _capacity = size;
+ }
+ }
+
+ void Reserve(unsigned newCapacity)
+ {
+ if (newCapacity > _capacity)
+ {
+ T *p = new T[newCapacity];
+ memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
+ }
+ }
+
+ void ClearAndReserve(unsigned newCapacity)
{
Clear();
- return (*this += v);
+ if (newCapacity > _capacity)
+ {
+ delete []_items;
+ _items = NULL;
+ _capacity = 0;
+ _items = new T[newCapacity];
+ _capacity = newCapacity;
+ }
+ }
+
+ void ClearAndSetSize(unsigned newSize)
+ {
+ ClearAndReserve(newSize);
+ _size = newSize;
+ }
+
+ void ChangeSize_KeepData(unsigned newSize)
+ {
+ if (newSize > _capacity)
+ {
+ T *p = new T[newSize];
+ memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newSize;
+ }
+ _size = newSize;
+ }
+
+ void ReserveDown()
+ {
+ if (_size == _capacity)
+ return;
+ T *p = NULL;
+ if (_size != 0)
+ {
+ p = new T[_size];
+ memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
+ }
+ delete []_items;
+ _items = p;
+ _capacity = _size;
+ }
+
+ ~CRecordVector() { delete []_items; }
+
+ void ClearAndFree()
+ {
+ delete []_items;
+ _items = NULL;
+ _size = 0;
+ _capacity = 0;
+ }
+
+ void Clear() { _size = 0; }
+
+ void DeleteBack() { _size--; }
+
+ void DeleteFrom(unsigned index)
+ {
+ // if (index <= _size)
+ _size = index;
+ }
+
+ void DeleteFrontal(unsigned num)
+ {
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _size -= num;
+ }
+ }
+
+ void Delete(unsigned index)
+ {
+ MoveItems(index, index + 1);
+ _size -= 1;
+ }
+
+ /*
+ void Delete(unsigned index, unsigned num)
+ {
+ if (num > 0)
+ {
+ MoveItems(index, index + num);
+ _size -= num;
+ }
+ }
+ */
+
+ CRecordVector& operator=(const CRecordVector &v)
+ {
+ unsigned size = v.Size();
+ if (size > _capacity)
+ {
+ delete []_items;
+ _capacity = 0;
+ _size = 0;
+ _items = NULL;
+ _items = new T[size];
+ _capacity = size;
+ }
+ _size = size;
+ memcpy(_items, v._items, (size_t)size * (size_t)sizeof(T));
+ return *this;
}
+
CRecordVector& operator+=(const CRecordVector &v)
{
- int size = v.Size();
- Reserve(Size() + size);
- for (int i = 0; i < size; i++)
- Add(v[i]);
+ unsigned size = v.Size();
+ Reserve(_size + size);
+ memcpy(_items + _size, v._items, (size_t)size * (size_t)sizeof(T));
+ _size += size;
return *this;
}
- int Add(T item)
+
+ unsigned Add(const T item)
{
ReserveOnePosition();
- ((T *)_items)[_size] = item;
+ _items[_size] = item;
return _size++;
}
- void Insert(int index, T item)
+
+ void AddInReserved(const T item)
{
- InsertOneItem(index);
- ((T *)_items)[index] = item;
+ _items[_size++] = item;
}
- // T* GetPointer() const { return (T*)_items; }
- // operator const T *() const { return _items; };
- const T& operator[](int index) const { return ((T *)_items)[index]; }
- T& operator[](int index) { return ((T *)_items)[index]; }
- const T& Front() const { return operator[](0); }
- T& Front() { return operator[](0); }
- const T& Back() const { return operator[](_size - 1); }
- T& Back() { return operator[](_size - 1); }
- void Swap(int i, int j)
+ void Insert(unsigned index, const T item)
{
- T temp = operator[](i);
- operator[](i) = operator[](j);
- operator[](j) = temp;
+ ReserveOnePosition();
+ MoveItems(index + 1, index);
+ _items[index] = item;
+ _size++;
}
- int FindInSorted(const T& item, int left, int right) const
+ void MoveToFront(unsigned index)
+ {
+ if (index != 0)
+ {
+ T temp = _items[index];
+ memmove(_items + 1, _items, (size_t)index * (size_t)sizeof(T));
+ _items[0] = temp;
+ }
+ }
+
+ const T& operator[](unsigned index) const { return _items[index]; }
+ T& operator[](unsigned index) { return _items[index]; }
+ const T& Front() const { return _items[0]; }
+ T& Front() { return _items[0]; }
+ const T& Back() const { return _items[_size - 1]; }
+ T& Back() { return _items[_size - 1]; }
+
+ /*
+ void Swap(unsigned i, unsigned j)
+ {
+ T temp = _items[i];
+ _items[i] = _items[j];
+ _items[j] = temp;
+ }
+ */
+
+ int FindInSorted(const T item, unsigned left, unsigned right) const
{
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T midVal = (*this)[mid];
+ if (item == midVal)
return mid;
- if (item < midValue)
+ if (item < midVal)
right = mid;
else
left = mid + 1;
@@ -94,16 +249,16 @@ public:
return -1;
}
- int FindInSorted(const T& item) const
+ int FindInSorted2(const T &item, unsigned left, unsigned right) const
{
- int left = 0, right = Size();
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
return mid;
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -111,16 +266,45 @@ public:
return -1;
}
- int AddToUniqueSorted(const T& item)
+ int FindInSorted(const T item) const
+ {
+ return FindInSorted(item, 0, _size);
+ }
+
+ int FindInSorted2(const T &item) const
+ {
+ return FindInSorted2(item, 0, _size);
+ }
+
+ unsigned AddToUniqueSorted(const T item)
+ {
+ unsigned left = 0, right = _size;
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T midVal = (*this)[mid];
+ if (item == midVal)
+ return mid;
+ if (item < midVal)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ unsigned AddToUniqueSorted2(const T &item)
{
- int left = 0, right = Size();
+ unsigned left = 0, right = _size;
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
return mid;
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -129,12 +313,12 @@ public:
return right;
}
- static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param)
+ static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param)
{
T temp = p[k];
for (;;)
{
- int s = (k << 1);
+ unsigned s = (k << 1);
if (s > size)
break;
if (s < size && compare(p + s + 1, p + s, param) > 0)
@@ -149,12 +333,12 @@ public:
void Sort(int (*compare)(const T*, const T*, void *), void *param)
{
- int size = _size;
+ unsigned size = _size;
if (size <= 1)
return;
T* p = (&Front()) - 1;
{
- int i = size / 2;
+ unsigned i = size >> 1;
do
SortRefDown(p, i, size, compare, param);
while (--i != 0);
@@ -168,6 +352,46 @@ public:
}
while (size > 1);
}
+
+ static void SortRefDown2(T* p, unsigned k, unsigned size)
+ {
+ T temp = p[k];
+ for (;;)
+ {
+ unsigned s = (k << 1);
+ if (s > size)
+ break;
+ if (s < size && p[s + 1].Compare(p[s]) > 0)
+ s++;
+ if (temp.Compare(p[s]) >= 0)
+ break;
+ p[k] = p[s];
+ k = s;
+ }
+ p[k] = temp;
+ }
+
+ void Sort2()
+ {
+ unsigned size = _size;
+ if (size <= 1)
+ return;
+ T* p = (&Front()) - 1;
+ {
+ unsigned i = size >> 1;
+ do
+ SortRefDown2(p, i, size);
+ while (--i != 0);
+ }
+ do
+ {
+ T temp = p[size];
+ p[size--] = p[1];
+ p[1] = temp;
+ SortRefDown2(p, 1, size);
+ }
+ while (size > 1);
+ }
};
typedef CRecordVector<int> CIntVector;
@@ -177,76 +401,197 @@ typedef CRecordVector<unsigned char> CByteVector;
typedef CRecordVector<void *> CPointerVector;
template <class T>
-class CObjectVector: public CPointerVector
+class CObjectVector
{
+ CPointerVector _v;
public:
+ unsigned Size() const { return _v.Size(); }
+ bool IsEmpty() const { return _v.IsEmpty(); }
+ void ReserveDown() { _v.ReserveDown(); }
+ // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); }
+ void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); }
+
CObjectVector() {};
- ~CObjectVector() { Clear(); };
- CObjectVector(const CObjectVector &v): CPointerVector() { *this = v; }
+ CObjectVector(const CObjectVector &v)
+ {
+ unsigned size = v.Size();
+ _v.ConstructReserve(size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
+ }
CObjectVector& operator=(const CObjectVector &v)
{
Clear();
- return (*this += v);
+ unsigned size = v.Size();
+ _v.Reserve(size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
+ return *this;
}
+
CObjectVector& operator+=(const CObjectVector &v)
{
- int size = v.Size();
- Reserve(Size() + size);
- for (int i = 0; i < size; i++)
- Add(v[i]);
+ unsigned size = v.Size();
+ _v.Reserve(Size() + size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
return *this;
}
- const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
- T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
- T& Front() { return operator[](0); }
+
+ const T& operator[](unsigned index) const { return *((T *)_v[index]); }
+ T& operator[](unsigned index) { return *((T *)_v[index]); }
const T& Front() const { return operator[](0); }
- T& Back() { return operator[](_size - 1); }
- const T& Back() const { return operator[](_size - 1); }
- int Add(const T& item) { return CPointerVector::Add(new T(item)); }
- void Insert(int index, const T& item) { CPointerVector::Insert(index, new T(item)); }
- virtual void Delete(int index, int num = 1)
+ T& Front() { return operator[](0); }
+ const T& Back() const { return operator[](_v.Size() - 1); }
+ T& Back() { return operator[](_v.Size() - 1); }
+
+ void MoveToFront(unsigned index) { _v.MoveToFront(index); }
+
+ unsigned Add(const T& item) { return _v.Add(new T(item)); }
+
+ void AddInReserved(const T& item) { _v.AddInReserved(new T(item)); }
+
+ T& AddNew()
+ {
+ T *p = new T;
+ _v.Add(p);
+ return *p;
+ }
+
+ T& AddNewInReserved()
+ {
+ T *p = new T;
+ _v.AddInReserved(p);
+ return *p;
+ }
+
+ void Insert(unsigned index, const T& item) { _v.Insert(index, new T(item)); }
+
+ T& InsertNew(unsigned index)
+ {
+ T *p = new T;
+ _v.Insert(index, p);
+ return *p;
+ }
+
+ ~CObjectVector()
+ {
+ for (unsigned i = _v.Size(); i != 0;)
+ delete (T *)_v[--i];
+ }
+
+ void ClearAndFree()
+ {
+ Clear();
+ _v.ClearAndFree();
+ }
+
+ void Clear()
+ {
+ for (unsigned i = _v.Size(); i != 0;)
+ delete (T *)_v[--i];
+ _v.Clear();
+ }
+
+ void DeleteFrom(unsigned index)
+ {
+ unsigned size = _v.Size();
+ for (unsigned i = index; i < size; i++)
+ delete (T *)_v[i];
+ _v.DeleteFrom(index);
+ }
+
+ void DeleteFrontal(unsigned num)
+ {
+ for (unsigned i = 0; i < num; i++)
+ delete (T *)_v[i];
+ _v.DeleteFrontal(num);
+ }
+
+ void DeleteBack()
{
- TestIndexAndCorrectNum(index, num);
- for (int i = 0; i < num; i++)
- delete (T *)(((void **)_items)[index + i]);
- CPointerVector::Delete(index, num);
+ delete (T *)_v[_v.Size() - 1];
+ _v.DeleteBack();
}
+
+ void Delete(unsigned index)
+ {
+ delete (T *)_v[index];
+ _v.Delete(index);
+ }
+
+ /*
+ void Delete(unsigned index, unsigned num)
+ {
+ for (unsigned i = 0; i < num; i++)
+ delete (T *)_v[index + i];
+ _v.Delete(index, num);
+ }
+ */
+
+ /*
int Find(const T& item) const
{
- for (int i = 0; i < Size(); i++)
+ unsigned size = Size();
+ for (unsigned i = 0; i < size; i++)
if (item == (*this)[i])
return i;
return -1;
}
+ */
+
int FindInSorted(const T& item) const
{
- int left = 0, right = Size();
+ unsigned left = 0, right = Size();
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
return mid;
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
}
return -1;
}
- int AddToSorted(const T& item)
+
+ unsigned AddToUniqueSorted(const T& item)
{
- int left = 0, right = Size();
+ unsigned left = 0, right = Size();
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ return mid;
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ /*
+ unsigned AddToSorted(const T& item)
+ {
+ unsigned left = 0, right = Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
{
right = mid + 1;
break;
}
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -254,13 +599,17 @@ public:
Insert(right, item);
return right;
}
+ */
void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
- { CPointerVector::Sort(compare, param); }
+ { _v.Sort(compare, param); }
static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
- { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
- void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }
+ { return (*(*((const T **)a1))).Compare(*(*((const T **)a2))); }
+
+ void Sort() { _v.Sort(CompareObjectItems, 0); }
};
+#define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++)
+
#endif
diff --git a/CPP/Common/MyWindows.cpp b/CPP/Common/MyWindows.cpp
index f940fc8a..1d9b1e61 100755..100644
--- a/CPP/Common/MyWindows.cpp
+++ b/CPP/Common/MyWindows.cpp
@@ -28,7 +28,7 @@ BSTR SysAllocStringByteLen(LPCSTR psz, UINT len)
BSTR bstr = (BSTR)((UINT *)p + 1);
if (psz)
{
- memmove(bstr, psz, len);
+ memcpy(bstr, psz, len);
Byte *pb = ((Byte *)bstr) + len;
for (unsigned i = 0; i < sizeof(OLECHAR) * 2; i++)
pb[i] = 0;
@@ -36,6 +36,22 @@ BSTR SysAllocStringByteLen(LPCSTR psz, UINT len)
return bstr;
}
+BSTR SysAllocStringLen(const OLECHAR *sz, UINT len)
+{
+ int realLen = sizeof(UINT) + len * sizeof(OLECHAR) + sizeof(OLECHAR);
+ void *p = AllocateForBSTR(realLen);
+ if (p == 0)
+ return 0;
+ *(UINT *)p = len * sizeof(OLECHAR);
+ BSTR bstr = (BSTR)((UINT *)p + 1);
+ if (sz)
+ {
+ memcpy(bstr, sz, len * sizeof(OLECHAR));
+ bstr[len] = 0;
+ }
+ return bstr;
+}
+
BSTR SysAllocString(const OLECHAR *sz)
{
if (sz == 0)
@@ -45,9 +61,9 @@ BSTR SysAllocString(const OLECHAR *sz)
void *p = AllocateForBSTR(len + sizeof(UINT));
if (p == 0)
return 0;
- *(UINT *)p = strLen;
+ *(UINT *)p = strLen * sizeof(OLECHAR);
BSTR bstr = (BSTR)((UINT *)p + 1);
- memmove(bstr, sz, len);
+ memcpy(bstr, sz, len);
return bstr;
}
@@ -77,7 +93,7 @@ HRESULT VariantClear(VARIANTARG *prop)
return S_OK;
}
-HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src)
+HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src)
{
HRESULT res = ::VariantClear(dest);
if (res != S_OK)
diff --git a/CPP/Common/MyWindows.h b/CPP/Common/MyWindows.h
index 780e1f5d..139a4e8b 100755..100644
--- a/CPP/Common/MyWindows.h
+++ b/CPP/Common/MyWindows.h
@@ -7,6 +7,11 @@
#include <windows.h>
+#ifdef UNDER_CE
+ #undef VARIANT_TRUE
+ #define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#endif
+
#else
#include <stddef.h> // for wchar_t
@@ -14,6 +19,8 @@
#include "MyGuidDef.h"
+#define WINAPI
+
typedef char CHAR;
typedef unsigned char UCHAR;
@@ -145,8 +152,6 @@ typedef WORD PROPVAR_PAD1;
typedef WORD PROPVAR_PAD2;
typedef WORD PROPVAR_PAD3;
-#ifdef __cplusplus
-
typedef struct tagPROPVARIANT
{
VARTYPE vt;
@@ -177,7 +182,7 @@ typedef tagVARIANT VARIANT;
typedef VARIANT VARIANTARG;
MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
-MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src);
typedef struct tagSTATPROPSTG
{
@@ -186,9 +191,8 @@ typedef struct tagSTATPROPSTG
VARTYPE vt;
} STATPROPSTG;
-#endif
-
MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocStringLen(const OLECHAR *sz, UINT len);
MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
MY_EXTERN_C void SysFreeString(BSTR bstr);
MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
@@ -199,6 +203,7 @@ MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
#define CP_ACP 0
#define CP_OEMCP 1
+#define CP_UTF8 65001
typedef enum tagSTREAM_SEEK
{
diff --git a/CPP/Common/MyXml.cpp b/CPP/Common/MyXml.cpp
index 8aa9ce8c..31e7b3df 100755..100644
--- a/CPP/Common/MyXml.cpp
+++ b/CPP/Common/MyXml.cpp
@@ -18,52 +18,19 @@ static bool IsSpaceChar(char c)
return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A);
}
-#define SKIP_SPACES(s, pos) while (IsSpaceChar(s[pos])) pos++;
+#define SKIP_SPACES(s) while (IsSpaceChar(*s)) s++;
-static bool ReadProperty(const AString &s, int &pos, CXmlProp &prop)
+int CXmlItem::FindProp(const AString &propName) const
{
- 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++)
+ FOR_VECTOR (i, Props)
if (Props[i].Name == propName)
return i;
return -1;
}
-AString CXmlItem::GetPropertyValue(const AString &propName) const
+AString CXmlItem::GetPropVal(const AString &propName) const
{
- int index = FindProperty(propName);
+ int index = FindProp(propName);
if (index >= 0)
return Props[index].Value;
return AString();
@@ -76,7 +43,7 @@ bool CXmlItem::IsTagged(const AString &tag) const
int CXmlItem::FindSubTag(const AString &tag) const
{
- for (int i = 0; i < SubItems.Size(); i++)
+ FOR_VECTOR (i, SubItems)
if (SubItems[i].IsTagged(tag))
return i;
return -1;
@@ -93,6 +60,17 @@ AString CXmlItem::GetSubString() const
return AString();
}
+const AString * CXmlItem::GetSubStringPtr() const
+{
+ if (SubItems.Size() == 1)
+ {
+ const CXmlItem &item = SubItems[0];
+ if (!item.IsTag)
+ return &item.Name;
+ }
+ return NULL;
+}
+
AString CXmlItem::GetSubStringForTag(const AString &tag) const
{
int index = FindSubTag(tag);
@@ -101,100 +79,169 @@ AString CXmlItem::GetSubStringForTag(const AString &tag) const
return AString();
}
-bool CXmlItem::ParseItems(const AString &s, int &pos, int numAllowedLevels)
+const char * CXmlItem::ParseItem(const char *s, int numAllowedLevels)
{
- if (numAllowedLevels == 0)
- return false;
- SubItems.Clear();
- AString finishString = "</";
+ SKIP_SPACES(s);
+
+ const char *beg = s;
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);
+ char c;
+ c = *s; if (c == 0 || c == '<') break; s++;
+ c = *s; if (c == 0 || c == '<') break; s++;
}
-}
-
-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)
+ if (*s == 0)
+ return NULL;
+ if (s != beg)
{
IsTag = false;
- Name += s.Mid(pos, pos2 - pos);
- pos = pos2;
- return true;
+ Name.SetFrom(beg, (unsigned)(s - beg));
+ return s;
}
+
IsTag = true;
- pos++;
- SKIP_SPACES(s, pos);
+ s++;
+ SKIP_SPACES(s);
- for (; pos < s.Length(); pos++)
- {
- char c = s[pos];
- if (!IsValidChar(c))
+ beg = s;
+ for (;; s++)
+ if (!IsValidChar(*s))
break;
- Name += c;
- }
- if (Name.IsEmpty() || pos == s.Length())
- return false;
+ if (s == beg || *s == 0)
+ return NULL;
+ Name.SetFrom(beg, (unsigned)(s - beg));
- int posTemp = pos;
for (;;)
{
- SKIP_SPACES(s, pos);
- if (s[pos] == '/')
+ beg = s;
+ SKIP_SPACES(s);
+ if (*s == '/')
{
- pos++;
- // SKIP_SPACES(s, pos);
- return (s[pos++] == '>');
+ s++;
+ // SKIP_SPACES(s);
+ if (*s != '>')
+ return NULL;
+ return s + 1;
}
- if (s[pos] == '>')
+ if (*s == '>')
{
- 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;
+ s++;
+ if (numAllowedLevels == 0)
+ return NULL;
+ SubItems.Clear();
+ for (;;)
+ {
+ SKIP_SPACES(s);
+ if (s[0] == '<' && s[1] == '/')
+ break;
+ CXmlItem &item = SubItems.AddNew();
+ s = item.ParseItem(s, numAllowedLevels - 1);
+ if (!s)
+ return NULL;
+ }
+
+ s += 2;
+ unsigned len = Name.Len();
+ for (unsigned i = 0; i < len; i++)
+ if (s[i] != Name[i])
+ return NULL;
+ s += len;
+ if (s[0] != '>')
+ return NULL;
+ return s + 1;
}
- if (posTemp == pos)
- return false;
+ if (beg == s)
+ return NULL;
- CXmlProp prop;
- if (!ReadProperty(s, pos, prop))
- return false;
- Props.Add(prop);
- posTemp = pos;
+ // ReadProperty
+ CXmlProp &prop = Props.AddNew();
+
+ beg = s;
+ for (;; s++)
+ {
+ char c = *s;
+ if (!IsValidChar(c))
+ break;
+ }
+ if (s == beg)
+ return NULL;
+ prop.Name.SetFrom(beg, (unsigned)(s - beg));
+
+ SKIP_SPACES(s);
+ if (*s != '=')
+ return NULL;
+ s++;
+ SKIP_SPACES(s);
+ if (*s != '\"')
+ return NULL;
+ s++;
+
+ beg = s;
+ for (;;)
+ {
+ char c = *s;
+ if (c == 0)
+ return NULL;
+ if (c == '\"')
+ break;
+ s++;
+ }
+ prop.Value.SetFrom(beg, (unsigned)(s - beg));
+ s++;
}
}
-static bool SkipHeader(const AString &s, int &pos, const AString &startString, const AString &endString)
+static bool SkipHeader(const AString &s, int &pos, const char *startString, const char *endString)
{
- SKIP_SPACES(s, pos);
- if (s.Mid(pos, startString.Length()) == startString)
+ while (IsSpaceChar(s[pos]))
+ pos++;
+ if (IsString1PrefixedByString2(s.Ptr(pos), startString))
{
- pos = s.Find(endString, pos);
+ const AString es = endString;
+ pos = s.Find(es, pos);
if (pos < 0)
return false;
- pos += endString.Length();
- SKIP_SPACES(s, pos);
+ pos += es.Len();
}
return true;
}
+void CXmlItem::AppendTo(AString &s) const
+{
+ if (IsTag)
+ s += '<';
+ s += Name;
+ if (IsTag)
+ {
+ FOR_VECTOR (i, Props)
+ {
+ const CXmlProp &prop = Props[i];
+ s += ' ';
+ s += prop.Name;
+ s += '=';
+ s += '\"';
+ s += prop.Value;
+ s += '\"';
+ }
+ s += '>';
+ }
+ FOR_VECTOR (i, SubItems)
+ {
+ const CXmlItem &item = SubItems[i];
+ if (i != 0 && !SubItems[i - 1].IsTag)
+ s += ' ';
+ item.AppendTo(s);
+ }
+ if (IsTag)
+ {
+ s += '<';
+ s += '/';
+ s += Name;
+ s += '>';
+ }
+}
+
bool CXml::Parse(const AString &s)
{
int pos = 0;
@@ -202,8 +249,14 @@ bool CXml::Parse(const AString &s)
return false;
if (!SkipHeader(s, pos, "<!DOCTYPE", ">"))
return false;
- if (!Root.ParseItem(s, pos, 1000))
+ const char *ptr = Root.ParseItem(s.Ptr(pos), 1000);
+ if (!ptr || !Root.IsTag)
return false;
- SKIP_SPACES(s, pos);
- return (pos == s.Length() && Root.IsTag);
+ SKIP_SPACES(ptr);
+ return *ptr == 0;
+}
+
+void CXml::AppendTo(AString &s) const
+{
+ Root.AppendTo(s);
}
diff --git a/CPP/Common/MyXml.h b/CPP/Common/MyXml.h
index c6e8829a..ae3663c3 100755..100644
--- a/CPP/Common/MyXml.h
+++ b/CPP/Common/MyXml.h
@@ -1,7 +1,7 @@
// MyXml.h
-#ifndef __MYXML_H
-#define __MYXML_H
+#ifndef __MY_XML_H
+#define __MY_XML_H
#include "MyString.h"
@@ -13,28 +13,31 @@ struct CXmlProp
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;
+ const char * ParseItem(const char *s, int numAllowedLevels);
+
+ bool IsTagged(const AString &tag) const throw();
+ int FindProp(const AString &propName) const throw();
+ AString GetPropVal(const AString &propName) const;
AString GetSubString() const;
- int FindSubTag(const AString &tag) const;
+ const AString * GetSubStringPtr() const throw();
+ int FindSubTag(const AString &tag) const throw();
AString GetSubStringForTag(const AString &tag) const;
+
+ void AppendTo(AString &s) const;
};
struct CXml
{
CXmlItem Root;
+
bool Parse(const AString &s);
+ void AppendTo(AString &s) const;
};
#endif
diff --git a/CPP/Common/NewHandler.cpp b/CPP/Common/NewHandler.cpp
index aad6e7d1..410f24e9 100755..100644
--- a/CPP/Common/NewHandler.cpp
+++ b/CPP/Common/NewHandler.cpp
@@ -11,6 +11,32 @@
#ifndef DEBUG_MEMORY_LEAK
#ifdef _WIN32
+
+/*
+void * my_new(size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void my_delete(void *p) throw()
+{
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
+ ::free(p);
+}
+
+void * my_Realloc(void *p, size_t newSize, size_t oldSize)
+{
+ void *newBuf = my_new(newSize);
+ memcpy(newBuf, p, oldSize);
+ my_delete(p);
+ return newBuf;
+}
+*/
+
void *
#ifdef _MSC_VER
__cdecl
@@ -30,18 +56,42 @@ __cdecl
#endif
operator delete(void *p) throw()
{
- /*
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
+ ::free(p);
+}
+
+/*
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new[](size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
if (p == 0)
- return;
- ::HeapFree(::GetProcessHeap(), 0, p);
- */
+ throw CNewException();
+ return p;
+}
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete[](void *p) throw()
+{
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
::free(p);
}
+*/
+
#endif
#else
-#pragma init_seg(lib)
+#include <stdio.h>
+
+// #pragma init_seg(lib)
const int kDebugSize = 1000000;
static void *a[kDebugSize];
static int index = 0;
@@ -51,10 +101,6 @@ void * __cdecl operator new(size_t size)
{
numAllocs++;
void *p = HeapAlloc(GetProcessHeap(), 0, size);
- if (index == 40)
- {
- int t = 1;
- }
if (index < kDebugSize)
{
a[index] = p;
diff --git a/CPP/Common/NewHandler.h b/CPP/Common/NewHandler.h
index 215ba05f..e3e7422c 100755..100644
--- a/CPP/Common/NewHandler.h
+++ b/CPP/Common/NewHandler.h
@@ -1,16 +1,68 @@
// Common/NewHandler.h
-#ifndef __COMMON_NEWHANDLER_H
-#define __COMMON_NEWHANDLER_H
+#ifndef __COMMON_NEW_HANDLER_H
+#define __COMMON_NEW_HANDLER_H
+
+/*
+This file must be included before any code that uses operators "delete" or "new".
+Also you must compile and link "NewHandler.cpp", if you use MSVC 6.0.
+The operator "new" in MSVC 6.0 doesn't throw exception "bad_alloc".
+So we define another version of operator "new" that throws "CNewException" on failure.
+
+If you use compiler that throws exception in "new" operator (GCC or new version of MSVC),
+you can compile without "NewHandler.cpp". So standard exception "bad_alloc" will be used.
+
+It's still allowed to use redefined version of operator "new" from "NewHandler.cpp"
+with any compiler. 7-Zip's code can work with "bad_alloc" and "CNewException" exceptions.
+But if you use some additional code (outside of 7-Zip's code), you must check
+that redefined version of operator "new" (that throws CNewException) is not
+problem for your code.
+
+Also we declare delete(void *p) throw() that creates smaller code.
+*/
+
class CNewException {};
+#ifdef WIN32
+// We can compile my_new and my_delete with _fastcall
+/*
+void * my_new(size_t size);
+void my_delete(void *p) throw();
+// void * my_Realloc(void *p, size_t newSize, size_t oldSize);
+*/
+#endif
+
#ifdef _WIN32
+
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new(size_t size);
+
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete(void *p) throw();
+
+#endif
+
+/*
+#ifdef _WIN32
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new[](size_t size);
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete[](void *p) throw();
#endif
+*/
#endif
diff --git a/CPP/Common/Random.cpp b/CPP/Common/Random.cpp
index 4bd3fcf9..4bd3fcf9 100755..100644
--- a/CPP/Common/Random.cpp
+++ b/CPP/Common/Random.cpp
diff --git a/CPP/Common/Random.h b/CPP/Common/Random.h
index ffef20d1..ffef20d1 100755..100644
--- a/CPP/Common/Random.h
+++ b/CPP/Common/Random.h
diff --git a/CPP/Common/Sha256Reg.cpp b/CPP/Common/Sha256Reg.cpp
new file mode 100644
index 00000000..6adb3cdc
--- /dev/null
+++ b/CPP/Common/Sha256Reg.cpp
@@ -0,0 +1,52 @@
+// Sha256Reg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/Sha256.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/ICoder.h"
+#include "../7zip/Common/RegisterCodec.h"
+
+class CSha256Hasher:
+ public IHasher,
+ public CMyUnknownImp
+{
+ CSha256 _sha;
+public:
+ CSha256Hasher() { Init(); };
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD_(void, Init)();
+ STDMETHOD_(void, Update)(const void *data, UInt32 size);
+ STDMETHOD_(void, Final)(Byte *digest);
+ STDMETHOD_(UInt32, GetDigestSize)();
+};
+
+STDMETHODIMP_(void) CSha256Hasher::Init()
+{
+ Sha256_Init(&_sha);
+}
+
+STDMETHODIMP_(void) CSha256Hasher::Update(const void *data, UInt32 size)
+{
+ Sha256_Update(&_sha, (const Byte *)data, size);
+}
+
+STDMETHODIMP_(void) CSha256Hasher::Final(Byte *digest)
+{
+ Sha256_Final(&_sha, digest);
+}
+
+STDMETHODIMP_(UInt32) CSha256Hasher::GetDigestSize()
+{
+ return SHA256_DIGEST_SIZE;
+}
+
+static IHasher *CreateHasher() { return new CSha256Hasher; }
+
+static CHasherInfo g_HasherInfo = { CreateHasher, 0xA, L"SHA256", SHA256_DIGEST_SIZE };
+
+REGISTER_HASHER(Sha256)
diff --git a/CPP/Common/StdAfx.h b/CPP/Common/StdAfx.h
index b8ba1d5c..420f5c32 100755..100644
--- a/CPP/Common/StdAfx.h
+++ b/CPP/Common/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-// #include "MyWindows.h"
-#include "NewHandler.h"
+#include "Common.h"
#endif
diff --git a/CPP/Common/StdInStream.cpp b/CPP/Common/StdInStream.cpp
index f3dcb85f..2d28c735 100755..100644
--- a/CPP/Common/StdInStream.cpp
+++ b/CPP/Common/StdInStream.cpp
@@ -8,12 +8,6 @@
#include "StringConvert.h"
#include "UTFConvert.h"
-#ifdef _MSC_VER
-// "was declared deprecated" disabling
-#pragma warning(disable : 4996 )
-#endif
-
-static const char kIllegalChar = '\0';
static const char kNewLineChar = '\n';
static const char *kEOFMessage = "Unexpected end of input stream";
@@ -42,11 +36,6 @@ bool CStdInStream::Close()
return !_streamIsOpen;
}
-CStdInStream::~CStdInStream()
-{
- Close();
-}
-
AString CStdInStream::ScanStringUntilNewLine(bool allowEOF)
{
AString s;
@@ -59,8 +48,8 @@ AString CStdInStream::ScanStringUntilNewLine(bool allowEOF)
break;
throw kEOFMessage;
}
- char c = char(intChar);
- if (c == kIllegalChar)
+ char c = (char)intChar;
+ if (c == 0)
throw kIllegalCharMessage;
if (c == kNewLineChar)
break;
@@ -88,7 +77,7 @@ void CStdInStream::ReadToString(AString &resultString)
resultString.Empty();
int c;
while ((c = GetChar()) != EOF)
- resultString += char(c);
+ resultString += (char)c;
}
bool CStdInStream::Eof()
@@ -103,5 +92,3 @@ int CStdInStream::GetChar()
throw kReadErrorMessage;
return c;
}
-
-
diff --git a/CPP/Common/StdInStream.h b/CPP/Common/StdInStream.h
index 0d182cc3..6d9ed670 100755..100644
--- a/CPP/Common/StdInStream.h
+++ b/CPP/Common/StdInStream.h
@@ -1,29 +1,30 @@
// Common/StdInStream.h
-#ifndef __COMMON_STDINSTREAM_H
-#define __COMMON_STDINSTREAM_H
+#ifndef __COMMON_STD_IN_STREAM_H
+#define __COMMON_STD_IN_STREAM_H
#include <stdio.h>
#include "MyString.h"
-#include "Types.h"
+#include "MyTypes.h"
class CStdInStream
{
- bool _streamIsOpen;
FILE *_stream;
+ bool _streamIsOpen;
public:
- CStdInStream(): _streamIsOpen(false) {};
- CStdInStream(FILE *stream): _streamIsOpen(false), _stream(stream) {};
- ~CStdInStream();
- bool Open(LPCTSTR fileName);
- bool Close();
+ CStdInStream(): _stream(0), _streamIsOpen(false) {};
+ CStdInStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
+ ~CStdInStream() { Close(); }
+
+ bool Open(LPCTSTR fileName) throw();
+ bool Close() throw();
AString ScanStringUntilNewLine(bool allowEOF = false);
void ReadToString(AString &resultString);
UString ScanUStringUntilNewLine();
- bool Eof();
+ bool Eof() throw();
int GetChar();
};
diff --git a/CPP/Common/StdOutStream.cpp b/CPP/Common/StdOutStream.cpp
index 061a7606..1d6d81a4 100755..100644
--- a/CPP/Common/StdOutStream.cpp
+++ b/CPP/Common/StdOutStream.cpp
@@ -9,19 +9,14 @@
#include "StringConvert.h"
#include "UTFConvert.h"
-#ifdef _MSC_VER
-// "was declared deprecated" disabling
-#pragma warning(disable : 4996 )
-#endif
-
static const char kNewLineChar = '\n';
static const char *kFileOpenMode = "wt";
extern int g_CodePage;
-CStdOutStream g_StdOut(stdout);
-CStdOutStream g_StdErr(stderr);
+CStdOutStream g_StdOut(stdout);
+CStdOutStream g_StdErr(stderr);
bool CStdOutStream::Open(const char *fileName)
{
@@ -47,14 +42,9 @@ bool CStdOutStream::Flush()
return (fflush(_stream) == 0);
}
-CStdOutStream::~CStdOutStream ()
-{
- Close();
-}
-
-CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream &))
+CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*func)(CStdOutStream &))
{
- (*aFunction)(*this);
+ (*func)(*this);
return *this;
}
@@ -83,22 +73,48 @@ CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)
return *this;
}
+void CStdOutStream::PrintUString(const UString &s, AString &temp)
+{
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
+ *this << (const char *)temp;
+}
+
CStdOutStream & CStdOutStream::operator<<(char c)
{
fputc(c, _stream);
return *this;
}
-CStdOutStream & CStdOutStream::operator<<(int number)
+CStdOutStream & CStdOutStream::operator<<(Int32 number)
+{
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
+}
+
+CStdOutStream & CStdOutStream::operator<<(Int64 number)
+{
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
+}
+
+CStdOutStream & CStdOutStream::operator<<(UInt32 number)
{
- char textString[32];
- ConvertInt64ToString(number, textString);
- return operator<<(textString);
+ char s[16];
+ ConvertUInt32ToString(number, s);
+ return operator<<(s);
}
CStdOutStream & CStdOutStream::operator<<(UInt64 number)
{
- char textString[32];
- ConvertUInt64ToString(number, textString);
- return operator<<(textString);
+ char s[32];
+ ConvertUInt64ToString(number, s);
+ return operator<<(s);
}
diff --git a/CPP/Common/StdOutStream.h b/CPP/Common/StdOutStream.h
index b0b2c615..42f43938 100755..100644
--- a/CPP/Common/StdOutStream.h
+++ b/CPP/Common/StdOutStream.h
@@ -1,33 +1,40 @@
// Common/StdOutStream.h
-#ifndef __COMMON_STDOUTSTREAM_H
-#define __COMMON_STDOUTSTREAM_H
+#ifndef __COMMON_STD_OUT_STREAM_H
+#define __COMMON_STD_OUT_STREAM_H
#include <stdio.h>
-#include "Types.h"
+#include "MyString.h"
+#include "MyTypes.h"
class CStdOutStream
{
- bool _streamIsOpen;
FILE *_stream;
+ bool _streamIsOpen;
public:
- CStdOutStream (): _streamIsOpen(false), _stream(0) {};
- CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {};
- ~CStdOutStream ();
+ CStdOutStream(): _stream(0), _streamIsOpen(false) {};
+ CStdOutStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
+ ~CStdOutStream() { Close(); }
+
operator FILE *() { return _stream; }
- bool Open(const char *fileName);
- bool Close();
- bool Flush();
- CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream &));
- CStdOutStream & operator<<(const char *string);
- CStdOutStream & operator<<(const wchar_t *string);
- CStdOutStream & operator<<(char c);
- CStdOutStream & operator<<(int number);
- CStdOutStream & operator<<(UInt64 number);
+ bool Open(const char *fileName) throw();
+ bool Close() throw();
+ bool Flush() throw();
+
+ CStdOutStream & operator<<(CStdOutStream & (* func)(CStdOutStream &));
+ CStdOutStream & operator<<(const char *s) throw();
+ CStdOutStream & operator<<(char c) throw();
+ CStdOutStream & operator<<(Int32 number) throw();
+ CStdOutStream & operator<<(Int64 number) throw();
+ CStdOutStream & operator<<(UInt32 number) throw();
+ CStdOutStream & operator<<(UInt64 number) throw();
+
+ CStdOutStream & operator<<(const wchar_t *s);
+ void PrintUString(const UString &s, AString &temp);
};
-CStdOutStream & endl(CStdOutStream & outStream);
+CStdOutStream & endl(CStdOutStream & outStream) throw();
extern CStdOutStream g_StdOut;
extern CStdOutStream g_StdErr;
diff --git a/CPP/Common/StringConvert.cpp b/CPP/Common/StringConvert.cpp
index 681895b7..0443a06c 100755..100644
--- a/CPP/Common/StringConvert.cpp
+++ b/CPP/Common/StringConvert.cpp
@@ -15,8 +15,8 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
if (!srcString.IsEmpty())
{
int numChars = MultiByteToWideChar(codePage, 0, srcString,
- srcString.Length(), resultString.GetBuffer(srcString.Length()),
- srcString.Length() + 1);
+ srcString.Len(), resultString.GetBuffer(srcString.Len()),
+ srcString.Len() + 1);
if (numChars == 0)
throw 282228;
resultString.ReleaseBuffer(numChars);
@@ -24,15 +24,83 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
return resultString;
}
+void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage)
+{
+ dest.Empty();
+ if (!srcString.IsEmpty())
+ {
+ wchar_t *destBuf = dest.GetBuffer(srcString.Len());
+ const char *sp = (const char *)srcString;
+ unsigned i;
+ for (i = 0;;)
+ {
+ char c = sp[i];
+ if ((Byte)c >= 0x80 || c == 0)
+ break;
+ destBuf[i++] = (wchar_t)c;
+ }
+
+ if (i != srcString.Len())
+ {
+ unsigned numChars = MultiByteToWideChar(codePage, 0, sp + i,
+ srcString.Len() - i, destBuf + i,
+ srcString.Len() + 1 - i);
+ if (numChars == 0)
+ throw 282228;
+ i += numChars;
+ }
+ dest.ReleaseBuffer(i);
+ }
+}
+
+void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
+{
+ dest.Empty();
+ defaultCharWasUsed = false;
+ if (!s.IsEmpty())
+ {
+ unsigned numRequiredBytes = s.Len() * 2;
+ char *destBuf = dest.GetBuffer(numRequiredBytes);
+ unsigned i;
+ const wchar_t *sp = (const wchar_t *)s;
+ for (i = 0;;)
+ {
+ wchar_t c = sp[i];
+ if (c >= 0x80 || c == 0)
+ break;
+ destBuf[i++] = (char)c;
+ }
+ defaultCharWasUsed = false;
+ if (i != s.Len())
+ {
+ BOOL defUsed;
+ unsigned numChars = WideCharToMultiByte(codePage, 0, sp + i, s.Len() - i,
+ destBuf + i, numRequiredBytes + 1 - i,
+ &defaultChar, &defUsed);
+ defaultCharWasUsed = (defUsed != FALSE);
+ if (numChars == 0)
+ throw 282229;
+ i += numChars;
+ }
+ dest.ReleaseBuffer(i);
+ }
+}
+
+void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage)
+{
+ bool defaultCharWasUsed;
+ UnicodeStringToMultiByte2(dest, srcString, codePage, '_', defaultCharWasUsed);
+}
+
AString UnicodeStringToMultiByte(const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
{
AString dest;
defaultCharWasUsed = false;
if (!s.IsEmpty())
{
- int numRequiredBytes = s.Length() * 2;
+ unsigned numRequiredBytes = s.Len() * 2;
BOOL defUsed;
- int numChars = WideCharToMultiByte(codePage, 0, s, s.Length(),
+ int numChars = WideCharToMultiByte(codePage, 0, s, s.Len(),
dest.GetBuffer(numRequiredBytes), numRequiredBytes + 1,
&defaultChar, &defUsed);
defaultCharWasUsed = (defUsed != FALSE);
@@ -53,7 +121,7 @@ AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
AString SystemStringToOemString(const CSysString &srcString)
{
AString result;
- CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));
+ CharToOem(srcString, result.GetBuffer(srcString.Len() * 2));
result.ReleaseBuffer();
return result;
}
@@ -64,12 +132,12 @@ AString SystemStringToOemString(const CSysString &srcString)
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
{
UString resultString;
- for (int i = 0; i < srcString.Length(); i++)
- resultString += wchar_t(srcString[i]);
+ for (unsigned i = 0; i < srcString.Len(); i++)
+ resultString += (wchar_t)srcString[i];
/*
if (!srcString.IsEmpty())
{
- int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1);
+ int numChars = mbstowcs(resultString.GetBuffer(srcString.Len()), srcString, srcString.Len() + 1);
if (numChars < 0) throw "Your environment does not support UNICODE";
resultString.ReleaseBuffer(numChars);
}
@@ -80,12 +148,12 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
{
AString resultString;
- for (int i = 0; i < srcString.Length(); i++)
- resultString += char(srcString[i]);
+ for (unsigned i = 0; i < srcString.Len(); i++)
+ resultString += (char)srcString[i];
/*
if (!srcString.IsEmpty())
{
- int numRequiredBytes = srcString.Length() * 6 + 1;
+ int numRequiredBytes = srcString.Len() * 6 + 1;
int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);
if (numChars < 0) throw "Your environment does not support UNICODE";
resultString.ReleaseBuffer(numChars);
diff --git a/CPP/Common/StringConvert.h b/CPP/Common/StringConvert.h
index cd737bec..8eea72ef 100755..100644
--- a/CPP/Common/StringConvert.h
+++ b/CPP/Common/StringConvert.h
@@ -3,15 +3,19 @@
#ifndef __COMMON_STRING_CONVERT_H
#define __COMMON_STRING_CONVERT_H
-#include "MyWindows.h"
#include "MyString.h"
-#include "Types.h"
+#include "MyWindows.h"
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+
+// optimized versions that work faster for ASCII strings
+void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage = CP_ACP);
+void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
+void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage);
+
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);
-
inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)
{ return unicodeString; }
inline const UString& GetUnicodeString(const UString &unicodeString)
diff --git a/CPP/Common/StringToInt.cpp b/CPP/Common/StringToInt.cpp
index 15474a42..ea59c0fa 100755..100644
--- a/CPP/Common/StringToInt.cpp
+++ b/CPP/Common/StringToInt.cpp
@@ -4,94 +4,140 @@
#include "StringToInt.h"
-UInt64 ConvertStringToUInt64(const char *s, const char **end)
+static const UInt32 k_UInt32_max = 0xFFFFFFFF;
+static const UInt64 k_UInt64_max = 0xFFFFFFFFFFFFFFFF;
+
+#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType) \
+ uintType ConvertStringTo ## uintType(const charType *s, const charType **end) { \
+ if (end) *end = s; \
+ uintType res = 0; \
+ for (;; s++) { \
+ charType c = *s; \
+ if (c < '0' || c > '9') { if (end) *end = s; return res; } \
+ if (res > (k_ ## uintType ## _max) / 10) return 0; \
+ res *= 10; \
+ unsigned v = (c - '0'); \
+ if (res > (k_ ## uintType ## _max) - v) return 0; \
+ res += v; }}
+
+CONVERT_STRING_TO_UINT_FUNC(UInt32, char)
+CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t)
+CONVERT_STRING_TO_UINT_FUNC(UInt64, char)
+CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t)
+
+Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end)
+{
+ if (end)
+ *end = s;
+ const wchar_t *s2 = s;
+ if (*s == '-')
+ s2++;
+ if (*s2 == 0)
+ return 0;
+ const wchar_t *end2;
+ UInt32 res = ConvertStringToUInt32(s2, &end2);
+ if (*s == '-')
+ {
+ if (res > ((UInt32)1 << (32 - 1)))
+ return 0;
+ }
+ else if ((res & ((UInt32)1 << (32 - 1))) != 0)
+ return 0;
+ if (end)
+ *end = end2;
+ if (*s == '-')
+ return -(Int32)res;
+ return (Int32)res;
+}
+
+UInt32 ConvertOctStringToUInt32(const char *s, const char **end)
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt32 res = 0;
+ for (;; s++)
{
char c = *s;
- if (c < '0' || c > '9')
+ if (c < '0' || c > '7')
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result *= 10;
- result += (c - '0');
- s++;
+ if ((res & (UInt32)7 << (32 - 3)) != 0)
+ return 0;
+ res <<= 3;
+ res |= (unsigned)(c - '0');
}
}
UInt64 ConvertOctStringToUInt64(const char *s, const char **end)
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt64 res = 0;
+ for (;; s++)
{
char c = *s;
if (c < '0' || c > '7')
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result <<= 3;
- result += (c - '0');
- s++;
+ if ((res & (UInt64)7 << (64 - 3)) != 0)
+ return 0;
+ res <<= 3;
+ res |= (unsigned)(c - '0');
}
}
-UInt64 ConvertHexStringToUInt64(const char *s, const char **end)
+UInt32 ConvertHexStringToUInt32(const char *s, const char **end)
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt32 res = 0;
+ for (;; s++)
{
char c = *s;
- UInt32 v;
+ unsigned v;
if (c >= '0' && c <= '9') v = (c - '0');
else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
else
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result <<= 4;
- result |= v;
- s++;
+ if ((res & (UInt32)0xF << (32 - 4)) != 0)
+ return 0;
+ res <<= 4;
+ res |= v;
}
}
-
-UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end)
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end)
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt64 res = 0;
+ for (;; s++)
{
- wchar_t c = *s;
- if (c < '0' || c > '9')
+ char c = *s;
+ unsigned v;
+ if (c >= '0' && c <= '9') v = (c - '0');
+ else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
+ else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
+ else
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result *= 10;
- result += (c - '0');
- s++;
+ if ((res & (UInt64)0xF << (64 - 4)) != 0)
+ return 0;
+ res <<= 4;
+ res |= v;
}
}
-
-
-Int64 ConvertStringToInt64(const char *s, const char **end)
-{
- if (*s == '-')
- return -(Int64)ConvertStringToUInt64(s + 1, end);
- return ConvertStringToUInt64(s, end);
-}
-
-Int64 ConvertStringToInt64(const wchar_t *s, const wchar_t **end)
-{
- if (*s == L'-')
- return -(Int64)ConvertStringToUInt64(s + 1, end);
- return ConvertStringToUInt64(s, end);
-}
diff --git a/CPP/Common/StringToInt.h b/CPP/Common/StringToInt.h
index cd99f17e..5c5d7d7f 100755..100644
--- a/CPP/Common/StringToInt.h
+++ b/CPP/Common/StringToInt.h
@@ -3,14 +3,19 @@
#ifndef __COMMON_STRING_TO_INT_H
#define __COMMON_STRING_TO_INT_H
-#include "Types.h"
+#include "MyTypes.h"
-UInt64 ConvertStringToUInt64(const char *s, const char **end);
-UInt64 ConvertOctStringToUInt64(const char *s, const char **end);
-UInt64 ConvertHexStringToUInt64(const char *s, const char **end);
-UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end);
+UInt32 ConvertStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertStringToUInt64(const char *s, const char **end) throw();
+UInt32 ConvertStringToUInt32(const wchar_t *s, const wchar_t **end) throw();
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) throw();
-Int64 ConvertStringToInt64(const char *s, const char **end);
-Int64 ConvertStringToInt64(const wchar_t *s, const wchar_t **end);
+Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw();
+
+UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw();
+
+UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw();
#endif
diff --git a/CPP/Common/TextConfig.cpp b/CPP/Common/TextConfig.cpp
index 34fedeb8..ad368791 100755..100644
--- a/CPP/Common/TextConfig.cpp
+++ b/CPP/Common/TextConfig.cpp
@@ -3,22 +3,19 @@
#include "StdAfx.h"
#include "TextConfig.h"
-
-#include "Defs.h"
#include "UTFConvert.h"
-static bool IsDelimitChar(char c)
+static inline bool IsDelimitChar(char c)
{
- return (c == ' ' || c == 0x0A || c == 0x0D ||
- c == '\0' || c == '\t');
+ return (c == ' ' || c == 0x0A || c == 0x0D || c == '\0' || c == '\t');
}
-static AString GetIDString(const char *string, int &finishPos)
+static AString GetIDString(const char *s, unsigned &finishPos)
{
AString result;
for (finishPos = 0; ; finishPos++)
{
- char c = string[finishPos];
+ char c = s[finishPos];
if (IsDelimitChar(c) || c == '=')
break;
result += c;
@@ -26,89 +23,78 @@ static AString GetIDString(const char *string, int &finishPos)
return result;
}
-static bool WaitNextLine(const AString &string, int &pos)
+static bool WaitNextLine(const AString &s, unsigned &pos)
{
- for (;pos < string.Length(); pos++)
- if (string[pos] == 0x0A)
+ for (; pos < s.Len(); pos++)
+ if (s[pos] == 0x0A)
return true;
return false;
}
-static bool SkipSpaces(const AString &string, int &pos)
+static bool SkipSpaces(const AString &s, unsigned &pos)
{
- for (;pos < string.Length(); pos++)
+ for (; pos < s.Len(); pos++)
{
- char c = string[pos];
+ char c = s[pos];
if (!IsDelimitChar(c))
{
if (c != ';')
return true;
- if (!WaitNextLine(string, pos))
+ if (!WaitNextLine(s, pos))
return false;
}
}
return false;
}
-bool GetTextConfig(const AString &string, CObjectVector<CTextConfigPair> &pairs)
+bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs)
{
pairs.Clear();
- int pos = 0;
+ unsigned pos = 0;
/////////////////////
// read strings
for (;;)
{
- if (!SkipSpaces(string, pos))
+ if (!SkipSpaces(s, pos))
break;
CTextConfigPair pair;
- int finishPos;
- AString temp = GetIDString(((const char *)string) + pos, finishPos);
+ unsigned finishPos;
+ AString temp = GetIDString(((const char *)s) + pos, finishPos);
if (!ConvertUTF8ToUnicode(temp, pair.ID))
return false;
if (finishPos == 0)
return false;
pos += finishPos;
- if (!SkipSpaces(string, pos))
+ if (!SkipSpaces(s, pos))
return false;
- if (string[pos] != '=')
+ if (s[pos] != '=')
return false;
pos++;
- if (!SkipSpaces(string, pos))
+ if (!SkipSpaces(s, pos))
return false;
- if (string[pos] != '\"')
+ if (s[pos] != '\"')
return false;
pos++;
AString message;
for (;;)
{
- if (pos >= string.Length())
+ if (pos >= s.Len())
return false;
- char c = string[pos++];
+ char c = s[pos++];
if (c == '\"')
break;
if (c == '\\')
{
- char c = string[pos++];
+ char c = s[pos++];
switch(c)
{
- case 'n':
- message += '\n';
- break;
- case 't':
- message += '\t';
- break;
- case '\\':
- message += '\\';
- break;
- case '\"':
- message += '\"';
- break;
- default:
- message += '\\';
- message += c;
- break;
+ case 'n': message += '\n'; break;
+ case 't': message += '\t'; break;
+ case '\\': message += '\\'; break;
+ case '\"': message += '\"'; break;
+ default: message += '\\'; message += c; break;
}
}
else
@@ -123,8 +109,8 @@ bool GetTextConfig(const AString &string, CObjectVector<CTextConfigPair> &pairs)
int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id)
{
- for (int i = 0; i < pairs.Size(); i++)
- if (pairs[i].ID.Compare(id) == 0)
+ FOR_VECTOR (i, pairs)
+ if (pairs[i].ID == id)
return i;
return -1;
}
diff --git a/CPP/Common/TextConfig.h b/CPP/Common/TextConfig.h
index a25142a7..cae4f17a 100755..100644
--- a/CPP/Common/TextConfig.h
+++ b/CPP/Common/TextConfig.h
@@ -1,9 +1,8 @@
// Common/TextConfig.h
-#ifndef __COMMON_TEXTCONFIG_H
-#define __COMMON_TEXTCONFIG_H
+#ifndef __COMMON_TEXT_CONFIG_H
+#define __COMMON_TEXT_CONFIG_H
-#include "MyVector.h"
#include "MyString.h"
struct CTextConfigPair
@@ -14,7 +13,7 @@ struct CTextConfigPair
bool GetTextConfig(const AString &text, CObjectVector<CTextConfigPair> &pairs);
-int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id);
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id) throw();
UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id);
#endif
diff --git a/CPP/Common/Types.h b/CPP/Common/Types.h
deleted file mode 100755
index 9365b327..00000000
--- a/CPP/Common/Types.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Common/Types.h
-
-#ifndef __COMMON_TYPES_H
-#define __COMMON_TYPES_H
-
-#include "../../C/Types.h"
-
-typedef int HRes;
-
-#endif
-
diff --git a/CPP/Common/UTFConvert.cpp b/CPP/Common/UTFConvert.cpp
index 95362430..c4b9404d 100755..100644
--- a/CPP/Common/UTFConvert.cpp
+++ b/CPP/Common/UTFConvert.cpp
@@ -2,18 +2,53 @@
#include "StdAfx.h"
+#include "MyTypes.h"
#include "UTFConvert.h"
-#include "Types.h"
static const Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen)
+bool CheckUTF8(const char *src)
+{
+ for (;;)
+ {
+ Byte c;
+ unsigned numAdds;
+ c = *src++;
+ if (c == 0)
+ return true;
+
+ if (c < 0x80)
+ continue;
+ if (c < 0xC0)
+ return false;
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (c < kUtf8Limits[numAdds])
+ break;
+ UInt32 value = (c - kUtf8Limits[numAdds - 1]);
+
+ do
+ {
+ Byte c2 = *src++;
+ if (c2 < 0x80 || c2 >= 0xC0)
+ return false;
+ value <<= 6;
+ value |= (c2 - 0x80);
+ }
+ while (--numAdds);
+
+ if (value >= 0x110000)
+ return false;
+ }
+}
+
+
+static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen) throw()
{
size_t destPos = 0, srcPos = 0;
for (;;)
{
Byte c;
- int numAdds;
+ unsigned numAdds;
if (srcPos == srcLen)
{
*destLen = destPos;
@@ -46,7 +81,7 @@ static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_
value <<= 6;
value |= (c2 - 0x80);
}
- while (--numAdds != 0);
+ while (--numAdds);
if (value < 0x10000)
{
@@ -124,11 +159,9 @@ bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
{
dest.Empty();
size_t destLen = 0;
- Utf8_To_Utf16(NULL, &destLen, src, src.Length());
- wchar_t *p = dest.GetBuffer((int)destLen);
- Bool res = Utf8_To_Utf16(p, &destLen, src, src.Length());
- p[destLen] = 0;
- dest.ReleaseBuffer();
+ Utf8_To_Utf16(NULL, &destLen, src, src.Len());
+ Bool res = Utf8_To_Utf16(dest.GetBuffer((unsigned)destLen), &destLen, src, src.Len());
+ dest.ReleaseBuffer((unsigned)destLen);
return res ? true : false;
}
@@ -136,10 +169,8 @@ bool ConvertUnicodeToUTF8(const UString &src, AString &dest)
{
dest.Empty();
size_t destLen = 0;
- Utf16_To_Utf8(NULL, &destLen, src, src.Length());
- char *p = dest.GetBuffer((int)destLen);
- Bool res = Utf16_To_Utf8(p, &destLen, src, src.Length());
- p[destLen] = 0;
- dest.ReleaseBuffer();
+ Utf16_To_Utf8(NULL, &destLen, src, src.Len());
+ Bool res = Utf16_To_Utf8(dest.GetBuffer((unsigned)destLen), &destLen, src, src.Len());
+ dest.ReleaseBuffer((unsigned)destLen);
return res ? true : false;
}
diff --git a/CPP/Common/UTFConvert.h b/CPP/Common/UTFConvert.h
index 2a14600d..16b02fe4 100755..100644
--- a/CPP/Common/UTFConvert.h
+++ b/CPP/Common/UTFConvert.h
@@ -1,10 +1,11 @@
// Common/UTFConvert.h
-#ifndef __COMMON_UTFCONVERT_H
-#define __COMMON_UTFCONVERT_H
+#ifndef __COMMON_UTF_CONVERT_H
+#define __COMMON_UTF_CONVERT_H
#include "MyString.h"
+bool CheckUTF8(const char *src) throw();
bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp
index 87d44971..182256ab 100755..100644
--- a/CPP/Common/Wildcard.cpp
+++ b/CPP/Common/Wildcard.cpp
@@ -2,8 +2,6 @@
#include "StdAfx.h"
-#include "../../C/Types.h"
-
#include "Wildcard.h"
bool g_CaseSensitive =
@@ -13,37 +11,43 @@ bool g_CaseSensitive =
true;
#endif
-static const wchar_t kAnyCharsChar = L'*';
-static const wchar_t kAnyCharChar = L'?';
-
-#ifdef _WIN32
-static const wchar_t kDirDelimiter1 = L'\\';
-#endif
-static const wchar_t kDirDelimiter2 = L'/';
-static const UString kWildCardCharSet = L"?*";
-
-static const UString kIllegalWildCardFileNameChars=
- L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF"
- L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
- L"\"/:<>\\|";
+bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
+{
+ if (g_CaseSensitive)
+ {
+ for (;;)
+ {
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++;
+ if (MyCharUpper(c1) !=
+ MyCharUpper(c2))
+ return false;
+ }
+ }
+ for (;;)
+ {
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++; if (c1 != c2) return false;
+ }
+}
-static inline bool IsCharDirLimiter(wchar_t c)
+int CompareFileNames(const wchar_t *s1, const wchar_t *s2)
{
- return (
- #ifdef _WIN32
- c == kDirDelimiter1 ||
- #endif
- c == kDirDelimiter2);
+ if (g_CaseSensitive)
+ return wcscmp(s1, s2);
+ return MyStringCompareNoCase(s1, s2);
}
-int CompareFileNames(const UString &s1, const UString &s2)
+#ifndef USE_UNICODE_FSTRING
+int CompareFileNames(const char *s1, const char *s2)
{
if (g_CaseSensitive)
- return s1.Compare(s2);
- return s1.CompareNoCase(s2);
+ return wcscmp(fs2us(s1), fs2us(s2));
+ return MyStringCompareNoCase(fs2us(s1), fs2us(s2));
}
+#endif
// -----------------------------------------
// this function compares name with mask
@@ -58,7 +62,7 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
wchar_t c = *name;
if (m == 0)
return (c == 0);
- if (m == kAnyCharsChar)
+ if (m == '*')
{
if (EnhancedMaskTest(mask + 1, name))
return true;
@@ -67,7 +71,7 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
}
else
{
- if (m == kAnyCharChar)
+ if (m == '?')
{
if (c == 0)
return false;
@@ -87,61 +91,84 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
void SplitPathToParts(const UString &path, UStringVector &pathParts)
{
pathParts.Clear();
- UString name;
- int len = path.Length();
+ unsigned len = path.Len();
if (len == 0)
return;
- for (int i = 0; i < len; i++)
- {
- wchar_t c = path[i];
- if (IsCharDirLimiter(c))
+ UString name;
+ unsigned prev = 0;
+ for (unsigned i = 0; i < len; i++)
+ if (IsCharDirLimiter(path[i]))
{
+ name.SetFrom(path.Ptr(prev), i - prev);
pathParts.Add(name);
- name.Empty();
+ prev = i + 1;
}
- else
- name += c;
- }
+ name.SetFrom(path.Ptr(prev), len - prev);
pathParts.Add(name);
}
-void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name)
+void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name)
{
- int i;
- for (i = path.Length() - 1; i >= 0; i--)
- if (IsCharDirLimiter(path[i]))
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsCharDirLimiter(*(p - 1)))
break;
- dirPrefix = path.Left(i + 1);
- name = path.Mid(i + 1);
+ dirPrefix.SetFrom(path, (unsigned)(p - start));
+ name = p;
+}
+
+void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name)
+{
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ if (p != start)
+ {
+ if (IsCharDirLimiter(*(p - 1)))
+ p--;
+ for (; p != start; p--)
+ if (IsCharDirLimiter(*(p - 1)))
+ break;
+ }
+ dirPrefix.SetFrom(path, (unsigned)(p - start));
+ name = p;
}
UString ExtractDirPrefixFromPath(const UString &path)
{
- int i;
- for (i = path.Length() - 1; i >= 0; i--)
- if (IsCharDirLimiter(path[i]))
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsCharDirLimiter(*(p - 1)))
break;
- return path.Left(i + 1);
+ return path.Left((unsigned)(p - start));
}
UString ExtractFileNameFromPath(const UString &path)
{
- int i;
- for (i = path.Length() - 1; i >= 0; i--)
- if (IsCharDirLimiter(path[i]))
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsCharDirLimiter(*(p - 1)))
break;
- return path.Mid(i + 1);
+ return p;
}
-bool CompareWildCardWithName(const UString &mask, const UString &name)
+bool DoesWildcardMatchName(const UString &mask, const UString &name)
{
return EnhancedMaskTest(mask, name);
}
-bool DoesNameContainWildCard(const UString &path)
+bool DoesNameContainWildcard(const UString &path)
{
- return (path.FindOneOf(kWildCardCharSet) >= 0);
+ for (unsigned i = 0; i < path.Len(); i++)
+ {
+ wchar_t c = path[i];
+ if (c == '*' || c == '?')
+ return true;
+ }
+ return false;
}
@@ -151,22 +178,36 @@ bool DoesNameContainWildCard(const UString &path)
namespace NWildcard {
+#ifdef _WIN32
+bool IsDriveColonName(const wchar_t *s)
+{
+ wchar_t c = s[0];
+ return c != 0 && s[1] == ':' && s[2] == 0 && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
+}
+#endif
+
/*
+
M = MaskParts.Size();
N = TestNameParts.Size();
File Dir
-ForFile req M<=N [N-M, N) -
- nonreq M=N [0, M) -
+ForFile rec M<=N [N-M, N) -
+!ForDir nonrec 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
+ForDir rec M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
+!ForFile nonrec [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
+ForFile rec m<=N [0, M) ... [N-M, N) same as ForBoth-File
+ForDir nonrec [0, M) same as ForBoth-File
*/
+bool CItem::AreAllAllowed() const
+{
+ return ForFile && ForDir && WildcardMatching && PathParts.Size() == 1 && PathParts.Front() == L"*";
+}
+
bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
{
if (!isFile && !ForDir)
@@ -176,36 +217,62 @@ bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
return false;
int start = 0;
int finish = 0;
+
if (isFile)
{
- if (!ForDir && !Recursive && delta !=0)
- return false;
+ if (!ForDir)
+ {
+ if (Recursive)
+ start = delta;
+ else if (delta !=0)
+ return false;
+ }
if (!ForFile && delta == 0)
return false;
- if (!ForDir && Recursive)
- start = delta;
}
+
if (Recursive)
{
finish = delta;
if (isFile && !ForFile)
finish = delta - 1;
}
+
for (int d = start; d <= finish; d++)
{
- int i;
+ unsigned i;
for (i = 0; i < PathParts.Size(); i++)
- if (!CompareWildCardWithName(PathParts[i], pathParts[i + d]))
- break;
+ {
+ if (WildcardMatching)
+ {
+ if (!DoesWildcardMatchName(PathParts[i], pathParts[i + d]))
+ break;
+ }
+ else
+ {
+ if (CompareFileNames(PathParts[i], pathParts[i + d]) != 0)
+ break;
+ }
+ }
if (i == PathParts.Size())
return true;
}
return false;
}
+bool CCensorNode::AreAllAllowed() const
+{
+ if (!Name.IsEmpty() ||
+ !SubNodes.IsEmpty() ||
+ !ExcludeItems.IsEmpty() ||
+ IncludeItems.Size() != 1)
+ return false;
+ return IncludeItems.Front().AreAllAllowed();
+}
+
int CCensorNode::FindSubNode(const UString &name) const
{
- for (int i = 0; i < SubNodes.Size(); i++)
+ FOR_VECTOR (i, SubNodes)
if (CompareFileNames(SubNodes[i].Name, name) == 0)
return i;
return -1;
@@ -223,11 +290,19 @@ void CCensorNode::AddItem(bool include, CItem &item)
{
if (item.PathParts.Size() <= 1)
{
+ if (item.PathParts.Size() != 0 && item.WildcardMatching)
+ {
+ if (!DoesNameContainWildcard(item.PathParts.Front()))
+ item.WildcardMatching = false;
+ }
AddItemSimple(include, item);
return;
}
const UString &front = item.PathParts.Front();
- if (DoesNameContainWildCard(front))
+
+ // We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name
+ // if (item.Wildcard)
+ if (DoesNameContainWildcard(front))
{
AddItemSimple(include, item);
return;
@@ -239,19 +314,20 @@ void CCensorNode::AddItem(bool include, CItem &item)
SubNodes[index].AddItem(include, item);
}
-void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir)
+void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching)
{
CItem item;
SplitPathToParts(path, item.PathParts);
item.Recursive = recursive;
item.ForFile = forFile;
item.ForDir = forDir;
+ item.WildcardMatching = wildcardMatching;
AddItem(include, item);
}
bool CCensorNode::NeedCheckSubDirs() const
{
- for (int i = 0; i < IncludeItems.Size(); i++)
+ FOR_VECTOR (i, IncludeItems)
{
const CItem &item = IncludeItems[i];
if (item.Recursive || item.PathParts.Size() > 1)
@@ -264,7 +340,7 @@ bool CCensorNode::AreThereIncludeItems() const
{
if (IncludeItems.Size() > 0)
return true;
- for (int i = 0; i < SubNodes.Size(); i++)
+ FOR_VECTOR (i, SubNodes)
if (SubNodes[i].AreThereIncludeItems())
return true;
return false;
@@ -273,13 +349,13 @@ bool CCensorNode::AreThereIncludeItems() const
bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
{
const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
- for (int i = 0; i < items.Size(); i++)
+ FOR_VECTOR (i, items)
if (items[i].CheckPath(pathParts, isFile))
return true;
return false;
}
-bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const
+bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const
{
if (CheckPathCurrent(false, pathParts, isFile))
{
@@ -288,30 +364,45 @@ bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include
}
include = true;
bool finded = CheckPathCurrent(true, pathParts, isFile);
- if (pathParts.Size() == 1)
+ if (pathParts.Size() <= 1)
return finded;
int index = FindSubNode(pathParts.Front());
if (index >= 0)
{
UStringVector pathParts2 = pathParts;
pathParts2.Delete(0);
- if (SubNodes[index].CheckPath(pathParts2, isFile, include))
+ if (SubNodes[index].CheckPathVect(pathParts2, isFile, include))
return true;
}
return finded;
}
-bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const
+bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const
{
UStringVector pathParts;
SplitPathToParts(path, pathParts);
- return CheckPath(pathParts, isFile, include);
+ if (CheckPathVect(pathParts, isFile, include))
+ {
+ if (!include || !isAltStream)
+ return true;
+ }
+ if (isAltStream && !pathParts.IsEmpty())
+ {
+ UString &back = pathParts.Back();
+ int pos = back.Find(L':');
+ if (pos > 0)
+ {
+ back.DeleteFrom(pos);
+ return CheckPathVect(pathParts, isFile, include);
+ }
+ }
+ return false;
}
-bool CCensorNode::CheckPath(const UString &path, bool isFile) const
+bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) const
{
bool include;
- if (CheckPath(path, isFile, include))
+ if (CheckPath2(isAltStream, path, isFile, include))
return include;
return false;
}
@@ -335,7 +426,7 @@ bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile
}
*/
-void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)
+void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching)
{
if (path.IsEmpty())
return;
@@ -347,13 +438,13 @@ void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)
path2.DeleteBack();
forFile = false;
}
- AddItem(include, path2, recursive, forFile, forFolder);
+ AddItem(include, path2, recursive, forFile, forFolder, wildcardMatching);
}
void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
{
ExcludeItems += fromNodes.ExcludeItems;
- for (int i = 0; i < fromNodes.SubNodes.Size(); i++)
+ FOR_VECTOR (i, fromNodes.SubNodes)
{
const CCensorNode &node = fromNodes.SubNodes[i];
int subNodeIndex = FindSubNode(node.Name);
@@ -365,13 +456,13 @@ void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
int CCensor::FindPrefix(const UString &prefix) const
{
- for (int i = 0; i < Pairs.Size(); i++)
+ FOR_VECTOR (i, Pairs)
if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)
return i;
return -1;
}
-void CCensor::AddItem(bool include, const UString &path, bool recursive)
+void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching)
{
UStringVector pathParts;
if (path.IsEmpty())
@@ -383,40 +474,82 @@ void CCensor::AddItem(bool include, const UString &path, bool recursive)
forFile = false;
pathParts.DeleteBack();
}
- const UString &front = pathParts.Front();
- bool isAbs = false;
- if (front.IsEmpty())
- isAbs = true;
- else if (front.Length() == 2 && front[1] == L':')
- isAbs = true;
- else
+
+ UString prefix;
+
+ if (pathMode != k_AbsPath)
{
- for (int i = 0; i < pathParts.Size(); i++)
+ const UString &front = pathParts.Front();
+ bool isAbs = false;
+
+ if (front.IsEmpty())
+ isAbs = true;
+ else
{
- const UString &part = pathParts[i];
- if (part == L".." || part == L".")
- {
+ #ifdef _WIN32
+
+ if (IsDriveColonName(front))
isAbs = true;
- break;
+ else
+
+ #endif
+
+ FOR_VECTOR (i, pathParts)
+ {
+ const UString &part = pathParts[i];
+ if (part == L".." || part == L".")
+ {
+ isAbs = true;
+ break;
+ }
+ }
+ }
+
+ unsigned numAbsParts = 0;
+ if (isAbs)
+ if (pathParts.Size() > 1)
+ numAbsParts = pathParts.Size() - 1;
+ else
+ numAbsParts = 1;
+
+ #ifdef _WIN32
+
+ // \\?\ case
+ if (numAbsParts >= 3)
+ {
+ if (pathParts[0].IsEmpty() &&
+ pathParts[1].IsEmpty() &&
+ pathParts[2] == L"?")
+ {
+ prefix =
+ WSTRING_PATH_SEPARATOR
+ WSTRING_PATH_SEPARATOR L"?"
+ WSTRING_PATH_SEPARATOR;
+ numAbsParts -= 3;
+ pathParts.DeleteFrontal(3);
}
}
- }
- int numAbsParts = 0;
- if (isAbs)
- if (pathParts.Size() > 1)
- numAbsParts = pathParts.Size() - 1;
- else
+
+ #endif
+
+ if (numAbsParts > 1 && pathMode == k_FullPath)
numAbsParts = 1;
- UString prefix;
- for (int i = 0; i < numAbsParts; i++)
- {
- const UString &front = pathParts.Front();
- if (DoesNameContainWildCard(front))
- break;
- prefix += front;
- prefix += WCHAR_PATH_SEPARATOR;
- pathParts.Delete(0);
+
+ // We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name
+ // if (wildcardMatching)
+ for (unsigned i = 0; i < numAbsParts; i++)
+ {
+ {
+ const UString &front = pathParts.Front();
+ if (DoesNameContainWildcard(front))
+ break;
+ prefix += front;
+ prefix += WCHAR_PATH_SEPARATOR;
+ }
+ pathParts.Delete(0);
+ }
}
+
int index = FindPrefix(prefix);
if (index < 0)
index = Pairs.Add(CPair(prefix));
@@ -426,16 +559,17 @@ void CCensor::AddItem(bool include, const UString &path, bool recursive)
item.ForDir = true;
item.ForFile = forFile;
item.Recursive = recursive;
+ item.WildcardMatching = wildcardMatching;
Pairs[index].Head.AddItem(include, item);
}
-bool CCensor::CheckPath(const UString &path, bool isFile) const
+bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const
{
bool finded = false;
- for (int i = 0; i < Pairs.Size(); i++)
+ FOR_VECTOR (i, Pairs)
{
bool include;
- if (Pairs[i].Head.CheckPath(path, isFile, include))
+ if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include))
{
if (!include)
return false;
@@ -447,16 +581,35 @@ bool CCensor::CheckPath(const UString &path, bool isFile) const
void CCensor::ExtendExclude()
{
- int i;
+ unsigned i;
for (i = 0; i < Pairs.Size(); i++)
if (Pairs[i].Prefix.IsEmpty())
break;
if (i == Pairs.Size())
return;
- int index = i;
+ unsigned index = i;
for (i = 0; i < Pairs.Size(); i++)
if (index != i)
Pairs[i].Head.ExtendExclude(Pairs[index].Head);
}
+void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode)
+{
+ FOR_VECTOR(i, CensorPaths)
+ {
+ const CCensorPath &cp = CensorPaths[i];
+ AddItem(censorPathMode, cp.Include, cp.Path, cp.Recursive, cp.WildcardMatching);
+ }
+ CensorPaths.Clear();
+}
+
+void CCensor::AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching)
+{
+ CCensorPath &cp = CensorPaths.AddNew();
+ cp.Path = path;
+ cp.Include = include;
+ cp.Recursive = recursive;
+ cp.WildcardMatching = wildcardMatching;
+}
+
}
diff --git a/CPP/Common/Wildcard.h b/CPP/Common/Wildcard.h
index 6d4cbcec..b9971202 100755..100644
--- a/CPP/Common/Wildcard.h
+++ b/CPP/Common/Wildcard.h
@@ -5,51 +5,90 @@
#include "MyString.h"
-int CompareFileNames(const UString &s1, const UString &s2);
+int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW;
+#ifndef USE_UNICODE_FSTRING
+ int CompareFileNames(const char *s1, const char *s2);
+#endif
+
+bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2);
+
+inline bool IsCharDirLimiter(wchar_t c)
+{
+ return c == WCHAR_PATH_SEPARATOR
+ #ifdef _WIN32
+ || c == L'/'
+ #endif
+ ;
+}
void SplitPathToParts(const UString &path, UStringVector &pathParts);
-void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name);
+void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name);
+void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name); // ignores dir delimiter at the end of (path)
+
UString ExtractDirPrefixFromPath(const UString &path);
UString ExtractFileNameFromPath(const UString &path);
-bool DoesNameContainWildCard(const UString &path);
-bool CompareWildCardWithName(const UString &mask, const UString &name);
+
+bool DoesNameContainWildcard(const UString &path);
+bool DoesWildcardMatchName(const UString &mask, const UString &name);
namespace NWildcard {
+#ifdef _WIN32
+// returns true, if name is like "a:", "c:", ...
+bool IsDriveColonName(const wchar_t *s);
+#endif
+
+
struct CItem
{
UStringVector PathParts;
bool Recursive;
bool ForFile;
bool ForDir;
+ bool WildcardMatching;
+
+ #ifdef _WIN32
+ bool IsDriveItem() const
+ {
+ return PathParts.Size() == 1 && !ForFile && ForDir && IsDriveColonName(PathParts[0]);
+ }
+ #endif
+
+ // CItem(): WildcardMatching(true) {}
+
+ bool AreAllAllowed() const;
bool CheckPath(const UStringVector &pathParts, bool isFile) const;
};
class CCensorNode
{
CCensorNode *Parent;
+
bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const;
void AddItemSimple(bool include, CItem &item);
- bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const;
+ bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const;
public:
CCensorNode(): Parent(0) { };
CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { };
- UString Name;
+
+ UString Name; // wildcard is not allowed here
CObjectVector<CCensorNode> SubNodes;
CObjectVector<CItem> IncludeItems;
CObjectVector<CItem> ExcludeItems;
+ bool AreAllAllowed() const;
+
int FindSubNode(const UString &path) const;
void AddItem(bool include, CItem &item);
- void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir);
- void AddItem2(bool include, const UString &path, bool recursive);
+ void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching);
+ void AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching);
bool NeedCheckSubDirs() const;
bool AreThereIncludeItems() const;
- bool CheckPath(const UString &path, bool isFile, bool &include) const;
- bool CheckPath(const UString &path, bool isFile) const;
+ bool CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const;
+ bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const;
// bool CheckPathToRoot(const UString &path, bool isFile, bool include) const;
@@ -60,21 +99,59 @@ struct CPair
{
UString Prefix;
CCensorNode Head;
+
CPair(const UString &prefix): Prefix(prefix) { };
};
+enum ECensorPathMode
+{
+ k_RelatPath, // absolute prefix as Prefix, remain path in Tree
+ k_FullPath, // drive prefix as Prefix, remain path in Tree
+ k_AbsPath // full path in Tree
+};
+
+struct CCensorPath
+{
+ UString Path;
+ bool Include;
+ bool Recursive;
+ bool WildcardMatching;
+
+ CCensorPath():
+ Include(true),
+ Recursive(false),
+ WildcardMatching(true)
+ {}
+};
+
class CCensor
{
int FindPrefix(const UString &prefix) const;
public:
CObjectVector<CPair> Pairs;
+
+ CObjectVector<NWildcard::CCensorPath> CensorPaths;
+
bool AllAreRelative() const
{ return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); }
- void AddItem(bool include, const UString &path, bool recursive);
- bool CheckPath(const UString &path, bool isFile) const;
+
+ void AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching);
+ bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
void ExtendExclude();
+
+ void AddPathsToCensor(NWildcard::ECensorPathMode censorPathMode);
+ void AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching);
+ void AddPreItem(const UString &path)
+ {
+ AddPreItem(true, path, false, false);
+ }
+ void AddPreItem_Wildcard()
+ {
+ AddPreItem(true, L"*", false, true);
+ }
};
+
}
#endif
diff --git a/CPP/Common/XzCrc64Reg.cpp b/CPP/Common/XzCrc64Reg.cpp
new file mode 100644
index 00000000..58413797
--- /dev/null
+++ b/CPP/Common/XzCrc64Reg.cpp
@@ -0,0 +1,54 @@
+// XzCrc64Reg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/CpuArch.h"
+#include "../../C/XzCrc64.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/ICoder.h"
+#include "../7zip/Common/RegisterCodec.h"
+
+class CXzCrc64Hasher:
+ public IHasher,
+ public CMyUnknownImp
+{
+ UInt64 _crc;
+public:
+ CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {}
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD_(void, Init)();
+ STDMETHOD_(void, Update)(const void *data, UInt32 size);
+ STDMETHOD_(void, Final)(Byte *digest);
+ STDMETHOD_(UInt32, GetDigestSize)();
+};
+
+STDMETHODIMP_(void) CXzCrc64Hasher::Init()
+{
+ _crc = CRC64_INIT_VAL;
+}
+
+STDMETHODIMP_(void) CXzCrc64Hasher::Update(const void *data, UInt32 size)
+{
+ _crc = Crc64Update(_crc, data, size);
+}
+
+STDMETHODIMP_(void) CXzCrc64Hasher::Final(Byte *digest)
+{
+ UInt64 val = CRC64_GET_DIGEST(_crc);
+ SetUi64(digest, val);
+}
+
+STDMETHODIMP_(UInt32) CXzCrc64Hasher::GetDigestSize()
+{
+ return 8;
+}
+
+static IHasher *CreateHasher() { return new CXzCrc64Hasher; }
+
+static CHasherInfo g_HasherInfo = { CreateHasher, 0x4, L"CRC64", 8 };
+
+REGISTER_HASHER(Crc64)