chore: initial commit (extracted from Launchers monorepo)
Plugin: ns7zip v2.0.0 Architectures: x86-ansi, x86-unicode, amd64-unicode License: LGPL-2.1-or-later
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
// Common/AutoPtr.h
|
||||
|
||||
#ifndef __COMMON_AUTOPTR_H
|
||||
#define __COMMON_AUTOPTR_H
|
||||
|
||||
template<class T> class CMyAutoPtr
|
||||
{
|
||||
T *_p;
|
||||
public:
|
||||
CMyAutoPtr(T *p = 0) : _p(p) {}
|
||||
CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {}
|
||||
CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p)
|
||||
{
|
||||
reset(p.release());
|
||||
return (*this);
|
||||
}
|
||||
~CMyAutoPtr() { delete _p; }
|
||||
T& operator*() const { return *_p; }
|
||||
// T* operator->() const { return (&**this); }
|
||||
T* get() const { return _p; }
|
||||
T* release()
|
||||
{
|
||||
T *tmp = _p;
|
||||
_p = 0;
|
||||
return tmp;
|
||||
}
|
||||
void reset(T* p = 0)
|
||||
{
|
||||
if (p != _p)
|
||||
delete _p;
|
||||
_p = p;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
// Common/CRC.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../C/7zCrc.h"
|
||||
|
||||
struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit;
|
||||
@@ -0,0 +1,92 @@
|
||||
// Common/C_FileIO.cpp
|
||||
|
||||
#include "C_FileIO.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace NC {
|
||||
namespace NFile {
|
||||
namespace NIO {
|
||||
|
||||
bool CFileBase::OpenBinary(const char *name, int flags)
|
||||
{
|
||||
#ifdef O_BINARY
|
||||
flags |= O_BINARY;
|
||||
#endif
|
||||
Close();
|
||||
_handle = ::open(name, flags, 0666);
|
||||
return _handle != -1;
|
||||
}
|
||||
|
||||
bool CFileBase::Close()
|
||||
{
|
||||
if (_handle == -1)
|
||||
return true;
|
||||
if (close(_handle) != 0)
|
||||
return false;
|
||||
_handle = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFileBase::GetLength(UInt64 &length) const
|
||||
{
|
||||
off_t curPos = Seek(0, SEEK_CUR);
|
||||
off_t lengthTemp = Seek(0, SEEK_END);
|
||||
Seek(curPos, SEEK_SET);
|
||||
length = (UInt64)lengthTemp;
|
||||
return true;
|
||||
}
|
||||
|
||||
off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const
|
||||
{
|
||||
return ::lseek(_handle, distanceToMove, moveMethod);
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// CInFile
|
||||
|
||||
bool CInFile::Open(const char *name)
|
||||
{
|
||||
return CFileBase::OpenBinary(name, O_RDONLY);
|
||||
}
|
||||
|
||||
bool CInFile::OpenShared(const char *name, bool)
|
||||
{
|
||||
return Open(name);
|
||||
}
|
||||
|
||||
ssize_t CInFile::Read(void *data, size_t size)
|
||||
{
|
||||
return read(_handle, data, size);
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// COutFile
|
||||
|
||||
bool COutFile::Create(const char *name, bool createAlways)
|
||||
{
|
||||
if (createAlways)
|
||||
{
|
||||
Close();
|
||||
_handle = ::creat(name, 0666);
|
||||
return _handle != -1;
|
||||
}
|
||||
return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY);
|
||||
}
|
||||
|
||||
bool COutFile::Open(const char *name, DWORD creationDisposition)
|
||||
{
|
||||
return Create(name, false);
|
||||
}
|
||||
|
||||
ssize_t COutFile::Write(const void *data, size_t size)
|
||||
{
|
||||
return write(_handle, data, size);
|
||||
}
|
||||
|
||||
}}}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Common/C_FileIO.h
|
||||
|
||||
#ifndef __COMMON_C_FILEIO_H
|
||||
#define __COMMON_C_FILEIO_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "MyTypes.h"
|
||||
#include "MyWindows.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
typedef size_t ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace NC {
|
||||
namespace NFile {
|
||||
namespace NIO {
|
||||
|
||||
class CFileBase
|
||||
{
|
||||
protected:
|
||||
int _handle;
|
||||
bool OpenBinary(const char *name, int flags);
|
||||
public:
|
||||
CFileBase(): _handle(-1) {};
|
||||
~CFileBase() { Close(); }
|
||||
bool Close();
|
||||
bool GetLength(UInt64 &length) const;
|
||||
off_t Seek(off_t distanceToMove, int moveMethod) const;
|
||||
};
|
||||
|
||||
class CInFile: public CFileBase
|
||||
{
|
||||
public:
|
||||
bool Open(const char *name);
|
||||
bool OpenShared(const char *name, bool shareForWrite);
|
||||
ssize_t Read(void *data, size_t size);
|
||||
};
|
||||
|
||||
class COutFile: public CFileBase
|
||||
{
|
||||
public:
|
||||
bool Create(const char *name, bool createAlways);
|
||||
bool Open(const char *name, DWORD creationDisposition);
|
||||
ssize_t Write(const void *data, size_t size);
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
// ComTry.h
|
||||
|
||||
#ifndef __COM_TRY_H
|
||||
#define __COM_TRY_H
|
||||
|
||||
#include "MyWindows.h"
|
||||
// #include "Exception.h"
|
||||
// #include "NewHandler.h"
|
||||
|
||||
#define COM_TRY_BEGIN try {
|
||||
#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; }
|
||||
|
||||
/*
|
||||
#define COM_TRY_END } \
|
||||
catch(const CNewException &) { return E_OUTOFMEMORY; } \
|
||||
catch(...) { return HRESULT_FROM_WIN32(ERROR_NOACCESS); } \
|
||||
*/
|
||||
// catch(const CSystemException &e) { return e.ErrorCode; }
|
||||
// catch(...) { return E_FAIL; }
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,197 @@
|
||||
// CommandLineParser.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CommandLineParser.h"
|
||||
|
||||
namespace NCommandLineParser {
|
||||
|
||||
bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
|
||||
{
|
||||
dest1.Empty();
|
||||
dest2.Empty();
|
||||
bool quoteMode = false;
|
||||
unsigned i;
|
||||
for (i = 0; i < src.Len(); i++)
|
||||
{
|
||||
wchar_t c = src[i];
|
||||
if ((c == L' ' || c == L'\t') && !quoteMode)
|
||||
{
|
||||
dest2 = src.Ptr(i + 1);
|
||||
return i != 0;
|
||||
}
|
||||
if (c == L'\"')
|
||||
quoteMode = !quoteMode;
|
||||
else
|
||||
dest1 += c;
|
||||
}
|
||||
return i != 0;
|
||||
}
|
||||
|
||||
void SplitCommandLine(const UString &s, UStringVector &parts)
|
||||
{
|
||||
UString sTemp (s);
|
||||
sTemp.Trim();
|
||||
parts.Clear();
|
||||
for (;;)
|
||||
{
|
||||
UString s1, s2;
|
||||
if (SplitCommandLine(sTemp, s1, s2))
|
||||
parts.Add(s1);
|
||||
if (s2.IsEmpty())
|
||||
break;
|
||||
sTemp = s2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char * const kStopSwitchParsing = "--";
|
||||
|
||||
static bool inline IsItSwitchChar(wchar_t c)
|
||||
{
|
||||
return (c == '-');
|
||||
}
|
||||
|
||||
CParser::CParser():
|
||||
_switches(NULL),
|
||||
StopSwitchIndex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
CParser::~CParser()
|
||||
{
|
||||
delete []_switches;
|
||||
}
|
||||
|
||||
|
||||
// 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, unsigned numSwitches)
|
||||
{
|
||||
if (s.IsEmpty() || !IsItSwitchChar(s[0]))
|
||||
return false;
|
||||
|
||||
unsigned pos = 1;
|
||||
unsigned switchIndex = 0;
|
||||
int maxLen = -1;
|
||||
|
||||
for (unsigned i = 0; i < numSwitches; i++)
|
||||
{
|
||||
const char * const key = switchForms[i].Key;
|
||||
unsigned switchLen = MyStringLen(key);
|
||||
if ((int)switchLen <= maxLen || pos + switchLen > s.Len())
|
||||
continue;
|
||||
if (IsString1PrefixedByString2_NoCase_Ascii((const wchar_t *)s + pos, key))
|
||||
{
|
||||
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 == 1)
|
||||
{
|
||||
sw.WithMinus = (s[pos] == '-');
|
||||
if (sw.WithMinus)
|
||||
return true;
|
||||
ErrorMessage = "Incorrect switch postfix:";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case NSwitchType::kChar:
|
||||
if (rem == 1)
|
||||
{
|
||||
wchar_t c = s[pos];
|
||||
if (c <= 0x7F)
|
||||
{
|
||||
sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);
|
||||
if (sw.PostCharIndex >= 0)
|
||||
return true;
|
||||
}
|
||||
ErrorMessage = "Incorrect switch postfix:";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case NSwitchType::kString:
|
||||
{
|
||||
sw.PostStrings.Add(s.Ptr(pos));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos != s.Len())
|
||||
{
|
||||
ErrorMessage = "Too long switch:";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CParser::ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings)
|
||||
{
|
||||
StopSwitchIndex = -1;
|
||||
ErrorMessage.Empty();
|
||||
ErrorLine.Empty();
|
||||
NonSwitchStrings.Clear();
|
||||
delete []_switches;
|
||||
_switches = NULL;
|
||||
_switches = new CSwitchResult[numSwitches];
|
||||
|
||||
FOR_VECTOR (i, commandStrings)
|
||||
{
|
||||
const UString &s = commandStrings[i];
|
||||
if (StopSwitchIndex < 0)
|
||||
{
|
||||
if (s.IsEqualTo(kStopSwitchParsing))
|
||||
{
|
||||
StopSwitchIndex = NonSwitchStrings.Size();
|
||||
continue;
|
||||
}
|
||||
if (!s.IsEmpty() && IsItSwitchChar(s[0]))
|
||||
{
|
||||
if (ParseString(s, switchForms, numSwitches))
|
||||
continue;
|
||||
ErrorLine = s;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
NonSwitchStrings.Add(s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// Common/CommandLineParser.h
|
||||
|
||||
#ifndef __COMMON_COMMAND_LINE_PARSER_H
|
||||
#define __COMMON_COMMAND_LINE_PARSER_H
|
||||
|
||||
#include "MyString.h"
|
||||
|
||||
namespace NCommandLineParser {
|
||||
|
||||
bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
|
||||
void SplitCommandLine(const UString &s, UStringVector &parts);
|
||||
|
||||
namespace NSwitchType
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kSimple,
|
||||
kMinus,
|
||||
kString,
|
||||
kChar
|
||||
};
|
||||
}
|
||||
|
||||
struct CSwitchForm
|
||||
{
|
||||
const char *Key;
|
||||
Byte Type;
|
||||
bool Multi;
|
||||
Byte MinLen;
|
||||
// int MaxLen;
|
||||
const char *PostCharSet;
|
||||
};
|
||||
|
||||
struct CSwitchResult
|
||||
{
|
||||
bool ThereIs;
|
||||
bool WithMinus;
|
||||
int PostCharIndex;
|
||||
UStringVector PostStrings;
|
||||
|
||||
CSwitchResult(): ThereIs(false) {};
|
||||
};
|
||||
|
||||
class CParser
|
||||
{
|
||||
CSwitchResult *_switches;
|
||||
|
||||
bool ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches);
|
||||
public:
|
||||
UStringVector NonSwitchStrings;
|
||||
int StopSwitchIndex; // NonSwitchStrings[StopSwitchIndex+] are after "--"
|
||||
AString ErrorMessage;
|
||||
UString ErrorLine;
|
||||
|
||||
CParser();
|
||||
~CParser();
|
||||
bool ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings);
|
||||
const CSwitchResult& operator[](unsigned index) const { return _switches[index]; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
// Common.h
|
||||
|
||||
#ifndef __COMMON_COMMON_H
|
||||
#define __COMMON_COMMON_H
|
||||
|
||||
/*
|
||||
This file is included to all cpp files in 7-Zip.
|
||||
Each folder contains StdAfx.h file that includes "Common.h".
|
||||
So 7-Zip includes "Common.h" in both modes:
|
||||
with precompiled StdAfx.h
|
||||
and
|
||||
without precompiled StdAfx.h
|
||||
|
||||
If you use 7-Zip code, you must include "Common.h" before other h files of 7-zip.
|
||||
If you don't need some things that are used in 7-Zip,
|
||||
you can change this h file or h files included in this file.
|
||||
*/
|
||||
|
||||
// compiler pragmas to disable some warnings
|
||||
#include "../../C/Compiler.h"
|
||||
|
||||
// it's <windows.h> or code that defines windows things, if it's not _WIN32
|
||||
#include "MyWindows.h"
|
||||
|
||||
// NewHandler.h and NewHandler.cpp redefine operator new() to throw exceptions, if compiled with old MSVC compilers
|
||||
#include "NewHandler.h"
|
||||
|
||||
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
|
||||
/* There is BUG in MSVC 6.0 compiler for operator new[]:
|
||||
It doesn't check overflow, when it calculates size in bytes for allocated array.
|
||||
So we can use MY_ARRAY_NEW macro instead of new[] operator. */
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1200) && !defined(_WIN64)
|
||||
#define MY_ARRAY_NEW(p, T, size) p = new T[(size > (unsigned)0xFFFFFFFF / sizeof(T)) ? (unsigned)0xFFFFFFFF / sizeof(T) : size];
|
||||
#else
|
||||
#define MY_ARRAY_NEW(p, T, size) p = new T[size];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,98 @@
|
||||
// CrcReg.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../C/7zCrc.h"
|
||||
#include "../../C/CpuArch.h"
|
||||
|
||||
#include "../Common/MyCom.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);
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
|
||||
extern CRC_FUNC g_CrcUpdate;
|
||||
extern CRC_FUNC g_CrcUpdateT8;
|
||||
extern CRC_FUNC g_CrcUpdateT4;
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
class CCrcHasher:
|
||||
public IHasher,
|
||||
public ICompressSetCoderProperties,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt32 _crc;
|
||||
CRC_FUNC _updateFunc;
|
||||
Byte mtDummy[1 << 7];
|
||||
|
||||
bool SetFunctions(UInt32 tSize);
|
||||
public:
|
||||
CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); }
|
||||
|
||||
MY_UNKNOWN_IMP2(IHasher, ICompressSetCoderProperties)
|
||||
INTERFACE_IHasher(;)
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
|
||||
};
|
||||
|
||||
bool CCrcHasher::SetFunctions(UInt32 tSize)
|
||||
{
|
||||
_updateFunc = g_CrcUpdate;
|
||||
|
||||
if (tSize == 1)
|
||||
_updateFunc = CrcUpdateT1;
|
||||
else if (tSize == 4)
|
||||
{
|
||||
if (g_CrcUpdateT4)
|
||||
_updateFunc = g_CrcUpdateT4;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (tSize == 8)
|
||||
{
|
||||
if (g_CrcUpdateT8)
|
||||
_updateFunc = g_CrcUpdateT8;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CCrcHasher::Init() throw()
|
||||
{
|
||||
_crc = CRC_INIT_VAL;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size) throw()
|
||||
{
|
||||
_crc = _updateFunc(_crc, data, size, g_CrcTable);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest) throw()
|
||||
{
|
||||
UInt32 val = CRC_GET_DIGEST(_crc);
|
||||
SetUi32(digest, val);
|
||||
}
|
||||
|
||||
REGISTER_HASHER(CCrcHasher, 0x1, "CRC32", 4)
|
||||
@@ -0,0 +1,15 @@
|
||||
// Common/Defs.h
|
||||
|
||||
#ifndef __COMMON_DEFS_H
|
||||
#define __COMMON_DEFS_H
|
||||
|
||||
template <class T> inline T MyMin(T a, T b) { return a < b ? a : b; }
|
||||
template <class T> inline T MyMax(T a, T b) { return a > b ? a : b; }
|
||||
|
||||
template <class T> inline int MyCompare(T a, T b)
|
||||
{ return a == b ? 0 : (a < b ? -1 : 1); }
|
||||
|
||||
inline int BoolToInt(bool v) { return (v ? 1 : 0); }
|
||||
inline bool IntToBool(int v) { return (v != 0); }
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
// Common/DynLimBuf.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DynLimBuf.h"
|
||||
#include "MyString.h"
|
||||
|
||||
CDynLimBuf::CDynLimBuf(size_t limit) throw()
|
||||
{
|
||||
_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) throw()
|
||||
{
|
||||
if (_error)
|
||||
return *this;
|
||||
if (_size == _pos)
|
||||
{
|
||||
size_t n = _sizeLimit - _size;
|
||||
if (n == 0)
|
||||
{
|
||||
_error = true;
|
||||
return *this;
|
||||
}
|
||||
if (n > _size)
|
||||
n = _size;
|
||||
|
||||
n += _pos;
|
||||
|
||||
Byte *newBuf = (Byte *)MyAlloc(n);
|
||||
if (!newBuf)
|
||||
{
|
||||
_error = true;
|
||||
return *this;
|
||||
}
|
||||
memcpy(newBuf, _chars, _pos);
|
||||
MyFree(_chars);
|
||||
_chars = newBuf;
|
||||
_size = n;
|
||||
}
|
||||
_chars[_pos++] = c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CDynLimBuf &CDynLimBuf::operator+=(const char *s) throw()
|
||||
{
|
||||
if (_error)
|
||||
return *this;
|
||||
unsigned len = MyStringLen(s);
|
||||
size_t rem = _sizeLimit - _pos;
|
||||
if (rem < len)
|
||||
{
|
||||
len = (unsigned)rem;
|
||||
_error = true;
|
||||
}
|
||||
if (_size - _pos < len)
|
||||
{
|
||||
size_t n = _pos + len;
|
||||
if (n - _size < _size)
|
||||
{
|
||||
n = _sizeLimit;
|
||||
if (n - _size > _size)
|
||||
n = _size * 2;
|
||||
}
|
||||
|
||||
Byte *newBuf = (Byte *)MyAlloc(n);
|
||||
if (!newBuf)
|
||||
{
|
||||
_error = true;
|
||||
return *this;
|
||||
}
|
||||
memcpy(newBuf, _chars, _pos);
|
||||
MyFree(_chars);
|
||||
_chars = newBuf;
|
||||
_size = n;
|
||||
}
|
||||
memcpy(_chars + _pos, s, len);
|
||||
_pos += len;
|
||||
return *this;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// 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);
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
CDynLimBuf &operator+=(wchar_t c);
|
||||
|
||||
public:
|
||||
CDynLimBuf(size_t limit) throw();
|
||||
~CDynLimBuf() { MyFree(_chars); }
|
||||
|
||||
size_t Len() const { return _pos; }
|
||||
bool IsError() const { return _error; }
|
||||
void Empty() { _pos = 0; _error = false; }
|
||||
|
||||
operator const Byte *() const { return _chars; }
|
||||
// const char *Ptr() const { return _chars; }
|
||||
|
||||
CDynLimBuf &operator+=(char c) throw();
|
||||
CDynLimBuf &operator+=(const char *s) throw();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
// Common/DynamicBuffer.h
|
||||
|
||||
#ifndef __COMMON_DYNAMIC_BUFFER_H
|
||||
#define __COMMON_DYNAMIC_BUFFER_H
|
||||
|
||||
template <class T> class CDynamicBuffer
|
||||
{
|
||||
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 = _size >= 64 ? _size : 64;
|
||||
if (delta < size)
|
||||
delta = size;
|
||||
size_t newCap = _size + delta;
|
||||
if (newCap < delta)
|
||||
{
|
||||
newCap = _size + size;
|
||||
if (newCap < size)
|
||||
throw 20120116;
|
||||
}
|
||||
|
||||
T *newBuffer = new T[newCap];
|
||||
if (_pos != 0)
|
||||
memcpy(newBuffer, _items, _pos * sizeof(T));
|
||||
delete []_items;
|
||||
_items = newBuffer;
|
||||
_size = newCap;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
size_t rem = _size - _pos;
|
||||
if (rem < addSize)
|
||||
Grow(addSize - rem);
|
||||
T *res = _items + _pos;
|
||||
_pos += addSize;
|
||||
return res;
|
||||
}
|
||||
|
||||
void AddData(const T *data, size_t size)
|
||||
{
|
||||
memcpy(GetCurPtrAndGrow(size), data, size * sizeof(T));
|
||||
}
|
||||
|
||||
const size_t GetPos() const { return _pos; }
|
||||
|
||||
// void Empty() { _pos = 0; }
|
||||
};
|
||||
|
||||
typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,193 @@
|
||||
// Common/IntToString.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../C/CpuArch.h"
|
||||
|
||||
#include "IntToString.h"
|
||||
|
||||
#define CONVERT_INT_TO_STR(charType, tempSize) \
|
||||
unsigned char temp[tempSize]; unsigned i = 0; \
|
||||
while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
|
||||
*s++ = (charType)('0' + (unsigned)val); \
|
||||
while (i != 0) { i--; *s++ = temp[i]; } \
|
||||
*s = 0;
|
||||
|
||||
void ConvertUInt32ToString(UInt32 val, char *s) throw()
|
||||
{
|
||||
CONVERT_INT_TO_STR(char, 16);
|
||||
}
|
||||
|
||||
void ConvertUInt64ToString(UInt64 val, char *s) throw()
|
||||
{
|
||||
if (val <= (UInt32)0xFFFFFFFF)
|
||||
{
|
||||
ConvertUInt32ToString((UInt32)val, s);
|
||||
return;
|
||||
}
|
||||
CONVERT_INT_TO_STR(char, 24);
|
||||
}
|
||||
|
||||
void ConvertUInt64ToOct(UInt64 val, char *s) throw()
|
||||
{
|
||||
UInt64 v = val;
|
||||
unsigned i;
|
||||
for (i = 1;; i++)
|
||||
{
|
||||
v >>= 3;
|
||||
if (v == 0)
|
||||
break;
|
||||
}
|
||||
s[i] = 0;
|
||||
do
|
||||
{
|
||||
unsigned t = (unsigned)(val & 0x7);
|
||||
val >>= 3;
|
||||
s[--i] = (char)('0' + t);
|
||||
}
|
||||
while (i);
|
||||
}
|
||||
|
||||
|
||||
#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
|
||||
|
||||
static inline char GetHexChar(unsigned t) { return GET_HEX_CHAR(t); }
|
||||
|
||||
|
||||
void ConvertUInt32ToHex(UInt32 val, char *s) throw()
|
||||
{
|
||||
UInt32 v = val;
|
||||
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] = GET_HEX_CHAR(t);
|
||||
}
|
||||
while (i);
|
||||
}
|
||||
|
||||
|
||||
void ConvertUInt64ToHex(UInt64 val, char *s) throw()
|
||||
{
|
||||
UInt64 v = val;
|
||||
unsigned i;
|
||||
for (i = 1;; i++)
|
||||
{
|
||||
v >>= 4;
|
||||
if (v == 0)
|
||||
break;
|
||||
}
|
||||
s[i] = 0;
|
||||
do
|
||||
{
|
||||
unsigned t = (unsigned)(val & 0xF);
|
||||
val >>= 4;
|
||||
s[--i] = GET_HEX_CHAR(t);
|
||||
}
|
||||
while (i);
|
||||
}
|
||||
|
||||
void ConvertUInt32ToHex8Digits(UInt32 val, char *s) throw()
|
||||
{
|
||||
s[8] = 0;
|
||||
for (int i = 7; i >= 0; i--)
|
||||
{
|
||||
unsigned t = val & 0xF;
|
||||
val >>= 4;
|
||||
s[i] = GET_HEX_CHAR(t);;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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) throw()
|
||||
{
|
||||
CONVERT_INT_TO_STR(wchar_t, 16);
|
||||
}
|
||||
|
||||
void ConvertUInt64ToString(UInt64 val, wchar_t *s) throw()
|
||||
{
|
||||
if (val <= (UInt32)0xFFFFFFFF)
|
||||
{
|
||||
ConvertUInt32ToString((UInt32)val, s);
|
||||
return;
|
||||
}
|
||||
CONVERT_INT_TO_STR(wchar_t, 24);
|
||||
}
|
||||
|
||||
void ConvertInt64ToString(Int64 val, char *s) throw()
|
||||
{
|
||||
if (val < 0)
|
||||
{
|
||||
*s++ = '-';
|
||||
val = -val;
|
||||
}
|
||||
ConvertUInt64ToString(val, s);
|
||||
}
|
||||
|
||||
void ConvertInt64ToString(Int64 val, wchar_t *s) throw()
|
||||
{
|
||||
if (val < 0)
|
||||
{
|
||||
*s++ = L'-';
|
||||
val = -val;
|
||||
}
|
||||
ConvertUInt64ToString(val, s);
|
||||
}
|
||||
|
||||
|
||||
static void ConvertByteToHex2Digits(unsigned v, char *s) throw()
|
||||
{
|
||||
s[0] = GetHexChar(v >> 4);
|
||||
s[1] = GetHexChar(v & 0xF);
|
||||
}
|
||||
|
||||
static void ConvertUInt16ToHex4Digits(UInt32 val, char *s) throw()
|
||||
{
|
||||
ConvertByteToHex2Digits(val >> 8, s);
|
||||
ConvertByteToHex2Digits(val & 0xFF, s + 2);
|
||||
}
|
||||
|
||||
char *RawLeGuidToString(const Byte *g, char *s) throw()
|
||||
{
|
||||
ConvertUInt32ToHex8Digits(GetUi32(g ), s); s += 8; *s++ = '-';
|
||||
ConvertUInt16ToHex4Digits(GetUi16(g + 4), s); s += 4; *s++ = '-';
|
||||
ConvertUInt16ToHex4Digits(GetUi16(g + 6), s); s += 4; *s++ = '-';
|
||||
for (unsigned i = 0; i < 8; i++)
|
||||
{
|
||||
if (i == 2)
|
||||
*s++ = '-';
|
||||
ConvertByteToHex2Digits(g[8 + i], s);
|
||||
s += 2;
|
||||
}
|
||||
*s = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
char *RawLeGuidToString_Braced(const Byte *g, char *s) throw()
|
||||
{
|
||||
*s++ = '{';
|
||||
s = RawLeGuidToString(g, s);
|
||||
*s++ = '}';
|
||||
*s = 0;
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Common/IntToString.h
|
||||
|
||||
#ifndef __COMMON_INT_TO_STRING_H
|
||||
#define __COMMON_INT_TO_STRING_H
|
||||
|
||||
#include "MyTypes.h"
|
||||
|
||||
void ConvertUInt32ToString(UInt32 value, char *s) throw();
|
||||
void ConvertUInt64ToString(UInt64 value, char *s) throw();
|
||||
|
||||
void ConvertUInt32ToString(UInt32 value, wchar_t *s) throw();
|
||||
void ConvertUInt64ToString(UInt64 value, wchar_t *s) throw();
|
||||
|
||||
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();
|
||||
|
||||
// use RawLeGuid only for RAW bytes that contain stored GUID as Little-endian.
|
||||
char *RawLeGuidToString(const Byte *guid, char *s) throw();
|
||||
char *RawLeGuidToString_Braced(const Byte *guid, char *s) throw();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,163 @@
|
||||
// Common/Lang.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Lang.h"
|
||||
#include "StringToInt.h"
|
||||
#include "UTFConvert.h"
|
||||
|
||||
#include "../Windows/FileIO.h"
|
||||
|
||||
void CLang::Clear() throw()
|
||||
{
|
||||
_ids.Clear();
|
||||
_offsets.Clear();
|
||||
delete []_text;
|
||||
_text = 0;
|
||||
}
|
||||
|
||||
static const char * const kLangSignature = ";!@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;
|
||||
if (s[0] == 0xFEFF)
|
||||
i++;
|
||||
|
||||
for (const char *p = kLangSignature;; i++)
|
||||
{
|
||||
Byte c = *p++;
|
||||
if (c == 0)
|
||||
break;
|
||||
if (s[i] != c)
|
||||
return false;
|
||||
}
|
||||
|
||||
_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;
|
||||
}
|
||||
|
||||
bool CLang::Open(CFSTR fileName, const char *id)
|
||||
{
|
||||
Clear();
|
||||
NWindows::NFile::NIO::CInFile file;
|
||||
if (!file.Open(fileName))
|
||||
return false;
|
||||
UInt64 length;
|
||||
if (!file.GetLength(length))
|
||||
return false;
|
||||
if (length > (1 << 20))
|
||||
return false;
|
||||
|
||||
AString s;
|
||||
unsigned len = (unsigned)length;
|
||||
char *p = s.GetBuf(len);
|
||||
UInt32 processed;
|
||||
if (!file.Read(p, len, processed))
|
||||
return false;
|
||||
file.Close();
|
||||
if (len != processed)
|
||||
return false;
|
||||
|
||||
char *p2 = p;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
char c = p[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c != 0x0D)
|
||||
*p2++ = c;
|
||||
}
|
||||
*p2 = 0;
|
||||
s.ReleaseBuf_SetLen((unsigned)(p2 - p));
|
||||
|
||||
if (OpenFromString(s))
|
||||
{
|
||||
const wchar_t *name = Get(0);
|
||||
if (name && StringsAreEqual_Ascii(name, id))
|
||||
return true;
|
||||
}
|
||||
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
const wchar_t *CLang::Get(UInt32 id) const throw()
|
||||
{
|
||||
int index = _ids.FindInSorted(id);
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
return _text + (size_t)_offsets[index];
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Common/Lang.h
|
||||
|
||||
#ifndef __COMMON_LANG_H
|
||||
#define __COMMON_LANG_H
|
||||
|
||||
#include "MyString.h"
|
||||
|
||||
class CLang
|
||||
{
|
||||
wchar_t *_text;
|
||||
CRecordVector<UInt32> _ids;
|
||||
CRecordVector<UInt32> _offsets;
|
||||
|
||||
bool OpenFromString(const AString &s);
|
||||
public:
|
||||
CLang(): _text(0) {}
|
||||
~CLang() { Clear(); }
|
||||
bool Open(CFSTR fileName, const char *id);
|
||||
void Clear() throw();
|
||||
const wchar_t *Get(UInt32 id) const throw();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,132 @@
|
||||
// Common/ListFileUtils.cpp
|
||||
|
||||
#include "StdAfx.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 AddName(UStringVector &strings, UString &s)
|
||||
{
|
||||
s.Trim();
|
||||
if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
|
||||
{
|
||||
s.DeleteBack();
|
||||
s.Delete(0);
|
||||
}
|
||||
if (!s.IsEmpty())
|
||||
strings.Add(s);
|
||||
}
|
||||
|
||||
bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, DWORD &lastError)
|
||||
{
|
||||
lastError = 0;
|
||||
NWindows::NFile::NIO::CInFile file;
|
||||
if (!file.Open(fileName))
|
||||
{
|
||||
lastError = ::GetLastError();
|
||||
return false;
|
||||
}
|
||||
UInt64 fileSize;
|
||||
if (!file.GetLength(fileSize))
|
||||
{
|
||||
lastError = ::GetLastError();
|
||||
return false;
|
||||
}
|
||||
if (fileSize >= ((UInt32)1 << 31) - 32)
|
||||
return false;
|
||||
UString u;
|
||||
if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE)
|
||||
{
|
||||
if ((fileSize & 1) != 0)
|
||||
return false;
|
||||
CByteArr buf((size_t)fileSize);
|
||||
UInt32 processed;
|
||||
if (!file.Read(buf, (UInt32)fileSize, processed))
|
||||
{
|
||||
lastError = ::GetLastError();
|
||||
return false;
|
||||
}
|
||||
if (processed != fileSize)
|
||||
return false;
|
||||
file.Close();
|
||||
unsigned num = (unsigned)fileSize / 2;
|
||||
wchar_t *p = u.GetBuf(num);
|
||||
if (codePage == MY__CP_UTF16)
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
{
|
||||
wchar_t c = GetUi16(buf + (size_t)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 + (size_t)i * 2);
|
||||
if (c == 0)
|
||||
return false;
|
||||
p[i] = c;
|
||||
}
|
||||
p[num] = 0;
|
||||
u.ReleaseBuf_SetLen(num);
|
||||
}
|
||||
else
|
||||
{
|
||||
AString s;
|
||||
char *p = s.GetBuf((unsigned)fileSize);
|
||||
UInt32 processed;
|
||||
if (!file.Read(p, (UInt32)fileSize, processed))
|
||||
{
|
||||
lastError = ::GetLastError();
|
||||
return false;
|
||||
}
|
||||
if (processed != fileSize)
|
||||
return false;
|
||||
file.Close();
|
||||
s.ReleaseBuf_CalcLen((unsigned)processed);
|
||||
if (s.Len() != processed)
|
||||
return false;
|
||||
|
||||
// #ifdef CP_UTF8
|
||||
if (codePage == CP_UTF8)
|
||||
{
|
||||
if (!ConvertUTF8ToUnicode(s, u))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
// #endif
|
||||
MultiByteToUnicodeString2(u, s, codePage);
|
||||
}
|
||||
|
||||
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 == '\n' || c == 0xD)
|
||||
{
|
||||
AddName(strings, s);
|
||||
s.Empty();
|
||||
}
|
||||
else
|
||||
s += c;
|
||||
}
|
||||
AddName(strings, s);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Common/ListFileUtils.h
|
||||
|
||||
#ifndef __COMMON_LIST_FILE_UTILS_H
|
||||
#define __COMMON_LIST_FILE_UTILS_H
|
||||
|
||||
#include "MyString.h"
|
||||
#include "MyTypes.h"
|
||||
|
||||
#define MY__CP_UTF16 1200
|
||||
#define MY__CP_UTF16BE 1201
|
||||
|
||||
// bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
|
||||
|
||||
// = CP_OEMCP
|
||||
bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage,
|
||||
DWORD &lastError);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,259 @@
|
||||
// Common/MyBuffer.h
|
||||
|
||||
#ifndef __COMMON_MY_BUFFER_H
|
||||
#define __COMMON_MY_BUFFER_H
|
||||
|
||||
#include "Defs.h"
|
||||
|
||||
/* 7-Zip now uses CBuffer only as CByteBuffer.
|
||||
So there is no need to use MY_ARRAY_NEW macro in CBuffer code. */
|
||||
|
||||
template <class T> class CBuffer
|
||||
{
|
||||
T *_items;
|
||||
size_t _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)
|
||||
{
|
||||
size_t size = buffer._size;
|
||||
if (size != 0)
|
||||
{
|
||||
_items = new T[size];
|
||||
memcpy(_items, buffer._items, size * sizeof(T));
|
||||
_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
~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);
|
||||
if (size != 0)
|
||||
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 (keepSize > _size)
|
||||
keepSize = _size;
|
||||
if (keepSize != 0)
|
||||
memcpy(newBuffer, _items, MyMin(keepSize, newSize) * sizeof(T));
|
||||
}
|
||||
delete []_items;
|
||||
_items = newBuffer;
|
||||
_size = newSize;
|
||||
}
|
||||
|
||||
CBuffer& operator=(const CBuffer &buffer)
|
||||
{
|
||||
if (&buffer != this)
|
||||
CopyFrom(buffer, buffer._size);
|
||||
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;
|
||||
if (size1 == 0)
|
||||
return true;
|
||||
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 true;
|
||||
if (size1 == 0)
|
||||
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 copy
|
||||
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)
|
||||
{
|
||||
MY_ARRAY_NEW(_items, T, size)
|
||||
// _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;
|
||||
MY_ARRAY_NEW(_items, T, newSize)
|
||||
// _items = new T[newSize];
|
||||
}
|
||||
};
|
||||
|
||||
typedef CObjArray<unsigned char> CByteArr;
|
||||
typedef CObjArray<bool> CBoolArr;
|
||||
typedef CObjArray<int> CIntArr;
|
||||
typedef CObjArray<unsigned> CUIntArr;
|
||||
|
||||
|
||||
template <class T> class CObjArray2
|
||||
{
|
||||
T *_items;
|
||||
unsigned _size;
|
||||
|
||||
// we disable copy
|
||||
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)
|
||||
{
|
||||
MY_ARRAY_NEW(newBuffer, T, size)
|
||||
// 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
|
||||
@@ -0,0 +1,100 @@
|
||||
// Common/MyBuffer2.h
|
||||
|
||||
#ifndef __COMMON_MY_BUFFER2_H
|
||||
#define __COMMON_MY_BUFFER2_H
|
||||
|
||||
#include "../../C/Alloc.h"
|
||||
|
||||
#include "MyTypes.h"
|
||||
|
||||
class CMidBuffer
|
||||
{
|
||||
Byte *_data;
|
||||
size_t _size;
|
||||
|
||||
CLASS_NO_COPY(CMidBuffer)
|
||||
|
||||
public:
|
||||
CMidBuffer(): _data(NULL), _size(0) {}
|
||||
~CMidBuffer() { ::MidFree(_data); }
|
||||
|
||||
void Free() { ::MidFree(_data); _data = NULL; _size = 0; }
|
||||
|
||||
bool IsAllocated() const { return _data != NULL; }
|
||||
operator Byte *() { return _data; }
|
||||
operator const Byte *() const { return _data; }
|
||||
size_t Size() const { return _size; }
|
||||
|
||||
void AllocAtLeast(size_t size)
|
||||
{
|
||||
if (!_data || size > _size)
|
||||
{
|
||||
::MidFree(_data);
|
||||
const size_t kMinSize = (size_t)1 << 16;
|
||||
if (size < kMinSize)
|
||||
size = kMinSize;
|
||||
_size = 0;
|
||||
_data = NULL;
|
||||
_data = (Byte *)::MidAlloc(size);
|
||||
if (_data)
|
||||
_size = size;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CAlignedBuffer
|
||||
{
|
||||
Byte *_data;
|
||||
size_t _size;
|
||||
|
||||
CLASS_NO_COPY(CAlignedBuffer)
|
||||
|
||||
public:
|
||||
CAlignedBuffer(): _data(NULL), _size(0) {}
|
||||
~CAlignedBuffer()
|
||||
{
|
||||
ISzAlloc_Free(&g_AlignedAlloc, _data);
|
||||
}
|
||||
|
||||
void Free()
|
||||
{
|
||||
ISzAlloc_Free(&g_AlignedAlloc, _data);
|
||||
_data = NULL;
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
bool IsAllocated() const { return _data != NULL; }
|
||||
operator Byte *() { return _data; }
|
||||
operator const Byte *() const { return _data; }
|
||||
size_t Size() const { return _size; }
|
||||
|
||||
void Alloc(size_t size)
|
||||
{
|
||||
if (!_data || size != _size)
|
||||
{
|
||||
ISzAlloc_Free(&g_AlignedAlloc, _data);
|
||||
_size = 0;
|
||||
_data = NULL;
|
||||
_data = (Byte *)ISzAlloc_Alloc(&g_AlignedAlloc, size);
|
||||
if (_data)
|
||||
_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
void AllocAtLeast(size_t size)
|
||||
{
|
||||
if (!_data || size > _size)
|
||||
{
|
||||
ISzAlloc_Free(&g_AlignedAlloc, _data);
|
||||
_size = 0;
|
||||
_data = NULL;
|
||||
_data = (Byte *)ISzAlloc_Alloc(&g_AlignedAlloc, size);
|
||||
if (_data)
|
||||
_size = size;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,277 @@
|
||||
// MyCom.h
|
||||
|
||||
#ifndef __MY_COM_H
|
||||
#define __MY_COM_H
|
||||
|
||||
#include "MyWindows.h"
|
||||
|
||||
#ifndef RINOK
|
||||
#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
class CMyComPtr
|
||||
{
|
||||
T* _p;
|
||||
public:
|
||||
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; }
|
||||
// T& operator*() const { return *_p; }
|
||||
T** operator&() { return &_p; }
|
||||
T* operator->() const { return _p; }
|
||||
T* operator=(T* p)
|
||||
{
|
||||
if (p)
|
||||
p->AddRef();
|
||||
if (_p)
|
||||
_p->Release();
|
||||
_p = p;
|
||||
return p;
|
||||
}
|
||||
T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
|
||||
bool operator!() const { return (_p == NULL); }
|
||||
// bool operator==(T* pT) const { return _p == pT; }
|
||||
void Attach(T* p2)
|
||||
{
|
||||
Release();
|
||||
_p = p2;
|
||||
}
|
||||
T* Detach()
|
||||
{
|
||||
T* pt = _p;
|
||||
_p = NULL;
|
||||
return pt;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
|
||||
{
|
||||
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
|
||||
{
|
||||
CLSID clsid;
|
||||
HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
|
||||
ATLASSERT(_p == NULL);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
|
||||
return hr;
|
||||
}
|
||||
*/
|
||||
template <class Q>
|
||||
HRESULT QueryInterface(REFGUID iid, Q** pp) const throw()
|
||||
{
|
||||
return _p->QueryInterface(iid, (void**)pp);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)
|
||||
{
|
||||
*bstr = ::SysAllocString(src);
|
||||
return (*bstr) ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
class CMyComBSTR
|
||||
{
|
||||
BSTR m_str;
|
||||
|
||||
public:
|
||||
CMyComBSTR(): m_str(NULL) {}
|
||||
~CMyComBSTR() { ::SysFreeString(m_str); }
|
||||
BSTR* operator&() { return &m_str; }
|
||||
operator LPCOLESTR() const { return m_str; }
|
||||
// operator bool() const { return m_str != NULL; }
|
||||
// bool operator!() const { return m_str == NULL; }
|
||||
private:
|
||||
// operator BSTR() const { return m_str; }
|
||||
|
||||
CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }
|
||||
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
|
||||
// CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
|
||||
CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
|
||||
|
||||
/*
|
||||
CMyComBSTR(REFGUID src)
|
||||
{
|
||||
LPOLESTR szGuid;
|
||||
StringFromCLSID(src, &szGuid);
|
||||
m_str = ::SysAllocString(szGuid);
|
||||
CoTaskMemFree(szGuid);
|
||||
}
|
||||
*/
|
||||
|
||||
CMyComBSTR& operator=(const CMyComBSTR& src)
|
||||
{
|
||||
if (m_str != src.m_str)
|
||||
{
|
||||
if (m_str)
|
||||
::SysFreeString(m_str);
|
||||
m_str = src.MyCopy();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
CMyComBSTR& operator=(LPCOLESTR src)
|
||||
{
|
||||
::SysFreeString(m_str);
|
||||
m_str = ::SysAllocString(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned Len() const { return ::SysStringLen(m_str); }
|
||||
|
||||
BSTR MyCopy() const
|
||||
{
|
||||
// We don't support Byte BSTRs here
|
||||
return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
|
||||
/*
|
||||
UINT byteLen = ::SysStringByteLen(m_str);
|
||||
BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
|
||||
if (res && byteLen != 0 && m_str)
|
||||
memcpy(res, m_str, byteLen);
|
||||
return res;
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
void Attach(BSTR src) { m_str = src; }
|
||||
BSTR Detach()
|
||||
{
|
||||
BSTR s = m_str;
|
||||
m_str = NULL;
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
|
||||
void Empty()
|
||||
{
|
||||
::SysFreeString(m_str);
|
||||
m_str = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
If CMyUnknownImp doesn't use virtual destructor, the code size is smaller.
|
||||
But if some class_1 derived from CMyUnknownImp
|
||||
uses MY_ADDREF_RELEASE and IUnknown::Release()
|
||||
and some another class_2 is derived from class_1,
|
||||
then class_1 must use virtual destructor:
|
||||
virtual ~class_1();
|
||||
In that case, class_1::Release() calls correct destructor of class_2.
|
||||
|
||||
Also you can use virtual ~CMyUnknownImp(), if you want to disable warning
|
||||
"class has virtual functions, but destructor is not virtual".
|
||||
*/
|
||||
|
||||
class CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
ULONG __m_RefCount;
|
||||
CMyUnknownImp(): __m_RefCount(0) {}
|
||||
|
||||
// virtual
|
||||
~CMyUnknownImp() {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
|
||||
(REFGUID iid, void **outObject) throw() { *outObject = NULL;
|
||||
|
||||
#define MY_QUERYINTERFACE_ENTRY(i) else if (iid == IID_ ## i) \
|
||||
{ *outObject = (void *)(i *)this; }
|
||||
|
||||
#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
|
||||
{ *outObject = (void *)(IUnknown *)(i *)this; }
|
||||
|
||||
#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
|
||||
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
|
||||
MY_QUERYINTERFACE_ENTRY(i)
|
||||
|
||||
#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; ++__m_RefCount; /* AddRef(); */ return S_OK; }
|
||||
|
||||
#define MY_ADDREF_RELEASE \
|
||||
STDMETHOD_(ULONG, AddRef)() throw() { return ++__m_RefCount; } \
|
||||
STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
|
||||
return __m_RefCount; delete this; return 0; }
|
||||
|
||||
#define MY_UNKNOWN_IMP_SPEC(i) \
|
||||
MY_QUERYINTERFACE_BEGIN \
|
||||
i \
|
||||
MY_QUERYINTERFACE_END \
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
|
||||
#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \
|
||||
MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \
|
||||
MY_QUERYINTERFACE_END \
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
|
||||
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
|
||||
MY_QUERYINTERFACE_ENTRY(i) \
|
||||
)
|
||||
|
||||
#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
|
||||
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i2) \
|
||||
)
|
||||
|
||||
#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
|
||||
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i2) \
|
||||
MY_QUERYINTERFACE_ENTRY(i3) \
|
||||
)
|
||||
|
||||
#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
|
||||
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i2) \
|
||||
MY_QUERYINTERFACE_ENTRY(i3) \
|
||||
MY_QUERYINTERFACE_ENTRY(i4) \
|
||||
)
|
||||
|
||||
#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
|
||||
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i2) \
|
||||
MY_QUERYINTERFACE_ENTRY(i3) \
|
||||
MY_QUERYINTERFACE_ENTRY(i4) \
|
||||
MY_QUERYINTERFACE_ENTRY(i5) \
|
||||
)
|
||||
|
||||
#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) \
|
||||
)
|
||||
|
||||
const HRESULT k_My_HRESULT_WritingWasCut = 0x20000010;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
// Common/Exception.h
|
||||
|
||||
#ifndef __COMMON_EXCEPTION_H
|
||||
#define __COMMON_EXCEPTION_H
|
||||
|
||||
#include "MyWindows.h"
|
||||
|
||||
struct CSystemException
|
||||
{
|
||||
HRESULT ErrorCode;
|
||||
CSystemException(HRESULT errorCode): ErrorCode(errorCode) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
// Common/MyGuidDef.h
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
|
||||
#include "MyTypes.h"
|
||||
|
||||
typedef struct {
|
||||
UInt32 Data1;
|
||||
UInt16 Data2;
|
||||
UInt16 Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define REFGUID const GUID &
|
||||
#else
|
||||
#define REFGUID const GUID *
|
||||
#endif
|
||||
|
||||
#define REFCLSID REFGUID
|
||||
#define REFIID REFGUID
|
||||
|
||||
#ifdef __cplusplus
|
||||
inline int operator==(REFGUID g1, REFGUID g2)
|
||||
{
|
||||
for (int i = 0; i < (int)sizeof(g1); i++)
|
||||
if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
inline int operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define MY_EXTERN_C extern "C"
|
||||
#else
|
||||
#define MY_EXTERN_C extern
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEFINE_GUID
|
||||
#undef DEFINE_GUID
|
||||
#endif
|
||||
|
||||
#ifdef INITGUID
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
#else
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
MY_EXTERN_C const GUID name
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
// Common/MyInitGuid.h
|
||||
|
||||
#ifndef __COMMON_MY_INITGUID_H
|
||||
#define __COMMON_MY_INITGUID_H
|
||||
|
||||
/*
|
||||
This file must be included only to one C++ file in project before
|
||||
declarations of COM interfaces with DEFINE_GUID macro.
|
||||
|
||||
Each GUID must be initialized exactly once in project.
|
||||
There are two different versions of the DEFINE_GUID macro in guiddef.h (MyGuidDef.h):
|
||||
- if INITGUID is not defined: DEFINE_GUID declares an external reference to the symbol name.
|
||||
- if INITGUID is defined: DEFINE_GUID initializes the symbol name to the value of the GUID.
|
||||
|
||||
Also we need IID_IUnknown that is initialized in some file for linking:
|
||||
MSVC: by default the linker uses some lib file that contains IID_IUnknown
|
||||
MinGW: add -luuid switch for linker
|
||||
WinCE: we define IID_IUnknown in this file
|
||||
Other: we define IID_IUnknown in this file
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef UNDER_CE
|
||||
#include <basetyps.h>
|
||||
#endif
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
#ifdef UNDER_CE
|
||||
DEFINE_GUID(IID_IUnknown,
|
||||
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define INITGUID
|
||||
#include "MyGuidDef.h"
|
||||
DEFINE_GUID(IID_IUnknown,
|
||||
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
// MyLinux.h
|
||||
|
||||
#ifndef __MY_LIN_LINUX_H
|
||||
#define __MY_LIN_LINUX_H
|
||||
|
||||
#define MY_LIN_S_IFMT 00170000
|
||||
#define MY_LIN_S_IFSOCK 0140000
|
||||
#define MY_LIN_S_IFLNK 0120000
|
||||
#define MY_LIN_S_IFREG 0100000
|
||||
#define MY_LIN_S_IFBLK 0060000
|
||||
#define MY_LIN_S_IFDIR 0040000
|
||||
#define MY_LIN_S_IFCHR 0020000
|
||||
#define MY_LIN_S_IFIFO 0010000
|
||||
|
||||
#define MY_LIN_S_ISLNK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFLNK)
|
||||
#define MY_LIN_S_ISREG(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFREG)
|
||||
#define MY_LIN_S_ISDIR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFDIR)
|
||||
#define MY_LIN_S_ISCHR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFCHR)
|
||||
#define MY_LIN_S_ISBLK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFBLK)
|
||||
#define MY_LIN_S_ISFIFO(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFIFO)
|
||||
#define MY_LIN_S_ISSOCK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFSOCK)
|
||||
|
||||
#define MY_LIN_S_ISUID 0004000
|
||||
#define MY_LIN_S_ISGID 0002000
|
||||
#define MY_LIN_S_ISVTX 0001000
|
||||
|
||||
#define MY_LIN_S_IRWXU 00700
|
||||
#define MY_LIN_S_IRUSR 00400
|
||||
#define MY_LIN_S_IWUSR 00200
|
||||
#define MY_LIN_S_IXUSR 00100
|
||||
|
||||
#define MY_LIN_S_IRWXG 00070
|
||||
#define MY_LIN_S_IRGRP 00040
|
||||
#define MY_LIN_S_IWGRP 00020
|
||||
#define MY_LIN_S_IXGRP 00010
|
||||
|
||||
#define MY_LIN_S_IRWXO 00007
|
||||
#define MY_LIN_S_IROTH 00004
|
||||
#define MY_LIN_S_IWOTH 00002
|
||||
#define MY_LIN_S_IXOTH 00001
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
// MyMap.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "MyMap.h"
|
||||
|
||||
static const unsigned kNumBitsMax = sizeof(UInt32) * 8;
|
||||
|
||||
static UInt32 GetSubBits(UInt32 value, unsigned startPos, unsigned numBits) throw()
|
||||
{
|
||||
if (startPos == sizeof(value) * 8)
|
||||
return 0;
|
||||
value >>= startPos;
|
||||
if (numBits == sizeof(value) * 8)
|
||||
return value;
|
||||
return value & (((UInt32)1 << numBits) - 1);
|
||||
}
|
||||
|
||||
static inline unsigned GetSubBit(UInt32 v, unsigned n) { return (unsigned)(v >> n) & 1; }
|
||||
|
||||
bool CMap32::Find(UInt32 key, UInt32 &valueRes) const throw()
|
||||
{
|
||||
valueRes = (UInt32)(Int32)-1;
|
||||
if (Nodes.Size() == 0)
|
||||
return false;
|
||||
if (Nodes.Size() == 1)
|
||||
{
|
||||
const CNode &n = Nodes[0];
|
||||
if (n.Len == kNumBitsMax)
|
||||
{
|
||||
valueRes = n.Values[0];
|
||||
return (key == n.Key);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned cur = 0;
|
||||
unsigned bitPos = kNumBitsMax;
|
||||
for (;;)
|
||||
{
|
||||
const CNode &n = Nodes[cur];
|
||||
bitPos -= n.Len;
|
||||
if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len))
|
||||
return false;
|
||||
unsigned bit = GetSubBit(key, --bitPos);
|
||||
if (n.IsLeaf[bit])
|
||||
{
|
||||
valueRes = n.Values[bit];
|
||||
return (key == n.Keys[bit]);
|
||||
}
|
||||
cur = (unsigned)n.Keys[bit];
|
||||
}
|
||||
}
|
||||
|
||||
bool CMap32::Set(UInt32 key, UInt32 value)
|
||||
{
|
||||
if (Nodes.Size() == 0)
|
||||
{
|
||||
CNode n;
|
||||
n.Key = n.Keys[0] = n.Keys[1] = key;
|
||||
n.Values[0] = n.Values[1] = value;
|
||||
n.IsLeaf[0] = n.IsLeaf[1] = 1;
|
||||
n.Len = kNumBitsMax;
|
||||
Nodes.Add(n);
|
||||
return false;
|
||||
}
|
||||
if (Nodes.Size() == 1)
|
||||
{
|
||||
CNode &n = Nodes[0];
|
||||
if (n.Len == kNumBitsMax)
|
||||
{
|
||||
if (key == n.Key)
|
||||
{
|
||||
n.Values[0] = n.Values[1] = value;
|
||||
return true;
|
||||
}
|
||||
unsigned i = kNumBitsMax - 1;
|
||||
for (; GetSubBit(key, i) == GetSubBit(n.Key, i); i--);
|
||||
n.Len = (UInt16)(kNumBitsMax - (1 + i));
|
||||
unsigned newBit = GetSubBit(key, i);
|
||||
n.Values[newBit] = value;
|
||||
n.Keys[newBit] = key;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned cur = 0;
|
||||
unsigned bitPos = kNumBitsMax;
|
||||
for (;;)
|
||||
{
|
||||
CNode &n = Nodes[cur];
|
||||
bitPos -= n.Len;
|
||||
if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len))
|
||||
{
|
||||
unsigned i = n.Len - 1;
|
||||
for (; GetSubBit(key, bitPos + i) == GetSubBit(n.Key, bitPos + i); i--);
|
||||
|
||||
CNode e2(n);
|
||||
e2.Len = (UInt16)i;
|
||||
|
||||
n.Len = (UInt16)(n.Len - (1 + i));
|
||||
unsigned newBit = GetSubBit(key, bitPos + i);
|
||||
n.Values[newBit] = value;
|
||||
n.IsLeaf[newBit] = 1;
|
||||
n.IsLeaf[1 - newBit] = 0;
|
||||
n.Keys[newBit] = key;
|
||||
n.Keys[1 - newBit] = Nodes.Size();
|
||||
Nodes.Add(e2);
|
||||
return false;
|
||||
}
|
||||
unsigned bit = GetSubBit(key, --bitPos);
|
||||
|
||||
if (n.IsLeaf[bit])
|
||||
{
|
||||
if (key == n.Keys[bit])
|
||||
{
|
||||
n.Values[bit] = value;
|
||||
return true;
|
||||
}
|
||||
unsigned i = bitPos - 1;
|
||||
for (; GetSubBit(key, i) == GetSubBit(n.Keys[bit], i); i--);
|
||||
|
||||
CNode e2;
|
||||
|
||||
unsigned newBit = GetSubBit(key, i);
|
||||
e2.Values[newBit] = value;
|
||||
e2.Values[1 - newBit] = n.Values[bit];
|
||||
e2.IsLeaf[newBit] = e2.IsLeaf[1 - newBit] = 1;
|
||||
e2.Keys[newBit] = key;
|
||||
e2.Keys[1 - newBit] = e2.Key = n.Keys[bit];
|
||||
e2.Len = (UInt16)(bitPos - (1 + i));
|
||||
|
||||
n.IsLeaf[bit] = 0;
|
||||
n.Keys[bit] = Nodes.Size();
|
||||
|
||||
Nodes.Add(e2);
|
||||
return false;
|
||||
}
|
||||
cur = (unsigned)n.Keys[bit];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// MyMap.h
|
||||
|
||||
#ifndef __COMMON_MYMAP_H
|
||||
#define __COMMON_MYMAP_H
|
||||
|
||||
#include "MyTypes.h"
|
||||
#include "MyVector.h"
|
||||
|
||||
class CMap32
|
||||
{
|
||||
struct CNode
|
||||
{
|
||||
UInt32 Key;
|
||||
UInt32 Keys[2];
|
||||
UInt32 Values[2];
|
||||
UInt16 Len;
|
||||
Byte IsLeaf[2];
|
||||
};
|
||||
CRecordVector<CNode> Nodes;
|
||||
|
||||
public:
|
||||
|
||||
void Clear() { Nodes.Clear(); }
|
||||
bool Find(UInt32 key, UInt32 &valueRes) const throw();
|
||||
bool Set(UInt32 key, UInt32 value); // returns true, if there is such key already
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,868 @@
|
||||
// Common/String.h
|
||||
|
||||
#ifndef __COMMON_STRING_H
|
||||
#define __COMMON_STRING_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "MyWindows.h"
|
||||
#include "MyTypes.h"
|
||||
#include "MyVector.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _NATIVE_WCHAR_T_DEFINED
|
||||
#define MY_NATIVE_WCHAR_T_DEFINED
|
||||
#endif
|
||||
#else
|
||||
#define MY_NATIVE_WCHAR_T_DEFINED
|
||||
#endif
|
||||
|
||||
/*
|
||||
native support for wchar_t:
|
||||
_MSC_VER == 1600 : /Zc:wchar_t is not supported
|
||||
_MSC_VER == 1310 (VS2003)
|
||||
? _MSC_VER == 1400 (VS2005) : wchar_t <- unsigned short
|
||||
/Zc:wchar_t : wchar_t <- __wchar_t, _WCHAR_T_DEFINED and _NATIVE_WCHAR_T_DEFINED
|
||||
_MSC_VER > 1400 (VS2008+)
|
||||
/Zc:wchar_t[-]
|
||||
/Zc:wchar_t is on by default
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/')
|
||||
#else
|
||||
#define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR)
|
||||
#endif
|
||||
|
||||
inline bool IsPathSepar(char c) { return IS_PATH_SEPAR(c); }
|
||||
inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); }
|
||||
|
||||
inline unsigned MyStringLen(const char *s)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; s[i] != 0; i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
inline void MyStringCopy(char *dest, const char *src)
|
||||
{
|
||||
while ((*dest++ = *src++) != 0);
|
||||
}
|
||||
|
||||
inline char *MyStpCpy(char *dest, const char *src)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
char c = *src;
|
||||
*dest = c;
|
||||
if (c == 0)
|
||||
return dest;
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
inline void MyStringCat(wchar_t *dest, const wchar_t *src)
|
||||
{
|
||||
MyStringCopy(dest + MyStringLen(dest), src);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
wchar_t c = *src;
|
||||
*dest = c;
|
||||
if (c == 0)
|
||||
return dest;
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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)((unsigned 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)((unsigned 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(char *s) throw();
|
||||
// void MyStringUpper_Ascii(wchar_t *s) throw();
|
||||
void MyStringLower_Ascii(char *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();
|
||||
bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw();
|
||||
bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *u, const char *a) throw();
|
||||
bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
|
||||
|
||||
#define MyStringCompare(s1, s2) wcscmp(s1, s2)
|
||||
int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
|
||||
// int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
|
||||
|
||||
// ---------- ASCII ----------
|
||||
// char values in ASCII strings must be less then 128
|
||||
bool StringsAreEqual_Ascii(const 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_);
|
||||
|
||||
|
||||
#define FORBID_STRING_OPS_2(cls, t) \
|
||||
void Find(t) const; \
|
||||
void Find(t, unsigned startIndex) const; \
|
||||
void ReverseFind(t) const; \
|
||||
void InsertAtFront(t); \
|
||||
void RemoveChar(t); \
|
||||
void Replace(t, t); \
|
||||
|
||||
#define FORBID_STRING_OPS(cls, t) \
|
||||
explicit cls(t); \
|
||||
explicit cls(const t *); \
|
||||
cls &operator=(t); \
|
||||
cls &operator=(const t *); \
|
||||
cls &operator+=(t); \
|
||||
cls &operator+=(const t *); \
|
||||
FORBID_STRING_OPS_2(cls, t); \
|
||||
|
||||
/*
|
||||
cls &operator+(t); \
|
||||
cls &operator+(const t *); \
|
||||
*/
|
||||
|
||||
#define FORBID_STRING_OPS_AString(t) FORBID_STRING_OPS(AString, t)
|
||||
#define FORBID_STRING_OPS_UString(t) FORBID_STRING_OPS(UString, t)
|
||||
#define FORBID_STRING_OPS_UString2(t) FORBID_STRING_OPS(UString2, t)
|
||||
|
||||
class AString
|
||||
{
|
||||
char *_chars;
|
||||
unsigned _len;
|
||||
unsigned _limit;
|
||||
|
||||
void MoveItems(unsigned dest, unsigned src)
|
||||
{
|
||||
memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char));
|
||||
}
|
||||
|
||||
void InsertSpace(unsigned &index, unsigned size);
|
||||
|
||||
void ReAlloc(unsigned newLimit);
|
||||
void ReAlloc2(unsigned newLimit);
|
||||
void SetStartLen(unsigned len);
|
||||
void Grow_1();
|
||||
void Grow(unsigned n);
|
||||
|
||||
AString(unsigned num, const char *s);
|
||||
AString(unsigned num, const AString &s);
|
||||
AString(const AString &s, char c); // it's for String + char
|
||||
AString(const char *s1, unsigned num1, const char *s2, unsigned num2);
|
||||
|
||||
friend AString operator+(const AString &s, char c) { return AString(s, c); } ;
|
||||
// friend AString operator+(char c, const AString &s); // is not supported
|
||||
|
||||
friend AString operator+(const AString &s1, const AString &s2);
|
||||
friend AString operator+(const AString &s1, const char *s2);
|
||||
friend AString operator+(const char *s1, const AString &s2);
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
|
||||
#ifdef MY_NATIVE_WCHAR_T_DEFINED
|
||||
FORBID_STRING_OPS_AString(wchar_t)
|
||||
#endif
|
||||
|
||||
FORBID_STRING_OPS_AString(signed char)
|
||||
FORBID_STRING_OPS_AString(unsigned char)
|
||||
FORBID_STRING_OPS_AString(short)
|
||||
FORBID_STRING_OPS_AString(unsigned short)
|
||||
FORBID_STRING_OPS_AString(int)
|
||||
FORBID_STRING_OPS_AString(unsigned)
|
||||
FORBID_STRING_OPS_AString(long)
|
||||
FORBID_STRING_OPS_AString(unsigned long)
|
||||
|
||||
public:
|
||||
explicit AString();
|
||||
explicit AString(char c);
|
||||
explicit AString(const char *s);
|
||||
AString(const AString &s);
|
||||
~AString() { MY_STRING_DELETE(_chars); }
|
||||
|
||||
unsigned Len() const { return _len; }
|
||||
bool IsEmpty() const { return _len == 0; }
|
||||
void Empty() { _len = 0; _chars[0] = 0; }
|
||||
|
||||
operator const char *() const { return _chars; }
|
||||
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[(size_t)_len - 1]; }
|
||||
|
||||
void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
|
||||
|
||||
char *GetBuf() { return _chars; }
|
||||
/* GetBuf(minLen): provides the buffer that can store
|
||||
at least (minLen) characters and additional null terminator.
|
||||
9.35: GetBuf doesn't preserve old characters and terminator */
|
||||
char *GetBuf(unsigned minLen)
|
||||
{
|
||||
if (minLen > _limit)
|
||||
ReAlloc2(minLen);
|
||||
return _chars;
|
||||
}
|
||||
char *GetBuf_SetEnd(unsigned minLen)
|
||||
{
|
||||
if (minLen > _limit)
|
||||
ReAlloc2(minLen);
|
||||
char *chars = _chars;
|
||||
chars[minLen] = 0;
|
||||
_len = minLen;
|
||||
return chars;
|
||||
}
|
||||
|
||||
void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
|
||||
void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
|
||||
void ReleaseBuf_CalcLen(unsigned maxLen)
|
||||
{
|
||||
char *chars = _chars;
|
||||
chars[maxLen] = 0;
|
||||
_len = MyStringLen(chars);
|
||||
}
|
||||
|
||||
AString &operator=(char c);
|
||||
AString &operator=(const char *s);
|
||||
AString &operator=(const AString &s);
|
||||
void SetFromWStr_if_Ascii(const wchar_t *s);
|
||||
// void SetFromBstr_if_Ascii(BSTR s);
|
||||
|
||||
AString &operator+=(char c)
|
||||
{
|
||||
if (_limit == _len)
|
||||
Grow_1();
|
||||
unsigned len = _len;
|
||||
char *chars = _chars;
|
||||
chars[len++] = c;
|
||||
chars[len] = 0;
|
||||
_len = len;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Add_Space();
|
||||
void Add_Space_if_NotEmpty();
|
||||
void Add_OptSpaced(const char *s);
|
||||
void Add_LF();
|
||||
void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
|
||||
|
||||
AString &operator+=(const char *s);
|
||||
AString &operator+=(const AString &s);
|
||||
|
||||
void Add_UInt32(UInt32 v);
|
||||
|
||||
void SetFrom(const char *s, unsigned len); // no check
|
||||
void SetFrom_CalcLen(const char *s, unsigned len);
|
||||
|
||||
AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
|
||||
AString Left(unsigned count) const { return AString(count, *this); }
|
||||
|
||||
// void MakeUpper() { MyStringUpper(_chars); }
|
||||
// void MakeLower() { MyStringLower(_chars); }
|
||||
void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
|
||||
|
||||
|
||||
bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; }
|
||||
bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
|
||||
// int Compare(const char *s) const { return MyStringCompare(_chars, s); }
|
||||
// int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
|
||||
// int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
|
||||
// int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
|
||||
bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
|
||||
bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
|
||||
|
||||
bool IsAscii() const
|
||||
{
|
||||
unsigned len = Len();
|
||||
const char *s = _chars;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
if ((unsigned char)s[i] >= 0x80)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
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 : (int)startIndex + pos;
|
||||
}
|
||||
|
||||
int ReverseFind(char c) const throw();
|
||||
int ReverseFind_Dot() const throw() { return ReverseFind('.'); }
|
||||
int ReverseFind_PathSepar() const throw();
|
||||
|
||||
int Find(const char *s) const { return Find(s, 0); }
|
||||
int Find(const char *s, unsigned startIndex) const throw();
|
||||
|
||||
void TrimLeft() throw();
|
||||
void TrimRight() throw();
|
||||
void Trim()
|
||||
{
|
||||
TrimRight();
|
||||
TrimLeft();
|
||||
}
|
||||
|
||||
void InsertAtFront(char c);
|
||||
// void Insert(unsigned index, char c);
|
||||
void Insert(unsigned index, const char *s);
|
||||
void Insert(unsigned index, const AString &s);
|
||||
|
||||
void RemoveChar(char ch) throw();
|
||||
|
||||
void Replace(char oldChar, char newChar) throw();
|
||||
void Replace(const AString &oldString, const AString &newString);
|
||||
|
||||
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 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; }
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
|
||||
void operator==(char c1, const AString &s2);
|
||||
void operator==(const AString &s1, char c2);
|
||||
|
||||
void operator+(char c, const AString &s); // this function can be OK, but we don't use it
|
||||
|
||||
void operator+(const AString &s, int c);
|
||||
void operator+(const AString &s, unsigned c);
|
||||
void operator+(int c, const AString &s);
|
||||
void operator+(unsigned c, const AString &s);
|
||||
void operator-(const AString &s, int c);
|
||||
void operator-(const AString &s, unsigned c);
|
||||
|
||||
|
||||
class UString
|
||||
{
|
||||
wchar_t *_chars;
|
||||
unsigned _len;
|
||||
unsigned _limit;
|
||||
|
||||
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 ReAlloc2(unsigned newLimit);
|
||||
void SetStartLen(unsigned len);
|
||||
void Grow_1();
|
||||
void Grow(unsigned n);
|
||||
|
||||
UString(unsigned num, const wchar_t *s); // for Mid
|
||||
UString(unsigned num, const UString &s); // for Left
|
||||
UString(const UString &s, wchar_t c); // it's for String + char
|
||||
UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2);
|
||||
|
||||
friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ;
|
||||
// friend UString operator+(wchar_t c, const UString &s); // is not supported
|
||||
|
||||
friend UString operator+(const UString &s1, const UString &s2);
|
||||
friend UString operator+(const UString &s1, const wchar_t *s2);
|
||||
friend UString operator+(const wchar_t *s1, const UString &s2);
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
|
||||
FORBID_STRING_OPS_UString(signed char)
|
||||
FORBID_STRING_OPS_UString(unsigned char)
|
||||
FORBID_STRING_OPS_UString(short)
|
||||
|
||||
#ifdef MY_NATIVE_WCHAR_T_DEFINED
|
||||
FORBID_STRING_OPS_UString(unsigned short)
|
||||
#endif
|
||||
|
||||
FORBID_STRING_OPS_UString(int)
|
||||
FORBID_STRING_OPS_UString(unsigned)
|
||||
FORBID_STRING_OPS_UString(long)
|
||||
FORBID_STRING_OPS_UString(unsigned long)
|
||||
|
||||
FORBID_STRING_OPS_2(UString, char)
|
||||
|
||||
public:
|
||||
UString();
|
||||
explicit UString(wchar_t c);
|
||||
explicit UString(char c);
|
||||
explicit UString(const char *s);
|
||||
// UString(const AString &s);
|
||||
UString(const wchar_t *s);
|
||||
UString(const UString &s);
|
||||
~UString() { MY_STRING_DELETE(_chars); }
|
||||
|
||||
unsigned Len() const { return _len; }
|
||||
bool IsEmpty() const { return _len == 0; }
|
||||
void Empty() { _len = 0; _chars[0] = 0; }
|
||||
|
||||
operator const wchar_t *() const { return _chars; }
|
||||
const wchar_t *Ptr() const { return _chars; }
|
||||
const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
|
||||
const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
|
||||
wchar_t Back() const { return _chars[(size_t)_len - 1]; }
|
||||
|
||||
void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
|
||||
|
||||
wchar_t *GetBuf() { return _chars; }
|
||||
|
||||
wchar_t *GetBuf(unsigned minLen)
|
||||
{
|
||||
if (minLen > _limit)
|
||||
ReAlloc2(minLen);
|
||||
return _chars;
|
||||
}
|
||||
wchar_t *GetBuf_SetEnd(unsigned minLen)
|
||||
{
|
||||
if (minLen > _limit)
|
||||
ReAlloc2(minLen);
|
||||
wchar_t *chars = _chars;
|
||||
chars[minLen] = 0;
|
||||
_len = minLen;
|
||||
return chars;
|
||||
}
|
||||
|
||||
void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
|
||||
void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
|
||||
void ReleaseBuf_CalcLen(unsigned maxLen)
|
||||
{
|
||||
wchar_t *chars = _chars;
|
||||
chars[maxLen] = 0;
|
||||
_len = MyStringLen(chars);
|
||||
}
|
||||
|
||||
UString &operator=(wchar_t c);
|
||||
UString &operator=(char c) { return (*this)=((wchar_t)(unsigned char)c); }
|
||||
UString &operator=(const wchar_t *s);
|
||||
UString &operator=(const UString &s);
|
||||
void SetFrom(const wchar_t *s, unsigned len); // no check
|
||||
void SetFromBstr(BSTR s);
|
||||
UString &operator=(const char *s);
|
||||
UString &operator=(const AString &s) { return operator=(s.Ptr()); }
|
||||
|
||||
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+=(char c) { return (*this)+=((wchar_t)(unsigned char)c); }
|
||||
|
||||
void Add_Space();
|
||||
void Add_Space_if_NotEmpty();
|
||||
void Add_LF();
|
||||
void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); }
|
||||
|
||||
UString &operator+=(const wchar_t *s);
|
||||
UString &operator+=(const UString &s);
|
||||
UString &operator+=(const char *s);
|
||||
UString &operator+=(const AString &s) { return operator+=(s.Ptr()); }
|
||||
|
||||
void Add_UInt32(UInt32 v);
|
||||
|
||||
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 IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
|
||||
bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_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_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); }
|
||||
bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
|
||||
|
||||
bool IsAscii() const
|
||||
{
|
||||
unsigned len = Len();
|
||||
const wchar_t *s = _chars;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
if (s[i] >= 0x80)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
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 ReverseFind(wchar_t c) const throw();
|
||||
int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); }
|
||||
int ReverseFind_PathSepar() const throw();
|
||||
|
||||
int Find(const wchar_t *s) const { return Find(s, 0); }
|
||||
int Find(const wchar_t *s, unsigned startIndex) 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; }
|
||||
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
|
||||
void operator==(wchar_t c1, const UString &s2);
|
||||
void operator==(const UString &s1, wchar_t c2);
|
||||
|
||||
void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it
|
||||
|
||||
void operator+(const AString &s1, const UString &s2);
|
||||
void operator+(const UString &s1, const AString &s2);
|
||||
|
||||
void operator+(const UString &s1, const char *s2);
|
||||
void operator+(const char *s1, const UString &s2);
|
||||
|
||||
void operator+(const UString &s, char c);
|
||||
void operator+(const UString &s, unsigned char c);
|
||||
void operator+(char c, const UString &s);
|
||||
void operator+(unsigned char c, const UString &s);
|
||||
void operator-(const UString &s1, wchar_t c);
|
||||
|
||||
#ifdef _WIN32
|
||||
// can we forbid these functions, if wchar_t is 32-bit ?
|
||||
void operator+(const UString &s, int c);
|
||||
void operator+(const UString &s, unsigned c);
|
||||
void operator+(int c, const UString &s);
|
||||
void operator+(unsigned c, const UString &s);
|
||||
void operator-(const UString &s1, int c);
|
||||
void operator-(const UString &s1, unsigned c);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class UString2
|
||||
{
|
||||
wchar_t *_chars;
|
||||
unsigned _len;
|
||||
|
||||
void ReAlloc2(unsigned newLimit);
|
||||
void SetStartLen(unsigned len);
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
|
||||
FORBID_STRING_OPS_UString2(char)
|
||||
FORBID_STRING_OPS_UString2(signed char)
|
||||
FORBID_STRING_OPS_UString2(unsigned char)
|
||||
FORBID_STRING_OPS_UString2(short)
|
||||
|
||||
UString2 &operator=(wchar_t c);
|
||||
UString2(wchar_t c);
|
||||
|
||||
public:
|
||||
UString2(): _chars(NULL), _len(0) {}
|
||||
UString2(const wchar_t *s);
|
||||
UString2(const UString2 &s);
|
||||
~UString2() { if (_chars) MY_STRING_DELETE(_chars); }
|
||||
|
||||
unsigned Len() const { return _len; }
|
||||
bool IsEmpty() const { return _len == 0; }
|
||||
// void Empty() { _len = 0; _chars[0] = 0; }
|
||||
|
||||
// operator const wchar_t *() const { return _chars; }
|
||||
const wchar_t *GetRawPtr() const { return _chars; }
|
||||
|
||||
int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
|
||||
|
||||
wchar_t *GetBuf(unsigned minLen)
|
||||
{
|
||||
if (!_chars || minLen > _len)
|
||||
ReAlloc2(minLen);
|
||||
return _chars;
|
||||
}
|
||||
void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
|
||||
|
||||
UString2 &operator=(const wchar_t *s);
|
||||
UString2 &operator=(const UString2 &s);
|
||||
void SetFromAscii(const char *s);
|
||||
};
|
||||
|
||||
bool operator==(const UString2 &s1, const UString2 &s2);
|
||||
bool operator==(const UString2 &s1, const wchar_t *s2);
|
||||
bool operator==(const wchar_t *s1, const UString2 &s2);
|
||||
|
||||
inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); }
|
||||
inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); }
|
||||
inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); }
|
||||
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
|
||||
void operator==(wchar_t c1, const UString2 &s2);
|
||||
void operator==(const UString2 &s1, wchar_t c2);
|
||||
bool operator<(const UString2 &s1, const UString2 &s2);
|
||||
bool operator>(const UString2 &s1, const UString2 &s2);
|
||||
|
||||
void operator+(const UString2 &s1, const UString2 &s2);
|
||||
void operator+(const UString2 &s1, const wchar_t *s2);
|
||||
void operator+(const wchar_t *s1, const UString2 &s2);
|
||||
void operator+(wchar_t c, const UString2 &s);
|
||||
void operator+(const UString2 &s, wchar_t c);
|
||||
void operator+(const UString2 &s, char c);
|
||||
void operator+(const UString2 &s, unsigned char c);
|
||||
void operator+(char c, const UString2 &s);
|
||||
void operator+(unsigned char c, const UString2 &s);
|
||||
void operator-(const UString2 &s1, wchar_t c);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef CObjectVector<AString> AStringVector;
|
||||
typedef CObjectVector<UString> UStringVector;
|
||||
|
||||
#ifdef _UNICODE
|
||||
typedef UString CSysString;
|
||||
#else
|
||||
typedef AString CSysString;
|
||||
#endif
|
||||
|
||||
typedef CObjectVector<CSysString> CSysStringVector;
|
||||
|
||||
|
||||
// ---------- FString ----------
|
||||
|
||||
#ifdef _WIN32
|
||||
#define USE_UNICODE_FSTRING
|
||||
#endif
|
||||
|
||||
#ifdef USE_UNICODE_FSTRING
|
||||
|
||||
#define __FTEXT(quote) L##quote
|
||||
|
||||
typedef wchar_t FChar;
|
||||
typedef UString FString;
|
||||
|
||||
#define fs2us(_x_) (_x_)
|
||||
#define us2fs(_x_) (_x_)
|
||||
FString fas2fs(const char *s);
|
||||
FString fas2fs(const AString &s);
|
||||
AString fs2fas(const FChar *s);
|
||||
|
||||
#else
|
||||
|
||||
#define __FTEXT(quote) quote
|
||||
|
||||
typedef char FChar;
|
||||
typedef AString FString;
|
||||
|
||||
UString fs2us(const FChar *s);
|
||||
UString fs2us(const FString &s);
|
||||
FString us2fs(const wchar_t *s);
|
||||
#define fas2fs(_x_) (_x_)
|
||||
#define fs2fas(_x_) (_x_)
|
||||
|
||||
#endif
|
||||
|
||||
#define FTEXT(quote) __FTEXT(quote)
|
||||
|
||||
#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR)
|
||||
#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR)
|
||||
|
||||
// #define FCHAR_ANY_MASK FTEXT('*')
|
||||
// #define FSTRING_ANY_MASK FTEXT("*")
|
||||
|
||||
typedef const FChar *CFSTR;
|
||||
|
||||
typedef CObjectVector<FString> FStringVector;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
|
||||
#define CLASS_NO_COPY(cls) \
|
||||
private: \
|
||||
cls(const cls &); \
|
||||
cls &operator=(const cls &);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
// MyUnknown.h
|
||||
|
||||
#ifndef __MY_UNKNOWN_H
|
||||
#define __MY_UNKNOWN_H
|
||||
|
||||
#include "MyWindows.h"
|
||||
|
||||
/*
|
||||
#ifdef _WIN32
|
||||
#include <basetyps.h>
|
||||
#include <unknwn.h>
|
||||
#else
|
||||
#include "MyWindows.h"
|
||||
#endif
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
// Common/MyVector.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
@@ -0,0 +1,634 @@
|
||||
// Common/MyVector.h
|
||||
|
||||
#ifndef __COMMON_MY_VECTOR_H
|
||||
#define __COMMON_MY_VECTOR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
template <class T>
|
||||
class CRecordVector
|
||||
{
|
||||
T *_items;
|
||||
unsigned _size;
|
||||
unsigned _capacity;
|
||||
|
||||
void MoveItems(unsigned destIndex, unsigned srcIndex)
|
||||
{
|
||||
memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T));
|
||||
}
|
||||
|
||||
void ReserveOnePosition()
|
||||
{
|
||||
if (_size == _capacity)
|
||||
{
|
||||
unsigned newCapacity = _capacity + (_capacity >> 2) + 1;
|
||||
T *p;
|
||||
MY_ARRAY_NEW(p, T, newCapacity);
|
||||
// p = new T[newCapacity];
|
||||
if (_size != 0)
|
||||
memcpy(p, _items, (size_t)_size * sizeof(T));
|
||||
delete []_items;
|
||||
_items = p;
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
CRecordVector(): _items(0), _size(0), _capacity(0) {}
|
||||
|
||||
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 * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned Size() const { return _size; }
|
||||
bool IsEmpty() const { return _size == 0; }
|
||||
|
||||
void ConstructReserve(unsigned size)
|
||||
{
|
||||
if (size != 0)
|
||||
{
|
||||
MY_ARRAY_NEW(_items, T, size)
|
||||
// _items = new T[size];
|
||||
_capacity = size;
|
||||
}
|
||||
}
|
||||
|
||||
void Reserve(unsigned newCapacity)
|
||||
{
|
||||
if (newCapacity > _capacity)
|
||||
{
|
||||
T *p;
|
||||
MY_ARRAY_NEW(p, T, newCapacity);
|
||||
// p = new T[newCapacity];
|
||||
if (_size != 0)
|
||||
memcpy(p, _items, (size_t)_size * sizeof(T));
|
||||
delete []_items;
|
||||
_items = p;
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
void ClearAndReserve(unsigned newCapacity)
|
||||
{
|
||||
Clear();
|
||||
if (newCapacity > _capacity)
|
||||
{
|
||||
delete []_items;
|
||||
_items = NULL;
|
||||
_capacity = 0;
|
||||
MY_ARRAY_NEW(_items, T, newCapacity)
|
||||
// _items = new T[newCapacity];
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
void ClearAndSetSize(unsigned newSize)
|
||||
{
|
||||
ClearAndReserve(newSize);
|
||||
_size = newSize;
|
||||
}
|
||||
|
||||
void ChangeSize_KeepData(unsigned newSize)
|
||||
{
|
||||
if (newSize > _capacity)
|
||||
{
|
||||
T *p;
|
||||
MY_ARRAY_NEW(p, T, newSize)
|
||||
// p = new T[newSize];
|
||||
if (_size != 0)
|
||||
memcpy(p, _items, (size_t)_size * sizeof(T));
|
||||
delete []_items;
|
||||
_items = p;
|
||||
_capacity = newSize;
|
||||
}
|
||||
_size = newSize;
|
||||
}
|
||||
|
||||
void ReserveDown()
|
||||
{
|
||||
if (_size == _capacity)
|
||||
return;
|
||||
T *p = NULL;
|
||||
if (_size != 0)
|
||||
{
|
||||
p = new T[_size];
|
||||
memcpy(p, _items, (size_t)_size * 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)
|
||||
{
|
||||
if (&v == this)
|
||||
return *this;
|
||||
unsigned size = v.Size();
|
||||
if (size > _capacity)
|
||||
{
|
||||
delete []_items;
|
||||
_capacity = 0;
|
||||
_size = 0;
|
||||
_items = NULL;
|
||||
_items = new T[size];
|
||||
_capacity = size;
|
||||
}
|
||||
_size = size;
|
||||
if (size != 0)
|
||||
memcpy(_items, v._items, (size_t)size * sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
CRecordVector& operator+=(const CRecordVector &v)
|
||||
{
|
||||
unsigned size = v.Size();
|
||||
Reserve(_size + size);
|
||||
if (size != 0)
|
||||
memcpy(_items + _size, v._items, (size_t)size * sizeof(T));
|
||||
_size += size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned Add(const T item)
|
||||
{
|
||||
ReserveOnePosition();
|
||||
_items[_size] = item;
|
||||
return _size++;
|
||||
}
|
||||
|
||||
void AddInReserved(const T item)
|
||||
{
|
||||
_items[_size++] = item;
|
||||
}
|
||||
|
||||
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 * 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_t)_size - 1]; }
|
||||
T& Back() { return _items[(size_t)_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)
|
||||
{
|
||||
unsigned mid = (left + right) / 2;
|
||||
const T midVal = (*this)[mid];
|
||||
if (item == midVal)
|
||||
return mid;
|
||||
if (item < midVal)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FindInSorted2(const T &item, unsigned left, unsigned right) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FindInSorted(const T item) const
|
||||
{
|
||||
return FindInSorted(item, 0, _size);
|
||||
}
|
||||
|
||||
int FindInSorted2(const T &item) const
|
||||
{
|
||||
return FindInSorted2(item, 0, _size);
|
||||
}
|
||||
|
||||
unsigned AddToUniqueSorted(const T item)
|
||||
{
|
||||
unsigned left = 0, right = _size;
|
||||
while (left != right)
|
||||
{
|
||||
unsigned mid = (left + right) / 2;
|
||||
const T midVal = (*this)[mid];
|
||||
if (item == midVal)
|
||||
return mid;
|
||||
if (item < midVal)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
}
|
||||
Insert(right, item);
|
||||
return right;
|
||||
}
|
||||
|
||||
unsigned AddToUniqueSorted2(const T &item)
|
||||
{
|
||||
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 (;;)
|
||||
{
|
||||
unsigned s = (k << 1);
|
||||
if (s > size)
|
||||
break;
|
||||
if (s < size && compare(p + s + 1, p + s, param) > 0)
|
||||
s++;
|
||||
if (compare(&temp, p + s, param) >= 0)
|
||||
break;
|
||||
p[k] = p[s];
|
||||
k = s;
|
||||
}
|
||||
p[k] = temp;
|
||||
}
|
||||
|
||||
void Sort(int (*compare)(const T*, const T*, void *), void *param)
|
||||
{
|
||||
unsigned size = _size;
|
||||
if (size <= 1)
|
||||
return;
|
||||
T* p = (&Front()) - 1;
|
||||
{
|
||||
unsigned i = size >> 1;
|
||||
do
|
||||
SortRefDown(p, i, size, compare, param);
|
||||
while (--i != 0);
|
||||
}
|
||||
do
|
||||
{
|
||||
T temp = p[size];
|
||||
p[size--] = p[1];
|
||||
p[1] = temp;
|
||||
SortRefDown(p, 1, size, compare, param);
|
||||
}
|
||||
while (size > 1);
|
||||
}
|
||||
|
||||
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[(size_t)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;
|
||||
typedef CRecordVector<unsigned int> CUIntVector;
|
||||
typedef CRecordVector<bool> CBoolVector;
|
||||
typedef CRecordVector<unsigned char> CByteVector;
|
||||
typedef CRecordVector<void *> CPointerVector;
|
||||
|
||||
template <class T>
|
||||
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(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)
|
||||
{
|
||||
if (&v == this)
|
||||
return *this;
|
||||
Clear();
|
||||
unsigned size = v.Size();
|
||||
_v.Reserve(size);
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
_v.AddInReserved(new T(v[i]));
|
||||
return *this;
|
||||
}
|
||||
|
||||
CObjectVector& operator+=(const CObjectVector &v)
|
||||
{
|
||||
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 *(T *)_v.Back(); }
|
||||
T& Back() { return *(T *)_v.Back(); }
|
||||
|
||||
void MoveToFront(unsigned index) { _v.MoveToFront(index); }
|
||||
|
||||
unsigned Add(const T& item) { return _v.Add(new T(item)); }
|
||||
|
||||
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.Back();
|
||||
_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
|
||||
{
|
||||
unsigned size = Size();
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
if (item == (*this)[i])
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
int FindInSorted(const T& item) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned AddToUniqueSorted(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;
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
{ _v.Sort(compare, param); }
|
||||
|
||||
static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
|
||||
{ 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
|
||||
@@ -0,0 +1,145 @@
|
||||
// MyWindows.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "MyWindows.h"
|
||||
|
||||
static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); }
|
||||
static inline void FreeForBSTR(void *pv) { ::free(pv);}
|
||||
|
||||
/* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string.
|
||||
We must select CBstrSizeType for another systems (not Win32):
|
||||
|
||||
if (CBstrSizeType is UINT32),
|
||||
then we support only strings smaller than 4 GB.
|
||||
Win32 version always has that limitation.
|
||||
|
||||
if (CBstrSizeType is UINT),
|
||||
(UINT can be 16/32/64-bit)
|
||||
We can support strings larger than 4 GB (if UINT is 64-bit),
|
||||
but sizeof(UINT) can be different in parts compiled by
|
||||
different compilers/settings,
|
||||
and we can't send such BSTR strings between such parts.
|
||||
*/
|
||||
|
||||
typedef UINT32 CBstrSizeType;
|
||||
// typedef UINT CBstrSizeType;
|
||||
|
||||
#define k_BstrSize_Max 0xFFFFFFFF
|
||||
// #define k_BstrSize_Max UINT_MAX
|
||||
// #define k_BstrSize_Max ((UINT)(INT)-1)
|
||||
|
||||
BSTR SysAllocStringByteLen(LPCSTR s, UINT len)
|
||||
{
|
||||
/* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end.
|
||||
We provide also aligned null OLECHAR at the end. */
|
||||
|
||||
if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(OLECHAR) - sizeof(CBstrSizeType)))
|
||||
return NULL;
|
||||
|
||||
UINT size = (len + sizeof(OLECHAR) + sizeof(OLECHAR) - 1) & ~(sizeof(OLECHAR) - 1);
|
||||
void *p = AllocateForBSTR(size + sizeof(CBstrSizeType));
|
||||
if (!p)
|
||||
return NULL;
|
||||
*(CBstrSizeType *)p = (CBstrSizeType)len;
|
||||
BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
|
||||
if (s)
|
||||
memcpy(bstr, s, len);
|
||||
for (; len < size; len++)
|
||||
((Byte *)bstr)[len] = 0;
|
||||
return bstr;
|
||||
}
|
||||
|
||||
BSTR SysAllocStringLen(const OLECHAR *s, UINT len)
|
||||
{
|
||||
if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(CBstrSizeType)) / sizeof(OLECHAR))
|
||||
return NULL;
|
||||
|
||||
UINT size = len * sizeof(OLECHAR);
|
||||
void *p = AllocateForBSTR(size + sizeof(CBstrSizeType) + sizeof(OLECHAR));
|
||||
if (!p)
|
||||
return NULL;
|
||||
*(CBstrSizeType *)p = (CBstrSizeType)size;
|
||||
BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
|
||||
if (s)
|
||||
memcpy(bstr, s, size);
|
||||
bstr[len] = 0;
|
||||
return bstr;
|
||||
}
|
||||
|
||||
BSTR SysAllocString(const OLECHAR *s)
|
||||
{
|
||||
if (!s)
|
||||
return 0;
|
||||
const OLECHAR *s2 = s;
|
||||
while (*s2 != 0)
|
||||
s2++;
|
||||
return SysAllocStringLen(s, (UINT)(s2 - s));
|
||||
}
|
||||
|
||||
void SysFreeString(BSTR bstr)
|
||||
{
|
||||
if (bstr)
|
||||
FreeForBSTR((CBstrSizeType *)bstr - 1);
|
||||
}
|
||||
|
||||
UINT SysStringByteLen(BSTR bstr)
|
||||
{
|
||||
if (!bstr)
|
||||
return 0;
|
||||
return *((CBstrSizeType *)bstr - 1);
|
||||
}
|
||||
|
||||
UINT SysStringLen(BSTR bstr)
|
||||
{
|
||||
if (!bstr)
|
||||
return 0;
|
||||
return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR);
|
||||
}
|
||||
|
||||
|
||||
HRESULT VariantClear(VARIANTARG *prop)
|
||||
{
|
||||
if (prop->vt == VT_BSTR)
|
||||
SysFreeString(prop->bstrVal);
|
||||
prop->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src)
|
||||
{
|
||||
HRESULT res = ::VariantClear(dest);
|
||||
if (res != S_OK)
|
||||
return res;
|
||||
if (src->vt == VT_BSTR)
|
||||
{
|
||||
dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal,
|
||||
SysStringByteLen(src->bstrVal));
|
||||
if (!dest->bstrVal)
|
||||
return E_OUTOFMEMORY;
|
||||
dest->vt = VT_BSTR;
|
||||
}
|
||||
else
|
||||
*dest = *src;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2)
|
||||
{
|
||||
if (ft1->dwHighDateTime < ft2->dwHighDateTime) return -1;
|
||||
if (ft1->dwHighDateTime > ft2->dwHighDateTime) return 1;
|
||||
if (ft1->dwLowDateTime < ft2->dwLowDateTime) return -1;
|
||||
if (ft1->dwLowDateTime > ft2->dwLowDateTime) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD GetLastError()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,231 @@
|
||||
// MyWindows.h
|
||||
|
||||
#ifndef __MY_WINDOWS_H
|
||||
#define __MY_WINDOWS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef UNDER_CE
|
||||
#undef VARIANT_TRUE
|
||||
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <stddef.h> // for wchar_t
|
||||
#include <string.h>
|
||||
// #include <stdint.h> // for uintptr_t
|
||||
|
||||
#include "MyGuidDef.h"
|
||||
|
||||
#define WINAPI
|
||||
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
|
||||
#undef BYTE
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
|
||||
#undef WORD
|
||||
typedef unsigned short WORD;
|
||||
typedef short VARIANT_BOOL;
|
||||
|
||||
typedef int INT;
|
||||
typedef Int32 INT32;
|
||||
typedef unsigned int UINT;
|
||||
typedef UInt32 UINT32;
|
||||
typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit
|
||||
typedef UINT32 ULONG;
|
||||
|
||||
#undef DWORD
|
||||
typedef UINT32 DWORD;
|
||||
|
||||
typedef long BOOL;
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
// typedef size_t ULONG_PTR;
|
||||
typedef size_t DWORD_PTR;
|
||||
// typedef uintptr_t UINT_PTR;
|
||||
// typedef ptrdiff_t UINT_PTR;
|
||||
|
||||
typedef Int64 LONGLONG;
|
||||
typedef UInt64 ULONGLONG;
|
||||
|
||||
typedef struct _LARGE_INTEGER { LONGLONG QuadPart; } LARGE_INTEGER;
|
||||
typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart; } ULARGE_INTEGER;
|
||||
|
||||
typedef const CHAR *LPCSTR;
|
||||
typedef CHAR TCHAR;
|
||||
typedef const TCHAR *LPCTSTR;
|
||||
typedef wchar_t WCHAR;
|
||||
typedef WCHAR OLECHAR;
|
||||
typedef const WCHAR *LPCWSTR;
|
||||
typedef OLECHAR *BSTR;
|
||||
typedef const OLECHAR *LPCOLESTR;
|
||||
typedef OLECHAR *LPOLESTR;
|
||||
|
||||
typedef struct _FILETIME
|
||||
{
|
||||
DWORD dwLowDateTime;
|
||||
DWORD dwHighDateTime;
|
||||
} FILETIME;
|
||||
|
||||
#define HRESULT LONG
|
||||
#define FAILED(Status) ((HRESULT)(Status)<0)
|
||||
typedef ULONG PROPID;
|
||||
typedef LONG SCODE;
|
||||
|
||||
#define ERROR_NEGATIVE_SEEK 131L
|
||||
|
||||
#define S_OK ((HRESULT)0x00000000L)
|
||||
#define S_FALSE ((HRESULT)0x00000001L)
|
||||
#define E_NOTIMPL ((HRESULT)0x80004001L)
|
||||
#define E_NOINTERFACE ((HRESULT)0x80004002L)
|
||||
#define E_ABORT ((HRESULT)0x80004004L)
|
||||
#define E_FAIL ((HRESULT)0x80004005L)
|
||||
#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)
|
||||
#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
|
||||
#define E_INVALIDARG ((HRESULT)0x80070057L)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STDMETHODCALLTYPE __stdcall
|
||||
#else
|
||||
#define STDMETHODCALLTYPE
|
||||
#endif
|
||||
|
||||
#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
|
||||
#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
|
||||
#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
|
||||
#define STDMETHODIMP STDMETHODIMP_(HRESULT)
|
||||
|
||||
#define PURE = 0
|
||||
|
||||
#define MIDL_INTERFACE(x) struct
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
DEFINE_GUID(IID_IUnknown,
|
||||
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
|
||||
struct IUnknown
|
||||
{
|
||||
STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
|
||||
STDMETHOD_(ULONG, AddRef)() PURE;
|
||||
STDMETHOD_(ULONG, Release)() PURE;
|
||||
#ifndef _WIN32
|
||||
virtual ~IUnknown() {}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef IUnknown *LPUNKNOWN;
|
||||
|
||||
#endif
|
||||
|
||||
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
|
||||
#define VARIANT_FALSE ((VARIANT_BOOL)0)
|
||||
|
||||
enum VARENUM
|
||||
{
|
||||
VT_EMPTY = 0,
|
||||
VT_NULL = 1,
|
||||
VT_I2 = 2,
|
||||
VT_I4 = 3,
|
||||
VT_R4 = 4,
|
||||
VT_R8 = 5,
|
||||
VT_CY = 6,
|
||||
VT_DATE = 7,
|
||||
VT_BSTR = 8,
|
||||
VT_DISPATCH = 9,
|
||||
VT_ERROR = 10,
|
||||
VT_BOOL = 11,
|
||||
VT_VARIANT = 12,
|
||||
VT_UNKNOWN = 13,
|
||||
VT_DECIMAL = 14,
|
||||
VT_I1 = 16,
|
||||
VT_UI1 = 17,
|
||||
VT_UI2 = 18,
|
||||
VT_UI4 = 19,
|
||||
VT_I8 = 20,
|
||||
VT_UI8 = 21,
|
||||
VT_INT = 22,
|
||||
VT_UINT = 23,
|
||||
VT_VOID = 24,
|
||||
VT_HRESULT = 25,
|
||||
VT_FILETIME = 64
|
||||
};
|
||||
|
||||
typedef unsigned short VARTYPE;
|
||||
typedef WORD PROPVAR_PAD1;
|
||||
typedef WORD PROPVAR_PAD2;
|
||||
typedef WORD PROPVAR_PAD3;
|
||||
|
||||
typedef struct tagPROPVARIANT
|
||||
{
|
||||
VARTYPE vt;
|
||||
PROPVAR_PAD1 wReserved1;
|
||||
PROPVAR_PAD2 wReserved2;
|
||||
PROPVAR_PAD3 wReserved3;
|
||||
union
|
||||
{
|
||||
CHAR cVal;
|
||||
UCHAR bVal;
|
||||
SHORT iVal;
|
||||
USHORT uiVal;
|
||||
LONG lVal;
|
||||
ULONG ulVal;
|
||||
INT intVal;
|
||||
UINT uintVal;
|
||||
LARGE_INTEGER hVal;
|
||||
ULARGE_INTEGER uhVal;
|
||||
VARIANT_BOOL boolVal;
|
||||
SCODE scode;
|
||||
FILETIME filetime;
|
||||
BSTR bstrVal;
|
||||
};
|
||||
} PROPVARIANT;
|
||||
|
||||
typedef PROPVARIANT tagVARIANT;
|
||||
typedef tagVARIANT VARIANT;
|
||||
typedef VARIANT VARIANTARG;
|
||||
|
||||
MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
|
||||
MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src);
|
||||
|
||||
typedef struct tagSTATPROPSTG
|
||||
{
|
||||
LPOLESTR lpwstrName;
|
||||
PROPID propid;
|
||||
VARTYPE vt;
|
||||
} STATPROPSTG;
|
||||
|
||||
MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
|
||||
MY_EXTERN_C BSTR SysAllocStringLen(const OLECHAR *sz, UINT len);
|
||||
MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
|
||||
MY_EXTERN_C void SysFreeString(BSTR bstr);
|
||||
MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
|
||||
MY_EXTERN_C UINT SysStringLen(BSTR bstr);
|
||||
|
||||
MY_EXTERN_C DWORD GetLastError();
|
||||
MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
|
||||
|
||||
#define CP_ACP 0
|
||||
#define CP_OEMCP 1
|
||||
#define CP_UTF8 65001
|
||||
|
||||
typedef enum tagSTREAM_SEEK
|
||||
{
|
||||
STREAM_SEEK_SET = 0,
|
||||
STREAM_SEEK_CUR = 1,
|
||||
STREAM_SEEK_END = 2
|
||||
} STREAM_SEEK;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,260 @@
|
||||
// MyXml.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "MyXml.h"
|
||||
|
||||
static bool IsValidChar(char c)
|
||||
{
|
||||
return
|
||||
c >= 'a' && c <= 'z' ||
|
||||
c >= 'A' && c <= 'Z' ||
|
||||
c >= '0' && c <= '9' ||
|
||||
c == '-';
|
||||
}
|
||||
|
||||
static bool IsSpaceChar(char c)
|
||||
{
|
||||
return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A);
|
||||
}
|
||||
|
||||
#define SKIP_SPACES(s) while (IsSpaceChar(*s)) s++;
|
||||
|
||||
int CXmlItem::FindProp(const char *propName) const throw()
|
||||
{
|
||||
FOR_VECTOR (i, Props)
|
||||
if (Props[i].Name == propName)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
AString CXmlItem::GetPropVal(const char *propName) const
|
||||
{
|
||||
int index = FindProp(propName);
|
||||
if (index >= 0)
|
||||
return Props[index].Value;
|
||||
return AString();
|
||||
}
|
||||
|
||||
bool CXmlItem::IsTagged(const char *tag) const throw()
|
||||
{
|
||||
return (IsTag && Name == tag);
|
||||
}
|
||||
|
||||
int CXmlItem::FindSubTag(const char *tag) const throw()
|
||||
{
|
||||
FOR_VECTOR (i, SubItems)
|
||||
if (SubItems[i].IsTagged(tag))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
AString CXmlItem::GetSubString() const
|
||||
{
|
||||
if (SubItems.Size() == 1)
|
||||
{
|
||||
const CXmlItem &item = SubItems[0];
|
||||
if (!item.IsTag)
|
||||
return item.Name;
|
||||
}
|
||||
return AString();
|
||||
}
|
||||
|
||||
const AString * CXmlItem::GetSubStringPtr() const throw()
|
||||
{
|
||||
if (SubItems.Size() == 1)
|
||||
{
|
||||
const CXmlItem &item = SubItems[0];
|
||||
if (!item.IsTag)
|
||||
return &item.Name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AString CXmlItem::GetSubStringForTag(const char *tag) const
|
||||
{
|
||||
int index = FindSubTag(tag);
|
||||
if (index >= 0)
|
||||
return SubItems[index].GetSubString();
|
||||
return AString();
|
||||
}
|
||||
|
||||
const char * CXmlItem::ParseItem(const char *s, int numAllowedLevels)
|
||||
{
|
||||
SKIP_SPACES(s);
|
||||
|
||||
const char *beg = s;
|
||||
for (;;)
|
||||
{
|
||||
char c;
|
||||
c = *s; if (c == 0 || c == '<') break; s++;
|
||||
c = *s; if (c == 0 || c == '<') break; s++;
|
||||
}
|
||||
if (*s == 0)
|
||||
return NULL;
|
||||
if (s != beg)
|
||||
{
|
||||
IsTag = false;
|
||||
Name.SetFrom(beg, (unsigned)(s - beg));
|
||||
return s;
|
||||
}
|
||||
|
||||
IsTag = true;
|
||||
|
||||
s++;
|
||||
SKIP_SPACES(s);
|
||||
|
||||
beg = s;
|
||||
for (;; s++)
|
||||
if (!IsValidChar(*s))
|
||||
break;
|
||||
if (s == beg || *s == 0)
|
||||
return NULL;
|
||||
Name.SetFrom(beg, (unsigned)(s - beg));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
beg = s;
|
||||
SKIP_SPACES(s);
|
||||
if (*s == '/')
|
||||
{
|
||||
s++;
|
||||
// SKIP_SPACES(s);
|
||||
if (*s != '>')
|
||||
return NULL;
|
||||
return s + 1;
|
||||
}
|
||||
if (*s == '>')
|
||||
{
|
||||
s++;
|
||||
if (numAllowedLevels == 0)
|
||||
return NULL;
|
||||
SubItems.Clear();
|
||||
for (;;)
|
||||
{
|
||||
SKIP_SPACES(s);
|
||||
if (s[0] == '<' && s[1] == '/')
|
||||
break;
|
||||
CXmlItem &item = SubItems.AddNew();
|
||||
s = item.ParseItem(s, numAllowedLevels - 1);
|
||||
if (!s)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s += 2;
|
||||
unsigned len = Name.Len();
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
if (s[i] != Name[i])
|
||||
return NULL;
|
||||
s += len;
|
||||
if (s[0] != '>')
|
||||
return NULL;
|
||||
return s + 1;
|
||||
}
|
||||
if (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 const char * SkipHeader(const char *s, const char *startString, const char *endString)
|
||||
{
|
||||
SKIP_SPACES(s);
|
||||
if (IsString1PrefixedByString2(s, startString))
|
||||
{
|
||||
s = strstr(s, endString);
|
||||
if (!s)
|
||||
return NULL;
|
||||
s += strlen(endString);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
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 char *s)
|
||||
{
|
||||
s = SkipHeader(s, "<?xml", "?>"); if (!s) return false;
|
||||
s = SkipHeader(s, "<!DOCTYPE", ">"); if (!s) return false;
|
||||
|
||||
s = Root.ParseItem(s, 1000);
|
||||
if (!s || !Root.IsTag)
|
||||
return false;
|
||||
SKIP_SPACES(s);
|
||||
return *s == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void CXml::AppendTo(AString &s) const
|
||||
{
|
||||
Root.AppendTo(s);
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,43 @@
|
||||
// MyXml.h
|
||||
|
||||
#ifndef __MY_XML_H
|
||||
#define __MY_XML_H
|
||||
|
||||
#include "MyString.h"
|
||||
|
||||
struct CXmlProp
|
||||
{
|
||||
AString Name;
|
||||
AString Value;
|
||||
};
|
||||
|
||||
class CXmlItem
|
||||
{
|
||||
public:
|
||||
AString Name;
|
||||
bool IsTag;
|
||||
CObjectVector<CXmlProp> Props;
|
||||
CObjectVector<CXmlItem> SubItems;
|
||||
|
||||
const char * ParseItem(const char *s, int numAllowedLevels);
|
||||
|
||||
bool IsTagged(const char *tag) const throw();
|
||||
int FindProp(const char *propName) const throw();
|
||||
AString GetPropVal(const char *propName) const;
|
||||
AString GetSubString() const;
|
||||
const AString * GetSubStringPtr() const throw();
|
||||
int FindSubTag(const char *tag) const throw();
|
||||
AString GetSubStringForTag(const char *tag) const;
|
||||
|
||||
void AppendTo(AString &s) const;
|
||||
};
|
||||
|
||||
struct CXml
|
||||
{
|
||||
CXmlItem Root;
|
||||
|
||||
bool Parse(const char *s);
|
||||
// void AppendTo(AString &s) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,163 @@
|
||||
// NewHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "NewHandler.h"
|
||||
|
||||
// #define DEBUG_MEMORY_LEAK
|
||||
|
||||
#ifndef DEBUG_MEMORY_LEAK
|
||||
|
||||
#ifdef _7ZIP_REDEFINE_OPERATOR_NEW
|
||||
|
||||
/*
|
||||
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);
|
||||
if (oldSize != 0)
|
||||
memcpy(newBuf, p, oldSize);
|
||||
my_delete(p);
|
||||
return newBuf;
|
||||
}
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// #pragma init_seg(lib)
|
||||
const int kDebugSize = 1000000;
|
||||
static void *a[kDebugSize];
|
||||
static int index = 0;
|
||||
|
||||
static int numAllocs = 0;
|
||||
void * __cdecl operator new(size_t size)
|
||||
{
|
||||
numAllocs++;
|
||||
void *p = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
if (index < kDebugSize)
|
||||
{
|
||||
a[index] = p;
|
||||
index++;
|
||||
}
|
||||
if (p == 0)
|
||||
throw CNewException();
|
||||
printf("Alloc %6d, size = %8u\n", numAllocs, (unsigned)size);
|
||||
return p;
|
||||
}
|
||||
|
||||
class CC
|
||||
{
|
||||
public:
|
||||
CC()
|
||||
{
|
||||
for (int i = 0; i < kDebugSize; i++)
|
||||
a[i] = 0;
|
||||
}
|
||||
~CC()
|
||||
{
|
||||
for (int i = 0; i < kDebugSize; i++)
|
||||
if (a[i] != 0)
|
||||
return;
|
||||
}
|
||||
} g_CC;
|
||||
|
||||
|
||||
void __cdecl operator delete(void *p)
|
||||
{
|
||||
if (p == 0)
|
||||
return;
|
||||
/*
|
||||
for (int i = 0; i < index; i++)
|
||||
if (a[i] == p)
|
||||
a[i] = 0;
|
||||
*/
|
||||
HeapFree(GetProcessHeap(), 0, p);
|
||||
numAllocs--;
|
||||
printf("Free %d\n", numAllocs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
int MemErrorVC(size_t)
|
||||
{
|
||||
throw CNewException();
|
||||
// return 1;
|
||||
}
|
||||
CNewHandlerSetter::CNewHandlerSetter()
|
||||
{
|
||||
// MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
|
||||
}
|
||||
CNewHandlerSetter::~CNewHandlerSetter()
|
||||
{
|
||||
// _set_new_handler(MemErrorOldVCFunction);
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,88 @@
|
||||
// Common/NewHandler.h
|
||||
|
||||
#ifndef __COMMON_NEW_HANDLER_H
|
||||
#define __COMMON_NEW_HANDLER_H
|
||||
|
||||
/*
|
||||
NewHandler.h and NewHandler.cpp allows to solve problem with compilers that
|
||||
don't throw exception in operator new().
|
||||
|
||||
This file must be included before any code that uses operators new() or delete()
|
||||
and you must compile and link "NewHandler.cpp", if you use some old MSVC compiler.
|
||||
|
||||
The operator new() in some MSVC versions doesn't throw exception std::bad_alloc.
|
||||
MSVC 6.0 (_MSC_VER == 1200) doesn't throw exception.
|
||||
The code produced by some another MSVC compilers also can be linked
|
||||
to library that doesn't throw exception.
|
||||
We suppose that code compiled with VS2015+ (_MSC_VER >= 1900) throws exception std::bad_alloc.
|
||||
For older _MSC_VER versions we redefine operator new() and operator delete().
|
||||
Our version of operator new() throws CNewException() exception on failure.
|
||||
|
||||
It's still allowed to use redefined version of operator new() from "NewHandler.cpp"
|
||||
with any compiler. 7-Zip's code can work with std::bad_alloc and CNewException() exceptions.
|
||||
But if you use some additional code (outside of 7-Zip's code), you must check
|
||||
that redefined version of operator new() is not problem for your code.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
// If you want to use default operator new(), you can disable the following line
|
||||
#define _7ZIP_REDEFINE_OPERATOR_NEW
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _7ZIP_REDEFINE_OPERATOR_NEW
|
||||
|
||||
// std::bad_alloc can require additional DLL dependency.
|
||||
// So we don't define CNewException as std::bad_alloc here.
|
||||
|
||||
class CNewException {};
|
||||
|
||||
void *
|
||||
#ifdef _MSC_VER
|
||||
__cdecl
|
||||
#endif
|
||||
operator new(size_t size);
|
||||
|
||||
void
|
||||
#ifdef _MSC_VER
|
||||
__cdecl
|
||||
#endif
|
||||
operator delete(void *p) throw();
|
||||
|
||||
#else
|
||||
|
||||
#include <new>
|
||||
|
||||
#define CNewException std::bad_alloc
|
||||
|
||||
#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,0 +1,28 @@
|
||||
// Common/Random.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <time.h>
|
||||
#else
|
||||
#include "MyWindows.h"
|
||||
#endif
|
||||
|
||||
#include "Random.h"
|
||||
|
||||
void CRandom::Init(unsigned int seed) { srand(seed); }
|
||||
|
||||
void CRandom::Init()
|
||||
{
|
||||
Init((unsigned int)
|
||||
#ifdef _WIN32
|
||||
GetTickCount()
|
||||
#else
|
||||
time(NULL)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
int CRandom::Generate() const { return rand(); }
|
||||
@@ -0,0 +1,14 @@
|
||||
// Common/Random.h
|
||||
|
||||
#ifndef __COMMON_RANDOM_H
|
||||
#define __COMMON_RANDOM_H
|
||||
|
||||
class CRandom
|
||||
{
|
||||
public:
|
||||
void Init();
|
||||
void Init(unsigned int seed);
|
||||
int Generate() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
// Sha1Reg.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../C/Sha1.h"
|
||||
|
||||
#include "../Common/MyCom.h"
|
||||
|
||||
#include "../7zip/Common/RegisterCodec.h"
|
||||
|
||||
class CSha1Hasher:
|
||||
public IHasher,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CSha1 _sha;
|
||||
Byte mtDummy[1 << 7];
|
||||
|
||||
public:
|
||||
CSha1Hasher() { Sha1_Init(&_sha); }
|
||||
|
||||
MY_UNKNOWN_IMP1(IHasher)
|
||||
INTERFACE_IHasher(;)
|
||||
};
|
||||
|
||||
STDMETHODIMP_(void) CSha1Hasher::Init() throw()
|
||||
{
|
||||
Sha1_Init(&_sha);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CSha1Hasher::Update(const void *data, UInt32 size) throw()
|
||||
{
|
||||
Sha1_Update(&_sha, (const Byte *)data, size);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CSha1Hasher::Final(Byte *digest) throw()
|
||||
{
|
||||
Sha1_Final(&_sha, digest);
|
||||
}
|
||||
|
||||
REGISTER_HASHER(CSha1Hasher, 0x201, "SHA1", SHA1_DIGEST_SIZE)
|
||||
@@ -0,0 +1,40 @@
|
||||
// Sha256Reg.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../C/Sha256.h"
|
||||
|
||||
#include "../Common/MyCom.h"
|
||||
|
||||
#include "../7zip/Common/RegisterCodec.h"
|
||||
|
||||
class CSha256Hasher:
|
||||
public IHasher,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CSha256 _sha;
|
||||
Byte mtDummy[1 << 7];
|
||||
|
||||
public:
|
||||
CSha256Hasher() { Sha256_Init(&_sha); }
|
||||
|
||||
MY_UNKNOWN_IMP1(IHasher)
|
||||
INTERFACE_IHasher(;)
|
||||
};
|
||||
|
||||
STDMETHODIMP_(void) CSha256Hasher::Init() throw()
|
||||
{
|
||||
Sha256_Init(&_sha);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CSha256Hasher::Update(const void *data, UInt32 size) throw()
|
||||
{
|
||||
Sha256_Update(&_sha, (const Byte *)data, size);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CSha256Hasher::Final(Byte *digest) throw()
|
||||
{
|
||||
Sha256_Final(&_sha, digest);
|
||||
}
|
||||
|
||||
REGISTER_HASHER(CSha256Hasher, 0xA, "SHA256", SHA256_DIGEST_SIZE)
|
||||
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
// Common/StdInStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
#include "StdInStream.h"
|
||||
#include "StringConvert.h"
|
||||
#include "UTFConvert.h"
|
||||
|
||||
// #define kEOFMessage "Unexpected end of input stream"
|
||||
// #define kReadErrorMessage "Error reading input stream"
|
||||
// #define kIllegalCharMessage "Illegal zero character in input stream"
|
||||
|
||||
#define kFileOpenMode TEXT("r")
|
||||
|
||||
extern int g_CodePage;
|
||||
|
||||
CStdInStream g_StdIn(stdin);
|
||||
|
||||
bool CStdInStream::Open(LPCTSTR fileName) throw()
|
||||
{
|
||||
Close();
|
||||
_stream = _tfopen(fileName, kFileOpenMode);
|
||||
_streamIsOpen = (_stream != 0);
|
||||
return _streamIsOpen;
|
||||
}
|
||||
|
||||
bool CStdInStream::Close() throw()
|
||||
{
|
||||
if (!_streamIsOpen)
|
||||
return true;
|
||||
_streamIsOpen = (fclose(_stream) != 0);
|
||||
return !_streamIsOpen;
|
||||
}
|
||||
|
||||
bool CStdInStream::ScanAStringUntilNewLine(AString &s)
|
||||
{
|
||||
s.Empty();
|
||||
for (;;)
|
||||
{
|
||||
int intChar = GetChar();
|
||||
if (intChar == EOF)
|
||||
return true;
|
||||
char c = (char)intChar;
|
||||
if (c == 0)
|
||||
return false;
|
||||
if (c == '\n')
|
||||
return true;
|
||||
s += c;
|
||||
}
|
||||
}
|
||||
|
||||
bool CStdInStream::ScanUStringUntilNewLine(UString &dest)
|
||||
{
|
||||
dest.Empty();
|
||||
AString s;
|
||||
bool res = ScanAStringUntilNewLine(s);
|
||||
int codePage = g_CodePage;
|
||||
if (codePage == -1)
|
||||
codePage = CP_OEMCP;
|
||||
if (codePage == CP_UTF8)
|
||||
ConvertUTF8ToUnicode(s, dest);
|
||||
else
|
||||
MultiByteToUnicodeString2(dest, s, (UINT)codePage);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
bool CStdInStream::ReadToString(AString &resultString)
|
||||
{
|
||||
resultString.Empty();
|
||||
for (;;)
|
||||
{
|
||||
int intChar = GetChar();
|
||||
if (intChar == EOF)
|
||||
return !Error();
|
||||
char c = (char)intChar;
|
||||
if (c == 0)
|
||||
return false;
|
||||
resultString += c;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
int CStdInStream::GetChar()
|
||||
{
|
||||
return fgetc(_stream); // getc() doesn't work in BeOS?
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Common/StdInStream.h
|
||||
|
||||
#ifndef __COMMON_STD_IN_STREAM_H
|
||||
#define __COMMON_STD_IN_STREAM_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "MyString.h"
|
||||
#include "MyTypes.h"
|
||||
|
||||
class CStdInStream
|
||||
{
|
||||
FILE *_stream;
|
||||
bool _streamIsOpen;
|
||||
public:
|
||||
CStdInStream(): _stream(0), _streamIsOpen(false) {};
|
||||
CStdInStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
|
||||
~CStdInStream() { Close(); }
|
||||
|
||||
bool Open(LPCTSTR fileName) throw();
|
||||
bool Close() throw();
|
||||
|
||||
// returns:
|
||||
// false, if ZERO character in stream
|
||||
// true, if EOF or '\n'
|
||||
bool ScanAStringUntilNewLine(AString &s);
|
||||
bool ScanUStringUntilNewLine(UString &s);
|
||||
// bool ReadToString(AString &resultString);
|
||||
|
||||
bool Eof() const throw() { return (feof(_stream) != 0); }
|
||||
bool Error() const throw() { return (ferror(_stream) != 0); }
|
||||
|
||||
int GetChar();
|
||||
};
|
||||
|
||||
extern CStdInStream g_StdIn;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,163 @@
|
||||
// Common/StdOutStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
#include "IntToString.h"
|
||||
#include "StdOutStream.h"
|
||||
#include "StringConvert.h"
|
||||
#include "UTFConvert.h"
|
||||
|
||||
#define kFileOpenMode "wt"
|
||||
|
||||
extern int g_CodePage;
|
||||
|
||||
CStdOutStream g_StdOut(stdout);
|
||||
CStdOutStream g_StdErr(stderr);
|
||||
|
||||
bool CStdOutStream::Open(const char *fileName) throw()
|
||||
{
|
||||
Close();
|
||||
_stream = fopen(fileName, kFileOpenMode);
|
||||
_streamIsOpen = (_stream != 0);
|
||||
return _streamIsOpen;
|
||||
}
|
||||
|
||||
bool CStdOutStream::Close() throw()
|
||||
{
|
||||
if (!_streamIsOpen)
|
||||
return true;
|
||||
if (fclose(_stream) != 0)
|
||||
return false;
|
||||
_stream = 0;
|
||||
_streamIsOpen = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CStdOutStream::Flush() throw()
|
||||
{
|
||||
return (fflush(_stream) == 0);
|
||||
}
|
||||
|
||||
CStdOutStream & endl(CStdOutStream & outStream) throw()
|
||||
{
|
||||
return outStream << '\n';
|
||||
}
|
||||
|
||||
CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)
|
||||
{
|
||||
int codePage = g_CodePage;
|
||||
if (codePage == -1)
|
||||
codePage = CP_OEMCP;
|
||||
AString dest;
|
||||
if (codePage == CP_UTF8)
|
||||
ConvertUnicodeToUTF8(s, dest);
|
||||
else
|
||||
UnicodeStringToMultiByte2(dest, s, (UINT)codePage);
|
||||
return operator<<((const char *)dest);
|
||||
}
|
||||
|
||||
void StdOut_Convert_UString_to_AString(const UString &s, AString &temp)
|
||||
{
|
||||
int codePage = g_CodePage;
|
||||
if (codePage == -1)
|
||||
codePage = CP_OEMCP;
|
||||
if (codePage == CP_UTF8)
|
||||
ConvertUnicodeToUTF8(s, temp);
|
||||
else
|
||||
UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
|
||||
}
|
||||
|
||||
void CStdOutStream::PrintUString(const UString &s, AString &temp)
|
||||
{
|
||||
StdOut_Convert_UString_to_AString(s, temp);
|
||||
*this << (const char *)temp;
|
||||
}
|
||||
|
||||
|
||||
static const wchar_t kReplaceChar = '_';
|
||||
|
||||
void CStdOutStream::Normalize_UString__LF_Allowed(UString &s)
|
||||
{
|
||||
unsigned len = s.Len();
|
||||
wchar_t *d = s.GetBuf();
|
||||
|
||||
if (IsTerminalMode)
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
wchar_t c = d[i];
|
||||
if (c <= 13 && c >= 7 && c != '\n')
|
||||
d[i] = kReplaceChar;
|
||||
}
|
||||
}
|
||||
|
||||
void CStdOutStream::Normalize_UString(UString &s)
|
||||
{
|
||||
unsigned len = s.Len();
|
||||
wchar_t *d = s.GetBuf();
|
||||
|
||||
if (IsTerminalMode)
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
wchar_t c = d[i];
|
||||
if (c <= 13 && c >= 7)
|
||||
d[i] = kReplaceChar;
|
||||
}
|
||||
else
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
wchar_t c = d[i];
|
||||
if (c == '\n')
|
||||
d[i] = kReplaceChar;
|
||||
}
|
||||
}
|
||||
|
||||
void CStdOutStream::NormalizePrint_UString(const UString &s, UString &tempU, AString &tempA)
|
||||
{
|
||||
tempU = s;
|
||||
Normalize_UString(tempU);
|
||||
PrintUString(tempU, tempA);
|
||||
}
|
||||
|
||||
void CStdOutStream::NormalizePrint_UString(const UString &s)
|
||||
{
|
||||
NormalizePrint_wstr(s);
|
||||
}
|
||||
|
||||
void CStdOutStream::NormalizePrint_wstr(const wchar_t *s)
|
||||
{
|
||||
UString tempU = s;
|
||||
Normalize_UString(tempU);
|
||||
AString tempA;
|
||||
PrintUString(tempU, tempA);
|
||||
}
|
||||
|
||||
|
||||
CStdOutStream & CStdOutStream::operator<<(Int32 number) throw()
|
||||
{
|
||||
char s[32];
|
||||
ConvertInt64ToString(number, s);
|
||||
return operator<<(s);
|
||||
}
|
||||
|
||||
CStdOutStream & CStdOutStream::operator<<(Int64 number) throw()
|
||||
{
|
||||
char s[32];
|
||||
ConvertInt64ToString(number, s);
|
||||
return operator<<(s);
|
||||
}
|
||||
|
||||
CStdOutStream & CStdOutStream::operator<<(UInt32 number) throw()
|
||||
{
|
||||
char s[16];
|
||||
ConvertUInt32ToString(number, s);
|
||||
return operator<<(s);
|
||||
}
|
||||
|
||||
CStdOutStream & CStdOutStream::operator<<(UInt64 number) throw()
|
||||
{
|
||||
char s[32];
|
||||
ConvertUInt64ToString(number, s);
|
||||
return operator<<(s);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// Common/StdOutStream.h
|
||||
|
||||
#ifndef __COMMON_STD_OUT_STREAM_H
|
||||
#define __COMMON_STD_OUT_STREAM_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "MyString.h"
|
||||
#include "MyTypes.h"
|
||||
|
||||
class CStdOutStream
|
||||
{
|
||||
FILE *_stream;
|
||||
bool _streamIsOpen;
|
||||
public:
|
||||
bool IsTerminalMode;
|
||||
|
||||
CStdOutStream(): _stream(0), _streamIsOpen(false), IsTerminalMode(false) {};
|
||||
CStdOutStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
|
||||
~CStdOutStream() { Close(); }
|
||||
|
||||
// void AttachStdStream(FILE *stream) { _stream = stream; _streamIsOpen = false; }
|
||||
// bool IsDefined() const { return _stream != NULL; }
|
||||
|
||||
operator FILE *() { return _stream; }
|
||||
bool Open(const char *fileName) throw();
|
||||
bool Close() throw();
|
||||
bool Flush() throw();
|
||||
|
||||
CStdOutStream & operator<<(CStdOutStream & (* func)(CStdOutStream &))
|
||||
{
|
||||
(*func)(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CStdOutStream & operator<<(const char *s) throw()
|
||||
{
|
||||
fputs(s, _stream);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CStdOutStream & operator<<(char c) throw()
|
||||
{
|
||||
fputc((unsigned char)c, _stream);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CStdOutStream & operator<<(Int32 number) throw();
|
||||
CStdOutStream & operator<<(Int64 number) throw();
|
||||
CStdOutStream & operator<<(UInt32 number) throw();
|
||||
CStdOutStream & operator<<(UInt64 number) throw();
|
||||
|
||||
CStdOutStream & operator<<(const wchar_t *s);
|
||||
void PrintUString(const UString &s, AString &temp);
|
||||
|
||||
void Normalize_UString__LF_Allowed(UString &s);
|
||||
void Normalize_UString(UString &s);
|
||||
|
||||
void NormalizePrint_UString(const UString &s, UString &tempU, AString &tempA);
|
||||
void NormalizePrint_UString(const UString &s);
|
||||
void NormalizePrint_wstr(const wchar_t *s);
|
||||
};
|
||||
|
||||
CStdOutStream & endl(CStdOutStream & outStream) throw();
|
||||
|
||||
extern CStdOutStream g_StdOut;
|
||||
extern CStdOutStream g_StdErr;
|
||||
|
||||
void StdOut_Convert_UString_to_AString(const UString &s, AString &temp);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,319 @@
|
||||
// Common/StringConvert.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "StringConvert.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static const char k_DefultChar = '_';
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/*
|
||||
MultiByteToWideChar(CodePage, DWORD dwFlags,
|
||||
LPCSTR lpMultiByteStr, int cbMultiByte,
|
||||
LPWSTR lpWideCharStr, int cchWideChar)
|
||||
|
||||
if (cbMultiByte == 0)
|
||||
return: 0. ERR: ERROR_INVALID_PARAMETER
|
||||
|
||||
if (cchWideChar == 0)
|
||||
return: the required buffer size in characters.
|
||||
|
||||
if (supplied buffer size was not large enough)
|
||||
return: 0. ERR: ERROR_INSUFFICIENT_BUFFER
|
||||
The number of filled characters in lpWideCharStr can be smaller than cchWideChar (if last character is complex)
|
||||
|
||||
If there are illegal characters:
|
||||
if MB_ERR_INVALID_CHARS is set in dwFlags:
|
||||
- the function stops conversion on illegal character.
|
||||
- Return: 0. ERR: ERROR_NO_UNICODE_TRANSLATION.
|
||||
|
||||
if MB_ERR_INVALID_CHARS is NOT set in dwFlags:
|
||||
before Vista: illegal character is dropped (skipped). WinXP-64: GetLastError() returns 0.
|
||||
in Vista+: illegal character is not dropped (MSDN). Undocumented: illegal
|
||||
character is converted to U+FFFD, which is REPLACEMENT CHARACTER.
|
||||
*/
|
||||
|
||||
|
||||
void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage)
|
||||
{
|
||||
dest.Empty();
|
||||
if (src.IsEmpty())
|
||||
return;
|
||||
{
|
||||
/*
|
||||
wchar_t *d = dest.GetBuf(src.Len());
|
||||
const char *s = (const char *)src;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0;;)
|
||||
{
|
||||
Byte c = (Byte)s[i];
|
||||
if (c >= 0x80 || c == 0)
|
||||
break;
|
||||
d[i++] = (wchar_t)c;
|
||||
}
|
||||
|
||||
if (i != src.Len())
|
||||
{
|
||||
unsigned len = MultiByteToWideChar(codePage, 0, s + i,
|
||||
src.Len() - i, d + i,
|
||||
src.Len() + 1 - i);
|
||||
if (len == 0)
|
||||
throw 282228;
|
||||
i += len;
|
||||
}
|
||||
|
||||
d[i] = 0;
|
||||
dest.ReleaseBuf_SetLen(i);
|
||||
*/
|
||||
unsigned len = MultiByteToWideChar(codePage, 0, src, src.Len(), NULL, 0);
|
||||
if (len == 0)
|
||||
{
|
||||
if (GetLastError() != 0)
|
||||
throw 282228;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = MultiByteToWideChar(codePage, 0, src, src.Len(), dest.GetBuf(len), len);
|
||||
if (len == 0)
|
||||
throw 282228;
|
||||
dest.ReleaseBuf_SetEnd(len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
int WideCharToMultiByte(
|
||||
UINT CodePage, DWORD dwFlags,
|
||||
LPCWSTR lpWideCharStr, int cchWideChar,
|
||||
LPSTR lpMultiByteStr, int cbMultiByte,
|
||||
LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
|
||||
|
||||
if (lpDefaultChar == NULL),
|
||||
- it uses system default value.
|
||||
|
||||
if (CodePage == CP_UTF7 || CodePage == CP_UTF8)
|
||||
if (lpDefaultChar != NULL || lpUsedDefaultChar != NULL)
|
||||
return: 0. ERR: ERROR_INVALID_PARAMETER.
|
||||
|
||||
The function operates most efficiently, if (lpDefaultChar == NULL && lpUsedDefaultChar == NULL)
|
||||
|
||||
*/
|
||||
|
||||
static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
|
||||
{
|
||||
dest.Empty();
|
||||
defaultCharWasUsed = false;
|
||||
if (src.IsEmpty())
|
||||
return;
|
||||
{
|
||||
/*
|
||||
unsigned numRequiredBytes = src.Len() * 2;
|
||||
char *d = dest.GetBuf(numRequiredBytes);
|
||||
const wchar_t *s = (const wchar_t *)src;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0;;)
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
if (c >= 0x80 || c == 0)
|
||||
break;
|
||||
d[i++] = (char)c;
|
||||
}
|
||||
|
||||
if (i != src.Len())
|
||||
{
|
||||
BOOL defUsed = FALSE;
|
||||
defaultChar = defaultChar;
|
||||
|
||||
bool isUtf = (codePage == CP_UTF8 || codePage == CP_UTF7);
|
||||
unsigned len = WideCharToMultiByte(codePage, 0, s + i, src.Len() - i,
|
||||
d + i, numRequiredBytes + 1 - i,
|
||||
(isUtf ? NULL : &defaultChar),
|
||||
(isUtf ? NULL : &defUsed));
|
||||
defaultCharWasUsed = (defUsed != FALSE);
|
||||
if (len == 0)
|
||||
throw 282229;
|
||||
i += len;
|
||||
}
|
||||
|
||||
d[i] = 0;
|
||||
dest.ReleaseBuf_SetLen(i);
|
||||
*/
|
||||
|
||||
/*
|
||||
if (codePage != CP_UTF7)
|
||||
{
|
||||
const wchar_t *s = (const wchar_t *)src;
|
||||
unsigned i;
|
||||
for (i = 0;; i++)
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
if (c >= 0x80 || c == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (s[i] == 0)
|
||||
{
|
||||
char *d = dest.GetBuf(src.Len());
|
||||
for (i = 0;;)
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
d[i++] = (char)c;
|
||||
}
|
||||
d[i] = 0;
|
||||
dest.ReleaseBuf_SetLen(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
unsigned len = WideCharToMultiByte(codePage, 0, src, src.Len(), NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
{
|
||||
if (GetLastError() != 0)
|
||||
throw 282228;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL defUsed = FALSE;
|
||||
bool isUtf = (codePage == CP_UTF8 || codePage == CP_UTF7);
|
||||
// defaultChar = defaultChar;
|
||||
len = WideCharToMultiByte(codePage, 0, src, src.Len(),
|
||||
dest.GetBuf(len), len,
|
||||
(isUtf ? NULL : &defaultChar),
|
||||
(isUtf ? NULL : &defUsed)
|
||||
);
|
||||
if (!isUtf)
|
||||
defaultCharWasUsed = (defUsed != FALSE);
|
||||
if (len == 0)
|
||||
throw 282228;
|
||||
dest.ReleaseBuf_SetEnd(len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#ifndef UNDER_CE
|
||||
AString SystemStringToOemString(const CSysString &src)
|
||||
{
|
||||
AString dest;
|
||||
const unsigned len = src.Len() * 2;
|
||||
CharToOem(src, dest.GetBuf(len));
|
||||
dest.ReleaseBuf_CalcLen(len);
|
||||
return dest;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
#else
|
||||
|
||||
void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT /* codePage */)
|
||||
{
|
||||
dest.Empty();
|
||||
if (src.IsEmpty())
|
||||
return;
|
||||
|
||||
size_t limit = ((size_t)src.Len() + 1) * 2;
|
||||
wchar_t *d = dest.GetBuf((unsigned)limit);
|
||||
size_t len = mbstowcs(d, src, limit);
|
||||
if (len != (size_t)-1)
|
||||
{
|
||||
dest.ReleaseBuf_SetEnd((unsigned)len);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
const char *s = (const char *)src;
|
||||
for (i = 0;;)
|
||||
{
|
||||
Byte c = (Byte)s[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
d[i++] = (wchar_t)c;
|
||||
}
|
||||
d[i] = 0;
|
||||
dest.ReleaseBuf_SetLen(i);
|
||||
}
|
||||
}
|
||||
|
||||
static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT /* codePage */, char defaultChar, bool &defaultCharWasUsed)
|
||||
{
|
||||
dest.Empty();
|
||||
defaultCharWasUsed = false;
|
||||
if (src.IsEmpty())
|
||||
return;
|
||||
|
||||
size_t limit = ((size_t)src.Len() + 1) * 6;
|
||||
char *d = dest.GetBuf((unsigned)limit);
|
||||
size_t len = wcstombs(d, src, limit);
|
||||
if (len != (size_t)-1)
|
||||
{
|
||||
dest.ReleaseBuf_SetEnd((unsigned)len);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
const wchar_t *s = (const wchar_t *)src;
|
||||
unsigned i;
|
||||
for (i = 0;;)
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c >= 0x100)
|
||||
{
|
||||
c = defaultChar;
|
||||
defaultCharWasUsed = true;
|
||||
}
|
||||
d[i++] = (char)c;
|
||||
}
|
||||
d[i] = 0;
|
||||
dest.ReleaseBuf_SetLen(i);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
UString MultiByteToUnicodeString(const AString &src, UINT codePage)
|
||||
{
|
||||
UString dest;
|
||||
MultiByteToUnicodeString2(dest, src, codePage);
|
||||
return dest;
|
||||
}
|
||||
|
||||
UString MultiByteToUnicodeString(const char *src, UINT codePage)
|
||||
{
|
||||
return MultiByteToUnicodeString(AString(src), codePage);
|
||||
}
|
||||
|
||||
|
||||
void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage)
|
||||
{
|
||||
bool defaultCharWasUsed;
|
||||
UnicodeStringToMultiByte2(dest, src, codePage, k_DefultChar, defaultCharWasUsed);
|
||||
}
|
||||
|
||||
AString UnicodeStringToMultiByte(const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
|
||||
{
|
||||
AString dest;
|
||||
UnicodeStringToMultiByte2(dest, src, codePage, defaultChar, defaultCharWasUsed);
|
||||
return dest;
|
||||
}
|
||||
|
||||
AString UnicodeStringToMultiByte(const UString &src, UINT codePage)
|
||||
{
|
||||
AString dest;
|
||||
bool defaultCharWasUsed;
|
||||
UnicodeStringToMultiByte2(dest, src, codePage, k_DefultChar, defaultCharWasUsed);
|
||||
return dest;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// Common/StringConvert.h
|
||||
|
||||
#ifndef __COMMON_STRING_CONVERT_H
|
||||
#define __COMMON_STRING_CONVERT_H
|
||||
|
||||
#include "MyString.h"
|
||||
#include "MyWindows.h"
|
||||
|
||||
UString MultiByteToUnicodeString(const AString &src, UINT codePage = CP_ACP);
|
||||
UString MultiByteToUnicodeString(const char *src, UINT codePage = CP_ACP);
|
||||
|
||||
// optimized versions that work faster for ASCII strings
|
||||
void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage = CP_ACP);
|
||||
// void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
|
||||
void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage);
|
||||
|
||||
AString UnicodeStringToMultiByte(const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
|
||||
AString UnicodeStringToMultiByte(const UString &src, UINT codePage = CP_ACP);
|
||||
|
||||
inline const wchar_t* GetUnicodeString(const wchar_t *u) { return u; }
|
||||
inline const UString& GetUnicodeString(const UString &u) { return u; }
|
||||
|
||||
inline UString GetUnicodeString(const AString &a) { return MultiByteToUnicodeString(a); }
|
||||
inline UString GetUnicodeString(const char *a) { return MultiByteToUnicodeString(a); }
|
||||
|
||||
inline UString GetUnicodeString(const AString &a, UINT codePage)
|
||||
{ return MultiByteToUnicodeString(a, codePage); }
|
||||
inline UString GetUnicodeString(const char *a, UINT codePage)
|
||||
{ return MultiByteToUnicodeString(a, codePage); }
|
||||
|
||||
inline const wchar_t* GetUnicodeString(const wchar_t *u, UINT) { return u; }
|
||||
inline const UString& GetUnicodeString(const UString &u, UINT) { return u; }
|
||||
|
||||
inline const char* GetAnsiString(const char *a) { return a; }
|
||||
inline const AString& GetAnsiString(const AString &a) { return a; }
|
||||
|
||||
inline AString GetAnsiString(const wchar_t *u) { return UnicodeStringToMultiByte(UString(u)); }
|
||||
inline AString GetAnsiString(const UString &u) { return UnicodeStringToMultiByte(u); }
|
||||
|
||||
/*
|
||||
inline const char* GetOemString(const char* oem)
|
||||
{ return oem; }
|
||||
inline const AString& GetOemString(const AString &oem)
|
||||
{ return oem; }
|
||||
*/
|
||||
const char* GetOemString(const char* oem);
|
||||
const AString& GetOemString(const AString &oem);
|
||||
inline AString GetOemString(const UString &u)
|
||||
{ return UnicodeStringToMultiByte(u, CP_OEMCP); }
|
||||
|
||||
#ifdef _UNICODE
|
||||
inline const wchar_t* GetSystemString(const wchar_t *u) { return u;}
|
||||
inline const UString& GetSystemString(const UString &u) { return u;}
|
||||
inline const wchar_t* GetSystemString(const wchar_t *u, UINT /* codePage */) { return u;}
|
||||
inline const UString& GetSystemString(const UString &u, UINT /* codePage */) { return u;}
|
||||
|
||||
inline UString GetSystemString(const AString &a, UINT codePage) { return MultiByteToUnicodeString(a, codePage); }
|
||||
inline UString GetSystemString(const char *a, UINT codePage) { return MultiByteToUnicodeString(a, codePage); }
|
||||
inline UString GetSystemString(const AString &a) { return MultiByteToUnicodeString(a); }
|
||||
inline UString GetSystemString(const char *a) { return MultiByteToUnicodeString(a); }
|
||||
#else
|
||||
inline const char* GetSystemString(const char *a) { return a; }
|
||||
inline const AString& GetSystemString(const AString &a) { return a; }
|
||||
inline const char* GetSystemString(const char *a, UINT) { return a; }
|
||||
inline const AString& GetSystemString(const AString &a, UINT) { return a; }
|
||||
|
||||
inline AString GetSystemString(const wchar_t *u) { return UnicodeStringToMultiByte(UString(u)); }
|
||||
inline AString GetSystemString(const UString &u) { return UnicodeStringToMultiByte(u); }
|
||||
inline AString GetSystemString(const UString &u, UINT codePage) { return UnicodeStringToMultiByte(u, codePage); }
|
||||
|
||||
|
||||
|
||||
/*
|
||||
inline AString GetSystemString(const wchar_t *u)
|
||||
{
|
||||
UString s;
|
||||
s = u;
|
||||
return UnicodeStringToMultiByte(s);
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef UNDER_CE
|
||||
AString SystemStringToOemString(const CSysString &src);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,144 @@
|
||||
// Common/StringToInt.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "StringToInt.h"
|
||||
|
||||
static const UInt32 k_UInt32_max = 0xFFFFFFFF;
|
||||
static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF);
|
||||
// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1;
|
||||
|
||||
#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType, charTypeUnsigned) \
|
||||
uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \
|
||||
if (end) *end = s; \
|
||||
uintType res = 0; \
|
||||
for (;; s++) { \
|
||||
charTypeUnsigned c = (charTypeUnsigned)*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, Byte)
|
||||
CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t, wchar_t)
|
||||
CONVERT_STRING_TO_UINT_FUNC(UInt64, char, Byte)
|
||||
CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t, wchar_t)
|
||||
|
||||
Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw()
|
||||
{
|
||||
if (end)
|
||||
*end = s;
|
||||
const wchar_t *s2 = s;
|
||||
if (*s == '-')
|
||||
s2++;
|
||||
if (*s2 == 0)
|
||||
return 0;
|
||||
const wchar_t *end2;
|
||||
UInt32 res = ConvertStringToUInt32(s2, &end2);
|
||||
if (*s == '-')
|
||||
{
|
||||
if (res > ((UInt32)1 << (32 - 1)))
|
||||
return 0;
|
||||
}
|
||||
else if ((res & ((UInt32)1 << (32 - 1))) != 0)
|
||||
return 0;
|
||||
if (end)
|
||||
*end = end2;
|
||||
if (*s == '-')
|
||||
return -(Int32)res;
|
||||
return (Int32)res;
|
||||
}
|
||||
|
||||
UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw()
|
||||
{
|
||||
if (end)
|
||||
*end = s;
|
||||
UInt32 res = 0;
|
||||
for (;; s++)
|
||||
{
|
||||
unsigned c = (unsigned char)*s;
|
||||
if (c < '0' || c > '7')
|
||||
{
|
||||
if (end)
|
||||
*end = s;
|
||||
return res;
|
||||
}
|
||||
if ((res & (UInt32)7 << (32 - 3)) != 0)
|
||||
return 0;
|
||||
res <<= 3;
|
||||
res |= (unsigned)(c - '0');
|
||||
}
|
||||
}
|
||||
|
||||
UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw()
|
||||
{
|
||||
if (end)
|
||||
*end = s;
|
||||
UInt64 res = 0;
|
||||
for (;; s++)
|
||||
{
|
||||
unsigned c = (unsigned char)*s;
|
||||
if (c < '0' || c > '7')
|
||||
{
|
||||
if (end)
|
||||
*end = s;
|
||||
return res;
|
||||
}
|
||||
if ((res & (UInt64)7 << (64 - 3)) != 0)
|
||||
return 0;
|
||||
res <<= 3;
|
||||
res |= (unsigned)(c - '0');
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw()
|
||||
{
|
||||
if (end)
|
||||
*end = s;
|
||||
UInt32 res = 0;
|
||||
for (;; s++)
|
||||
{
|
||||
unsigned c = (Byte)*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)
|
||||
*end = s;
|
||||
return res;
|
||||
}
|
||||
if ((res & (UInt32)0xF << (32 - 4)) != 0)
|
||||
return 0;
|
||||
res <<= 4;
|
||||
res |= v;
|
||||
}
|
||||
}
|
||||
|
||||
UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw()
|
||||
{
|
||||
if (end)
|
||||
*end = s;
|
||||
UInt64 res = 0;
|
||||
for (;; s++)
|
||||
{
|
||||
unsigned c = (Byte)*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)
|
||||
*end = s;
|
||||
return res;
|
||||
}
|
||||
if ((res & (UInt64)0xF << (64 - 4)) != 0)
|
||||
return 0;
|
||||
res <<= 4;
|
||||
res |= v;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Common/StringToInt.h
|
||||
|
||||
#ifndef __COMMON_STRING_TO_INT_H
|
||||
#define __COMMON_STRING_TO_INT_H
|
||||
|
||||
#include "MyTypes.h"
|
||||
|
||||
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();
|
||||
|
||||
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
|
||||
@@ -0,0 +1,124 @@
|
||||
// Common/TextConfig.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "TextConfig.h"
|
||||
#include "UTFConvert.h"
|
||||
|
||||
static inline bool IsDelimitChar(char c)
|
||||
{
|
||||
return (c == ' ' || c == 0x0A || c == 0x0D || c == '\0' || c == '\t');
|
||||
}
|
||||
|
||||
static AString GetIDString(const char *s, unsigned &finishPos)
|
||||
{
|
||||
AString result;
|
||||
for (finishPos = 0; ; finishPos++)
|
||||
{
|
||||
char c = s[finishPos];
|
||||
if (IsDelimitChar(c) || c == '=')
|
||||
break;
|
||||
result += c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool WaitNextLine(const AString &s, unsigned &pos)
|
||||
{
|
||||
for (; pos < s.Len(); pos++)
|
||||
if (s[pos] == 0x0A)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool SkipSpaces(const AString &s, unsigned &pos)
|
||||
{
|
||||
for (; pos < s.Len(); pos++)
|
||||
{
|
||||
char c = s[pos];
|
||||
if (!IsDelimitChar(c))
|
||||
{
|
||||
if (c != ';')
|
||||
return true;
|
||||
if (!WaitNextLine(s, pos))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs)
|
||||
{
|
||||
pairs.Clear();
|
||||
unsigned pos = 0;
|
||||
|
||||
/////////////////////
|
||||
// read strings
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!SkipSpaces(s, pos))
|
||||
break;
|
||||
CTextConfigPair pair;
|
||||
unsigned finishPos;
|
||||
const AString temp (GetIDString(((const char *)s) + pos, finishPos));
|
||||
if (!ConvertUTF8ToUnicode(temp, pair.ID))
|
||||
return false;
|
||||
if (finishPos == 0)
|
||||
return false;
|
||||
pos += finishPos;
|
||||
if (!SkipSpaces(s, pos))
|
||||
return false;
|
||||
if (s[pos] != '=')
|
||||
return false;
|
||||
pos++;
|
||||
if (!SkipSpaces(s, pos))
|
||||
return false;
|
||||
if (s[pos] != '\"')
|
||||
return false;
|
||||
pos++;
|
||||
AString message;
|
||||
for (;;)
|
||||
{
|
||||
if (pos >= s.Len())
|
||||
return false;
|
||||
char c = s[pos++];
|
||||
if (c == '\"')
|
||||
break;
|
||||
if (c == '\\')
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
message += c;
|
||||
}
|
||||
if (!ConvertUTF8ToUnicode(message, pair.String))
|
||||
return false;
|
||||
pairs.Add(pair);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const char *id) throw()
|
||||
{
|
||||
FOR_VECTOR (i, pairs)
|
||||
if (pairs[i].ID.IsEqualTo(id))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const char *id)
|
||||
{
|
||||
int index = FindTextConfigItem(pairs, id);
|
||||
if (index < 0)
|
||||
return UString();
|
||||
return pairs[index].String;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Common/TextConfig.h
|
||||
|
||||
#ifndef __COMMON_TEXT_CONFIG_H
|
||||
#define __COMMON_TEXT_CONFIG_H
|
||||
|
||||
#include "MyString.h"
|
||||
|
||||
struct CTextConfigPair
|
||||
{
|
||||
UString ID;
|
||||
UString String;
|
||||
};
|
||||
|
||||
bool GetTextConfig(const AString &text, CObjectVector<CTextConfigPair> &pairs);
|
||||
|
||||
int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const char *id) throw();
|
||||
UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const char *id);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,288 @@
|
||||
// UTFConvert.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "MyTypes.h"
|
||||
#include "UTFConvert.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _WCHART_IS_16BIT 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
_UTF8_START(n) - is a base value for start byte (head), if there are (n) additional bytes after start byte
|
||||
|
||||
n : _UTF8_START(n) : Bits of code point
|
||||
|
||||
0 : 0x80 : : unused
|
||||
1 : 0xC0 : 11 :
|
||||
2 : 0xE0 : 16 : Basic Multilingual Plane
|
||||
3 : 0xF0 : 21 : Unicode space
|
||||
3 : 0xF8 : 26 :
|
||||
5 : 0xFC : 31 : UCS-4
|
||||
6 : 0xFE : 36 : We can use it, if we want to encode any 32-bit value
|
||||
7 : 0xFF :
|
||||
*/
|
||||
|
||||
#define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
|
||||
|
||||
#define _UTF8_HEAD_PARSE2(n) if (c < _UTF8_START((n) + 1)) { numBytes = (n); c -= _UTF8_START(n); }
|
||||
|
||||
#define _UTF8_HEAD_PARSE \
|
||||
_UTF8_HEAD_PARSE2(1) \
|
||||
else _UTF8_HEAD_PARSE2(2) \
|
||||
else _UTF8_HEAD_PARSE2(3) \
|
||||
else _UTF8_HEAD_PARSE2(4) \
|
||||
else _UTF8_HEAD_PARSE2(5) \
|
||||
|
||||
// else _UTF8_HEAD_PARSE2(6)
|
||||
|
||||
bool CheckUTF8(const char *src, bool allowReduced) throw()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
Byte c = *src++;
|
||||
if (c == 0)
|
||||
return true;
|
||||
|
||||
if (c < 0x80)
|
||||
continue;
|
||||
if (c < 0xC0) // (c < 0xC0 + 2) // if we support only optimal encoding chars
|
||||
return false;
|
||||
|
||||
unsigned numBytes;
|
||||
_UTF8_HEAD_PARSE
|
||||
else
|
||||
return false;
|
||||
|
||||
UInt32 val = c;
|
||||
|
||||
do
|
||||
{
|
||||
Byte c2 = *src++;
|
||||
if (c2 < 0x80 || c2 >= 0xC0)
|
||||
return allowReduced && c2 == 0;
|
||||
val <<= 6;
|
||||
val |= (c2 - 0x80);
|
||||
}
|
||||
while (--numBytes);
|
||||
|
||||
if (val >= 0x110000)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define _ERROR_UTF8 \
|
||||
{ if (dest) dest[destPos] = (wchar_t)0xFFFD; destPos++; ok = false; continue; }
|
||||
|
||||
static bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, const char *srcLim) throw()
|
||||
{
|
||||
size_t destPos = 0;
|
||||
bool ok = true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte c;
|
||||
if (src == srcLim)
|
||||
{
|
||||
*destLen = destPos;
|
||||
return ok;
|
||||
}
|
||||
c = *src++;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
if (dest)
|
||||
dest[destPos] = (wchar_t)c;
|
||||
destPos++;
|
||||
continue;
|
||||
}
|
||||
if (c < 0xC0)
|
||||
_ERROR_UTF8
|
||||
|
||||
unsigned numBytes;
|
||||
_UTF8_HEAD_PARSE
|
||||
else
|
||||
_ERROR_UTF8
|
||||
|
||||
UInt32 val = c;
|
||||
|
||||
do
|
||||
{
|
||||
Byte c2;
|
||||
if (src == srcLim)
|
||||
break;
|
||||
c2 = *src;
|
||||
if (c2 < 0x80 || c2 >= 0xC0)
|
||||
break;
|
||||
src++;
|
||||
val <<= 6;
|
||||
val |= (c2 - 0x80);
|
||||
}
|
||||
while (--numBytes);
|
||||
|
||||
if (numBytes != 0)
|
||||
_ERROR_UTF8
|
||||
|
||||
if (val < 0x10000)
|
||||
{
|
||||
if (dest)
|
||||
dest[destPos] = (wchar_t)val;
|
||||
destPos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
val -= 0x10000;
|
||||
if (val >= 0x100000)
|
||||
_ERROR_UTF8
|
||||
if (dest)
|
||||
{
|
||||
dest[destPos + 0] = (wchar_t)(0xD800 + (val >> 10));
|
||||
dest[destPos + 1] = (wchar_t)(0xDC00 + (val & 0x3FF));
|
||||
}
|
||||
destPos += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
|
||||
|
||||
#define _UTF8_HEAD(n, val) ((char)(_UTF8_START(n) + (val >> (6 * (n)))))
|
||||
#define _UTF8_CHAR(n, val) ((char)(0x80 + (((val) >> (6 * (n))) & 0x3F)))
|
||||
|
||||
static size_t Utf16_To_Utf8_Calc(const wchar_t *src, const wchar_t *srcLim)
|
||||
{
|
||||
size_t size = srcLim - src;
|
||||
for (;;)
|
||||
{
|
||||
if (src == srcLim)
|
||||
return size;
|
||||
|
||||
UInt32 val = *src++;
|
||||
|
||||
if (val < 0x80)
|
||||
continue;
|
||||
|
||||
if (val < _UTF8_RANGE(1))
|
||||
{
|
||||
size++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
|
||||
{
|
||||
UInt32 c2 = *src;
|
||||
if (c2 >= 0xDC00 && c2 < 0xE000)
|
||||
{
|
||||
src++;
|
||||
size += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WCHART_IS_16BIT
|
||||
|
||||
size += 2;
|
||||
|
||||
#else
|
||||
|
||||
if (val < _UTF8_RANGE(2)) size += 2;
|
||||
else if (val < _UTF8_RANGE(3)) size += 3;
|
||||
else if (val < _UTF8_RANGE(4)) size += 4;
|
||||
else if (val < _UTF8_RANGE(5)) size += 5;
|
||||
else size += 6;
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static char *Utf16_To_Utf8(char *dest, const wchar_t *src, const wchar_t *srcLim)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (src == srcLim)
|
||||
return dest;
|
||||
|
||||
UInt32 val = *src++;
|
||||
|
||||
if (val < 0x80)
|
||||
{
|
||||
*dest++ = (char)val;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (val < _UTF8_RANGE(1))
|
||||
{
|
||||
dest[0] = _UTF8_HEAD(1, val);
|
||||
dest[1] = _UTF8_CHAR(0, val);
|
||||
dest += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
|
||||
{
|
||||
UInt32 c2 = *src;
|
||||
if (c2 >= 0xDC00 && c2 < 0xE000)
|
||||
{
|
||||
src++;
|
||||
val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
|
||||
dest[0] = _UTF8_HEAD(3, val);
|
||||
dest[1] = _UTF8_CHAR(2, val);
|
||||
dest[2] = _UTF8_CHAR(1, val);
|
||||
dest[3] = _UTF8_CHAR(0, val);
|
||||
dest += 4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WCHART_IS_16BIT
|
||||
if (val < _UTF8_RANGE(2))
|
||||
#endif
|
||||
{
|
||||
dest[0] = _UTF8_HEAD(2, val);
|
||||
dest[1] = _UTF8_CHAR(1, val);
|
||||
dest[2] = _UTF8_CHAR(0, val);
|
||||
dest += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifndef _WCHART_IS_16BIT
|
||||
|
||||
UInt32 b;
|
||||
unsigned numBits;
|
||||
if (val < _UTF8_RANGE(3)) { numBits = 6 * 3; b = _UTF8_HEAD(3, val); }
|
||||
else if (val < _UTF8_RANGE(4)) { numBits = 6 * 4; b = _UTF8_HEAD(4, val); }
|
||||
else if (val < _UTF8_RANGE(5)) { numBits = 6 * 5; b = _UTF8_HEAD(5, val); }
|
||||
else { numBits = 6 * 6; b = _UTF8_START(6); }
|
||||
|
||||
*dest++ = (Byte)b;
|
||||
|
||||
do
|
||||
{
|
||||
numBits -= 6;
|
||||
*dest++ = (char)(0x80 + ((val >> numBits) & 0x3F));
|
||||
}
|
||||
while (numBits != 0);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
|
||||
{
|
||||
dest.Empty();
|
||||
size_t destLen = 0;
|
||||
Utf8_To_Utf16(NULL, &destLen, src, src.Ptr(src.Len()));
|
||||
bool res = Utf8_To_Utf16(dest.GetBuf((unsigned)destLen), &destLen, src, src.Ptr(src.Len()));
|
||||
dest.ReleaseBuf_SetEnd((unsigned)destLen);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ConvertUnicodeToUTF8(const UString &src, AString &dest)
|
||||
{
|
||||
dest.Empty();
|
||||
size_t destLen = Utf16_To_Utf8_Calc(src, src.Ptr(src.Len()));
|
||||
Utf16_To_Utf8(dest.GetBuf((unsigned)destLen), src, src.Ptr(src.Len()));
|
||||
dest.ReleaseBuf_SetEnd((unsigned)destLen);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Common/UTFConvert.h
|
||||
|
||||
#ifndef __COMMON_UTF_CONVERT_H
|
||||
#define __COMMON_UTF_CONVERT_H
|
||||
|
||||
#include "MyString.h"
|
||||
|
||||
bool CheckUTF8(const char *src, bool allowReduced = false) throw();
|
||||
bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
|
||||
void ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,676 @@
|
||||
// Common/Wildcard.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Wildcard.h"
|
||||
|
||||
bool g_CaseSensitive =
|
||||
#ifdef _WIN32
|
||||
false;
|
||||
#else
|
||||
true;
|
||||
#endif
|
||||
|
||||
|
||||
bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
if (g_CaseSensitive)
|
||||
return IsString1PrefixedByString2(s1, s2);
|
||||
return IsString1PrefixedByString2_NoCase(s1, s2);
|
||||
}
|
||||
|
||||
int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
|
||||
{
|
||||
if (g_CaseSensitive)
|
||||
return MyStringCompare(s1, s2);
|
||||
return MyStringCompareNoCase(s1, s2);
|
||||
}
|
||||
|
||||
#ifndef USE_UNICODE_FSTRING
|
||||
int CompareFileNames(const char *s1, const char *s2)
|
||||
{
|
||||
const UString u1 = fs2us(s1);
|
||||
const UString u2 = fs2us(s2);
|
||||
if (g_CaseSensitive)
|
||||
return MyStringCompare(u1, u2);
|
||||
return MyStringCompareNoCase(u1, u2);
|
||||
}
|
||||
#endif
|
||||
|
||||
// -----------------------------------------
|
||||
// this function compares name with mask
|
||||
// ? - any char
|
||||
// * - any char or empty
|
||||
|
||||
static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
wchar_t m = *mask;
|
||||
wchar_t c = *name;
|
||||
if (m == 0)
|
||||
return (c == 0);
|
||||
if (m == '*')
|
||||
{
|
||||
if (EnhancedMaskTest(mask + 1, name))
|
||||
return true;
|
||||
if (c == 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m == '?')
|
||||
{
|
||||
if (c == 0)
|
||||
return false;
|
||||
}
|
||||
else if (m != c)
|
||||
if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c))
|
||||
return false;
|
||||
mask++;
|
||||
}
|
||||
name++;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Splits path to strings
|
||||
|
||||
void SplitPathToParts(const UString &path, UStringVector &pathParts)
|
||||
{
|
||||
pathParts.Clear();
|
||||
unsigned len = path.Len();
|
||||
if (len == 0)
|
||||
return;
|
||||
UString name;
|
||||
unsigned prev = 0;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
if (IsPathSepar(path[i]))
|
||||
{
|
||||
name.SetFrom(path.Ptr(prev), i - prev);
|
||||
pathParts.Add(name);
|
||||
prev = i + 1;
|
||||
}
|
||||
name.SetFrom(path.Ptr(prev), len - prev);
|
||||
pathParts.Add(name);
|
||||
}
|
||||
|
||||
void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name)
|
||||
{
|
||||
const wchar_t *start = path;
|
||||
const wchar_t *p = start + path.Len();
|
||||
for (; p != start; p--)
|
||||
if (IsPathSepar(*(p - 1)))
|
||||
break;
|
||||
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 (IsPathSepar(*(p - 1)))
|
||||
p--;
|
||||
for (; p != start; p--)
|
||||
if (IsPathSepar(*(p - 1)))
|
||||
break;
|
||||
}
|
||||
dirPrefix.SetFrom(path, (unsigned)(p - start));
|
||||
name = p;
|
||||
}
|
||||
|
||||
/*
|
||||
UString ExtractDirPrefixFromPath(const UString &path)
|
||||
{
|
||||
return path.Left(path.ReverseFind_PathSepar() + 1));
|
||||
}
|
||||
*/
|
||||
|
||||
UString ExtractFileNameFromPath(const UString &path)
|
||||
{
|
||||
return UString(path.Ptr(path.ReverseFind_PathSepar() + 1));
|
||||
}
|
||||
|
||||
|
||||
bool DoesWildcardMatchName(const UString &mask, const UString &name)
|
||||
{
|
||||
return EnhancedMaskTest(mask, name);
|
||||
}
|
||||
|
||||
bool DoesNameContainWildcard(const UString &path)
|
||||
{
|
||||
for (unsigned i = 0; i < path.Len(); i++)
|
||||
{
|
||||
wchar_t c = path[i];
|
||||
if (c == '*' || c == '?')
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------'
|
||||
// NWildcard
|
||||
|
||||
namespace NWildcard {
|
||||
|
||||
/*
|
||||
|
||||
M = MaskParts.Size();
|
||||
N = TestNameParts.Size();
|
||||
|
||||
File Dir
|
||||
ForFile rec M<=N [N-M, N) -
|
||||
!ForDir nonrec M=N [0, M) -
|
||||
|
||||
ForDir rec M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
|
||||
!ForFile nonrec [0, M) same as ForBoth-File
|
||||
|
||||
ForFile rec m<=N [0, M) ... [N-M, N) same as ForBoth-File
|
||||
ForDir nonrec [0, M) same as ForBoth-File
|
||||
|
||||
*/
|
||||
|
||||
bool CItem::AreAllAllowed() const
|
||||
{
|
||||
return ForFile && ForDir && WildcardMatching && PathParts.Size() == 1 && PathParts.Front() == L"*";
|
||||
}
|
||||
|
||||
bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
|
||||
{
|
||||
if (!isFile && !ForDir)
|
||||
return false;
|
||||
|
||||
/*
|
||||
if (PathParts.IsEmpty())
|
||||
{
|
||||
// PathParts.IsEmpty() means all items (universal wildcard)
|
||||
if (!isFile)
|
||||
return true;
|
||||
if (pathParts.Size() <= 1)
|
||||
return ForFile;
|
||||
return (ForDir || Recursive && ForFile);
|
||||
}
|
||||
*/
|
||||
|
||||
int delta = (int)pathParts.Size() - (int)PathParts.Size();
|
||||
if (delta < 0)
|
||||
return false;
|
||||
int start = 0;
|
||||
int finish = 0;
|
||||
|
||||
if (isFile)
|
||||
{
|
||||
if (!ForDir)
|
||||
{
|
||||
if (Recursive)
|
||||
start = delta;
|
||||
else if (delta !=0)
|
||||
return false;
|
||||
}
|
||||
if (!ForFile && delta == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Recursive)
|
||||
{
|
||||
finish = delta;
|
||||
if (isFile && !ForFile)
|
||||
finish = delta - 1;
|
||||
}
|
||||
|
||||
for (int d = start; d <= finish; d++)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < PathParts.Size(); i++)
|
||||
{
|
||||
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_VECTOR (i, SubNodes)
|
||||
if (CompareFileNames(SubNodes[i].Name, name) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CCensorNode::AddItemSimple(bool include, CItem &item)
|
||||
{
|
||||
if (include)
|
||||
IncludeItems.Add(item);
|
||||
else
|
||||
ExcludeItems.Add(item);
|
||||
}
|
||||
|
||||
void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex)
|
||||
{
|
||||
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();
|
||||
|
||||
// WIN32 doesn't support wildcards in file names
|
||||
if (item.WildcardMatching
|
||||
&& ignoreWildcardIndex != 0
|
||||
&& DoesNameContainWildcard(front))
|
||||
{
|
||||
AddItemSimple(include, item);
|
||||
return;
|
||||
}
|
||||
int index = FindSubNode(front);
|
||||
if (index < 0)
|
||||
index = SubNodes.Add(CCensorNode(front, this));
|
||||
item.PathParts.Delete(0);
|
||||
SubNodes[index].AddItem(include, item, ignoreWildcardIndex - 1);
|
||||
}
|
||||
|
||||
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_VECTOR (i, IncludeItems)
|
||||
{
|
||||
const CItem &item = IncludeItems[i];
|
||||
if (item.Recursive || item.PathParts.Size() > 1)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCensorNode::AreThereIncludeItems() const
|
||||
{
|
||||
if (IncludeItems.Size() > 0)
|
||||
return true;
|
||||
FOR_VECTOR (i, SubNodes)
|
||||
if (SubNodes[i].AreThereIncludeItems())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
|
||||
{
|
||||
const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
|
||||
FOR_VECTOR (i, items)
|
||||
if (items[i].CheckPath(pathParts, isFile))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const
|
||||
{
|
||||
if (CheckPathCurrent(false, pathParts, isFile))
|
||||
{
|
||||
include = false;
|
||||
return true;
|
||||
}
|
||||
include = true;
|
||||
bool finded = CheckPathCurrent(true, pathParts, isFile);
|
||||
if (pathParts.Size() <= 1)
|
||||
return finded;
|
||||
int index = FindSubNode(pathParts.Front());
|
||||
if (index >= 0)
|
||||
{
|
||||
UStringVector pathParts2 = pathParts;
|
||||
pathParts2.Delete(0);
|
||||
if (SubNodes[index].CheckPathVect(pathParts2, isFile, include))
|
||||
return true;
|
||||
}
|
||||
return finded;
|
||||
}
|
||||
|
||||
/*
|
||||
bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const
|
||||
{
|
||||
UStringVector pathParts;
|
||||
SplitPathToParts(path, pathParts);
|
||||
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(bool isAltStream, const UString &path, bool isFile) const
|
||||
{
|
||||
bool include;
|
||||
if (CheckPath2(isAltStream, path, isFile, include))
|
||||
return include;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const
|
||||
{
|
||||
if (CheckPathCurrent(include, pathParts, isFile))
|
||||
return true;
|
||||
if (Parent == 0)
|
||||
return false;
|
||||
pathParts.Insert(0, Name);
|
||||
return Parent->CheckPathToRoot(include, pathParts, isFile);
|
||||
}
|
||||
|
||||
/*
|
||||
bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const
|
||||
{
|
||||
UStringVector pathParts;
|
||||
SplitPathToParts(path, pathParts);
|
||||
return CheckPathToRoot(include, pathParts, isFile);
|
||||
}
|
||||
*/
|
||||
|
||||
void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching)
|
||||
{
|
||||
if (path.IsEmpty())
|
||||
return;
|
||||
bool forFile = true;
|
||||
bool forFolder = true;
|
||||
UString path2 (path);
|
||||
if (IsPathSepar(path.Back()))
|
||||
{
|
||||
path2.DeleteBack();
|
||||
forFile = false;
|
||||
}
|
||||
AddItem(include, path2, recursive, forFile, forFolder, wildcardMatching);
|
||||
}
|
||||
|
||||
void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
|
||||
{
|
||||
ExcludeItems += fromNodes.ExcludeItems;
|
||||
FOR_VECTOR (i, fromNodes.SubNodes)
|
||||
{
|
||||
const CCensorNode &node = fromNodes.SubNodes[i];
|
||||
int subNodeIndex = FindSubNode(node.Name);
|
||||
if (subNodeIndex < 0)
|
||||
subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this));
|
||||
SubNodes[subNodeIndex].ExtendExclude(node);
|
||||
}
|
||||
}
|
||||
|
||||
int CCensor::FindPrefix(const UString &prefix) const
|
||||
{
|
||||
FOR_VECTOR (i, Pairs)
|
||||
if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#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');
|
||||
}
|
||||
|
||||
unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts)
|
||||
{
|
||||
if (pathParts.IsEmpty())
|
||||
return 0;
|
||||
|
||||
unsigned testIndex = 0;
|
||||
if (pathParts[0].IsEmpty())
|
||||
{
|
||||
if (pathParts.Size() < 4
|
||||
|| !pathParts[1].IsEmpty()
|
||||
|| pathParts[2] != L"?")
|
||||
return 0;
|
||||
testIndex = 3;
|
||||
}
|
||||
if (NWildcard::IsDriveColonName(pathParts[testIndex]))
|
||||
return testIndex + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static unsigned GetNumPrefixParts(const UStringVector &pathParts)
|
||||
{
|
||||
if (pathParts.IsEmpty())
|
||||
return 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
if (IsDriveColonName(pathParts[0]))
|
||||
return 1;
|
||||
if (!pathParts[0].IsEmpty())
|
||||
return 0;
|
||||
|
||||
if (pathParts.Size() == 1)
|
||||
return 1;
|
||||
if (!pathParts[1].IsEmpty())
|
||||
return 1;
|
||||
if (pathParts.Size() == 2)
|
||||
return 2;
|
||||
if (pathParts[2] == L".")
|
||||
return 3;
|
||||
|
||||
unsigned networkParts = 2;
|
||||
if (pathParts[2] == L"?")
|
||||
{
|
||||
if (pathParts.Size() == 3)
|
||||
return 3;
|
||||
if (IsDriveColonName(pathParts[3]))
|
||||
return 4;
|
||||
if (!pathParts[3].IsEqualTo_Ascii_NoCase("UNC"))
|
||||
return 3;
|
||||
networkParts = 4;
|
||||
}
|
||||
|
||||
networkParts +=
|
||||
// 2; // server/share
|
||||
1; // server
|
||||
if (pathParts.Size() <= networkParts)
|
||||
return pathParts.Size();
|
||||
return networkParts;
|
||||
|
||||
#else
|
||||
|
||||
return pathParts[0].IsEmpty() ? 1 : 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching)
|
||||
{
|
||||
if (path.IsEmpty())
|
||||
throw "Empty file path";
|
||||
|
||||
UStringVector pathParts;
|
||||
SplitPathToParts(path, pathParts);
|
||||
|
||||
bool forFile = true;
|
||||
if (pathParts.Back().IsEmpty())
|
||||
{
|
||||
forFile = false;
|
||||
pathParts.DeleteBack();
|
||||
}
|
||||
|
||||
UString prefix;
|
||||
|
||||
int ignoreWildcardIndex = -1;
|
||||
|
||||
// #ifdef _WIN32
|
||||
// we ignore "?" wildcard in "\\?\" prefix.
|
||||
if (pathParts.Size() >= 3
|
||||
&& pathParts[0].IsEmpty()
|
||||
&& pathParts[1].IsEmpty()
|
||||
&& pathParts[2] == L"?")
|
||||
ignoreWildcardIndex = 2;
|
||||
// #endif
|
||||
|
||||
if (pathMode != k_AbsPath)
|
||||
{
|
||||
ignoreWildcardIndex = -1;
|
||||
|
||||
const unsigned numPrefixParts = GetNumPrefixParts(pathParts);
|
||||
unsigned numSkipParts = numPrefixParts;
|
||||
|
||||
if (pathMode != k_FullPath)
|
||||
{
|
||||
if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts)
|
||||
numSkipParts = pathParts.Size() - 1;
|
||||
}
|
||||
{
|
||||
int dotsIndex = -1;
|
||||
for (unsigned i = numPrefixParts; i < pathParts.Size(); i++)
|
||||
{
|
||||
const UString &part = pathParts[i];
|
||||
if (part == L".." || part == L".")
|
||||
dotsIndex = i;
|
||||
}
|
||||
|
||||
if (dotsIndex >= 0)
|
||||
if (dotsIndex == (int)pathParts.Size() - 1)
|
||||
numSkipParts = pathParts.Size();
|
||||
else
|
||||
numSkipParts = pathParts.Size() - 1;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < numSkipParts; i++)
|
||||
{
|
||||
{
|
||||
const UString &front = pathParts.Front();
|
||||
// WIN32 doesn't support wildcards in file names
|
||||
if (wildcardMatching)
|
||||
if (i >= numPrefixParts && DoesNameContainWildcard(front))
|
||||
break;
|
||||
prefix += front;
|
||||
prefix.Add_PathSepar();
|
||||
}
|
||||
pathParts.Delete(0);
|
||||
}
|
||||
}
|
||||
|
||||
int index = FindPrefix(prefix);
|
||||
if (index < 0)
|
||||
index = Pairs.Add(CPair(prefix));
|
||||
|
||||
if (pathMode != k_AbsPath)
|
||||
{
|
||||
if (pathParts.IsEmpty() || pathParts.Size() == 1 && pathParts[0].IsEmpty())
|
||||
{
|
||||
// we create universal item, if we skip all parts as prefix (like \ or L:\ )
|
||||
pathParts.Clear();
|
||||
pathParts.Add(UString("*"));
|
||||
forFile = true;
|
||||
wildcardMatching = true;
|
||||
recursive = false;
|
||||
}
|
||||
}
|
||||
|
||||
CItem item;
|
||||
item.PathParts = pathParts;
|
||||
item.ForDir = true;
|
||||
item.ForFile = forFile;
|
||||
item.Recursive = recursive;
|
||||
item.WildcardMatching = wildcardMatching;
|
||||
Pairs[index].Head.AddItem(include, item, ignoreWildcardIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const
|
||||
{
|
||||
bool finded = false;
|
||||
FOR_VECTOR (i, Pairs)
|
||||
{
|
||||
bool include;
|
||||
if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include))
|
||||
{
|
||||
if (!include)
|
||||
return false;
|
||||
finded = true;
|
||||
}
|
||||
}
|
||||
return finded;
|
||||
}
|
||||
*/
|
||||
|
||||
void CCensor::ExtendExclude()
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < Pairs.Size(); i++)
|
||||
if (Pairs[i].Prefix.IsEmpty())
|
||||
break;
|
||||
if (i == Pairs.Size())
|
||||
return;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
// Common/Wildcard.h
|
||||
|
||||
#ifndef __COMMON_WILDCARD_H
|
||||
#define __COMMON_WILDCARD_H
|
||||
|
||||
#include "MyString.h"
|
||||
|
||||
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);
|
||||
|
||||
void SplitPathToParts(const UString &path, UStringVector &pathParts);
|
||||
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 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);
|
||||
unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts);
|
||||
#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);
|
||||
public:
|
||||
bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const;
|
||||
|
||||
CCensorNode(): Parent(0) { };
|
||||
CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { };
|
||||
|
||||
UString Name; // WIN32 doesn't support wildcards in file names
|
||||
CObjectVector<CCensorNode> SubNodes;
|
||||
CObjectVector<CItem> IncludeItems;
|
||||
CObjectVector<CItem> ExcludeItems;
|
||||
|
||||
bool AreAllAllowed() const;
|
||||
|
||||
int FindSubNode(const UString &path) const;
|
||||
|
||||
void AddItem(bool include, CItem &item, int ignoreWildcardIndex = -1);
|
||||
void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching);
|
||||
void AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching);
|
||||
|
||||
bool NeedCheckSubDirs() const;
|
||||
bool AreThereIncludeItems() 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;
|
||||
void ExtendExclude(const CCensorNode &fromNodes);
|
||||
};
|
||||
|
||||
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(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, UString("*"), false, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
// XzCrc64Init.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../C/XzCrc64.h"
|
||||
|
||||
static struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;
|
||||
@@ -0,0 +1,42 @@
|
||||
// XzCrc64Reg.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../C/CpuArch.h"
|
||||
#include "../../C/XzCrc64.h"
|
||||
|
||||
#include "../Common/MyCom.h"
|
||||
|
||||
#include "../7zip/Common/RegisterCodec.h"
|
||||
|
||||
class CXzCrc64Hasher:
|
||||
public IHasher,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt64 _crc;
|
||||
Byte mtDummy[1 << 7];
|
||||
|
||||
public:
|
||||
CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {}
|
||||
|
||||
MY_UNKNOWN_IMP1(IHasher)
|
||||
INTERFACE_IHasher(;)
|
||||
};
|
||||
|
||||
STDMETHODIMP_(void) CXzCrc64Hasher::Init() throw()
|
||||
{
|
||||
_crc = CRC64_INIT_VAL;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CXzCrc64Hasher::Update(const void *data, UInt32 size) throw()
|
||||
{
|
||||
_crc = Crc64Update(_crc, data, size);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CXzCrc64Hasher::Final(Byte *digest) throw()
|
||||
{
|
||||
UInt64 val = CRC64_GET_DIGEST(_crc);
|
||||
SetUi64(digest, val);
|
||||
}
|
||||
|
||||
REGISTER_HASHER(CXzCrc64Hasher, 0x4, "CRC64", 8)
|
||||
Reference in New Issue
Block a user