This commit is contained in:
Igor Pavlov
2015-06-15 00:00:00 +00:00
committed by Kornel Lesiński
parent 0713a3ab80
commit 54490d51d5
591 changed files with 34932 additions and 16390 deletions

View File

@@ -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:";

View File

@@ -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)

View File

@@ -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();
};

View File

@@ -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; }

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}
// ----------------------------------------
/*

View File

@@ -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;

View File

@@ -27,4 +27,9 @@ struct CBoolPair
}
};
#define CLASS_NO_COPY(cls) \
private: \
cls(const cls &); \
cls &operator=(const cls &);
#endif

View File

@@ -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);

View File

@@ -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
View 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)

View File

@@ -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)

View File

@@ -39,7 +39,7 @@ public:
CStdOutStream & operator<<(char c) throw()
{
fputc(c, _stream);
fputc((unsigned char)c, _stream);
return *this;
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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');

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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()
{

View File

@@ -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);

View File

@@ -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)