mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 21:14:58 -06:00
15.05
This commit is contained in:
committed by
Kornel Lesiński
parent
0713a3ab80
commit
54490d51d5
@@ -11,7 +11,7 @@ static bool IsString1PrefixedByString2_NoCase(const wchar_t *u, const char *a)
|
||||
char c = *a;
|
||||
if (c == 0)
|
||||
return true;
|
||||
if (MyCharLower_Ascii(c) != MyCharLower_Ascii(*u))
|
||||
if ((unsigned char)MyCharLower_Ascii(c) != MyCharLower_Ascii(*u))
|
||||
return false;
|
||||
a++;
|
||||
u++;
|
||||
@@ -135,24 +135,28 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
|
||||
switch (form.Type)
|
||||
{
|
||||
case NSwitchType::kMinus:
|
||||
if (rem != 0)
|
||||
if (rem == 1)
|
||||
{
|
||||
sw.WithMinus = (s[pos] == '-');
|
||||
if (sw.WithMinus)
|
||||
pos++;
|
||||
return true;
|
||||
ErrorMessage = "Incorrect switch postfix:";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case NSwitchType::kChar:
|
||||
if (rem != 0)
|
||||
if (rem == 1)
|
||||
{
|
||||
wchar_t c = s[pos];
|
||||
if (c <= 0x7F)
|
||||
{
|
||||
sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);
|
||||
if (sw.PostCharIndex >= 0)
|
||||
pos++;
|
||||
return true;
|
||||
}
|
||||
ErrorMessage = "Incorrect switch postfix:";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -160,6 +164,7 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
|
||||
sw.PostStrings.Add((const wchar_t *)s + pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pos != s.Len())
|
||||
{
|
||||
ErrorMessage = "Too long switch:";
|
||||
|
||||
@@ -7,22 +7,17 @@
|
||||
|
||||
#include "../Common/MyCom.h"
|
||||
|
||||
#include "../7zip/ICoder.h"
|
||||
#include "../7zip/Common/RegisterCodec.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
|
||||
extern CRC_FUNC g_CrcUpdate;
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
#endif
|
||||
|
||||
#ifndef MY_CPU_BE
|
||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
#endif
|
||||
extern CRC_FUNC g_CrcUpdateT8;
|
||||
extern CRC_FUNC g_CrcUpdateT4;
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
@@ -33,62 +28,42 @@ class CCrcHasher:
|
||||
{
|
||||
UInt32 _crc;
|
||||
CRC_FUNC _updateFunc;
|
||||
Byte mtDummy[1 << 7];
|
||||
|
||||
bool SetFunctions(UInt32 tSize);
|
||||
public:
|
||||
CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); }
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
|
||||
STDMETHOD_(void, Init)();
|
||||
STDMETHOD_(void, Update)(const void *data, UInt32 size);
|
||||
STDMETHOD_(void, Final)(Byte *digest);
|
||||
STDMETHOD_(UInt32, GetDigestSize)();
|
||||
INTERFACE_IHasher(;)
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
|
||||
};
|
||||
|
||||
STDMETHODIMP_(void) CCrcHasher::Init()
|
||||
{
|
||||
_crc = CRC_INIT_VAL;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size)
|
||||
{
|
||||
_crc = _updateFunc(_crc, data, size, g_CrcTable);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest)
|
||||
{
|
||||
UInt32 val = CRC_GET_DIGEST(_crc);
|
||||
SetUi32(digest, val);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UInt32) CCrcHasher::GetDigestSize()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool CCrcHasher::SetFunctions(UInt32 tSize)
|
||||
{
|
||||
_updateFunc = g_CrcUpdate;
|
||||
if (tSize == 4)
|
||||
|
||||
if (tSize == 1)
|
||||
_updateFunc = CrcUpdateT1;
|
||||
else if (tSize == 4)
|
||||
{
|
||||
#ifndef MY_CPU_BE
|
||||
_updateFunc = CrcUpdateT4;
|
||||
#endif
|
||||
if (g_CrcUpdateT4)
|
||||
_updateFunc = g_CrcUpdateT4;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (tSize == 8)
|
||||
{
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
_updateFunc = CrcUpdateT8;
|
||||
#else
|
||||
if (g_CrcUpdateT8)
|
||||
_updateFunc = g_CrcUpdateT8;
|
||||
else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs,
|
||||
const PROPVARIANT *coderProps, UInt32 numProps)
|
||||
STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
|
||||
{
|
||||
for (UInt32 i = 0; i < numProps; i++)
|
||||
{
|
||||
@@ -104,8 +79,20 @@ STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IHasher *CreateHasher() { return new CCrcHasher(); }
|
||||
STDMETHODIMP_(void) CCrcHasher::Init() throw()
|
||||
{
|
||||
_crc = CRC_INIT_VAL;
|
||||
}
|
||||
|
||||
static CHasherInfo g_HasherInfo = { CreateHasher, 0x1, L"CRC32", 4 };
|
||||
STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size) throw()
|
||||
{
|
||||
_crc = _updateFunc(_crc, data, size, g_CrcTable);
|
||||
}
|
||||
|
||||
REGISTER_HASHER(Crc32)
|
||||
STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest) throw()
|
||||
{
|
||||
UInt32 val = CRC_GET_DIGEST(_crc);
|
||||
SetUi32(digest, val);
|
||||
}
|
||||
|
||||
REGISTER_HASHER(CCrcHasher, 0x1, "CRC32", 4)
|
||||
|
||||
@@ -18,6 +18,10 @@ class CDynLimBuf
|
||||
bool _error;
|
||||
|
||||
CDynLimBuf(const CDynLimBuf &s);
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
CDynLimBuf &operator+=(wchar_t c);
|
||||
|
||||
public:
|
||||
CDynLimBuf(size_t limit) throw();
|
||||
~CDynLimBuf() { MyFree(_chars); }
|
||||
@@ -29,7 +33,7 @@ public:
|
||||
// const char *Ptr() const { return _chars; }
|
||||
|
||||
CDynLimBuf &operator+=(char c) throw();
|
||||
CDynLimBuf &operator+=(const char *s) throw();
|
||||
CDynLimBuf &operator+=(const char *s) throw();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ template <class T> class CDynamicBuffer
|
||||
}
|
||||
|
||||
T *newBuffer = new T[newCap];
|
||||
memcpy(newBuffer, _items, _pos * sizeof(T));
|
||||
if (_pos != 0)
|
||||
memcpy(newBuffer, _items, _pos * sizeof(T));
|
||||
delete []_items;
|
||||
_items = newBuffer;
|
||||
_size = newCap;
|
||||
@@ -34,8 +35,8 @@ template <class T> class CDynamicBuffer
|
||||
|
||||
public:
|
||||
CDynamicBuffer(): _items(0), _size(0), _pos(0) {}
|
||||
// operator T *() { return _items; };
|
||||
operator const T *() const { return _items; };
|
||||
// operator T *() { return _items; }
|
||||
operator const T *() const { return _items; }
|
||||
~CDynamicBuffer() { delete []_items; }
|
||||
|
||||
T *GetCurPtrAndGrow(size_t addSize)
|
||||
@@ -48,6 +49,11 @@ public:
|
||||
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; }
|
||||
|
||||
@@ -120,15 +120,17 @@ bool CLang::Open(CFSTR fileName, const wchar_t *id)
|
||||
return false;
|
||||
if (length > (1 << 20))
|
||||
return false;
|
||||
|
||||
AString s;
|
||||
unsigned len = (unsigned)length;
|
||||
char *p = s.GetBuffer(len);
|
||||
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++)
|
||||
{
|
||||
@@ -138,13 +140,16 @@ bool CLang::Open(CFSTR fileName, const wchar_t *id)
|
||||
if (c != 0x0D)
|
||||
*p2++ = c;
|
||||
}
|
||||
s.ReleaseBuffer((unsigned)(p2 - p));
|
||||
*p2 = 0;
|
||||
s.ReleaseBuf_SetLen((unsigned)(p2 - p));
|
||||
|
||||
if (OpenFromString(s))
|
||||
{
|
||||
const wchar_t *s = Get(0);
|
||||
if (s && wcscmp(s, id) == 0)
|
||||
const wchar_t *name = Get(0);
|
||||
if (name && wcscmp(name, id) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class CLang
|
||||
bool OpenFromString(const AString &s);
|
||||
public:
|
||||
CLang(): _text(0) {}
|
||||
~CLang() { Clear(); };
|
||||
~CLang() { Clear(); }
|
||||
bool Open(CFSTR fileName, const wchar_t *id);
|
||||
void Clear() throw();
|
||||
const wchar_t *Get(UInt32 id) const throw();
|
||||
|
||||
@@ -48,7 +48,7 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage
|
||||
return false;
|
||||
file.Close();
|
||||
unsigned num = (unsigned)fileSize / 2;
|
||||
wchar_t *p = u.GetBuffer(num);
|
||||
wchar_t *p = u.GetBuf(num);
|
||||
if (codePage == MY__CP_UTF16)
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
{
|
||||
@@ -65,20 +65,20 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage
|
||||
return false;
|
||||
p[i] = c;
|
||||
}
|
||||
u.ReleaseBuffer(num);
|
||||
p[num] = 0;
|
||||
u.ReleaseBuf_SetLen(num);
|
||||
}
|
||||
else
|
||||
{
|
||||
AString s;
|
||||
char *p = s.GetBuffer((unsigned)fileSize);
|
||||
char *p = s.GetBuf((unsigned)fileSize);
|
||||
UInt32 processed;
|
||||
if (!file.Read(p, (UInt32)fileSize, processed))
|
||||
return false;
|
||||
if (processed != fileSize)
|
||||
return false;
|
||||
file.Close();
|
||||
p[processed] = 0;
|
||||
s.ReleaseBuffer();
|
||||
s.ReleaseBuf_CalcLen((unsigned)processed);
|
||||
if (s.Len() != processed)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -10,15 +10,6 @@ template <class T> class CBuffer
|
||||
T *_items;
|
||||
size_t _size;
|
||||
|
||||
void CopyToEmpty(const CBuffer &buffer)
|
||||
{
|
||||
if (buffer._size > 0)
|
||||
{
|
||||
_items = new T[buffer._size];
|
||||
memcpy(_items, buffer._items, buffer._size * sizeof(T));
|
||||
_size = buffer._size;
|
||||
}
|
||||
}
|
||||
public:
|
||||
void Free()
|
||||
{
|
||||
@@ -32,11 +23,21 @@ public:
|
||||
|
||||
CBuffer(): _items(0), _size(0) {};
|
||||
CBuffer(size_t size): _items(0), _size(0) { _items = new T[size]; _size = size; }
|
||||
CBuffer(const CBuffer &buffer): _items(0), _size(0) { CopyToEmpty(buffer); }
|
||||
CBuffer(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; };
|
||||
operator T *() { return _items; }
|
||||
operator const T *() const { return _items; }
|
||||
size_t Size() const { return _size; }
|
||||
|
||||
void Alloc(size_t size)
|
||||
@@ -65,7 +66,8 @@ public:
|
||||
void CopyFrom(const T *data, size_t size)
|
||||
{
|
||||
Alloc(size);
|
||||
memcpy(_items, data, size * sizeof(T));
|
||||
if (size != 0)
|
||||
memcpy(_items, data, size * sizeof(T));
|
||||
}
|
||||
|
||||
void ChangeSize_KeepData(size_t newSize, size_t keepSize)
|
||||
@@ -73,10 +75,10 @@ public:
|
||||
if (newSize == _size)
|
||||
return;
|
||||
T *newBuffer = NULL;
|
||||
if (newSize > 0)
|
||||
if (newSize != 0)
|
||||
{
|
||||
newBuffer = new T[newSize];
|
||||
if (_size > 0)
|
||||
if (_size != 0)
|
||||
memcpy(newBuffer, _items, MyMin(MyMin(_size, keepSize), newSize) * sizeof(T));
|
||||
}
|
||||
delete []_items;
|
||||
@@ -86,8 +88,8 @@ public:
|
||||
|
||||
CBuffer& operator=(const CBuffer &buffer)
|
||||
{
|
||||
Free();
|
||||
CopyToEmpty(buffer);
|
||||
if (&buffer != this)
|
||||
CopyFrom(buffer, buffer._size);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
@@ -98,6 +100,8 @@ 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;
|
||||
}
|
||||
|
||||
@@ -107,6 +111,8 @@ 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 false;
|
||||
return memcmp(b1, b2, size1 * sizeof(T)) != 0;
|
||||
}
|
||||
|
||||
@@ -134,8 +140,8 @@ public:
|
||||
CObjArray(): _items(0) {};
|
||||
~CObjArray() { delete []_items; }
|
||||
|
||||
operator T *() { return _items; };
|
||||
operator const T *() const { return _items; };
|
||||
operator T *() { return _items; }
|
||||
operator const T *() const { return _items; }
|
||||
|
||||
void Alloc(size_t newSize)
|
||||
{
|
||||
@@ -172,7 +178,7 @@ public:
|
||||
CObjArray2(const CObjArray2 &buffer): _items(0), _size(0)
|
||||
{
|
||||
size_t newSize = buffer._size;
|
||||
if (newSize > 0)
|
||||
if (newSize != 0)
|
||||
{
|
||||
T *newBuffer = new T[newSize];;
|
||||
_items = newBuffer;
|
||||
@@ -196,8 +202,8 @@ public:
|
||||
|
||||
~CObjArray2() { delete []_items; }
|
||||
|
||||
operator T *() { return _items; };
|
||||
operator const T *() const { return _items; };
|
||||
operator T *() { return _items; }
|
||||
operator const T *() const { return _items; }
|
||||
|
||||
unsigned Size() const { return (unsigned)_size; }
|
||||
bool IsEmpty() const { return _size == 0; }
|
||||
@@ -208,7 +214,7 @@ public:
|
||||
if (size == _size)
|
||||
return;
|
||||
T *newBuffer = NULL;
|
||||
if (size > 0)
|
||||
if (size != 0)
|
||||
newBuffer = new T[size];
|
||||
delete []_items;
|
||||
_items = newBuffer;
|
||||
@@ -220,7 +226,7 @@ public:
|
||||
{
|
||||
Free();
|
||||
size_t newSize = buffer._size;
|
||||
if (newSize > 0)
|
||||
if (newSize != 0)
|
||||
{
|
||||
T *newBuffer = new T[newSize];;
|
||||
_items = newBuffer;
|
||||
|
||||
@@ -76,19 +76,28 @@ public:
|
||||
inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)
|
||||
{
|
||||
*bstr = ::SysAllocString(src);
|
||||
return (*bstr != NULL) ? S_OK : E_OUTOFMEMORY;
|
||||
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)
|
||||
{
|
||||
@@ -98,7 +107,7 @@ public:
|
||||
CoTaskMemFree(szGuid);
|
||||
}
|
||||
*/
|
||||
~CMyComBSTR() { ::SysFreeString(m_str); }
|
||||
|
||||
CMyComBSTR& operator=(const CMyComBSTR& src)
|
||||
{
|
||||
if (m_str != src.m_str)
|
||||
@@ -109,22 +118,29 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
CMyComBSTR& operator=(LPCOLESTR src)
|
||||
{
|
||||
::SysFreeString(m_str);
|
||||
m_str = ::SysAllocString(src);
|
||||
return *this;
|
||||
}
|
||||
// unsigned Len() const { return ::SysStringLen(m_str); }
|
||||
operator BSTR() const { return m_str; }
|
||||
BSTR* operator&() { return &m_str; }
|
||||
|
||||
unsigned Len() const { return ::SysStringLen(m_str); }
|
||||
|
||||
BSTR MyCopy() const
|
||||
{
|
||||
int byteLen = ::SysStringByteLen(m_str);
|
||||
// We don't support Byte BSTRs here
|
||||
return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
|
||||
/*
|
||||
UINT byteLen = ::SysStringByteLen(m_str);
|
||||
BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
|
||||
memcpy(res, m_str, byteLen);
|
||||
if (res && byteLen != 0 && m_str)
|
||||
memcpy(res, m_str, byteLen);
|
||||
return res;
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
void Attach(BSTR src) { m_str = src; }
|
||||
BSTR Detach()
|
||||
@@ -134,12 +150,12 @@ public:
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
|
||||
void Empty()
|
||||
{
|
||||
::SysFreeString(m_str);
|
||||
m_str = NULL;
|
||||
}
|
||||
bool operator!() const { return (m_str == NULL); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
@@ -149,6 +165,8 @@ class CMyUnknownImp
|
||||
public:
|
||||
ULONG __m_RefCount;
|
||||
CMyUnknownImp(): __m_RefCount(0) {}
|
||||
|
||||
// virtual ~CMyUnknownImp() {};
|
||||
};
|
||||
|
||||
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
|
||||
@@ -164,7 +182,7 @@ public:
|
||||
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
|
||||
MY_QUERYINTERFACE_ENTRY(i)
|
||||
|
||||
#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; AddRef(); return S_OK; }
|
||||
#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; } \
|
||||
@@ -239,4 +257,6 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
|
||||
MY_QUERYINTERFACE_ENTRY(i7) \
|
||||
)
|
||||
|
||||
const HRESULT k_My_HRESULT_WritingWasCut = 0x20000010;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -65,6 +65,17 @@ void MyStringUpper_Ascii(wchar_t *s)
|
||||
}
|
||||
*/
|
||||
|
||||
void MyStringLower_Ascii(char *s) throw()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
char c = *s;
|
||||
if (c == 0)
|
||||
return;
|
||||
*s++ = MyCharLower_Ascii(c);
|
||||
}
|
||||
}
|
||||
|
||||
void MyStringLower_Ascii(wchar_t *s) throw()
|
||||
{
|
||||
for (;;)
|
||||
@@ -272,6 +283,17 @@ bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw()
|
||||
}
|
||||
}
|
||||
|
||||
bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
wchar_t c2 = *s2++; if (c2 == 0) return true;
|
||||
wchar_t c1 = *s1++;
|
||||
if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// NTFS order: uses upper case
|
||||
int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw()
|
||||
{
|
||||
@@ -290,7 +312,8 @@ 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()
|
||||
/*
|
||||
int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num)
|
||||
{
|
||||
for (; num != 0; num--)
|
||||
{
|
||||
@@ -307,7 +330,7 @@ int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// ---------- AString ----------
|
||||
|
||||
@@ -317,15 +340,27 @@ void AString::InsertSpace(unsigned &index, unsigned size)
|
||||
MoveItems(index + size, index);
|
||||
}
|
||||
|
||||
#define k_Alloc_Len_Limit 0x40000000
|
||||
|
||||
void AString::ReAlloc(unsigned newLimit)
|
||||
{
|
||||
if (newLimit < _len || newLimit >= 0x20000000) throw 20130220;
|
||||
if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130220;
|
||||
// MY_STRING_REALLOC(_chars, char, newLimit + 1, _len + 1);
|
||||
char *newBuf = MY_STRING_NEW(char, newLimit + 1);
|
||||
memcpy(newBuf, _chars, (size_t)(_len + 1)); \
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
_limit = newLimit;
|
||||
}
|
||||
|
||||
void AString::ReAlloc2(unsigned newLimit)
|
||||
{
|
||||
if (newLimit >= k_Alloc_Len_Limit) throw 20130220;
|
||||
// MY_STRING_REALLOC(_chars, char, newLimit + 1, 0);
|
||||
char *newBuf = MY_STRING_NEW(char, newLimit + 1);
|
||||
newBuf[0] = 0;
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
_limit = newLimit;
|
||||
}
|
||||
|
||||
@@ -477,6 +512,63 @@ AString &AString::operator=(const AString &s)
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AString::SetFromWStr_if_Ascii(const wchar_t *s)
|
||||
{
|
||||
unsigned len = 0;
|
||||
{
|
||||
for (;; len++)
|
||||
{
|
||||
wchar_t c = s[len];
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c >= 0x80)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (len > _limit)
|
||||
{
|
||||
char *newBuf = MY_STRING_NEW(char, len + 1);
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
_limit = len;
|
||||
}
|
||||
_len = len;
|
||||
char *dest = _chars;
|
||||
unsigned i;
|
||||
for (i = 0; i < len; i++)
|
||||
dest[i] = (char)s[i];
|
||||
dest[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void AString::SetFromBstr_if_Ascii(BSTR s)
|
||||
{
|
||||
unsigned len = ::SysStringLen(s);
|
||||
{
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
if (s[i] <= 0 || s[i] >= 0x80)
|
||||
return;
|
||||
}
|
||||
if (len > _limit)
|
||||
{
|
||||
char *newBuf = MY_STRING_NEW(char, len + 1);
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
_limit = len;
|
||||
}
|
||||
_len = len;
|
||||
char *dest = _chars;
|
||||
unsigned i;
|
||||
for (i = 0; i < len; i++)
|
||||
dest[i] = (char)s[i];
|
||||
dest[i] = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
void AString::Add_Space() { operator+=(' '); }
|
||||
void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
|
||||
void AString::Add_LF() { operator+=('\n'); }
|
||||
|
||||
AString &AString::operator+=(const char *s)
|
||||
{
|
||||
unsigned len = MyStringLen(s);
|
||||
@@ -503,25 +595,50 @@ void AString::SetFrom(const char *s, unsigned len) // no check
|
||||
_chars = newBuf;
|
||||
_limit = len;
|
||||
}
|
||||
memcpy(_chars, s, len);
|
||||
if (len != 0)
|
||||
memcpy(_chars, s, len);
|
||||
_chars[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
|
||||
int AString::Find(const AString &s, unsigned startIndex) const throw()
|
||||
void AString::SetFrom_CalcLen(const char *s, unsigned len) // no check
|
||||
{
|
||||
if (s.IsEmpty())
|
||||
unsigned i;
|
||||
for (i = 0; i < len; i++)
|
||||
if (s[i] == 0)
|
||||
break;
|
||||
SetFrom(s, i);
|
||||
}
|
||||
|
||||
int AString::Find(const char *s, unsigned startIndex) const throw()
|
||||
{
|
||||
const char *fs = strstr(_chars + startIndex, s);
|
||||
if (!fs)
|
||||
return -1;
|
||||
return (int)(fs - _chars);
|
||||
|
||||
/*
|
||||
if (s[0] == 0)
|
||||
return startIndex;
|
||||
for (; startIndex < _len; startIndex++)
|
||||
unsigned len = MyStringLen(s);
|
||||
const char *p = _chars + startIndex;
|
||||
for (;; p++)
|
||||
{
|
||||
unsigned j;
|
||||
for (j = 0; j < s._len && startIndex + j < _len; j++)
|
||||
if (_chars[startIndex + j] != s._chars[j])
|
||||
const char c = *p;
|
||||
if (c != s[0])
|
||||
{
|
||||
if (c == 0)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
unsigned i;
|
||||
for (i = 1; i < len; i++)
|
||||
if (p[i] != s[i])
|
||||
break;
|
||||
if (j == s._len)
|
||||
return (int)startIndex;
|
||||
if (i == len)
|
||||
return (int)(p - _chars);
|
||||
}
|
||||
return -1;
|
||||
*/
|
||||
}
|
||||
|
||||
int AString::ReverseFind(char c) const throw()
|
||||
@@ -539,6 +656,22 @@ int AString::ReverseFind(char c) const throw()
|
||||
}
|
||||
}
|
||||
|
||||
int AString::ReverseFind_PathSepar() const throw()
|
||||
{
|
||||
if (_len == 0)
|
||||
return -1;
|
||||
const char *p = _chars + _len - 1;
|
||||
for (;;)
|
||||
{
|
||||
char c = *p;
|
||||
if (IS_PATH_SEPAR(c))
|
||||
return (int)(p - _chars);
|
||||
if (p == _chars)
|
||||
return -1;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
void AString::TrimLeft() throw()
|
||||
{
|
||||
const char *p = _chars;
|
||||
@@ -559,15 +692,14 @@ void AString::TrimLeft() throw()
|
||||
void AString::TrimRight() throw()
|
||||
{
|
||||
const char *p = _chars;
|
||||
int i;
|
||||
for (i = _len - 1; i >= 0; i--)
|
||||
unsigned i;
|
||||
for (i = _len; i != 0; i--)
|
||||
{
|
||||
char c = p[i];
|
||||
char c = p[i - 1];
|
||||
if (c != ' ' && c != '\n' && c != '\t')
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
if ((unsigned)i != _len)
|
||||
if (i != _len)
|
||||
{
|
||||
_chars[i] = 0;
|
||||
_len = i;
|
||||
@@ -616,19 +748,28 @@ void AString::Insert(unsigned index, const AString &s)
|
||||
|
||||
void AString::RemoveChar(char ch) throw()
|
||||
{
|
||||
int pos = Find(ch);
|
||||
if (pos < 0)
|
||||
return;
|
||||
const char *src = _chars;
|
||||
char *dest = _chars + pos;
|
||||
pos++;
|
||||
unsigned len = _len;
|
||||
for (; (unsigned)pos < len; pos++)
|
||||
char *src = _chars;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char c = src[(unsigned)pos];
|
||||
char c = *src++;
|
||||
if (c == 0)
|
||||
return;
|
||||
if (c == ch)
|
||||
break;
|
||||
}
|
||||
|
||||
char *dest = src - 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char c = *src++;
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c != ch)
|
||||
*dest++ = c;
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
_len = (unsigned)(dest - _chars);
|
||||
}
|
||||
@@ -645,7 +786,7 @@ void AString::Replace(char oldChar, char newChar) throw()
|
||||
pos = Find(oldChar, pos);
|
||||
if (pos < 0)
|
||||
break;
|
||||
_chars[pos] = newChar;
|
||||
_chars[(unsigned)pos] = newChar;
|
||||
pos++;
|
||||
// number++;
|
||||
}
|
||||
@@ -753,13 +894,23 @@ void UString::InsertSpace(unsigned index, unsigned size)
|
||||
|
||||
void UString::ReAlloc(unsigned newLimit)
|
||||
{
|
||||
if (newLimit < _len || newLimit >= 0x20000000) throw 20130221;
|
||||
if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130221;
|
||||
// MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, _len + 1);
|
||||
wchar_t *newBuf = MY_STRING_NEW(wchar_t, newLimit + 1);
|
||||
wmemcpy(newBuf, _chars, _len + 1);
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
_limit = newLimit;
|
||||
}
|
||||
|
||||
void UString::ReAlloc2(unsigned newLimit)
|
||||
{
|
||||
if (newLimit >= k_Alloc_Len_Limit) throw 20130221;
|
||||
// MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);
|
||||
wchar_t *newBuf = MY_STRING_NEW(wchar_t, newLimit + 1);
|
||||
newBuf[0] = 0;
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
_limit = newLimit;
|
||||
}
|
||||
|
||||
@@ -854,14 +1005,15 @@ UString::UString(wchar_t c)
|
||||
|
||||
UString::UString(const wchar_t *s)
|
||||
{
|
||||
SetStartLen(MyStringLen(s));
|
||||
MyStringCopy(_chars, s);
|
||||
unsigned len = MyStringLen(s);
|
||||
SetStartLen(len);
|
||||
wmemcpy(_chars, s, len + 1);
|
||||
}
|
||||
|
||||
UString::UString(const UString &s)
|
||||
{
|
||||
SetStartLen(s._len);
|
||||
MyStringCopy(_chars, s._chars);
|
||||
wmemcpy(_chars, s._chars, s._len + 1);
|
||||
}
|
||||
|
||||
UString &UString::operator=(wchar_t c)
|
||||
@@ -890,7 +1042,7 @@ UString &UString::operator=(const wchar_t *s)
|
||||
_limit = len;
|
||||
}
|
||||
_len = len;
|
||||
MyStringCopy(_chars, s);
|
||||
wmemcpy(_chars, s, len + 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -907,15 +1059,44 @@ UString &UString::operator=(const UString &s)
|
||||
_limit = len;
|
||||
}
|
||||
_len = len;
|
||||
MyStringCopy(_chars, s._chars);
|
||||
wmemcpy(_chars, s._chars, len + 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void UString::SetFromBstr(BSTR s)
|
||||
{
|
||||
unsigned len = ::SysStringLen(s);
|
||||
if (len > _limit)
|
||||
{
|
||||
wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
_limit = len;
|
||||
}
|
||||
_len = len;
|
||||
// if (s)
|
||||
wmemcpy(_chars, s, len + 1);
|
||||
}
|
||||
|
||||
void UString::Add_Space() { operator+=(L' '); }
|
||||
void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
|
||||
|
||||
void UString::Add_LF()
|
||||
{
|
||||
if (_limit == _len)
|
||||
Grow_1();
|
||||
unsigned len = _len;
|
||||
wchar_t *chars = _chars;
|
||||
chars[len++] = L'\n';
|
||||
chars[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
|
||||
UString &UString::operator+=(const wchar_t *s)
|
||||
{
|
||||
unsigned len = MyStringLen(s);
|
||||
Grow(len);
|
||||
MyStringCopy(_chars + _len, s);
|
||||
wmemcpy(_chars + _len, s, len + 1);
|
||||
_len += len;
|
||||
return *this;
|
||||
}
|
||||
@@ -923,7 +1104,7 @@ UString &UString::operator+=(const wchar_t *s)
|
||||
UString &UString::operator+=(const UString &s)
|
||||
{
|
||||
Grow(s._len);
|
||||
MyStringCopy(_chars + _len, s._chars);
|
||||
wmemcpy(_chars + _len, s._chars, s._len + 1);
|
||||
_len += s._len;
|
||||
return *this;
|
||||
}
|
||||
@@ -937,7 +1118,8 @@ void UString::SetFrom(const wchar_t *s, unsigned len) // no check
|
||||
_chars = newBuf;
|
||||
_limit = len;
|
||||
}
|
||||
wmemcpy(_chars, s, len);
|
||||
if (len != 0)
|
||||
wmemcpy(_chars, s, len);
|
||||
_chars[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
@@ -954,38 +1136,53 @@ void UString::SetFromAscii(const char *s)
|
||||
}
|
||||
wchar_t *chars = _chars;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
chars[i] = s[i];
|
||||
chars[i] = (unsigned char)s[i];
|
||||
chars[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
|
||||
void UString::AddAsciiStr(const char *s)
|
||||
void UString::AddAscii(const char *s)
|
||||
{
|
||||
unsigned len = MyStringLen(s);
|
||||
Grow(len);
|
||||
wchar_t *chars = _chars + _len;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
chars[i] = s[i];
|
||||
chars[i] = (unsigned char)s[i];
|
||||
chars[len] = 0;
|
||||
_len += len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int UString::Find(const UString &s, unsigned startIndex) const throw()
|
||||
int UString::Find(const wchar_t *s, unsigned startIndex) const throw()
|
||||
{
|
||||
if (s.IsEmpty())
|
||||
const wchar_t *fs = wcsstr(_chars + startIndex, s);
|
||||
if (!fs)
|
||||
return -1;
|
||||
return (int)(fs - _chars);
|
||||
|
||||
/*
|
||||
if (s[0] == 0)
|
||||
return startIndex;
|
||||
for (; startIndex < _len; startIndex++)
|
||||
unsigned len = MyStringLen(s);
|
||||
const wchar_t *p = _chars + startIndex;
|
||||
for (;; p++)
|
||||
{
|
||||
unsigned j;
|
||||
for (j = 0; j < s._len && startIndex + j < _len; j++)
|
||||
if (_chars[startIndex + j] != s._chars[j])
|
||||
const wchar_t c = *p;
|
||||
if (c != s[0])
|
||||
{
|
||||
if (c == 0)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
unsigned i;
|
||||
for (i = 1; i < len; i++)
|
||||
if (p[i] != s[i])
|
||||
break;
|
||||
if (j == s._len)
|
||||
return (int)startIndex;
|
||||
if (i == len)
|
||||
return (int)(p - _chars);
|
||||
}
|
||||
return -1;
|
||||
*/
|
||||
}
|
||||
|
||||
int UString::ReverseFind(wchar_t c) const throw()
|
||||
@@ -1003,6 +1200,22 @@ int UString::ReverseFind(wchar_t c) const throw()
|
||||
}
|
||||
}
|
||||
|
||||
int UString::ReverseFind_PathSepar() const throw()
|
||||
{
|
||||
if (_len == 0)
|
||||
return -1;
|
||||
const wchar_t *p = _chars + _len - 1;
|
||||
for (;;)
|
||||
{
|
||||
wchar_t c = *p;
|
||||
if (IS_PATH_SEPAR(c))
|
||||
return (int)(p - _chars);
|
||||
if (p == _chars)
|
||||
return -1;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
void UString::TrimLeft() throw()
|
||||
{
|
||||
const wchar_t *p = _chars;
|
||||
@@ -1023,15 +1236,14 @@ void UString::TrimLeft() throw()
|
||||
void UString::TrimRight() throw()
|
||||
{
|
||||
const wchar_t *p = _chars;
|
||||
int i;
|
||||
for (i = _len - 1; i >= 0; i--)
|
||||
unsigned i;
|
||||
for (i = _len; i != 0; i--)
|
||||
{
|
||||
wchar_t c = p[i];
|
||||
wchar_t c = p[i - 1];
|
||||
if (c != ' ' && c != '\n' && c != '\t')
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
if ((unsigned)i != _len)
|
||||
if (i != _len)
|
||||
{
|
||||
_chars[i] = 0;
|
||||
_len = i;
|
||||
@@ -1080,19 +1292,28 @@ void UString::Insert(unsigned index, const UString &s)
|
||||
|
||||
void UString::RemoveChar(wchar_t ch) throw()
|
||||
{
|
||||
int pos = Find(ch);
|
||||
if (pos < 0)
|
||||
return;
|
||||
const wchar_t *src = _chars;
|
||||
wchar_t *dest = _chars + pos;
|
||||
pos++;
|
||||
unsigned len = _len;
|
||||
for (; (unsigned)pos < len; pos++)
|
||||
wchar_t *src = _chars;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wchar_t c = src[(unsigned)pos];
|
||||
wchar_t c = *src++;
|
||||
if (c == 0)
|
||||
return;
|
||||
if (c == ch)
|
||||
break;
|
||||
}
|
||||
|
||||
wchar_t *dest = src - 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wchar_t c = *src++;
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c != ch)
|
||||
*dest++ = c;
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
_len = (unsigned)(dest - _chars);
|
||||
}
|
||||
@@ -1109,7 +1330,7 @@ void UString::Replace(wchar_t oldChar, wchar_t newChar) throw()
|
||||
pos = Find(oldChar, pos);
|
||||
if (pos < 0)
|
||||
break;
|
||||
_chars[pos] = newChar;
|
||||
_chars[(unsigned)pos] = newChar;
|
||||
pos++;
|
||||
// number++;
|
||||
}
|
||||
@@ -1166,6 +1387,135 @@ void UString::DeleteFrontal(unsigned num) throw()
|
||||
}
|
||||
|
||||
|
||||
// ---------- UString2 ----------
|
||||
|
||||
void UString2::ReAlloc2(unsigned newLimit)
|
||||
{
|
||||
if (newLimit >= k_Alloc_Len_Limit) throw 20130221;
|
||||
// MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);
|
||||
_chars = MY_STRING_NEW(wchar_t, newLimit + 1);
|
||||
}
|
||||
|
||||
void UString2::SetStartLen(unsigned len)
|
||||
{
|
||||
_chars = 0;
|
||||
_chars = MY_STRING_NEW(wchar_t, len + 1);
|
||||
_len = len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
UString2::UString2(wchar_t c)
|
||||
{
|
||||
SetStartLen(1);
|
||||
_chars[0] = c;
|
||||
_chars[1] = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
UString2::UString2(const wchar_t *s)
|
||||
{
|
||||
unsigned len = MyStringLen(s);
|
||||
SetStartLen(len);
|
||||
wmemcpy(_chars, s, len + 1);
|
||||
}
|
||||
|
||||
UString2::UString2(const UString2 &s): _chars(NULL), _len(0)
|
||||
{
|
||||
if (s._chars)
|
||||
{
|
||||
SetStartLen(s._len);
|
||||
wmemcpy(_chars, s._chars, s._len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
UString2 &UString2::operator=(wchar_t c)
|
||||
{
|
||||
if (1 > _len)
|
||||
{
|
||||
wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1);
|
||||
if (_chars)
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
}
|
||||
_len = 1;
|
||||
_chars[0] = c;
|
||||
_chars[1] = 0;
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
|
||||
UString2 &UString2::operator=(const wchar_t *s)
|
||||
{
|
||||
unsigned len = MyStringLen(s);
|
||||
if (len > _len)
|
||||
{
|
||||
wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
|
||||
if (_chars)
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
}
|
||||
_len = len;
|
||||
MyStringCopy(_chars, s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void UString2::SetFromAscii(const char *s)
|
||||
{
|
||||
unsigned len = MyStringLen(s);
|
||||
if (len > _len)
|
||||
{
|
||||
wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
|
||||
if (_chars)
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
}
|
||||
wchar_t *chars = _chars;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
chars[i] = (unsigned char)s[i];
|
||||
chars[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
|
||||
UString2 &UString2::operator=(const UString2 &s)
|
||||
{
|
||||
if (&s == this)
|
||||
return *this;
|
||||
unsigned len = s._len;
|
||||
if (len > _len)
|
||||
{
|
||||
wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
|
||||
if (_chars)
|
||||
MY_STRING_DELETE(_chars);
|
||||
_chars = newBuf;
|
||||
}
|
||||
_len = len;
|
||||
MyStringCopy(_chars, s._chars);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const UString2 &s1, const UString2 &s2)
|
||||
{
|
||||
return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0);
|
||||
}
|
||||
|
||||
bool operator==(const UString2 &s1, const wchar_t *s2)
|
||||
{
|
||||
if (s1.IsEmpty())
|
||||
return (*s2 == 0);
|
||||
return wcscmp(s1.GetRawPtr(), s2) == 0;
|
||||
}
|
||||
|
||||
bool operator==(const wchar_t *s1, const UString2 &s2)
|
||||
{
|
||||
if (s2.IsEmpty())
|
||||
return (*s1 == 0);
|
||||
return wcscmp(s1, s2.GetRawPtr()) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
|
||||
/*
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
#include "MyTypes.h"
|
||||
#include "MyVector.h"
|
||||
|
||||
#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;
|
||||
@@ -50,6 +59,21 @@ inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
|
||||
while ((*dest++ = *src++) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
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();
|
||||
|
||||
@@ -81,7 +105,7 @@ inline wchar_t MyCharUpper_Ascii(wchar_t c)
|
||||
inline char MyCharLower_Ascii(char c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return (char)(c + 0x20);
|
||||
return (char)((unsigned char)c + 0x20);
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -134,6 +158,7 @@ inline wchar_t MyCharLower(wchar_t c) throw()
|
||||
// char *MyStringLower(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;
|
||||
@@ -142,9 +167,10 @@ 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_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
|
||||
|
||||
int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
|
||||
int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
|
||||
// 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
|
||||
@@ -170,6 +196,7 @@ class AString
|
||||
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);
|
||||
@@ -186,6 +213,17 @@ class AString
|
||||
friend AString operator+(const AString &s1, const char *s2);
|
||||
friend AString operator+(const char *s1, const AString &s2);
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
AString &operator+=(wchar_t c);
|
||||
AString &operator=(wchar_t c);
|
||||
AString(wchar_t c);
|
||||
void Find(wchar_t c) const;
|
||||
void Find(wchar_t c, unsigned startIndex) const;
|
||||
void ReverseFind(wchar_t c) const;
|
||||
void InsertAtFront(wchar_t c);
|
||||
void RemoveChar(wchar_t ch);
|
||||
void Replace(wchar_t oldChar, wchar_t newChar);
|
||||
|
||||
public:
|
||||
AString();
|
||||
AString(char c);
|
||||
@@ -205,20 +243,39 @@ public:
|
||||
|
||||
void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
|
||||
|
||||
// The minimum size of the character buffer in characters.
|
||||
// This value does not include space for a null terminator.
|
||||
char *GetBuffer(unsigned minBufLen)
|
||||
/* 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 (minBufLen > _limit)
|
||||
ReAlloc(minBufLen);
|
||||
if (minLen > _limit)
|
||||
ReAlloc2(minLen);
|
||||
return _chars;
|
||||
}
|
||||
void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
|
||||
void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
|
||||
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)
|
||||
{
|
||||
@@ -231,18 +288,30 @@ public:
|
||||
_len = len;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Add_Space();
|
||||
void Add_Space_if_NotEmpty();
|
||||
void Add_LF();
|
||||
void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
|
||||
|
||||
AString &operator+=(const char *s);
|
||||
AString &operator+=(const AString &s);
|
||||
void AddAscii(const char *s) { operator+=(s); }
|
||||
|
||||
void SetFrom(const char *s, unsigned len); // no check
|
||||
void SetFrom_CalcLen(const char *s, unsigned len);
|
||||
// void SetFromAscii(const char *s) { operator+=(s); }
|
||||
|
||||
// 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); }
|
||||
@@ -250,16 +319,29 @@ public:
|
||||
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 Find(const AString &s) const { return Find(s, 0); }
|
||||
int Find(const AString &s, unsigned startIndex) 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()
|
||||
@@ -274,9 +356,10 @@ public:
|
||||
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();
|
||||
@@ -312,6 +395,19 @@ inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() !
|
||||
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
|
||||
@@ -328,6 +424,7 @@ class UString
|
||||
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);
|
||||
@@ -344,6 +441,27 @@ class UString
|
||||
friend UString operator+(const UString &s1, const wchar_t *s2);
|
||||
friend UString operator+(const wchar_t *s1, const UString &s2);
|
||||
|
||||
// ---------- forbidden functions ----------
|
||||
|
||||
UString &operator+=(char c);
|
||||
UString &operator+=(unsigned char c);
|
||||
UString &operator=(char c);
|
||||
UString &operator=(unsigned char c);
|
||||
UString(char c);
|
||||
UString(unsigned char c);
|
||||
void Find(char c) const;
|
||||
void Find(unsigned char c) const;
|
||||
void Find(char c, unsigned startIndex) const;
|
||||
void Find(unsigned char c, unsigned startIndex) const;
|
||||
void ReverseFind(char c) const;
|
||||
void ReverseFind(unsigned char c) const;
|
||||
void InsertAtFront(char c);
|
||||
void InsertAtFront(unsigned char c);
|
||||
void RemoveChar(char ch);
|
||||
void RemoveChar(unsigned char ch);
|
||||
void Replace(char oldChar, char newChar);
|
||||
void Replace(unsigned char oldChar, unsigned char newChar);
|
||||
|
||||
public:
|
||||
UString();
|
||||
UString(wchar_t c);
|
||||
@@ -363,20 +481,35 @@ public:
|
||||
|
||||
void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
|
||||
|
||||
// The minimum size of the character buffer in characters.
|
||||
// This value does not include space for a null terminator.
|
||||
wchar_t *GetBuffer(unsigned minBufLen)
|
||||
wchar_t *GetBuf(unsigned minLen)
|
||||
{
|
||||
if (minBufLen > _limit)
|
||||
ReAlloc(minBufLen);
|
||||
if (minLen > _limit)
|
||||
ReAlloc2(minLen);
|
||||
return _chars;
|
||||
}
|
||||
void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
|
||||
void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
|
||||
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=(const wchar_t *s);
|
||||
UString &operator=(const UString &s);
|
||||
void SetFromBstr(BSTR s);
|
||||
|
||||
UString &operator+=(wchar_t c)
|
||||
{
|
||||
@@ -390,13 +523,18 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
void SetFrom(const wchar_t *s, unsigned len); // no check
|
||||
|
||||
void SetFromAscii(const char *s);
|
||||
void AddAsciiStr(const char *s);
|
||||
void AddAscii(const char *s);
|
||||
|
||||
UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
|
||||
UString Left(unsigned count) const { return UString(count, *this); }
|
||||
@@ -407,23 +545,38 @@ public:
|
||||
void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
|
||||
|
||||
bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
|
||||
bool IsEqualToNoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
|
||||
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(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 Find(const UString &s) const { return Find(s, 0); }
|
||||
int Find(const UString &s, unsigned startIndex) const throw();
|
||||
|
||||
int ReverseFind(wchar_t c) const throw();
|
||||
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();
|
||||
@@ -439,9 +592,10 @@ public:
|
||||
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();
|
||||
@@ -468,6 +622,110 @@ inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1,
|
||||
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 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 ----------
|
||||
|
||||
UString2 &operator=(char c);
|
||||
UString2 &operator=(unsigned char c);
|
||||
UString2 &operator=(wchar_t c);
|
||||
UString2(char c);
|
||||
UString2(unsigned char c);
|
||||
|
||||
public:
|
||||
UString2(): _chars(NULL), _len(0) {}
|
||||
// UString2(wchar_t c);
|
||||
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; }
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -27,4 +27,9 @@ struct CBoolPair
|
||||
}
|
||||
};
|
||||
|
||||
#define CLASS_NO_COPY(cls) \
|
||||
private: \
|
||||
cls(const cls &); \
|
||||
cls &operator=(const cls &);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,7 +12,7 @@ class CRecordVector
|
||||
|
||||
void MoveItems(unsigned destIndex, unsigned srcIndex)
|
||||
{
|
||||
memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * (size_t)sizeof(T));
|
||||
memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T));
|
||||
}
|
||||
|
||||
void ReserveOnePosition()
|
||||
@@ -21,7 +21,8 @@ class CRecordVector
|
||||
{
|
||||
unsigned newCapacity = _capacity + (_capacity >> 2) + 1;
|
||||
T *p = new T[newCapacity];
|
||||
memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
|
||||
if (_size != 0)
|
||||
memcpy(p, _items, (size_t)_size * sizeof(T));
|
||||
delete []_items;
|
||||
_items = p;
|
||||
_capacity = newCapacity;
|
||||
@@ -40,7 +41,7 @@ public:
|
||||
_items = new T[size];
|
||||
_size = size;
|
||||
_capacity = size;
|
||||
memcpy(_items, v._items, (size_t)size * (size_t)sizeof(T));
|
||||
memcpy(_items, v._items, (size_t)size * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +62,8 @@ public:
|
||||
if (newCapacity > _capacity)
|
||||
{
|
||||
T *p = new T[newCapacity];
|
||||
memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
|
||||
if (_size != 0)
|
||||
memcpy(p, _items, (size_t)_size * sizeof(T));
|
||||
delete []_items;
|
||||
_items = p;
|
||||
_capacity = newCapacity;
|
||||
@@ -92,7 +94,8 @@ public:
|
||||
if (newSize > _capacity)
|
||||
{
|
||||
T *p = new T[newSize];
|
||||
memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
|
||||
if (_size != 0)
|
||||
memcpy(p, _items, (size_t)_size * sizeof(T));
|
||||
delete []_items;
|
||||
_items = p;
|
||||
_capacity = newSize;
|
||||
@@ -108,7 +111,7 @@ public:
|
||||
if (_size != 0)
|
||||
{
|
||||
p = new T[_size];
|
||||
memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
|
||||
memcpy(p, _items, (size_t)_size * sizeof(T));
|
||||
}
|
||||
delete []_items;
|
||||
_items = p;
|
||||
@@ -163,6 +166,8 @@ public:
|
||||
|
||||
CRecordVector& operator=(const CRecordVector &v)
|
||||
{
|
||||
if (&v == this)
|
||||
return *this;
|
||||
unsigned size = v.Size();
|
||||
if (size > _capacity)
|
||||
{
|
||||
@@ -174,7 +179,8 @@ public:
|
||||
_capacity = size;
|
||||
}
|
||||
_size = size;
|
||||
memcpy(_items, v._items, (size_t)size * (size_t)sizeof(T));
|
||||
if (size != 0)
|
||||
memcpy(_items, v._items, (size_t)size * sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -182,7 +188,8 @@ public:
|
||||
{
|
||||
unsigned size = v.Size();
|
||||
Reserve(_size + size);
|
||||
memcpy(_items + _size, v._items, (size_t)size * (size_t)sizeof(T));
|
||||
if (size != 0)
|
||||
memcpy(_items + _size, v._items, (size_t)size * sizeof(T));
|
||||
_size += size;
|
||||
return *this;
|
||||
}
|
||||
@@ -212,7 +219,7 @@ public:
|
||||
if (index != 0)
|
||||
{
|
||||
T temp = _items[index];
|
||||
memmove(_items + 1, _items, (size_t)index * (size_t)sizeof(T));
|
||||
memmove(_items + 1, _items, (size_t)index * sizeof(T));
|
||||
_items[0] = temp;
|
||||
}
|
||||
}
|
||||
@@ -421,6 +428,8 @@ public:
|
||||
}
|
||||
CObjectVector& operator=(const CObjectVector &v)
|
||||
{
|
||||
if (&v == this)
|
||||
return *this;
|
||||
Clear();
|
||||
unsigned size = v.Size();
|
||||
_v.Reserve(size);
|
||||
|
||||
@@ -31,7 +31,8 @@ void my_delete(void *p) throw()
|
||||
void * my_Realloc(void *p, size_t newSize, size_t oldSize)
|
||||
{
|
||||
void *newBuf = my_new(newSize);
|
||||
memcpy(newBuf, p, oldSize);
|
||||
if (oldSize != 0)
|
||||
memcpy(newBuf, p, oldSize);
|
||||
my_delete(p);
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
40
CPP/Common/Sha1Reg.cpp
Normal file
40
CPP/Common/Sha1Reg.cpp
Normal file
@@ -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_IMP
|
||||
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)
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "../Common/MyCom.h"
|
||||
|
||||
#include "../7zip/ICoder.h"
|
||||
#include "../7zip/Common/RegisterCodec.h"
|
||||
|
||||
class CSha256Hasher:
|
||||
@@ -14,39 +13,28 @@ class CSha256Hasher:
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CSha256 _sha;
|
||||
Byte mtDummy[1 << 7];
|
||||
|
||||
public:
|
||||
CSha256Hasher() { Init(); };
|
||||
CSha256Hasher() { Sha256_Init(&_sha); }
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD_(void, Init)();
|
||||
STDMETHOD_(void, Update)(const void *data, UInt32 size);
|
||||
STDMETHOD_(void, Final)(Byte *digest);
|
||||
STDMETHOD_(UInt32, GetDigestSize)();
|
||||
INTERFACE_IHasher(;)
|
||||
};
|
||||
|
||||
STDMETHODIMP_(void) CSha256Hasher::Init()
|
||||
STDMETHODIMP_(void) CSha256Hasher::Init() throw()
|
||||
{
|
||||
Sha256_Init(&_sha);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CSha256Hasher::Update(const void *data, UInt32 size)
|
||||
STDMETHODIMP_(void) CSha256Hasher::Update(const void *data, UInt32 size) throw()
|
||||
{
|
||||
Sha256_Update(&_sha, (const Byte *)data, size);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CSha256Hasher::Final(Byte *digest)
|
||||
STDMETHODIMP_(void) CSha256Hasher::Final(Byte *digest) throw()
|
||||
{
|
||||
Sha256_Final(&_sha, digest);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UInt32) CSha256Hasher::GetDigestSize()
|
||||
{
|
||||
return SHA256_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
static IHasher *CreateHasher() { return new CSha256Hasher; }
|
||||
|
||||
static CHasherInfo g_HasherInfo = { CreateHasher, 0xA, L"SHA256", SHA256_DIGEST_SIZE };
|
||||
|
||||
REGISTER_HASHER(Sha256)
|
||||
REGISTER_HASHER(CSha256Hasher, 0xA, "SHA256", SHA256_DIGEST_SIZE)
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
|
||||
CStdOutStream & operator<<(char c) throw()
|
||||
{
|
||||
fputc(c, _stream);
|
||||
fputc((unsigned char)c, _stream);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,158 +8,306 @@
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static const char k_DefultChar = '_';
|
||||
|
||||
#ifdef _WIN32
|
||||
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
|
||||
{
|
||||
UString resultString;
|
||||
if (!srcString.IsEmpty())
|
||||
{
|
||||
int numChars = MultiByteToWideChar(codePage, 0, srcString,
|
||||
srcString.Len(), resultString.GetBuffer(srcString.Len()),
|
||||
srcString.Len() + 1);
|
||||
if (numChars == 0)
|
||||
throw 282228;
|
||||
resultString.ReleaseBuffer(numChars);
|
||||
}
|
||||
return resultString;
|
||||
}
|
||||
|
||||
void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage)
|
||||
/*
|
||||
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 (!srcString.IsEmpty())
|
||||
if (src.IsEmpty())
|
||||
return;
|
||||
{
|
||||
wchar_t *destBuf = dest.GetBuffer(srcString.Len());
|
||||
const char *sp = (const char *)srcString;
|
||||
/*
|
||||
wchar_t *d = dest.GetBuf(src.Len());
|
||||
const char *s = (const char *)src;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0;;)
|
||||
{
|
||||
char c = sp[i];
|
||||
if ((Byte)c >= 0x80 || c == 0)
|
||||
break;
|
||||
destBuf[i++] = (wchar_t)c;
|
||||
}
|
||||
|
||||
if (i != srcString.Len())
|
||||
{
|
||||
unsigned numChars = MultiByteToWideChar(codePage, 0, sp + i,
|
||||
srcString.Len() - i, destBuf + i,
|
||||
srcString.Len() + 1 - i);
|
||||
if (numChars == 0)
|
||||
throw 282228;
|
||||
i += numChars;
|
||||
}
|
||||
dest.ReleaseBuffer(i);
|
||||
}
|
||||
}
|
||||
|
||||
void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
|
||||
{
|
||||
dest.Empty();
|
||||
defaultCharWasUsed = false;
|
||||
if (!s.IsEmpty())
|
||||
{
|
||||
unsigned numRequiredBytes = s.Len() * 2;
|
||||
char *destBuf = dest.GetBuffer(numRequiredBytes);
|
||||
unsigned i;
|
||||
const wchar_t *sp = (const wchar_t *)s;
|
||||
for (i = 0;;)
|
||||
{
|
||||
wchar_t c = sp[i];
|
||||
Byte c = (Byte)s[i];
|
||||
if (c >= 0x80 || c == 0)
|
||||
break;
|
||||
destBuf[i++] = (char)c;
|
||||
d[i++] = (wchar_t)c;
|
||||
}
|
||||
defaultCharWasUsed = false;
|
||||
if (i != s.Len())
|
||||
|
||||
if (i != src.Len())
|
||||
{
|
||||
BOOL defUsed;
|
||||
unsigned numChars = WideCharToMultiByte(codePage, 0, sp + i, s.Len() - i,
|
||||
destBuf + i, numRequiredBytes + 1 - i,
|
||||
&defaultChar, &defUsed);
|
||||
defaultCharWasUsed = (defUsed != FALSE);
|
||||
if (numChars == 0)
|
||||
throw 282229;
|
||||
i += numChars;
|
||||
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);
|
||||
}
|
||||
dest.ReleaseBuffer(i);
|
||||
}
|
||||
}
|
||||
|
||||
void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage)
|
||||
/*
|
||||
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)
|
||||
{
|
||||
bool defaultCharWasUsed;
|
||||
UnicodeStringToMultiByte2(dest, srcString, codePage, '_', 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AString UnicodeStringToMultiByte(const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
|
||||
/*
|
||||
#ifndef UNDER_CE
|
||||
AString SystemStringToOemString(const CSysString &src)
|
||||
{
|
||||
AString dest;
|
||||
defaultCharWasUsed = false;
|
||||
if (!s.IsEmpty())
|
||||
{
|
||||
unsigned numRequiredBytes = s.Len() * 2;
|
||||
BOOL defUsed;
|
||||
int numChars = WideCharToMultiByte(codePage, 0, s, s.Len(),
|
||||
dest.GetBuffer(numRequiredBytes), numRequiredBytes + 1,
|
||||
&defaultChar, &defUsed);
|
||||
defaultCharWasUsed = (defUsed != FALSE);
|
||||
if (numChars == 0)
|
||||
throw 282229;
|
||||
dest.ReleaseBuffer(numChars);
|
||||
}
|
||||
const unsigned len = src.Len() * 2;
|
||||
CharToOem(src, dest.GetBuf(len));
|
||||
dest.ReleaseBuf_CalcLen(len);
|
||||
return dest;
|
||||
}
|
||||
|
||||
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
|
||||
{
|
||||
bool defaultCharWasUsed;
|
||||
return UnicodeStringToMultiByte(srcString, codePage, '_', defaultCharWasUsed);
|
||||
}
|
||||
|
||||
#ifndef UNDER_CE
|
||||
AString SystemStringToOemString(const CSysString &srcString)
|
||||
{
|
||||
AString result;
|
||||
CharToOem(srcString, result.GetBuffer(srcString.Len() * 2));
|
||||
result.ReleaseBuffer();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
#else
|
||||
|
||||
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
|
||||
void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT /* codePage */)
|
||||
{
|
||||
UString resultString;
|
||||
for (unsigned i = 0; i < srcString.Len(); i++)
|
||||
resultString += (wchar_t)srcString[i];
|
||||
/*
|
||||
if (!srcString.IsEmpty())
|
||||
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)
|
||||
{
|
||||
int numChars = mbstowcs(resultString.GetBuffer(srcString.Len()), srcString, srcString.Len() + 1);
|
||||
if (numChars < 0) throw "Your environment does not support UNICODE";
|
||||
resultString.ReleaseBuffer(numChars);
|
||||
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);
|
||||
}
|
||||
*/
|
||||
return resultString;
|
||||
}
|
||||
|
||||
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
|
||||
static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT /* codePage */, char defaultChar, bool &defaultCharWasUsed)
|
||||
{
|
||||
AString resultString;
|
||||
for (unsigned i = 0; i < srcString.Len(); i++)
|
||||
resultString += (char)srcString[i];
|
||||
/*
|
||||
if (!srcString.IsEmpty())
|
||||
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)
|
||||
{
|
||||
int numRequiredBytes = srcString.Len() * 6 + 1;
|
||||
int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);
|
||||
if (numChars < 0) throw "Your environment does not support UNICODE";
|
||||
resultString.ReleaseBuffer(numChars);
|
||||
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);
|
||||
}
|
||||
*/
|
||||
return resultString;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
UString MultiByteToUnicodeString(const AString &src, UINT codePage)
|
||||
{
|
||||
UString dest;
|
||||
MultiByteToUnicodeString2(dest, src, codePage);
|
||||
return dest;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_AC
|
||||
|
||||
// optimized versions that work faster for ASCII strings
|
||||
void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage = CP_ACP);
|
||||
void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
|
||||
// void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
|
||||
void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage);
|
||||
|
||||
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
|
||||
|
||||
@@ -8,12 +8,12 @@ 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) \
|
||||
#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++) { \
|
||||
charType c = *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; \
|
||||
@@ -21,10 +21,10 @@ static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF);
|
||||
if (res > (k_ ## uintType ## _max) - v) return 0; \
|
||||
res += v; }}
|
||||
|
||||
CONVERT_STRING_TO_UINT_FUNC(UInt32, char)
|
||||
CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t)
|
||||
CONVERT_STRING_TO_UINT_FUNC(UInt64, char)
|
||||
CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t)
|
||||
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()
|
||||
{
|
||||
@@ -58,7 +58,7 @@ UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw()
|
||||
UInt32 res = 0;
|
||||
for (;; s++)
|
||||
{
|
||||
char c = *s;
|
||||
unsigned c = (unsigned char)*s;
|
||||
if (c < '0' || c > '7')
|
||||
{
|
||||
if (end)
|
||||
@@ -79,7 +79,7 @@ UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw()
|
||||
UInt64 res = 0;
|
||||
for (;; s++)
|
||||
{
|
||||
char c = *s;
|
||||
unsigned c = (unsigned char)*s;
|
||||
if (c < '0' || c > '7')
|
||||
{
|
||||
if (end)
|
||||
@@ -100,7 +100,7 @@ UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw()
|
||||
UInt32 res = 0;
|
||||
for (;; s++)
|
||||
{
|
||||
char c = *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');
|
||||
@@ -125,7 +125,7 @@ UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw()
|
||||
UInt64 res = 0;
|
||||
for (;; s++)
|
||||
{
|
||||
char c = *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');
|
||||
|
||||
@@ -5,56 +5,91 @@
|
||||
#include "MyTypes.h"
|
||||
#include "UTFConvert.h"
|
||||
|
||||
static const Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
#ifdef _WIN32
|
||||
#define _WCHART_IS_16BIT 1
|
||||
#endif
|
||||
|
||||
bool CheckUTF8(const char *src) throw()
|
||||
/*
|
||||
_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;
|
||||
unsigned numAdds;
|
||||
c = *src++;
|
||||
Byte c = *src++;
|
||||
if (c == 0)
|
||||
return true;
|
||||
|
||||
if (c < 0x80)
|
||||
continue;
|
||||
if (c < 0xC0)
|
||||
if (c < 0xC0) // (c < 0xC0 + 2) // if we support only optimal encoding chars
|
||||
return false;
|
||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
||||
if (c < kUtf8Limits[numAdds])
|
||||
break;
|
||||
UInt32 value = (c - kUtf8Limits[numAdds - 1]);
|
||||
|
||||
unsigned numBytes;
|
||||
_UTF8_HEAD_PARSE
|
||||
else
|
||||
return false;
|
||||
|
||||
UInt32 val = c;
|
||||
|
||||
do
|
||||
{
|
||||
Byte c2 = *src++;
|
||||
if (c2 < 0x80 || c2 >= 0xC0)
|
||||
return false;
|
||||
value <<= 6;
|
||||
value |= (c2 - 0x80);
|
||||
return allowReduced && c2 == 0;
|
||||
val <<= 6;
|
||||
val |= (c2 - 0x80);
|
||||
}
|
||||
while (--numAdds);
|
||||
while (--numBytes);
|
||||
|
||||
if (value >= 0x110000)
|
||||
if (val >= 0x110000)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen) throw()
|
||||
#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, srcPos = 0;
|
||||
size_t destPos = 0;
|
||||
bool ok = true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte c;
|
||||
unsigned numAdds;
|
||||
if (srcPos == srcLen)
|
||||
if (src == srcLim)
|
||||
{
|
||||
*destLen = destPos;
|
||||
return True;
|
||||
return ok;
|
||||
}
|
||||
c = (Byte)src[srcPos++];
|
||||
c = *src++;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
@@ -64,113 +99,190 @@ static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_
|
||||
continue;
|
||||
}
|
||||
if (c < 0xC0)
|
||||
break;
|
||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
||||
if (c < kUtf8Limits[numAdds])
|
||||
break;
|
||||
UInt32 value = (c - kUtf8Limits[numAdds - 1]);
|
||||
_ERROR_UTF8
|
||||
|
||||
unsigned numBytes;
|
||||
_UTF8_HEAD_PARSE
|
||||
else
|
||||
_ERROR_UTF8
|
||||
|
||||
UInt32 val = c;
|
||||
|
||||
do
|
||||
{
|
||||
Byte c2;
|
||||
if (srcPos == srcLen)
|
||||
if (src == srcLim)
|
||||
break;
|
||||
c2 = (Byte)src[srcPos++];
|
||||
c2 = *src;
|
||||
if (c2 < 0x80 || c2 >= 0xC0)
|
||||
break;
|
||||
value <<= 6;
|
||||
value |= (c2 - 0x80);
|
||||
src++;
|
||||
val <<= 6;
|
||||
val |= (c2 - 0x80);
|
||||
}
|
||||
while (--numAdds);
|
||||
|
||||
if (value < 0x10000)
|
||||
while (--numBytes);
|
||||
|
||||
if (numBytes != 0)
|
||||
_ERROR_UTF8
|
||||
|
||||
if (val < 0x10000)
|
||||
{
|
||||
if (dest)
|
||||
dest[destPos] = (wchar_t)value;
|
||||
dest[destPos] = (wchar_t)val;
|
||||
destPos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
value -= 0x10000;
|
||||
if (value >= 0x100000)
|
||||
break;
|
||||
val -= 0x10000;
|
||||
if (val >= 0x100000)
|
||||
_ERROR_UTF8
|
||||
if (dest)
|
||||
{
|
||||
dest[destPos + 0] = (wchar_t)(0xD800 + (value >> 10));
|
||||
dest[destPos + 1] = (wchar_t)(0xDC00 + (value & 0x3FF));
|
||||
dest[destPos + 0] = (wchar_t)(0xD800 + (val >> 10));
|
||||
dest[destPos + 1] = (wchar_t)(0xDC00 + (val & 0x3FF));
|
||||
}
|
||||
destPos += 2;
|
||||
}
|
||||
}
|
||||
*destLen = destPos;
|
||||
return False;
|
||||
}
|
||||
|
||||
static Bool Utf16_To_Utf8(char *dest, size_t *destLen, const wchar_t *src, size_t srcLen)
|
||||
#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 destPos = 0, srcPos = 0;
|
||||
size_t size = srcLim - src;
|
||||
for (;;)
|
||||
{
|
||||
unsigned numAdds;
|
||||
UInt32 value;
|
||||
if (srcPos == srcLen)
|
||||
if (src == srcLim)
|
||||
return size;
|
||||
|
||||
UInt32 val = *src++;
|
||||
|
||||
if (val < 0x80)
|
||||
continue;
|
||||
|
||||
if (val < _UTF8_RANGE(1))
|
||||
{
|
||||
*destLen = destPos;
|
||||
return True;
|
||||
}
|
||||
value = src[srcPos++];
|
||||
if (value < 0x80)
|
||||
{
|
||||
if (dest)
|
||||
dest[destPos] = (char)value;
|
||||
destPos++;
|
||||
size++;
|
||||
continue;
|
||||
}
|
||||
if (value >= 0xD800 && value < 0xE000)
|
||||
|
||||
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
|
||||
{
|
||||
UInt32 c2;
|
||||
if (value >= 0xDC00 || srcPos == srcLen)
|
||||
break;
|
||||
c2 = src[srcPos++];
|
||||
if (c2 < 0xDC00 || c2 >= 0xE000)
|
||||
break;
|
||||
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
|
||||
UInt32 c2 = *src;
|
||||
if (c2 >= 0xDC00 && c2 < 0xE000)
|
||||
{
|
||||
src++;
|
||||
size += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
||||
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
|
||||
break;
|
||||
if (dest)
|
||||
dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
|
||||
destPos++;
|
||||
|
||||
#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
|
||||
{
|
||||
numAdds--;
|
||||
if (dest)
|
||||
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
|
||||
destPos++;
|
||||
numBits -= 6;
|
||||
*dest++ = (char)(0x80 + ((val >> numBits) & 0x3F));
|
||||
}
|
||||
while (numAdds != 0);
|
||||
while (numBits != 0);
|
||||
|
||||
#endif
|
||||
}
|
||||
*destLen = destPos;
|
||||
return False;
|
||||
}
|
||||
|
||||
bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
|
||||
{
|
||||
dest.Empty();
|
||||
size_t destLen = 0;
|
||||
Utf8_To_Utf16(NULL, &destLen, src, src.Len());
|
||||
Bool res = Utf8_To_Utf16(dest.GetBuffer((unsigned)destLen), &destLen, src, src.Len());
|
||||
dest.ReleaseBuffer((unsigned)destLen);
|
||||
return res ? true : false;
|
||||
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;
|
||||
}
|
||||
|
||||
bool ConvertUnicodeToUTF8(const UString &src, AString &dest)
|
||||
void ConvertUnicodeToUTF8(const UString &src, AString &dest)
|
||||
{
|
||||
dest.Empty();
|
||||
size_t destLen = 0;
|
||||
Utf16_To_Utf8(NULL, &destLen, src, src.Len());
|
||||
Bool res = Utf16_To_Utf8(dest.GetBuffer((unsigned)destLen), &destLen, src, src.Len());
|
||||
dest.ReleaseBuffer((unsigned)destLen);
|
||||
return res ? true : false;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
#include "MyString.h"
|
||||
|
||||
bool CheckUTF8(const char *src) throw();
|
||||
bool CheckUTF8(const char *src, bool allowReduced = false) throw();
|
||||
bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
|
||||
bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
|
||||
void ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,22 +15,8 @@ bool g_CaseSensitive =
|
||||
bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
if (g_CaseSensitive)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
wchar_t c2 = *s2++; if (c2 == 0) return true;
|
||||
wchar_t c1 = *s1++;
|
||||
if (MyCharUpper(c1) !=
|
||||
MyCharUpper(c2))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wchar_t c2 = *s2++; if (c2 == 0) return true;
|
||||
wchar_t c1 = *s1++; if (c1 != c2) return false;
|
||||
}
|
||||
return IsString1PrefixedByString2(s1, s2);
|
||||
return IsString1PrefixedByString2_NoCase(s1, s2);
|
||||
}
|
||||
|
||||
int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
|
||||
@@ -97,7 +83,7 @@ void SplitPathToParts(const UString &path, UStringVector &pathParts)
|
||||
UString name;
|
||||
unsigned prev = 0;
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
if (IsCharDirLimiter(path[i]))
|
||||
if (IsPathSepar(path[i]))
|
||||
{
|
||||
name.SetFrom(path.Ptr(prev), i - prev);
|
||||
pathParts.Add(name);
|
||||
@@ -112,7 +98,7 @@ 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 (IsCharDirLimiter(*(p - 1)))
|
||||
if (IsPathSepar(*(p - 1)))
|
||||
break;
|
||||
dirPrefix.SetFrom(path, (unsigned)(p - start));
|
||||
name = p;
|
||||
@@ -124,10 +110,10 @@ void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &na
|
||||
const wchar_t *p = start + path.Len();
|
||||
if (p != start)
|
||||
{
|
||||
if (IsCharDirLimiter(*(p - 1)))
|
||||
if (IsPathSepar(*(p - 1)))
|
||||
p--;
|
||||
for (; p != start; p--)
|
||||
if (IsCharDirLimiter(*(p - 1)))
|
||||
if (IsPathSepar(*(p - 1)))
|
||||
break;
|
||||
}
|
||||
dirPrefix.SetFrom(path, (unsigned)(p - start));
|
||||
@@ -139,7 +125,7 @@ UString ExtractDirPrefixFromPath(const UString &path)
|
||||
const wchar_t *start = path;
|
||||
const wchar_t *p = start + path.Len();
|
||||
for (; p != start; p--)
|
||||
if (IsCharDirLimiter(*(p - 1)))
|
||||
if (IsPathSepar(*(p - 1)))
|
||||
break;
|
||||
return path.Left((unsigned)(p - start));
|
||||
}
|
||||
@@ -149,7 +135,7 @@ UString ExtractFileNameFromPath(const UString &path)
|
||||
const wchar_t *start = path;
|
||||
const wchar_t *p = start + path.Len();
|
||||
for (; p != start; p--)
|
||||
if (IsCharDirLimiter(*(p - 1)))
|
||||
if (IsPathSepar(*(p - 1)))
|
||||
break;
|
||||
return p;
|
||||
}
|
||||
@@ -177,15 +163,6 @@ bool DoesNameContainWildcard(const UString &path)
|
||||
|
||||
namespace NWildcard {
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
bool IsDriveColonName(const wchar_t *s)
|
||||
{
|
||||
wchar_t c = s[0];
|
||||
return c != 0 && s[1] == ':' && s[2] == 0 && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
M = MaskParts.Size();
|
||||
@@ -212,6 +189,19 @@ 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;
|
||||
@@ -286,7 +276,7 @@ void CCensorNode::AddItemSimple(bool include, CItem &item)
|
||||
ExcludeItems.Add(item);
|
||||
}
|
||||
|
||||
void CCensorNode::AddItem(bool include, CItem &item)
|
||||
void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex)
|
||||
{
|
||||
if (item.PathParts.Size() <= 1)
|
||||
{
|
||||
@@ -300,9 +290,10 @@ void CCensorNode::AddItem(bool include, CItem &item)
|
||||
}
|
||||
const UString &front = item.PathParts.Front();
|
||||
|
||||
// We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name
|
||||
// if (item.Wildcard)
|
||||
if (DoesNameContainWildcard(front))
|
||||
// WIN32 doesn't support wildcards in file names
|
||||
if (item.WildcardMatching
|
||||
&& ignoreWildcardIndex != 0
|
||||
&& DoesNameContainWildcard(front))
|
||||
{
|
||||
AddItemSimple(include, item);
|
||||
return;
|
||||
@@ -311,7 +302,7 @@ void CCensorNode::AddItem(bool include, CItem &item)
|
||||
if (index < 0)
|
||||
index = SubNodes.Add(CCensorNode(front, this));
|
||||
item.PathParts.Delete(0);
|
||||
SubNodes[index].AddItem(include, item);
|
||||
SubNodes[index].AddItem(include, item, ignoreWildcardIndex - 1);
|
||||
}
|
||||
|
||||
void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching)
|
||||
@@ -377,6 +368,7 @@ bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, boo
|
||||
return finded;
|
||||
}
|
||||
|
||||
/*
|
||||
bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const
|
||||
{
|
||||
UStringVector pathParts;
|
||||
@@ -406,6 +398,7 @@ bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile)
|
||||
return include;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const
|
||||
{
|
||||
@@ -433,7 +426,7 @@ void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bo
|
||||
bool forFile = true;
|
||||
bool forFolder = true;
|
||||
UString path2 = path;
|
||||
if (IsCharDirLimiter(path.Back()))
|
||||
if (IsPathSepar(path.Back()))
|
||||
{
|
||||
path2.DeleteBack();
|
||||
forFile = false;
|
||||
@@ -462,12 +455,90 @@ int CCensor::FindPrefix(const UString &prefix) const
|
||||
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)
|
||||
{
|
||||
UStringVector pathParts;
|
||||
if (path.IsEmpty())
|
||||
throw "Empty file path";
|
||||
|
||||
UStringVector pathParts;
|
||||
SplitPathToParts(path, pathParts);
|
||||
|
||||
bool forFile = true;
|
||||
if (pathParts.Back().IsEmpty())
|
||||
{
|
||||
@@ -477,74 +548,55 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
|
||||
|
||||
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)
|
||||
{
|
||||
const UString &front = pathParts.Front();
|
||||
bool isAbs = false;
|
||||
|
||||
if (front.IsEmpty())
|
||||
isAbs = true;
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
if (IsDriveColonName(front))
|
||||
isAbs = true;
|
||||
else
|
||||
|
||||
#endif
|
||||
|
||||
FOR_VECTOR (i, pathParts)
|
||||
{
|
||||
const UString &part = pathParts[i];
|
||||
if (part == L".." || part == L".")
|
||||
{
|
||||
isAbs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned numAbsParts = 0;
|
||||
if (isAbs)
|
||||
if (pathParts.Size() > 1)
|
||||
numAbsParts = pathParts.Size() - 1;
|
||||
else
|
||||
numAbsParts = 1;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// \\?\ case
|
||||
if (numAbsParts >= 3)
|
||||
{
|
||||
if (pathParts[0].IsEmpty() &&
|
||||
pathParts[1].IsEmpty() &&
|
||||
pathParts[2] == L"?")
|
||||
{
|
||||
prefix =
|
||||
WSTRING_PATH_SEPARATOR
|
||||
WSTRING_PATH_SEPARATOR L"?"
|
||||
WSTRING_PATH_SEPARATOR;
|
||||
numAbsParts -= 3;
|
||||
pathParts.DeleteFrontal(3);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (numAbsParts > 1 && pathMode == k_FullPath)
|
||||
numAbsParts = 1;
|
||||
ignoreWildcardIndex = -1;
|
||||
|
||||
// We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name
|
||||
// if (wildcardMatching)
|
||||
for (unsigned i = 0; i < numAbsParts; i++)
|
||||
const 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();
|
||||
if (DoesNameContainWildcard(front))
|
||||
break;
|
||||
// WIN32 doesn't support wildcards in file names
|
||||
if (wildcardMatching)
|
||||
if (i >= numPrefixParts && DoesNameContainWildcard(front))
|
||||
break;
|
||||
prefix += front;
|
||||
prefix += WCHAR_PATH_SEPARATOR;
|
||||
prefix.Add_PathSepar();
|
||||
}
|
||||
pathParts.Delete(0);
|
||||
}
|
||||
@@ -554,15 +606,29 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
|
||||
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(L"*");
|
||||
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);
|
||||
Pairs[index].Head.AddItem(include, item, ignoreWildcardIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const
|
||||
{
|
||||
bool finded = false;
|
||||
@@ -578,6 +644,7 @@ bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) cons
|
||||
}
|
||||
return finded;
|
||||
}
|
||||
*/
|
||||
|
||||
void CCensor::ExtendExclude()
|
||||
{
|
||||
|
||||
@@ -12,15 +12,6 @@ int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW;
|
||||
|
||||
bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2);
|
||||
|
||||
inline bool IsCharDirLimiter(wchar_t c)
|
||||
{
|
||||
return c == WCHAR_PATH_SEPARATOR
|
||||
#ifdef _WIN32
|
||||
|| c == L'/'
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
void SplitPathToParts(const UString &path, UStringVector &pathParts);
|
||||
void SplitPathToParts_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)
|
||||
@@ -36,9 +27,9 @@ 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;
|
||||
@@ -66,12 +57,13 @@ class CCensorNode
|
||||
|
||||
bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const;
|
||||
void AddItemSimple(bool include, CItem &item);
|
||||
bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const;
|
||||
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; // wildcard is not allowed here
|
||||
UString Name; // WIN32 doesn't support wildcards in file names
|
||||
CObjectVector<CCensorNode> SubNodes;
|
||||
CObjectVector<CItem> IncludeItems;
|
||||
CObjectVector<CItem> ExcludeItems;
|
||||
@@ -80,15 +72,15 @@ public:
|
||||
|
||||
int FindSubNode(const UString &path) const;
|
||||
|
||||
void AddItem(bool include, CItem &item);
|
||||
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 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;
|
||||
@@ -136,7 +128,7 @@ public:
|
||||
{ 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;
|
||||
// bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
|
||||
void ExtendExclude();
|
||||
|
||||
void AddPathsToCensor(NWildcard::ECensorPathMode censorPathMode);
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "../Common/MyCom.h"
|
||||
|
||||
#include "../7zip/ICoder.h"
|
||||
#include "../7zip/Common/RegisterCodec.h"
|
||||
|
||||
class CXzCrc64Hasher:
|
||||
@@ -15,40 +14,29 @@ class CXzCrc64Hasher:
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt64 _crc;
|
||||
Byte mtDummy[1 << 7];
|
||||
|
||||
public:
|
||||
CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {}
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD_(void, Init)();
|
||||
STDMETHOD_(void, Update)(const void *data, UInt32 size);
|
||||
STDMETHOD_(void, Final)(Byte *digest);
|
||||
STDMETHOD_(UInt32, GetDigestSize)();
|
||||
INTERFACE_IHasher(;)
|
||||
};
|
||||
|
||||
STDMETHODIMP_(void) CXzCrc64Hasher::Init()
|
||||
STDMETHODIMP_(void) CXzCrc64Hasher::Init() throw()
|
||||
{
|
||||
_crc = CRC64_INIT_VAL;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CXzCrc64Hasher::Update(const void *data, UInt32 size)
|
||||
STDMETHODIMP_(void) CXzCrc64Hasher::Update(const void *data, UInt32 size) throw()
|
||||
{
|
||||
_crc = Crc64Update(_crc, data, size);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CXzCrc64Hasher::Final(Byte *digest)
|
||||
STDMETHODIMP_(void) CXzCrc64Hasher::Final(Byte *digest) throw()
|
||||
{
|
||||
UInt64 val = CRC64_GET_DIGEST(_crc);
|
||||
SetUi64(digest, val);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UInt32) CXzCrc64Hasher::GetDigestSize()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
static IHasher *CreateHasher() { return new CXzCrc64Hasher; }
|
||||
|
||||
static CHasherInfo g_HasherInfo = { CreateHasher, 0x4, L"CRC64", 8 };
|
||||
|
||||
REGISTER_HASHER(Crc64)
|
||||
REGISTER_HASHER(CXzCrc64Hasher, 0x4, "CRC64", 8)
|
||||
|
||||
Reference in New Issue
Block a user