mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 09:15:00 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
0
CPP/Common/AutoPtr.h
Executable file → Normal file
0
CPP/Common/AutoPtr.h
Executable file → Normal file
@@ -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
|
||||
0
CPP/Common/CRC.cpp
Executable file → Normal file
0
CPP/Common/CRC.cpp
Executable file → Normal file
0
CPP/Common/C_FileIO.cpp
Executable file → Normal file
0
CPP/Common/C_FileIO.cpp
Executable file → Normal file
2
CPP/Common/C_FileIO.h
Executable file → Normal file
2
CPP/Common/C_FileIO.h
Executable file → Normal file
@@ -6,7 +6,7 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "Types.h"
|
||||
#include "MyTypes.h"
|
||||
#include "MyWindows.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
0
CPP/Common/ComTry.h
Executable file → Normal file
0
CPP/Common/ComTry.h
Executable file → Normal file
277
CPP/Common/CommandLineParser.cpp
Executable file → Normal file
277
CPP/Common/CommandLineParser.cpp
Executable file → Normal file
@@ -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)
|
||||
{
|
||||
if (IsItSwitchChar(s[pos]))
|
||||
pos++;
|
||||
const int kNoLen = -1;
|
||||
int matchedSwitchIndex = 0; // GCC Warning
|
||||
int maxLen = kNoLen;
|
||||
for (int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
|
||||
{
|
||||
int switchLen = MyStringLen(switchForms[switchIndex].IDString);
|
||||
if (switchLen <= maxLen || pos + switchLen > len)
|
||||
continue;
|
||||
|
||||
UString temp = s + pos;
|
||||
temp = temp.Left(switchLen);
|
||||
if (temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
|
||||
// if (_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
|
||||
{
|
||||
matchedSwitchIndex = switchIndex;
|
||||
maxLen = switchLen;
|
||||
}
|
||||
}
|
||||
if (maxLen == kNoLen)
|
||||
throw "maxLen == kNoLen";
|
||||
CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
|
||||
const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
|
||||
if ((!switchForm.Multi) && matchedSwitch.ThereIs)
|
||||
throw "switch must be single";
|
||||
matchedSwitch.ThereIs = true;
|
||||
pos += maxLen;
|
||||
int tailSize = len - pos;
|
||||
NSwitchType::EEnum type = switchForm.Type;
|
||||
switch(type)
|
||||
unsigned pos = 1;
|
||||
unsigned switchIndex = 0;
|
||||
int maxLen = -1;
|
||||
|
||||
for (unsigned i = 0; i < _numSwitches; i++)
|
||||
{
|
||||
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))
|
||||
{
|
||||
case NSwitchType::kPostMinus:
|
||||
{
|
||||
if (tailSize == 0)
|
||||
matchedSwitch.WithMinus = false;
|
||||
else
|
||||
{
|
||||
matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
|
||||
if (matchedSwitch.WithMinus)
|
||||
pos++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NSwitchType::kPostChar:
|
||||
{
|
||||
if (tailSize < switchForm.MinLen)
|
||||
throw "switch is not full";
|
||||
UString set = switchForm.PostCharSet;
|
||||
const int kEmptyCharValue = -1;
|
||||
if (tailSize == 0)
|
||||
matchedSwitch.PostCharIndex = kEmptyCharValue;
|
||||
else
|
||||
{
|
||||
int index = set.Find(s[pos]);
|
||||
if (index < 0)
|
||||
matchedSwitch.PostCharIndex = kEmptyCharValue;
|
||||
else
|
||||
{
|
||||
matchedSwitch.PostCharIndex = index;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NSwitchType::kLimitedPostString:
|
||||
case NSwitchType::kUnLimitedPostString:
|
||||
{
|
||||
int minLen = switchForm.MinLen;
|
||||
if (tailSize < minLen)
|
||||
throw "switch is not full";
|
||||
if (type == NSwitchType::kUnLimitedPostString)
|
||||
{
|
||||
matchedSwitch.PostStrings.Add(s.Mid(pos));
|
||||
return true;
|
||||
}
|
||||
int maxLen = switchForm.MaxLen;
|
||||
UString stringSwitch = s.Mid(pos, minLen);
|
||||
pos += minLen;
|
||||
for (int i = minLen; i < maxLen && pos < len; i++, pos++)
|
||||
{
|
||||
wchar_t c = s[pos];
|
||||
if (IsItSwitchChar(c))
|
||||
break;
|
||||
stringSwitch += c;
|
||||
}
|
||||
matchedSwitch.PostStrings.Add(stringSwitch);
|
||||
break;
|
||||
}
|
||||
case NSwitchType::kSimple:
|
||||
break;
|
||||
switchIndex = i;
|
||||
maxLen = switchLen;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxLen < 0)
|
||||
{
|
||||
ErrorMessage = "Unknown switch:";
|
||||
return false;
|
||||
}
|
||||
|
||||
pos += maxLen;
|
||||
|
||||
CSwitchResult &sw = _switches[switchIndex];
|
||||
const CSwitchForm &form = switchForms[switchIndex];
|
||||
|
||||
if (!form.Multi && sw.ThereIs)
|
||||
{
|
||||
ErrorMessage = "Multiple instances for switch:";
|
||||
return false;
|
||||
}
|
||||
|
||||
sw.ThereIs = true;
|
||||
|
||||
int rem = s.Len() - pos;
|
||||
if (rem < form.MinLen)
|
||||
{
|
||||
ErrorMessage = "Too short switch:";
|
||||
return false;
|
||||
}
|
||||
|
||||
sw.WithMinus = false;
|
||||
sw.PostCharIndex = -1;
|
||||
|
||||
switch (form.Type)
|
||||
{
|
||||
case NSwitchType::kMinus:
|
||||
if (rem != 0)
|
||||
{
|
||||
sw.WithMinus = (s[pos] == '-');
|
||||
if (sw.WithMinus)
|
||||
pos++;
|
||||
}
|
||||
break;
|
||||
|
||||
case NSwitchType::kChar:
|
||||
if (rem != 0)
|
||||
{
|
||||
wchar_t c = s[pos];
|
||||
if (c <= 0x7F)
|
||||
{
|
||||
sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);
|
||||
if (sw.PostCharIndex >= 0)
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
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
|
||||
bool CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings)
|
||||
{
|
||||
return _switches[index];
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
// Command parsing procedures
|
||||
|
||||
int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
|
||||
const UString &commandString, UString &postString)
|
||||
{
|
||||
for (int i = 0; i < numCommandForms; i++)
|
||||
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;
|
||||
}
|
||||
if (!s.IsEmpty() && IsItSwitchChar(s[0]))
|
||||
{
|
||||
if (ParseString(s, switchForms))
|
||||
continue;
|
||||
ErrorLine = s;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (commandString == id)
|
||||
{
|
||||
postString.Empty();
|
||||
return i;
|
||||
}
|
||||
NonSwitchStrings.Add(s);
|
||||
}
|
||||
return -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
49
CPP/Common/CommandLineParser.h
Executable file → Normal file
49
CPP/Common/CommandLineParser.h
Executable file → Normal file
@@ -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
|
||||
|
||||
13
CPP/Common/Common.h
Normal file
13
CPP/Common/Common.h
Normal file
@@ -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
|
||||
111
CPP/Common/CrcReg.cpp
Normal file
111
CPP/Common/CrcReg.cpp
Normal file
@@ -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)
|
||||
0
CPP/Common/Defs.h
Executable file → Normal file
0
CPP/Common/Defs.h
Executable file → Normal file
100
CPP/Common/DynLimBuf.cpp
Normal file
100
CPP/Common/DynLimBuf.cpp
Normal file
@@ -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;
|
||||
}
|
||||
36
CPP/Common/DynLimBuf.h
Normal file
36
CPP/Common/DynLimBuf.h
Normal file
@@ -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
|
||||
72
CPP/Common/DynamicBuffer.h
Executable file → Normal file
72
CPP/Common/DynamicBuffer.h
Executable file → Normal file
@@ -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
|
||||
|
||||
165
CPP/Common/IntToString.cpp
Executable file → Normal file
165
CPP/Common/IntToString.cpp
Executable file → Normal file
@@ -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
|
||||
{
|
||||
int delta = (int)(value % base);
|
||||
temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10)));
|
||||
value /= base;
|
||||
}
|
||||
while (value != 0);
|
||||
do
|
||||
*s++ = temp[--pos];
|
||||
while (pos > 0);
|
||||
*s = '\0';
|
||||
CONVERT_INT_TO_STR(char, 24);
|
||||
}
|
||||
|
||||
void ConvertUInt64ToString(UInt64 value, wchar_t *s)
|
||||
void ConvertUInt64ToOct(UInt64 val, char *s)
|
||||
{
|
||||
wchar_t temp[32];
|
||||
int pos = 0;
|
||||
UInt64 v = val;
|
||||
unsigned i;
|
||||
for (i = 1;; i++)
|
||||
{
|
||||
v >>= 3;
|
||||
if (v == 0)
|
||||
break;
|
||||
}
|
||||
s[i] = 0;
|
||||
do
|
||||
{
|
||||
temp[pos++] = (wchar_t)(L'0' + (int)(value % 10));
|
||||
value /= 10;
|
||||
unsigned t = (unsigned)(val & 0x7);
|
||||
val >>= 3;
|
||||
s[--i] = (char)('0' + t);
|
||||
}
|
||||
while (value != 0);
|
||||
do
|
||||
*s++ = temp[--pos];
|
||||
while (pos > 0);
|
||||
*s = L'\0';
|
||||
while (i);
|
||||
}
|
||||
|
||||
void ConvertUInt32ToString(UInt32 value, char *s) { ConvertUInt64ToString(value, s); }
|
||||
void ConvertUInt32ToString(UInt32 value, wchar_t *s) { ConvertUInt64ToString(value, s); }
|
||||
|
||||
void ConvertInt64ToString(Int64 value, char *s)
|
||||
void ConvertUInt32ToHex(UInt32 val, char *s)
|
||||
{
|
||||
if (value < 0)
|
||||
UInt32 v = val;
|
||||
unsigned i;
|
||||
for (i = 1;; i++)
|
||||
{
|
||||
v >>= 4;
|
||||
if (v == 0)
|
||||
break;
|
||||
}
|
||||
s[i] = 0;
|
||||
do
|
||||
{
|
||||
unsigned t = (unsigned)((val & 0xF));
|
||||
val >>= 4;
|
||||
s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
|
||||
}
|
||||
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
|
||||
{
|
||||
unsigned t = (unsigned)((val & 0xF));
|
||||
val >>= 4;
|
||||
s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
|
||||
}
|
||||
while (i);
|
||||
}
|
||||
|
||||
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 ConvertUInt32ToHex8Digits(UInt32 val, wchar_t *s)
|
||||
{
|
||||
s[8] = 0;
|
||||
for (int i = 7; i >= 0; i--)
|
||||
{
|
||||
unsigned t = val & 0xF;
|
||||
val >>= 4;
|
||||
s[i] = (wchar_t)(((t < 10) ? ('0' + t) : ('A' + (t - 10))));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void ConvertUInt32ToString(UInt32 val, wchar_t *s)
|
||||
{
|
||||
CONVERT_INT_TO_STR(wchar_t, 16);
|
||||
}
|
||||
|
||||
void ConvertUInt64ToString(UInt64 val, wchar_t *s)
|
||||
{
|
||||
if (val <= (UInt32)0xFFFFFFFF)
|
||||
{
|
||||
ConvertUInt32ToString((UInt32)val, s);
|
||||
return;
|
||||
}
|
||||
CONVERT_INT_TO_STR(wchar_t, 24);
|
||||
}
|
||||
|
||||
void ConvertInt64ToString(Int64 val, char *s)
|
||||
{
|
||||
if (val < 0)
|
||||
{
|
||||
*s++ = '-';
|
||||
value = -value;
|
||||
val = -val;
|
||||
}
|
||||
ConvertUInt64ToString(value, s);
|
||||
ConvertUInt64ToString(val, s);
|
||||
}
|
||||
|
||||
void ConvertInt64ToString(Int64 value, wchar_t *s)
|
||||
void ConvertInt64ToString(Int64 val, wchar_t *s)
|
||||
{
|
||||
if (value < 0)
|
||||
if (val < 0)
|
||||
{
|
||||
*s++ = L'-';
|
||||
value = -value;
|
||||
val = -val;
|
||||
}
|
||||
ConvertUInt64ToString(value, s);
|
||||
}
|
||||
|
||||
void ConvertUInt32ToHexWithZeros(UInt32 value, char *s)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
int t = value & 0xF;
|
||||
value >>= 4;
|
||||
s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
|
||||
}
|
||||
s[8] = '\0';
|
||||
ConvertUInt64ToString(val, s);
|
||||
}
|
||||
|
||||
23
CPP/Common/IntToString.h
Executable file → Normal file
23
CPP/Common/IntToString.h
Executable file → Normal file
@@ -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
|
||||
|
||||
210
CPP/Common/Lang.cpp
Executable file → Normal file
210
CPP/Common/Lang.cpp
Executable file → Normal file
@@ -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()
|
||||
{
|
||||
value = 0;
|
||||
delete []_text;
|
||||
_text = 0;
|
||||
_ids.Clear();
|
||||
_offsets.Clear();
|
||||
}
|
||||
|
||||
static const wchar_t *kLangSignature = L";!@Lang2@!UTF-8!";
|
||||
|
||||
bool CLang::OpenFromString(const AString &s2)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
_text = new wchar_t[s.Len() - i + 1];
|
||||
wchar_t *text = _text;
|
||||
|
||||
Int32 id = -100;
|
||||
UInt32 pos = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static bool WaitNextLine(const AString &s, int &pos)
|
||||
bool CLang::Open(CFSTR fileName, const wchar_t *id)
|
||||
{
|
||||
for (; pos < s.Length(); pos++)
|
||||
if (s[pos] == 0x0A)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int CompareLangItems(void *const *elem1, void *const *elem2, void *)
|
||||
{
|
||||
const CLangPair &langPair1 = *(*((const CLangPair **)elem1));
|
||||
const CLangPair &langPair2 = *(*((const CLangPair **)elem2));
|
||||
return MyCompare(langPair1.Value, langPair2.Value);
|
||||
}
|
||||
|
||||
bool CLang::Open(CFSTR fileName)
|
||||
{
|
||||
_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 (len != processed)
|
||||
return false;
|
||||
char *p2 = p;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
if (Byte(s[0]) == 0xEF && Byte(s[1]) == 0xBB && Byte(s[2]) == 0xBF)
|
||||
pos += 3;
|
||||
char c = p[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c != 0x0D)
|
||||
*p2++ = c;
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// read header
|
||||
|
||||
AString stringID = ";!@Lang@!UTF-8!";
|
||||
if (s.Mid(pos, stringID.Length()) != stringID)
|
||||
return false;
|
||||
pos += stringID.Length();
|
||||
|
||||
if (!WaitNextLine(s, pos))
|
||||
return false;
|
||||
|
||||
CObjectVector<CTextConfigPair> pairs;
|
||||
if (!GetTextConfig(s.Mid(pos), pairs))
|
||||
return false;
|
||||
|
||||
_langPairs.Reserve(pairs.Size());
|
||||
for (int i = 0; i < pairs.Size(); i++)
|
||||
s.ReleaseBuffer((unsigned)(p2 - p));
|
||||
if (OpenFromString(s))
|
||||
{
|
||||
CTextConfigPair textConfigPair = pairs[i];
|
||||
CLangPair langPair;
|
||||
if (!HexStringToNumber(textConfigPair.ID, langPair.Value))
|
||||
return false;
|
||||
langPair.String = textConfigPair.String;
|
||||
_langPairs.Add(langPair);
|
||||
const wchar_t *s = Get(0);
|
||||
if (s && wcscmp(s, id) == 0)
|
||||
return true;
|
||||
}
|
||||
_langPairs.Sort(CompareLangItems, NULL);
|
||||
return true;
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
int CLang::FindItem(UInt32 value) const
|
||||
const wchar_t *CLang::Get(UInt32 id) const
|
||||
{
|
||||
int left = 0, right = _langPairs.Size();
|
||||
while (left != right)
|
||||
{
|
||||
UInt32 mid = (left + right) / 2;
|
||||
UInt32 midValue = _langPairs[mid].Value;
|
||||
if (value == midValue)
|
||||
return mid;
|
||||
if (value < midValue)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CLang::GetMessage(UInt32 value, UString &message) const
|
||||
{
|
||||
int index = FindItem(value);
|
||||
int index = _ids.FindInSorted(id);
|
||||
if (index < 0)
|
||||
return false;
|
||||
message = _langPairs[index].String;
|
||||
return true;
|
||||
return NULL;
|
||||
return _text + (size_t)_offsets[index];
|
||||
}
|
||||
|
||||
24
CPP/Common/Lang.h
Executable file → Normal file
24
CPP/Common/Lang.h
Executable file → Normal file
@@ -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
|
||||
|
||||
|
||||
|
||||
127
CPP/Common/ListFileUtils.cpp
Executable file → Normal file
127
CPP/Common/ListFileUtils.cpp
Executable file → Normal file
@@ -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))
|
||||
UInt64 fileSize;
|
||||
if (!file.GetLength(fileSize))
|
||||
return false;
|
||||
if (length > ((UInt32)1 << 31))
|
||||
if (fileSize >= ((UInt32)1 << 31) - 32)
|
||||
return false;
|
||||
AString s;
|
||||
char *p = s.GetBuffer((int)length + 1);
|
||||
UInt32 processed;
|
||||
if (!file.Read(p, (UInt32)length, processed))
|
||||
return false;
|
||||
p[(UInt32)length] = 0;
|
||||
s.ReleaseBuffer();
|
||||
file.Close();
|
||||
|
||||
UString u;
|
||||
#ifdef CP_UTF8
|
||||
if (codePage == CP_UTF8)
|
||||
if (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);
|
||||
}
|
||||
|
||||
UString t;
|
||||
for (int i = 0; i < u.Length(); i++)
|
||||
{
|
||||
wchar_t c = u[i];
|
||||
if (c == L'\n' || c == 0xD)
|
||||
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)
|
||||
{
|
||||
t.Trim();
|
||||
RemoveQuote(t);
|
||||
if (!t.IsEmpty())
|
||||
resultStrings.Add(t);
|
||||
t.Empty();
|
||||
if (!ConvertUTF8ToUnicode(s, u))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
t += c;
|
||||
// #endif
|
||||
MultiByteToUnicodeString2(u, s, codePage);
|
||||
}
|
||||
t.Trim();
|
||||
RemoveQuote(t);
|
||||
if (!t.IsEmpty())
|
||||
resultStrings.Add(t);
|
||||
|
||||
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)
|
||||
{
|
||||
AddName(strings, s);
|
||||
s.Empty();
|
||||
}
|
||||
else
|
||||
s += c;
|
||||
}
|
||||
AddName(strings, s);
|
||||
return true;
|
||||
}
|
||||
|
||||
5
CPP/Common/ListFileUtils.h
Executable file → Normal file
5
CPP/Common/ListFileUtils.h
Executable file → Normal file
@@ -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);
|
||||
|
||||
|
||||
237
CPP/Common/MyBuffer.h
Normal file
237
CPP/Common/MyBuffer.h
Normal file
@@ -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
|
||||
63
CPP/Common/MyCom.h
Executable file → Normal file
63
CPP/Common/MyCom.h
Executable file → Normal file
@@ -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
|
||||
|
||||
0
CPP/Common/MyException.h
Executable file → Normal file
0
CPP/Common/MyException.h
Executable file → Normal file
2
CPP/Common/MyGuidDef.h
Executable file → Normal file
2
CPP/Common/MyGuidDef.h
Executable file → Normal file
@@ -3,7 +3,7 @@
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
|
||||
#include "Types.h"
|
||||
#include "MyTypes.h"
|
||||
|
||||
typedef struct {
|
||||
UInt32 Data1;
|
||||
|
||||
0
CPP/Common/MyInitGuid.h
Executable file → Normal file
0
CPP/Common/MyInitGuid.h
Executable file → Normal file
14
CPP/Common/MyMap.cpp
Executable file → Normal file
14
CPP/Common/MyMap.cpp
Executable file → Normal file
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
4
CPP/Common/MyMap.h
Executable file → Normal file
4
CPP/Common/MyMap.h
Executable file → Normal file
@@ -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
|
||||
};
|
||||
|
||||
|
||||
1146
CPP/Common/MyString.cpp
Executable file → Normal file
1146
CPP/Common/MyString.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
868
CPP/Common/MyString.h
Executable file → Normal file
868
CPP/Common/MyString.h
Executable file → Normal file
@@ -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)
|
||||
{
|
||||
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(char *dest, const char *src)
|
||||
{
|
||||
while ((*dest++ = *src++) != 0);
|
||||
}
|
||||
|
||||
int FindCharPosInString(const char *s, char c);
|
||||
int FindCharPosInString(const wchar_t *s, wchar_t c);
|
||||
|
||||
inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
|
||||
{ return (p + 1); }
|
||||
inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
|
||||
{ return (p + 1); }
|
||||
inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
|
||||
{ return (p - 1); }
|
||||
inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
|
||||
{ return (p - 1); }
|
||||
|
||||
wchar_t MyCharUpper(wchar_t c);
|
||||
// wchar_t MyCharLower(wchar_t c);
|
||||
|
||||
char *MyStringUpper(char *s);
|
||||
char *MyStringLower(char *s);
|
||||
|
||||
wchar_t *MyStringUpper(wchar_t *s);
|
||||
wchar_t *MyStringLower(wchar_t *s);
|
||||
|
||||
const char* MyStringGetNextCharPointer(const char *p);
|
||||
const char* MyStringGetPrevCharPointer(const char *base, const char *p);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Compare
|
||||
|
||||
int MyStringCompare(const char *s1, const char *s2);
|
||||
int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
|
||||
|
||||
int MyStringCompareNoCase(const char *s1, const char *s2);
|
||||
int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
|
||||
|
||||
template <class T>
|
||||
class CStringBase
|
||||
inline char *MyStpCpy(char *dest, const char *src)
|
||||
{
|
||||
void TrimLeftWithCharSet(const CStringBase &charSet)
|
||||
for (;;)
|
||||
{
|
||||
const T *p = _chars;
|
||||
while (charSet.Find(*p) >= 0 && (*p != 0))
|
||||
p = GetNextCharPointer(p);
|
||||
Delete(0, (int)(p - _chars));
|
||||
Byte c = *src;
|
||||
*dest = c;
|
||||
if (c == 0)
|
||||
return dest;
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
void TrimRightWithCharSet(const CStringBase &charSet)
|
||||
{
|
||||
const T *p = _chars;
|
||||
const T *pLast = NULL;
|
||||
while (*p != 0)
|
||||
{
|
||||
if (charSet.Find(*p) >= 0)
|
||||
{
|
||||
if (pLast == NULL)
|
||||
pLast = p;
|
||||
}
|
||||
else
|
||||
pLast = NULL;
|
||||
p = GetNextCharPointer(p);
|
||||
}
|
||||
if (pLast != NULL)
|
||||
{
|
||||
int i = (int)(pLast - _chars);
|
||||
Delete(i, _length - i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void MoveItems(int destIndex, int srcIndex)
|
||||
inline unsigned MyStringLen(const wchar_t *s)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; s[i] != 0; i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
|
||||
{
|
||||
while ((*dest++ = *src++) != 0);
|
||||
}
|
||||
|
||||
int FindCharPosInString(const char *s, char c) throw();
|
||||
int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef _UNICODE
|
||||
#define STRING_UNICODE_THROW
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef STRING_UNICODE_THROW
|
||||
#define STRING_UNICODE_THROW throw()
|
||||
#endif
|
||||
|
||||
/*
|
||||
inline char MyCharUpper_Ascii(char c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return (char)(c - 0x20);
|
||||
return c;
|
||||
}
|
||||
inline wchar_t MyCharUpper_Ascii(wchar_t c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return (wchar_t)(c - 0x20);
|
||||
return c;
|
||||
}
|
||||
*/
|
||||
|
||||
inline char MyCharLower_Ascii(char c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return (char)(c + 0x20);
|
||||
return c;
|
||||
}
|
||||
|
||||
inline wchar_t MyCharLower_Ascii(wchar_t c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return (wchar_t)(c + 0x20);
|
||||
return c;
|
||||
}
|
||||
|
||||
wchar_t MyCharUpper_WIN(wchar_t c) throw();
|
||||
|
||||
inline wchar_t MyCharUpper(wchar_t c) throw()
|
||||
{
|
||||
if (c < 'a') return c;
|
||||
if (c <= 'z') return (wchar_t)(c - 0x20);
|
||||
if (c <= 0x7F) return c;
|
||||
#ifdef _WIN32
|
||||
#ifdef _UNICODE
|
||||
return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
|
||||
#else
|
||||
return (wchar_t)MyCharUpper_WIN(c);
|
||||
#endif
|
||||
#else
|
||||
return (wchar_t)towupper(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
wchar_t MyCharLower_WIN(wchar_t c) throw();
|
||||
|
||||
inline wchar_t MyCharLower(wchar_t c) throw()
|
||||
{
|
||||
if (c < 'A') return c;
|
||||
if (c <= 'Z') return (wchar_t)(c + 0x20);
|
||||
if (c <= 0x7F) return c;
|
||||
#ifdef _WIN32
|
||||
#ifdef _UNICODE
|
||||
return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
|
||||
#else
|
||||
return (wchar_t)MyCharLower_WIN(c);
|
||||
#endif
|
||||
#else
|
||||
return (wchar_t)tolower(c);
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
// char *MyStringUpper(char *s) throw();
|
||||
// char *MyStringLower(char *s) throw();
|
||||
|
||||
// void MyStringUpper_Ascii(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; }
|
||||
|
||||
CStringBase& operator=(T c)
|
||||
AString &operator=(char c);
|
||||
AString &operator=(const char *s);
|
||||
AString &operator=(const AString &s);
|
||||
|
||||
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)
|
||||
{
|
||||
Empty();
|
||||
int length = MyStringLen(chars);
|
||||
SetCapacity(length);
|
||||
MyStringCopy(_chars, chars);
|
||||
_length = length;
|
||||
return *this;
|
||||
}
|
||||
CStringBase& operator=(const CStringBase& s)
|
||||
{
|
||||
if (&s == this)
|
||||
return *this;
|
||||
Empty();
|
||||
SetCapacity(s._length);
|
||||
MyStringCopy(_chars, s._chars);
|
||||
_length = s._length;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CStringBase& operator+=(T c)
|
||||
{
|
||||
GrowLength(1);
|
||||
_chars[_length] = c;
|
||||
_chars[++_length] = 0;
|
||||
return *this;
|
||||
}
|
||||
CStringBase& operator+=(const T *s)
|
||||
{
|
||||
int len = MyStringLen(s);
|
||||
GrowLength(len);
|
||||
MyStringCopy(_chars + _length, s);
|
||||
_length += len;
|
||||
return *this;
|
||||
}
|
||||
CStringBase& operator+=(const CStringBase &s)
|
||||
{
|
||||
GrowLength(s._length);
|
||||
MyStringCopy(_chars + _length, s._chars);
|
||||
_length += s._length;
|
||||
return *this;
|
||||
}
|
||||
void Empty()
|
||||
{
|
||||
_length = 0;
|
||||
_chars[0] = 0;
|
||||
}
|
||||
int Length() const { return _length; }
|
||||
bool IsEmpty() const { return (_length == 0); }
|
||||
|
||||
CStringBase Mid(int startIndex) const
|
||||
{ return Mid(startIndex, _length - startIndex); }
|
||||
CStringBase Mid(int startIndex, int count) const
|
||||
{
|
||||
if (startIndex + count > _length)
|
||||
count = _length - startIndex;
|
||||
|
||||
if (startIndex == 0 && startIndex + count == _length)
|
||||
return *this;
|
||||
|
||||
CStringBase<T> result;
|
||||
result.SetCapacity(count);
|
||||
// MyStringNCopy(result._chars, _chars + startIndex, count);
|
||||
for (int i = 0; i < count; i++)
|
||||
result._chars[i] = _chars[startIndex + i];
|
||||
result._chars[count] = 0;
|
||||
result._length = count;
|
||||
return result;
|
||||
}
|
||||
CStringBase Left(int count) const
|
||||
{ return Mid(0, count); }
|
||||
CStringBase Right(int count) const
|
||||
{
|
||||
if (count > _length)
|
||||
count = _length;
|
||||
return Mid(_length - count, count);
|
||||
}
|
||||
AString &operator+=(const char *s);
|
||||
AString &operator+=(const AString &s);
|
||||
|
||||
void MakeUpper() { MyStringUpper(_chars); }
|
||||
void MakeLower() { MyStringLower(_chars); }
|
||||
void SetFrom(const char *s, unsigned len); // no check
|
||||
// AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
|
||||
AString Left(unsigned count) const { return AString(count, *this); }
|
||||
|
||||
int Compare(const CStringBase& s) const
|
||||
{ return MyStringCompare(_chars, s._chars); }
|
||||
// void MakeUpper() { MyStringUpper(_chars); }
|
||||
// void MakeLower() { MyStringLower(_chars); }
|
||||
|
||||
int Compare(const T *s) const
|
||||
{ return MyStringCompare(_chars, s); }
|
||||
|
||||
int CompareNoCase(const CStringBase& s) const
|
||||
{ return MyStringCompareNoCase(_chars, s._chars); }
|
||||
|
||||
int CompareNoCase(const T *s) const
|
||||
{ return MyStringCompareNoCase(_chars, s); }
|
||||
|
||||
/*
|
||||
int Collate(const CStringBase& s) const
|
||||
{ return MyStringCollate(_chars, s._chars); }
|
||||
int CollateNoCase(const CStringBase& s) const
|
||||
{ return MyStringCollateNoCase(_chars, s._chars); }
|
||||
*/
|
||||
|
||||
int Find(T c) const { return FindCharPosInString(_chars, c); }
|
||||
int Find(T c, int startIndex) const
|
||||
// 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
|
||||
{
|
||||
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;
|
||||
return pos < 0 ? -1 : (int)startIndex + pos;
|
||||
}
|
||||
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(T c)
|
||||
{
|
||||
const T *p = _chars;
|
||||
while (c == *p)
|
||||
p = GetNextCharPointer(p);
|
||||
Delete(0, p - _chars);
|
||||
}
|
||||
private:
|
||||
CStringBase GetTrimDefaultCharSet()
|
||||
{
|
||||
CStringBase<T> charSet;
|
||||
charSet += (T)' ';
|
||||
charSet += (T)'\n';
|
||||
charSet += (T)'\t';
|
||||
return charSet;
|
||||
}
|
||||
public:
|
||||
|
||||
void TrimLeft()
|
||||
{
|
||||
TrimLeftWithCharSet(GetTrimDefaultCharSet());
|
||||
}
|
||||
void TrimRight()
|
||||
{
|
||||
TrimRightWithCharSet(GetTrimDefaultCharSet());
|
||||
}
|
||||
void TrimRight(T c)
|
||||
{
|
||||
const T *p = _chars;
|
||||
const T *pLast = NULL;
|
||||
while (*p != 0)
|
||||
{
|
||||
if (*p == c)
|
||||
{
|
||||
if (pLast == NULL)
|
||||
pLast = p;
|
||||
}
|
||||
else
|
||||
pLast = NULL;
|
||||
p = GetNextCharPointer(p);
|
||||
}
|
||||
if (pLast != NULL)
|
||||
{
|
||||
int i = pLast - _chars;
|
||||
Delete(i, _length - i);
|
||||
}
|
||||
}
|
||||
void 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(char c);
|
||||
// void Insert(unsigned index, char c);
|
||||
void Insert(unsigned index, const char *s);
|
||||
void Insert(unsigned index, const AString &s);
|
||||
|
||||
// !!!!!!!!!!!!!!! test it if newChar = '\0'
|
||||
int Replace(T oldChar, T newChar)
|
||||
void RemoveChar(char ch) throw();
|
||||
void Replace(char oldChar, char newChar) throw();
|
||||
void Replace(const AString &oldString, const AString &newString);
|
||||
|
||||
void Delete(unsigned index) throw();
|
||||
void Delete(unsigned index, unsigned count) throw();
|
||||
void DeleteFrontal(unsigned num) throw();
|
||||
void DeleteBack() { _chars[--_len] = 0; }
|
||||
void DeleteFrom(unsigned index)
|
||||
{
|
||||
if (oldChar == newChar)
|
||||
return 0;
|
||||
int number = 0;
|
||||
int pos = 0;
|
||||
while (pos < Length())
|
||||
if (index < _len)
|
||||
{
|
||||
pos = Find(oldChar, pos);
|
||||
if (pos < 0)
|
||||
break;
|
||||
_chars[pos] = newChar;
|
||||
pos++;
|
||||
number++;
|
||||
_len = index;
|
||||
_chars[index] = 0;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
int Replace(const CStringBase &oldString, const CStringBase &newString)
|
||||
{
|
||||
if (oldString.IsEmpty())
|
||||
return 0;
|
||||
if (oldString == newString)
|
||||
return 0;
|
||||
int oldStringLength = oldString.Length();
|
||||
int newStringLength = newString.Length();
|
||||
int number = 0;
|
||||
int pos = 0;
|
||||
while (pos < _length)
|
||||
{
|
||||
pos = Find(oldString, pos);
|
||||
if (pos < 0)
|
||||
break;
|
||||
Delete(pos, oldStringLength);
|
||||
Insert(pos, newString);
|
||||
pos += newStringLength;
|
||||
number++;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
int Delete(int index, int count = 1)
|
||||
{
|
||||
if (index + count > _length)
|
||||
count = _length - index;
|
||||
if (count > 0)
|
||||
{
|
||||
MoveItems(index, index + count);
|
||||
_length -= count;
|
||||
}
|
||||
return _length;
|
||||
}
|
||||
void DeleteBack() { Delete(_length - 1); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
|
||||
bool operator<(const AString &s1, const AString &s2);
|
||||
bool operator>(const AString &s1, const AString &s2);
|
||||
|
||||
/*
|
||||
bool operator==(const AString &s1, const AString &s2);
|
||||
bool operator==(const AString &s1, const char *s2);
|
||||
bool operator==(const char *s1, const AString &s2);
|
||||
|
||||
bool operator!=(const AString &s1, const AString &s2);
|
||||
bool operator!=(const AString &s1, const char *s2);
|
||||
bool operator!=(const char *s1, const AString &s2);
|
||||
*/
|
||||
|
||||
inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
|
||||
inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; }
|
||||
inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
|
||||
|
||||
inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
|
||||
inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; }
|
||||
inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
|
||||
|
||||
|
||||
|
||||
class UString
|
||||
{
|
||||
CStringBase<T> result(s1);
|
||||
result += s2;
|
||||
return result;
|
||||
}
|
||||
wchar_t *_chars;
|
||||
unsigned _len;
|
||||
unsigned _limit;
|
||||
|
||||
template <class T>
|
||||
CStringBase<T> operator+(const CStringBase<T>& s, T c)
|
||||
{
|
||||
CStringBase<T> result(s);
|
||||
result += c;
|
||||
return result;
|
||||
}
|
||||
void MoveItems(unsigned dest, unsigned src)
|
||||
{
|
||||
memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
void InsertSpace(unsigned index, unsigned size);
|
||||
|
||||
void ReAlloc(unsigned newLimit);
|
||||
void SetStartLen(unsigned len);
|
||||
void Grow_1();
|
||||
void Grow(unsigned n);
|
||||
|
||||
template <class T>
|
||||
CStringBase<T> operator+(T c, const CStringBase<T>& s)
|
||||
{
|
||||
CStringBase<T> result(c);
|
||||
result += s;
|
||||
return result;
|
||||
}
|
||||
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);
|
||||
|
||||
template <class T>
|
||||
CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
|
||||
{
|
||||
CStringBase<T> result(s);
|
||||
result += chars;
|
||||
return result;
|
||||
}
|
||||
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
|
||||
|
||||
template <class T>
|
||||
CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
|
||||
{
|
||||
CStringBase<T> result(chars);
|
||||
result += s;
|
||||
return result;
|
||||
}
|
||||
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);
|
||||
|
||||
template <class T>
|
||||
bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
|
||||
{ return (s1.Compare(s2) == 0); }
|
||||
public:
|
||||
UString();
|
||||
UString(wchar_t c);
|
||||
UString(const wchar_t *s);
|
||||
UString(const UString &s);
|
||||
~UString() { MY_STRING_DELETE(_chars); }
|
||||
|
||||
template <class T>
|
||||
bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
|
||||
{ return (s1.Compare(s2) < 0); }
|
||||
unsigned Len() const { return _len; }
|
||||
bool IsEmpty() const { return _len == 0; }
|
||||
void Empty() { _len = 0; _chars[0] = 0; }
|
||||
|
||||
template <class T>
|
||||
bool operator==(const T *s1, const CStringBase<T>& s2)
|
||||
{ return (s2.Compare(s1) == 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]; }
|
||||
|
||||
template <class T>
|
||||
bool operator==(const CStringBase<T>& s1, const T *s2)
|
||||
{ return (s1.Compare(s2) == 0); }
|
||||
void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
|
||||
|
||||
template <class T>
|
||||
bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
|
||||
{ return (s1.Compare(s2) != 0); }
|
||||
// The minimum size of the character buffer in characters.
|
||||
// This value does not include space for a null terminator.
|
||||
wchar_t *GetBuffer(unsigned minBufLen)
|
||||
{
|
||||
if (minBufLen > _limit)
|
||||
ReAlloc(minBufLen);
|
||||
return _chars;
|
||||
}
|
||||
void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
|
||||
void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
|
||||
|
||||
template <class T>
|
||||
bool operator!=(const T *s1, const CStringBase<T>& s2)
|
||||
{ return (s2.Compare(s1) != 0); }
|
||||
UString &operator=(wchar_t c);
|
||||
UString &operator=(const wchar_t *s);
|
||||
UString &operator=(const UString &s);
|
||||
|
||||
template <class T>
|
||||
bool operator!=(const CStringBase<T>& s1, const T *s2)
|
||||
{ return (s1.Compare(s2) != 0); }
|
||||
UString &operator+=(wchar_t c)
|
||||
{
|
||||
if (_limit == _len)
|
||||
Grow_1();
|
||||
unsigned len = _len;
|
||||
wchar_t *chars = _chars;
|
||||
chars[len++] = c;
|
||||
chars[len] = 0;
|
||||
_len = len;
|
||||
return *this;
|
||||
}
|
||||
|
||||
UString &operator+=(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
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
void InsertAtFront(wchar_t c);
|
||||
// void Insert(unsigned index, wchar_t c);
|
||||
void Insert(unsigned index, const wchar_t *s);
|
||||
void Insert(unsigned index, const UString &s);
|
||||
|
||||
void RemoveChar(wchar_t ch) throw();
|
||||
void Replace(wchar_t oldChar, wchar_t newChar) throw();
|
||||
void Replace(const UString &oldString, const UString &newString);
|
||||
|
||||
void Delete(unsigned index) throw();
|
||||
void Delete(unsigned index, unsigned count) throw();
|
||||
void DeleteFrontal(unsigned num) throw();
|
||||
void DeleteBack() { _chars[--_len] = 0; }
|
||||
void DeleteFrom(unsigned index)
|
||||
{
|
||||
if (index < _len)
|
||||
{
|
||||
_len = index;
|
||||
_chars[index] = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool operator<(const UString &s1, const UString &s2);
|
||||
bool operator>(const UString &s1, const UString &s2);
|
||||
|
||||
inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
|
||||
inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
|
||||
inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
|
||||
|
||||
inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
|
||||
inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
|
||||
inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
|
||||
|
||||
typedef CStringBase<char> AString;
|
||||
typedef CStringBase<wchar_t> UString;
|
||||
|
||||
typedef CObjectVector<AString> AStringVector;
|
||||
typedef CObjectVector<UString> UStringVector;
|
||||
|
||||
30
CPP/Common/MyTypes.h
Normal file
30
CPP/Common/MyTypes.h
Normal file
@@ -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
|
||||
0
CPP/Common/MyUnknown.h
Executable file → Normal file
0
CPP/Common/MyUnknown.h
Executable file → Normal file
84
CPP/Common/MyVector.cpp
Executable file → Normal file
84
CPP/Common/MyVector.cpp
Executable file → Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
599
CPP/Common/MyVector.h
Executable file → Normal file
599
CPP/Common/MyVector.h
Executable file → Normal file
@@ -1,92 +1,247 @@
|
||||
// Common/Vector.h
|
||||
// Common/MyVector.h
|
||||
|
||||
#ifndef __COMMON_VECTOR_H
|
||||
#define __COMMON_VECTOR_H
|
||||
|
||||
#include "Defs.h"
|
||||
|
||||
class CBaseRecordVector
|
||||
{
|
||||
void MoveItems(int destIndex, int srcIndex);
|
||||
protected:
|
||||
int _capacity;
|
||||
int _size;
|
||||
void *_items;
|
||||
size_t _itemSize;
|
||||
|
||||
void ReserveOnePosition();
|
||||
void InsertOneItem(int index);
|
||||
void TestIndexAndCorrectNum(int index, int &num) const
|
||||
{ if (index + num > _size) num = _size - index; }
|
||||
public:
|
||||
CBaseRecordVector(size_t itemSize): _capacity(0), _size(0), _items(0), _itemSize(itemSize) {}
|
||||
virtual ~CBaseRecordVector();
|
||||
void ClearAndFree();
|
||||
int Size() const { return _size; }
|
||||
bool IsEmpty() const { return (_size == 0); }
|
||||
void Reserve(int newCapacity);
|
||||
void ReserveDown();
|
||||
virtual void Delete(int index, int num = 1);
|
||||
void Clear();
|
||||
void DeleteFrom(int index);
|
||||
void DeleteBack();
|
||||
};
|
||||
#ifndef __COMMON_MY_VECTOR_H
|
||||
#define __COMMON_MY_VECTOR_H
|
||||
|
||||
template <class T>
|
||||
class CRecordVector: public CBaseRecordVector
|
||||
class CRecordVector
|
||||
{
|
||||
T *_items;
|
||||
unsigned _size;
|
||||
unsigned _capacity;
|
||||
|
||||
void MoveItems(unsigned destIndex, unsigned srcIndex)
|
||||
{
|
||||
memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * (size_t)sizeof(T));
|
||||
}
|
||||
|
||||
void ReserveOnePosition()
|
||||
{
|
||||
if (_size == _capacity)
|
||||
{
|
||||
unsigned newCapacity = _capacity + (_capacity >> 2) + 1;
|
||||
T *p = new T[newCapacity];
|
||||
memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
|
||||
delete []_items;
|
||||
_items = p;
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
CRecordVector(): CBaseRecordVector(sizeof(T)){};
|
||||
CRecordVector(const CRecordVector &v): CBaseRecordVector(sizeof(T)) { *this = v; }
|
||||
CRecordVector& operator=(const CRecordVector &v)
|
||||
|
||||
CRecordVector(): _items(0), _size(0), _capacity(0) {}
|
||||
|
||||
CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0)
|
||||
{
|
||||
unsigned size = v.Size();
|
||||
if (size != 0)
|
||||
{
|
||||
_items = new T[size];
|
||||
_size = size;
|
||||
_capacity = size;
|
||||
memcpy(_items, v._items, (size_t)size * (size_t)sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned Size() const { return _size; }
|
||||
bool IsEmpty() const { return _size == 0; }
|
||||
|
||||
void ConstructReserve(unsigned size)
|
||||
{
|
||||
if (size != 0)
|
||||
{
|
||||
_items = new T[size];
|
||||
_capacity = size;
|
||||
}
|
||||
}
|
||||
|
||||
void Reserve(unsigned newCapacity)
|
||||
{
|
||||
if (newCapacity > _capacity)
|
||||
{
|
||||
T *p = new T[newCapacity];
|
||||
memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
|
||||
delete []_items;
|
||||
_items = p;
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
void ClearAndReserve(unsigned newCapacity)
|
||||
{
|
||||
Clear();
|
||||
return (*this += v);
|
||||
if (newCapacity > _capacity)
|
||||
{
|
||||
delete []_items;
|
||||
_items = NULL;
|
||||
_capacity = 0;
|
||||
_items = new T[newCapacity];
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
CRecordVector& operator+=(const CRecordVector &v)
|
||||
|
||||
void ClearAndSetSize(unsigned newSize)
|
||||
{
|
||||
int size = v.Size();
|
||||
Reserve(Size() + size);
|
||||
for (int i = 0; i < size; i++)
|
||||
Add(v[i]);
|
||||
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;
|
||||
}
|
||||
int Add(T item)
|
||||
|
||||
CRecordVector& operator+=(const CRecordVector &v)
|
||||
{
|
||||
unsigned size = v.Size();
|
||||
Reserve(_size + size);
|
||||
memcpy(_items + _size, v._items, (size_t)size * (size_t)sizeof(T));
|
||||
_size += size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned Add(const T item)
|
||||
{
|
||||
ReserveOnePosition();
|
||||
((T *)_items)[_size] = item;
|
||||
_items[_size] = item;
|
||||
return _size++;
|
||||
}
|
||||
void Insert(int index, T item)
|
||||
{
|
||||
InsertOneItem(index);
|
||||
((T *)_items)[index] = item;
|
||||
}
|
||||
// T* GetPointer() const { return (T*)_items; }
|
||||
// operator const T *() const { return _items; };
|
||||
const T& operator[](int index) const { return ((T *)_items)[index]; }
|
||||
T& operator[](int index) { return ((T *)_items)[index]; }
|
||||
const T& Front() const { return operator[](0); }
|
||||
T& Front() { return operator[](0); }
|
||||
const T& Back() const { return operator[](_size - 1); }
|
||||
T& Back() { return operator[](_size - 1); }
|
||||
|
||||
void Swap(int i, int j)
|
||||
void AddInReserved(const T item)
|
||||
{
|
||||
T temp = operator[](i);
|
||||
operator[](i) = operator[](j);
|
||||
operator[](j) = temp;
|
||||
_items[_size++] = item;
|
||||
}
|
||||
|
||||
int FindInSorted(const T& item, int left, int right) const
|
||||
void Insert(unsigned index, const T item)
|
||||
{
|
||||
ReserveOnePosition();
|
||||
MoveItems(index + 1, index);
|
||||
_items[index] = item;
|
||||
_size++;
|
||||
}
|
||||
|
||||
void MoveToFront(unsigned index)
|
||||
{
|
||||
if (index != 0)
|
||||
{
|
||||
T temp = _items[index];
|
||||
memmove(_items + 1, _items, (size_t)index * (size_t)sizeof(T));
|
||||
_items[0] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
const T& operator[](unsigned index) const { return _items[index]; }
|
||||
T& operator[](unsigned index) { return _items[index]; }
|
||||
const T& Front() const { return _items[0]; }
|
||||
T& Front() { return _items[0]; }
|
||||
const T& Back() const { return _items[_size - 1]; }
|
||||
T& Back() { return _items[_size - 1]; }
|
||||
|
||||
/*
|
||||
void Swap(unsigned i, unsigned j)
|
||||
{
|
||||
T temp = _items[i];
|
||||
_items[i] = _items[j];
|
||||
_items[j] = temp;
|
||||
}
|
||||
*/
|
||||
|
||||
int FindInSorted(const T item, unsigned left, unsigned right) const
|
||||
{
|
||||
while (left != right)
|
||||
{
|
||||
int mid = (left + right) / 2;
|
||||
const T& midValue = (*this)[mid];
|
||||
if (item == midValue)
|
||||
unsigned mid = (left + right) / 2;
|
||||
const T midVal = (*this)[mid];
|
||||
if (item == midVal)
|
||||
return mid;
|
||||
if (item < midValue)
|
||||
if (item < midVal)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
@@ -94,16 +249,16 @@ public:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FindInSorted(const T& item) const
|
||||
int FindInSorted2(const T &item, unsigned left, unsigned right) const
|
||||
{
|
||||
int left = 0, right = Size();
|
||||
while (left != right)
|
||||
{
|
||||
int mid = (left + right) / 2;
|
||||
const T& midValue = (*this)[mid];
|
||||
if (item == midValue)
|
||||
unsigned mid = (left + right) / 2;
|
||||
const T& midVal = (*this)[mid];
|
||||
int comp = item.Compare(midVal);
|
||||
if (comp == 0)
|
||||
return mid;
|
||||
if (item < midValue)
|
||||
if (comp < 0)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
@@ -111,16 +266,26 @@ public:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int AddToUniqueSorted(const T& item)
|
||||
int FindInSorted(const T item) const
|
||||
{
|
||||
int left = 0, right = Size();
|
||||
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)
|
||||
{
|
||||
int mid = (left + right) / 2;
|
||||
const T& midValue = (*this)[mid];
|
||||
if (item == midValue)
|
||||
unsigned mid = (left + right) / 2;
|
||||
const T midVal = (*this)[mid];
|
||||
if (item == midVal)
|
||||
return mid;
|
||||
if (item < midValue)
|
||||
if (item < midVal)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
@@ -129,12 +294,31 @@ public:
|
||||
return right;
|
||||
}
|
||||
|
||||
static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param)
|
||||
unsigned AddToUniqueSorted2(const T &item)
|
||||
{
|
||||
unsigned left = 0, right = _size;
|
||||
while (left != right)
|
||||
{
|
||||
unsigned mid = (left + right) / 2;
|
||||
const T& midVal = (*this)[mid];
|
||||
int comp = item.Compare(midVal);
|
||||
if (comp == 0)
|
||||
return mid;
|
||||
if (comp < 0)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
}
|
||||
Insert(right, item);
|
||||
return right;
|
||||
}
|
||||
|
||||
static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param)
|
||||
{
|
||||
T temp = p[k];
|
||||
for (;;)
|
||||
{
|
||||
int s = (k << 1);
|
||||
unsigned s = (k << 1);
|
||||
if (s > size)
|
||||
break;
|
||||
if (s < size && compare(p + s + 1, p + s, param) > 0)
|
||||
@@ -149,12 +333,12 @@ public:
|
||||
|
||||
void Sort(int (*compare)(const T*, const T*, void *), void *param)
|
||||
{
|
||||
int size = _size;
|
||||
unsigned size = _size;
|
||||
if (size <= 1)
|
||||
return;
|
||||
T* p = (&Front()) - 1;
|
||||
{
|
||||
int i = size / 2;
|
||||
unsigned i = size >> 1;
|
||||
do
|
||||
SortRefDown(p, i, size, compare, param);
|
||||
while (--i != 0);
|
||||
@@ -168,6 +352,46 @@ public:
|
||||
}
|
||||
while (size > 1);
|
||||
}
|
||||
|
||||
static void SortRefDown2(T* p, unsigned k, unsigned size)
|
||||
{
|
||||
T temp = p[k];
|
||||
for (;;)
|
||||
{
|
||||
unsigned s = (k << 1);
|
||||
if (s > size)
|
||||
break;
|
||||
if (s < size && p[s + 1].Compare(p[s]) > 0)
|
||||
s++;
|
||||
if (temp.Compare(p[s]) >= 0)
|
||||
break;
|
||||
p[k] = p[s];
|
||||
k = s;
|
||||
}
|
||||
p[k] = temp;
|
||||
}
|
||||
|
||||
void Sort2()
|
||||
{
|
||||
unsigned size = _size;
|
||||
if (size <= 1)
|
||||
return;
|
||||
T* p = (&Front()) - 1;
|
||||
{
|
||||
unsigned i = size >> 1;
|
||||
do
|
||||
SortRefDown2(p, i, size);
|
||||
while (--i != 0);
|
||||
}
|
||||
do
|
||||
{
|
||||
T temp = p[size];
|
||||
p[size--] = p[1];
|
||||
p[1] = temp;
|
||||
SortRefDown2(p, 1, size);
|
||||
}
|
||||
while (size > 1);
|
||||
}
|
||||
};
|
||||
|
||||
typedef CRecordVector<int> CIntVector;
|
||||
@@ -177,76 +401,174 @@ 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);
|
||||
}
|
||||
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);
|
||||
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& 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)
|
||||
|
||||
CObjectVector& operator+=(const CObjectVector &v)
|
||||
{
|
||||
TestIndexAndCorrectNum(index, num);
|
||||
for (int i = 0; i < num; i++)
|
||||
delete (T *)(((void **)_items)[index + i]);
|
||||
CPointerVector::Delete(index, num);
|
||||
unsigned size = v.Size();
|
||||
_v.Reserve(Size() + size);
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
_v.AddInReserved(new T(v[i]));
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T& operator[](unsigned index) const { return *((T *)_v[index]); }
|
||||
T& operator[](unsigned index) { return *((T *)_v[index]); }
|
||||
const T& Front() const { return operator[](0); }
|
||||
T& Front() { return operator[](0); }
|
||||
const T& Back() const { return 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()
|
||||
{
|
||||
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)
|
||||
{
|
||||
right = mid + 1;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
@@ -255,12 +577,39 @@ public:
|
||||
return right;
|
||||
}
|
||||
|
||||
/*
|
||||
unsigned AddToSorted(const T& item)
|
||||
{
|
||||
unsigned left = 0, right = Size();
|
||||
while (left != right)
|
||||
{
|
||||
unsigned mid = (left + right) / 2;
|
||||
const T& midVal = (*this)[mid];
|
||||
int comp = item.Compare(midVal);
|
||||
if (comp == 0)
|
||||
{
|
||||
right = mid + 1;
|
||||
break;
|
||||
}
|
||||
if (comp < 0)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
}
|
||||
Insert(right, item);
|
||||
return right;
|
||||
}
|
||||
*/
|
||||
|
||||
void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
|
||||
{ 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
|
||||
|
||||
24
CPP/Common/MyWindows.cpp
Executable file → Normal file
24
CPP/Common/MyWindows.cpp
Executable file → Normal file
@@ -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)
|
||||
|
||||
15
CPP/Common/MyWindows.h
Executable file → Normal file
15
CPP/Common/MyWindows.h
Executable file → Normal file
@@ -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
|
||||
{
|
||||
|
||||
267
CPP/Common/MyXml.cpp
Executable file → Normal file
267
CPP/Common/MyXml.cpp
Executable file → Normal file
@@ -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;
|
||||
}
|
||||
if (posTemp == pos)
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
CXmlProp prop;
|
||||
if (!ReadProperty(s, pos, prop))
|
||||
return false;
|
||||
Props.Add(prop);
|
||||
posTemp = pos;
|
||||
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 (beg == s)
|
||||
return NULL;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
23
CPP/Common/MyXml.h
Executable file → Normal file
23
CPP/Common/MyXml.h
Executable file → Normal file
@@ -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
|
||||
|
||||
66
CPP/Common/NewHandler.cpp
Executable file → Normal file
66
CPP/Common/NewHandler.cpp
Executable file → Normal file
@@ -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);
|
||||
*/
|
||||
// if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
|
||||
::free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
void *
|
||||
#ifdef _MSC_VER
|
||||
__cdecl
|
||||
#endif
|
||||
operator new[](size_t size)
|
||||
{
|
||||
// void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
|
||||
void *p = ::malloc(size);
|
||||
if (p == 0)
|
||||
throw CNewException();
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef _MSC_VER
|
||||
__cdecl
|
||||
#endif
|
||||
operator delete[](void *p) throw()
|
||||
{
|
||||
// if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
|
||||
::free(p);
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#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;
|
||||
|
||||
58
CPP/Common/NewHandler.h
Executable file → Normal file
58
CPP/Common/NewHandler.h
Executable file → Normal file
@@ -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
|
||||
|
||||
#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
|
||||
|
||||
0
CPP/Common/Random.cpp
Executable file → Normal file
0
CPP/Common/Random.cpp
Executable file → Normal file
0
CPP/Common/Random.h
Executable file → Normal file
0
CPP/Common/Random.h
Executable file → Normal file
52
CPP/Common/Sha256Reg.cpp
Normal file
52
CPP/Common/Sha256Reg.cpp
Normal file
@@ -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)
|
||||
3
CPP/Common/StdAfx.h
Executable file → Normal file
3
CPP/Common/StdAfx.h
Executable file → Normal file
@@ -3,7 +3,6 @@
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
// #include "MyWindows.h"
|
||||
#include "NewHandler.h"
|
||||
#include "Common.h"
|
||||
|
||||
#endif
|
||||
|
||||
19
CPP/Common/StdInStream.cpp
Executable file → Normal file
19
CPP/Common/StdInStream.cpp
Executable file → Normal file
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
21
CPP/Common/StdInStream.h
Executable file → Normal file
21
CPP/Common/StdInStream.h
Executable file → Normal file
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
58
CPP/Common/StdOutStream.cpp
Executable file → Normal file
58
CPP/Common/StdOutStream.cpp
Executable file → Normal file
@@ -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 ()
|
||||
CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*func)(CStdOutStream &))
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(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 textString[32];
|
||||
ConvertInt64ToString(number, textString);
|
||||
return operator<<(textString);
|
||||
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 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);
|
||||
}
|
||||
|
||||
41
CPP/Common/StdOutStream.h
Executable file → Normal file
41
CPP/Common/StdOutStream.h
Executable file → Normal file
@@ -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;
|
||||
|
||||
90
CPP/Common/StringConvert.cpp
Executable file → Normal file
90
CPP/Common/StringConvert.cpp
Executable file → Normal file
@@ -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);
|
||||
|
||||
10
CPP/Common/StringConvert.h
Executable file → Normal file
10
CPP/Common/StringConvert.h
Executable file → Normal file
@@ -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)
|
||||
|
||||
148
CPP/Common/StringToInt.cpp
Executable file → Normal file
148
CPP/Common/StringToInt.cpp
Executable file → Normal file
@@ -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)
|
||||
{
|
||||
UInt64 result = 0;
|
||||
for (;;)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
19
CPP/Common/StringToInt.h
Executable file → Normal file
19
CPP/Common/StringToInt.h
Executable file → Normal file
@@ -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
|
||||
|
||||
74
CPP/Common/TextConfig.cpp
Executable file → Normal file
74
CPP/Common/TextConfig.cpp
Executable file → Normal file
@@ -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;
|
||||
}
|
||||
|
||||
7
CPP/Common/TextConfig.h
Executable file → Normal file
7
CPP/Common/TextConfig.h
Executable file → Normal file
@@ -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
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// Common/Types.h
|
||||
|
||||
#ifndef __COMMON_TYPES_H
|
||||
#define __COMMON_TYPES_H
|
||||
|
||||
#include "../../C/Types.h"
|
||||
|
||||
typedef int HRes;
|
||||
|
||||
#endif
|
||||
|
||||
59
CPP/Common/UTFConvert.cpp
Executable file → Normal file
59
CPP/Common/UTFConvert.cpp
Executable file → Normal file
@@ -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;
|
||||
}
|
||||
|
||||
5
CPP/Common/UTFConvert.h
Executable file → Normal file
5
CPP/Common/UTFConvert.h
Executable file → Normal file
@@ -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);
|
||||
|
||||
|
||||
401
CPP/Common/Wildcard.cpp
Executable file → Normal file
401
CPP/Common/Wildcard.cpp
Executable file → Normal file
@@ -2,8 +2,6 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../C/Types.h"
|
||||
|
||||
#include "Wildcard.h"
|
||||
|
||||
bool g_CaseSensitive =
|
||||
@@ -13,38 +11,44 @@ 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"\"/:<>\\|";
|
||||
|
||||
|
||||
static inline bool IsCharDirLimiter(wchar_t c)
|
||||
{
|
||||
return (
|
||||
#ifdef _WIN32
|
||||
c == kDirDelimiter1 ||
|
||||
#endif
|
||||
c == kDirDelimiter2);
|
||||
}
|
||||
|
||||
int CompareFileNames(const UString &s1, const UString &s2)
|
||||
bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
if (g_CaseSensitive)
|
||||
return s1.Compare(s2);
|
||||
return s1.CompareNoCase(s2);
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int CompareFileNames(const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
if (g_CaseSensitive)
|
||||
return wcscmp(s1, s2);
|
||||
return MyStringCompareNoCase(s1, s2);
|
||||
}
|
||||
|
||||
#ifndef USE_UNICODE_FSTRING
|
||||
int CompareFileNames(const char *s1, const char *s2)
|
||||
{
|
||||
if (g_CaseSensitive)
|
||||
return wcscmp(fs2us(s1), fs2us(s2));
|
||||
return MyStringCompareNoCase(fs2us(s1), fs2us(s2));
|
||||
}
|
||||
#endif
|
||||
|
||||
// -----------------------------------------
|
||||
// this function compares name with mask
|
||||
// ? - any char
|
||||
@@ -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
|
||||
{
|
||||
for (int i = 0; i < pathParts.Size(); i++)
|
||||
{
|
||||
const UString &part = pathParts[i];
|
||||
if (part == L".." || part == L".")
|
||||
{
|
||||
isAbs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
int numAbsParts = 0;
|
||||
if (isAbs)
|
||||
if (pathParts.Size() > 1)
|
||||
numAbsParts = pathParts.Size() - 1;
|
||||
else
|
||||
numAbsParts = 1;
|
||||
|
||||
UString prefix;
|
||||
for (int i = 0; i < numAbsParts; i++)
|
||||
|
||||
if (pathMode != k_AbsPath)
|
||||
{
|
||||
const UString &front = pathParts.Front();
|
||||
if (DoesNameContainWildCard(front))
|
||||
break;
|
||||
prefix += front;
|
||||
prefix += WCHAR_PATH_SEPARATOR;
|
||||
pathParts.Delete(0);
|
||||
bool isAbs = false;
|
||||
|
||||
if (front.IsEmpty())
|
||||
isAbs = true;
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
if (IsDriveColonName(front))
|
||||
isAbs = true;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (numAbsParts > 1 && pathMode == k_FullPath)
|
||||
numAbsParts = 1;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
101
CPP/Common/Wildcard.h
Executable file → Normal file
101
CPP/Common/Wildcard.h
Executable file → Normal file
@@ -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
|
||||
|
||||
54
CPP/Common/XzCrc64Reg.cpp
Normal file
54
CPP/Common/XzCrc64Reg.cpp
Normal file
@@ -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)
|
||||
Reference in New Issue
Block a user