ruby-lzma 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/README.markdown +15 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/ext/Alloc.cpp +118 -0
- data/ext/Alloc.h +29 -0
- data/ext/BinTree.h +55 -0
- data/ext/BinTree2.h +12 -0
- data/ext/BinTree3.h +16 -0
- data/ext/BinTree3Z.h +16 -0
- data/ext/BinTree4.h +18 -0
- data/ext/BinTree4b.h +20 -0
- data/ext/BinTreeMain.h +444 -0
- data/ext/BranchX86.c +101 -0
- data/ext/BranchX86.h +19 -0
- data/ext/CRC.cpp +61 -0
- data/ext/CRC.h +36 -0
- data/ext/C_FileIO.h +45 -0
- data/ext/CommandLineParser.h +82 -0
- data/ext/Defs.h +20 -0
- data/ext/FileStreams.h +98 -0
- data/ext/HC.h +55 -0
- data/ext/HC2.h +13 -0
- data/ext/HC3.h +17 -0
- data/ext/HC4.h +19 -0
- data/ext/HC4b.h +21 -0
- data/ext/HCMain.h +350 -0
- data/ext/ICoder.h +156 -0
- data/ext/IMatchFinder.h +63 -0
- data/ext/IStream.h +62 -0
- data/ext/InBuffer.cpp +80 -0
- data/ext/InBuffer.h +76 -0
- data/ext/LZInWindow.cpp +102 -0
- data/ext/LZInWindow.h +84 -0
- data/ext/LZMA.h +82 -0
- data/ext/LZMADecoder.h +248 -0
- data/ext/LZMAEncoder.cpp +1504 -0
- data/ext/LZMAEncoder.h +416 -0
- data/ext/LZOutWindow.cpp +17 -0
- data/ext/LZOutWindow.h +66 -0
- data/ext/LzmaBench.h +11 -0
- data/ext/LzmaDecode.c +588 -0
- data/ext/LzmaDecode.h +131 -0
- data/ext/LzmaRam.cpp +228 -0
- data/ext/LzmaRam.h +46 -0
- data/ext/LzmaRamDecode.c +79 -0
- data/ext/LzmaRamDecode.h +55 -0
- data/ext/MyCom.h +203 -0
- data/ext/MyGuidDef.h +54 -0
- data/ext/MyInitGuid.h +13 -0
- data/ext/MyString.h +631 -0
- data/ext/MyUnknown.h +24 -0
- data/ext/MyWindows.h +183 -0
- data/ext/OutBuffer.cpp +117 -0
- data/ext/OutBuffer.h +64 -0
- data/ext/Pat.h +318 -0
- data/ext/Pat2.h +22 -0
- data/ext/Pat2H.h +24 -0
- data/ext/Pat2R.h +20 -0
- data/ext/Pat3H.h +24 -0
- data/ext/Pat4H.h +24 -0
- data/ext/PatMain.h +989 -0
- data/ext/RangeCoder.h +205 -0
- data/ext/RangeCoderBit.cpp +80 -0
- data/ext/RangeCoderBit.h +120 -0
- data/ext/RangeCoderBitTree.h +161 -0
- data/ext/RangeCoderOpt.h +31 -0
- data/ext/StdAfx.h +8 -0
- data/ext/StreamUtils.cpp +44 -0
- data/ext/StreamUtils.h +11 -0
- data/ext/StringConvert.h +71 -0
- data/ext/StringToInt.h +17 -0
- data/ext/Types.h +19 -0
- data/ext/Vector.h +211 -0
- data/ext/extconf.rb +7 -0
- data/ext/lzma_ruby.cpp +51 -0
- data/ext/lzmalib.h +64 -0
- data/ext/mylib.cpp +81 -0
- data/java/SevenZip/CRC.java +52 -0
- data/java/SevenZip/Compression/LZ/BinTree.java +382 -0
- data/java/SevenZip/Compression/LZ/InWindow.java +131 -0
- data/java/SevenZip/Compression/LZ/OutWindow.java +85 -0
- data/java/SevenZip/Compression/LZMA/Base.java +88 -0
- data/java/SevenZip/Compression/LZMA/Decoder.java +329 -0
- data/java/SevenZip/Compression/LZMA/Encoder.java +1415 -0
- data/java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java +55 -0
- data/java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java +99 -0
- data/java/SevenZip/Compression/RangeCoder/Decoder.java +88 -0
- data/java/SevenZip/Compression/RangeCoder/Encoder.java +151 -0
- data/java/SevenZip/ICodeProgress.java +6 -0
- data/java/SevenZip/LzmaAlone.java +253 -0
- data/java/SevenZip/LzmaBench.java +391 -0
- data/java/com/ephemeronindustries/lzma/LZMA.java +104 -0
- data/lib/lzma.rb +32 -0
- data/ruby-lzma.gemspec +136 -0
- data/test/test_lzma.rb +42 -0
- metadata +157 -0
data/ext/LzmaRamDecode.h
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
/* LzmaRamDecode.h */
|
2
|
+
|
3
|
+
#ifndef __LzmaRamDecode_h
|
4
|
+
#define __LzmaRamDecode_h
|
5
|
+
|
6
|
+
#include <stdlib.h>
|
7
|
+
|
8
|
+
/*
|
9
|
+
LzmaRamGetUncompressedSize:
|
10
|
+
In:
|
11
|
+
inBuffer - input data
|
12
|
+
inSize - input data size
|
13
|
+
Out:
|
14
|
+
outSize - uncompressed size
|
15
|
+
Return code:
|
16
|
+
0 - OK
|
17
|
+
1 - Error in headers
|
18
|
+
*/
|
19
|
+
|
20
|
+
int LzmaRamGetUncompressedSize(
|
21
|
+
const unsigned char *inBuffer,
|
22
|
+
size_t inSize,
|
23
|
+
size_t *outSize);
|
24
|
+
|
25
|
+
|
26
|
+
/*
|
27
|
+
LzmaRamDecompress:
|
28
|
+
In:
|
29
|
+
inBuffer - input data
|
30
|
+
inSize - input data size
|
31
|
+
outBuffer - output data
|
32
|
+
outSize - output size
|
33
|
+
allocFunc - alloc function (can be malloc)
|
34
|
+
freeFunc - free function (can be free)
|
35
|
+
Out:
|
36
|
+
outSizeProcessed - processed size
|
37
|
+
Return code:
|
38
|
+
0 - OK
|
39
|
+
1 - Error in headers / data stream
|
40
|
+
2 - Memory allocating error
|
41
|
+
|
42
|
+
Memory requirements depend from properties of LZMA stream.
|
43
|
+
With default lzma settings it's about 16 KB.
|
44
|
+
*/
|
45
|
+
|
46
|
+
int LzmaRamDecompress(
|
47
|
+
const unsigned char *inBuffer,
|
48
|
+
size_t inSize,
|
49
|
+
unsigned char *outBuffer,
|
50
|
+
size_t outSize,
|
51
|
+
size_t *outSizeProcessed,
|
52
|
+
void * (*allocFunc)(size_t size),
|
53
|
+
void (*freeFunc)(void *));
|
54
|
+
|
55
|
+
#endif
|
data/ext/MyCom.h
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
// MyCom.h
|
2
|
+
|
3
|
+
#ifndef __MYCOM_H
|
4
|
+
#define __MYCOM_H
|
5
|
+
|
6
|
+
#include "MyWindows.h"
|
7
|
+
|
8
|
+
#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
|
9
|
+
|
10
|
+
template <class T>
|
11
|
+
class CMyComPtr
|
12
|
+
{
|
13
|
+
T* _p;
|
14
|
+
public:
|
15
|
+
// typedef T _PtrClass;
|
16
|
+
CMyComPtr() { _p = NULL;}
|
17
|
+
CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
|
18
|
+
CMyComPtr(const CMyComPtr<T>& lp)
|
19
|
+
{
|
20
|
+
if ((_p = lp._p) != NULL)
|
21
|
+
_p->AddRef();
|
22
|
+
}
|
23
|
+
~CMyComPtr() { if (_p) _p->Release(); }
|
24
|
+
void Release() { if (_p) { _p->Release(); _p = NULL; } }
|
25
|
+
operator T*() const { return (T*)_p; }
|
26
|
+
// T& operator*() const { return *_p; }
|
27
|
+
T** operator&() { return &_p; }
|
28
|
+
T* operator->() const { return _p; }
|
29
|
+
T* operator=(T* p)
|
30
|
+
{
|
31
|
+
if (p != 0)
|
32
|
+
p->AddRef();
|
33
|
+
if (_p)
|
34
|
+
_p->Release();
|
35
|
+
_p = p;
|
36
|
+
return p;
|
37
|
+
}
|
38
|
+
T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
|
39
|
+
bool operator!() const { return (_p == NULL); }
|
40
|
+
// bool operator==(T* pT) const { return _p == pT; }
|
41
|
+
// Compare two objects for equivalence
|
42
|
+
void Attach(T* p2)
|
43
|
+
{
|
44
|
+
Release();
|
45
|
+
_p = p2;
|
46
|
+
}
|
47
|
+
T* Detach()
|
48
|
+
{
|
49
|
+
T* pt = _p;
|
50
|
+
_p = NULL;
|
51
|
+
return pt;
|
52
|
+
}
|
53
|
+
#ifdef _WIN32
|
54
|
+
HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
|
55
|
+
{
|
56
|
+
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
|
57
|
+
}
|
58
|
+
#endif
|
59
|
+
/*
|
60
|
+
HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
|
61
|
+
{
|
62
|
+
CLSID clsid;
|
63
|
+
HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
|
64
|
+
ATLASSERT(_p == NULL);
|
65
|
+
if (SUCCEEDED(hr))
|
66
|
+
hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
|
67
|
+
return hr;
|
68
|
+
}
|
69
|
+
*/
|
70
|
+
template <class Q>
|
71
|
+
HRESULT QueryInterface(REFGUID iid, Q** pp) const
|
72
|
+
{
|
73
|
+
return _p->QueryInterface(iid, (void**)pp);
|
74
|
+
}
|
75
|
+
};
|
76
|
+
|
77
|
+
//////////////////////////////////////////////////////////
|
78
|
+
|
79
|
+
class CMyComBSTR
|
80
|
+
{
|
81
|
+
public:
|
82
|
+
BSTR m_str;
|
83
|
+
CMyComBSTR() { m_str = NULL; }
|
84
|
+
CMyComBSTR(LPCOLESTR pSrc) { m_str = ::SysAllocString(pSrc); }
|
85
|
+
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
|
86
|
+
// CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
|
87
|
+
CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
|
88
|
+
/*
|
89
|
+
CMyComBSTR(REFGUID src)
|
90
|
+
{
|
91
|
+
LPOLESTR szGuid;
|
92
|
+
StringFromCLSID(src, &szGuid);
|
93
|
+
m_str = ::SysAllocString(szGuid);
|
94
|
+
CoTaskMemFree(szGuid);
|
95
|
+
}
|
96
|
+
*/
|
97
|
+
~CMyComBSTR() { ::SysFreeString(m_str); }
|
98
|
+
CMyComBSTR& operator=(const CMyComBSTR& src)
|
99
|
+
{
|
100
|
+
if (m_str != src.m_str)
|
101
|
+
{
|
102
|
+
if (m_str)
|
103
|
+
::SysFreeString(m_str);
|
104
|
+
m_str = src.MyCopy();
|
105
|
+
}
|
106
|
+
return *this;
|
107
|
+
}
|
108
|
+
CMyComBSTR& operator=(LPCOLESTR pSrc)
|
109
|
+
{
|
110
|
+
::SysFreeString(m_str);
|
111
|
+
m_str = ::SysAllocString(pSrc);
|
112
|
+
return *this;
|
113
|
+
}
|
114
|
+
unsigned int Length() const { return ::SysStringLen(m_str); }
|
115
|
+
operator BSTR() const { return m_str; }
|
116
|
+
BSTR* operator&() { return &m_str; }
|
117
|
+
BSTR MyCopy() const
|
118
|
+
{
|
119
|
+
int byteLen = ::SysStringByteLen(m_str);
|
120
|
+
BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
|
121
|
+
memmove(res, m_str, byteLen);
|
122
|
+
return res;
|
123
|
+
}
|
124
|
+
void Attach(BSTR src) { m_str = src; }
|
125
|
+
BSTR Detach()
|
126
|
+
{
|
127
|
+
BSTR s = m_str;
|
128
|
+
m_str = NULL;
|
129
|
+
return s;
|
130
|
+
}
|
131
|
+
void Empty()
|
132
|
+
{
|
133
|
+
::SysFreeString(m_str);
|
134
|
+
m_str = NULL;
|
135
|
+
}
|
136
|
+
bool operator!() const { return (m_str == NULL); }
|
137
|
+
};
|
138
|
+
|
139
|
+
|
140
|
+
//////////////////////////////////////////////////////////
|
141
|
+
|
142
|
+
class CMyUnknownImp
|
143
|
+
{
|
144
|
+
public:
|
145
|
+
ULONG __m_RefCount;
|
146
|
+
CMyUnknownImp(): __m_RefCount(0) {}
|
147
|
+
};
|
148
|
+
|
149
|
+
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
|
150
|
+
(REFGUID iid, void **outObject) {
|
151
|
+
|
152
|
+
#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
|
153
|
+
{ *outObject = (void *)(i *)this; AddRef(); return S_OK; }
|
154
|
+
|
155
|
+
#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
|
156
|
+
|
157
|
+
#define MY_ADDREF_RELEASE \
|
158
|
+
STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
|
159
|
+
STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
|
160
|
+
return __m_RefCount; delete this; return 0; }
|
161
|
+
|
162
|
+
#define MY_UNKNOWN_IMP_SPEC(i) \
|
163
|
+
MY_QUERYINTERFACE_BEGIN \
|
164
|
+
i \
|
165
|
+
MY_QUERYINTERFACE_END \
|
166
|
+
MY_ADDREF_RELEASE
|
167
|
+
|
168
|
+
|
169
|
+
#define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \
|
170
|
+
MY_QUERYINTERFACE_END \
|
171
|
+
MY_ADDREF_RELEASE
|
172
|
+
|
173
|
+
#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
|
174
|
+
MY_QUERYINTERFACE_ENTRY(i) \
|
175
|
+
)
|
176
|
+
|
177
|
+
#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
|
178
|
+
MY_QUERYINTERFACE_ENTRY(i1) \
|
179
|
+
MY_QUERYINTERFACE_ENTRY(i2) \
|
180
|
+
)
|
181
|
+
|
182
|
+
#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
|
183
|
+
MY_QUERYINTERFACE_ENTRY(i1) \
|
184
|
+
MY_QUERYINTERFACE_ENTRY(i2) \
|
185
|
+
MY_QUERYINTERFACE_ENTRY(i3) \
|
186
|
+
)
|
187
|
+
|
188
|
+
#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
|
189
|
+
MY_QUERYINTERFACE_ENTRY(i1) \
|
190
|
+
MY_QUERYINTERFACE_ENTRY(i2) \
|
191
|
+
MY_QUERYINTERFACE_ENTRY(i3) \
|
192
|
+
MY_QUERYINTERFACE_ENTRY(i4) \
|
193
|
+
)
|
194
|
+
|
195
|
+
#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
|
196
|
+
MY_QUERYINTERFACE_ENTRY(i1) \
|
197
|
+
MY_QUERYINTERFACE_ENTRY(i2) \
|
198
|
+
MY_QUERYINTERFACE_ENTRY(i3) \
|
199
|
+
MY_QUERYINTERFACE_ENTRY(i4) \
|
200
|
+
MY_QUERYINTERFACE_ENTRY(i5) \
|
201
|
+
)
|
202
|
+
|
203
|
+
#endif
|
data/ext/MyGuidDef.h
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
// Common/MyGuidDef.h
|
2
|
+
|
3
|
+
#ifndef GUID_DEFINED
|
4
|
+
#define GUID_DEFINED
|
5
|
+
|
6
|
+
#include "Types.h"
|
7
|
+
|
8
|
+
typedef struct {
|
9
|
+
UInt32 Data1;
|
10
|
+
UInt16 Data2;
|
11
|
+
UInt16 Data3;
|
12
|
+
unsigned char Data4[8];
|
13
|
+
} GUID;
|
14
|
+
|
15
|
+
#ifdef __cplusplus
|
16
|
+
#define REFGUID const GUID &
|
17
|
+
#else
|
18
|
+
#define REFGUID const GUID *
|
19
|
+
#endif
|
20
|
+
|
21
|
+
#define REFCLSID REFGUID
|
22
|
+
#define REFIID REFGUID
|
23
|
+
|
24
|
+
#ifdef __cplusplus
|
25
|
+
inline bool operator==(REFGUID g1, REFGUID g2)
|
26
|
+
{
|
27
|
+
for (int i = 0; i < (int)sizeof(g1); i++)
|
28
|
+
if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
|
29
|
+
return false;
|
30
|
+
return true;
|
31
|
+
}
|
32
|
+
inline bool operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
|
33
|
+
#endif
|
34
|
+
|
35
|
+
#ifdef __cplusplus
|
36
|
+
#define MY_EXTERN_C extern "C"
|
37
|
+
#else
|
38
|
+
#define MY_EXTERN_C extern
|
39
|
+
#endif
|
40
|
+
|
41
|
+
#endif // GUID_DEFINED
|
42
|
+
|
43
|
+
|
44
|
+
#ifdef DEFINE_GUID
|
45
|
+
#undef DEFINE_GUID
|
46
|
+
#endif
|
47
|
+
|
48
|
+
#ifdef INITGUID
|
49
|
+
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
50
|
+
MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
51
|
+
#else
|
52
|
+
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
53
|
+
MY_EXTERN_C const GUID name
|
54
|
+
#endif
|
data/ext/MyInitGuid.h
ADDED
data/ext/MyString.h
ADDED
@@ -0,0 +1,631 @@
|
|
1
|
+
// Common/MyString.h
|
2
|
+
|
3
|
+
#ifndef __COMMON_STRING_H
|
4
|
+
#define __COMMON_STRING_H
|
5
|
+
|
6
|
+
#include <string.h>
|
7
|
+
// #include <wchar.h>
|
8
|
+
|
9
|
+
#include "Vector.h"
|
10
|
+
|
11
|
+
#ifdef _WIN32
|
12
|
+
#include "MyWindows.h"
|
13
|
+
#endif
|
14
|
+
|
15
|
+
static const char *kTrimDefaultCharSet = " \n\t";
|
16
|
+
|
17
|
+
template <class T>
|
18
|
+
inline int MyStringLen(const T *s)
|
19
|
+
{
|
20
|
+
int i;
|
21
|
+
for (i = 0; s[i] != '\0'; i++);
|
22
|
+
return i;
|
23
|
+
}
|
24
|
+
|
25
|
+
template <class T>
|
26
|
+
inline T * MyStringCopy(T *dest, const T *src)
|
27
|
+
{
|
28
|
+
T *destStart = dest;
|
29
|
+
while((*dest++ = *src++) != 0);
|
30
|
+
return destStart;
|
31
|
+
}
|
32
|
+
|
33
|
+
inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
|
34
|
+
{ return (p + 1); }
|
35
|
+
inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
|
36
|
+
{ return (p + 1); }
|
37
|
+
inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
|
38
|
+
{ return (p - 1); }
|
39
|
+
inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
|
40
|
+
{ return (p - 1); }
|
41
|
+
|
42
|
+
#ifdef _WIN32
|
43
|
+
|
44
|
+
inline char* MyStringGetNextCharPointer(char *p)
|
45
|
+
{ return CharNextA(p); }
|
46
|
+
inline const char* MyStringGetNextCharPointer(const char *p)
|
47
|
+
{ return CharNextA(p); }
|
48
|
+
|
49
|
+
inline char* MyStringGetPrevCharPointer(char *base, char *p)
|
50
|
+
{ return CharPrevA(base, p); }
|
51
|
+
inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
|
52
|
+
{ return CharPrevA(base, p); }
|
53
|
+
|
54
|
+
inline char MyCharUpper(char c)
|
55
|
+
{ return (char)(unsigned int)CharUpperA((LPSTR)(unsigned int)(unsigned char)c); }
|
56
|
+
#ifdef _UNICODE
|
57
|
+
inline wchar_t MyCharUpper(wchar_t c)
|
58
|
+
{ return (wchar_t)CharUpperW((LPWSTR)c); }
|
59
|
+
#else
|
60
|
+
wchar_t MyCharUpper(wchar_t c);
|
61
|
+
#endif
|
62
|
+
|
63
|
+
inline char MyCharLower(char c)
|
64
|
+
{ return (char)(unsigned int)CharLowerA((LPSTR)(unsigned int)(unsigned char)c); }
|
65
|
+
#ifdef _UNICODE
|
66
|
+
inline wchar_t MyCharLower(wchar_t c)
|
67
|
+
{ return (wchar_t)CharLowerW((LPWSTR)c); }
|
68
|
+
#else
|
69
|
+
wchar_t MyCharLower(wchar_t c);
|
70
|
+
#endif
|
71
|
+
|
72
|
+
inline char * MyStringUpper(char *s) { return CharUpperA(s); }
|
73
|
+
#ifdef _UNICODE
|
74
|
+
inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
|
75
|
+
#else
|
76
|
+
wchar_t * MyStringUpper(wchar_t *s);
|
77
|
+
#endif
|
78
|
+
|
79
|
+
inline char * MyStringLower(char *s) { return CharLowerA(s); }
|
80
|
+
#ifdef _UNICODE
|
81
|
+
inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
|
82
|
+
#else
|
83
|
+
wchar_t * MyStringLower(wchar_t *s);
|
84
|
+
#endif
|
85
|
+
|
86
|
+
#else // Standard-C
|
87
|
+
wchar_t MyCharUpper(wchar_t c);
|
88
|
+
#endif
|
89
|
+
|
90
|
+
//////////////////////////////////////
|
91
|
+
// Compare
|
92
|
+
|
93
|
+
/*
|
94
|
+
#ifndef _WIN32_WCE
|
95
|
+
int MyStringCollate(const char *s1, const char *s2);
|
96
|
+
int MyStringCollateNoCase(const char *s1, const char *s2);
|
97
|
+
#endif
|
98
|
+
int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
|
99
|
+
int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
|
100
|
+
*/
|
101
|
+
|
102
|
+
int MyStringCompare(const char *s1, const char *s2);
|
103
|
+
int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
|
104
|
+
|
105
|
+
#ifdef _WIN32
|
106
|
+
int MyStringCompareNoCase(const char *s1, const char *s2);
|
107
|
+
#endif
|
108
|
+
|
109
|
+
int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
|
110
|
+
|
111
|
+
template <class T>
|
112
|
+
class CStringBase
|
113
|
+
{
|
114
|
+
void TrimLeftWithCharSet(const CStringBase &charSet)
|
115
|
+
{
|
116
|
+
const T *p = _chars;
|
117
|
+
while (charSet.Find(*p) >= 0 && (*p != 0))
|
118
|
+
p = GetNextCharPointer(p);
|
119
|
+
Delete(0, (int)(p - _chars));
|
120
|
+
}
|
121
|
+
void TrimRightWithCharSet(const CStringBase &charSet)
|
122
|
+
{
|
123
|
+
const T *p = _chars;
|
124
|
+
const T *pLast = NULL;
|
125
|
+
while (*p != 0)
|
126
|
+
{
|
127
|
+
if (charSet.Find(*p) >= 0)
|
128
|
+
{
|
129
|
+
if (pLast == NULL)
|
130
|
+
pLast = p;
|
131
|
+
}
|
132
|
+
else
|
133
|
+
pLast = NULL;
|
134
|
+
p = GetNextCharPointer(p);
|
135
|
+
}
|
136
|
+
if(pLast != NULL)
|
137
|
+
{
|
138
|
+
int i = (int)(pLast - _chars);
|
139
|
+
Delete(i, _length - i);
|
140
|
+
}
|
141
|
+
|
142
|
+
}
|
143
|
+
void MoveItems(int destIndex, int srcIndex)
|
144
|
+
{
|
145
|
+
memmove(_chars + destIndex, _chars + srcIndex,
|
146
|
+
sizeof(T) * (_length - srcIndex + 1));
|
147
|
+
}
|
148
|
+
|
149
|
+
void InsertSpace(int &index, int size)
|
150
|
+
{
|
151
|
+
CorrectIndex(index);
|
152
|
+
GrowLength(size);
|
153
|
+
MoveItems(index + size, index);
|
154
|
+
}
|
155
|
+
|
156
|
+
static T *GetNextCharPointer(T *p)
|
157
|
+
{ return MyStringGetNextCharPointer(p); }
|
158
|
+
static const T *GetNextCharPointer(const T *p)
|
159
|
+
{ return MyStringGetNextCharPointer(p); }
|
160
|
+
static T *GetPrevCharPointer(T *base, T *p)
|
161
|
+
{ return MyStringGetPrevCharPointer(base, p); }
|
162
|
+
static const T *GetPrevCharPointer(const T *base, const T *p)
|
163
|
+
{ return MyStringGetPrevCharPointer(base, p); }
|
164
|
+
protected:
|
165
|
+
T *_chars;
|
166
|
+
int _length;
|
167
|
+
int _capacity;
|
168
|
+
|
169
|
+
void SetCapacity(int newCapacity)
|
170
|
+
{
|
171
|
+
int realCapacity = newCapacity + 1;
|
172
|
+
if(realCapacity == _capacity)
|
173
|
+
return;
|
174
|
+
/*
|
175
|
+
const int kMaxStringSize = 0x20000000;
|
176
|
+
#ifndef _WIN32_WCE
|
177
|
+
if(newCapacity > kMaxStringSize || newCapacity < _length)
|
178
|
+
throw 1052337;
|
179
|
+
#endif
|
180
|
+
*/
|
181
|
+
T *newBuffer = new T[realCapacity];
|
182
|
+
if(_capacity > 0)
|
183
|
+
{
|
184
|
+
for (int i = 0; i < (_length + 1); i++)
|
185
|
+
newBuffer[i] = _chars[i];
|
186
|
+
delete []_chars;
|
187
|
+
_chars = newBuffer;
|
188
|
+
}
|
189
|
+
else
|
190
|
+
{
|
191
|
+
_chars = newBuffer;
|
192
|
+
_chars[0] = 0;
|
193
|
+
}
|
194
|
+
_capacity = realCapacity;
|
195
|
+
}
|
196
|
+
|
197
|
+
void GrowLength(int n)
|
198
|
+
{
|
199
|
+
int freeSize = _capacity - _length - 1;
|
200
|
+
if (n <= freeSize)
|
201
|
+
return;
|
202
|
+
int delta;
|
203
|
+
if (_capacity > 64)
|
204
|
+
delta = _capacity / 2;
|
205
|
+
else if (_capacity > 8)
|
206
|
+
delta = 16;
|
207
|
+
else
|
208
|
+
delta = 4;
|
209
|
+
if (freeSize + delta < n)
|
210
|
+
delta = n - freeSize;
|
211
|
+
SetCapacity(_capacity + delta);
|
212
|
+
}
|
213
|
+
|
214
|
+
void CorrectIndex(int &index) const
|
215
|
+
{
|
216
|
+
if (index > _length)
|
217
|
+
index = _length;
|
218
|
+
}
|
219
|
+
|
220
|
+
public:
|
221
|
+
CStringBase(): _chars(0), _length(0), _capacity(0)
|
222
|
+
{ SetCapacity(16 - 1); }
|
223
|
+
CStringBase(T c): _chars(0), _length(0), _capacity(0)
|
224
|
+
{
|
225
|
+
SetCapacity(1);
|
226
|
+
_chars[0] = c;
|
227
|
+
_chars[1] = 0;
|
228
|
+
_length = 1;
|
229
|
+
}
|
230
|
+
CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
|
231
|
+
{
|
232
|
+
int length = MyStringLen(chars);
|
233
|
+
SetCapacity(length);
|
234
|
+
MyStringCopy(_chars, chars); // can be optimized by memove()
|
235
|
+
_length = length;
|
236
|
+
}
|
237
|
+
CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0)
|
238
|
+
{
|
239
|
+
SetCapacity(s._length);
|
240
|
+
MyStringCopy(_chars, s._chars);
|
241
|
+
_length = s._length;
|
242
|
+
}
|
243
|
+
~CStringBase() { delete []_chars; }
|
244
|
+
|
245
|
+
operator const T*() const { return _chars;}
|
246
|
+
|
247
|
+
// The minimum size of the character buffer in characters.
|
248
|
+
// This value does not include space for a null terminator.
|
249
|
+
T* GetBuffer(int minBufLength)
|
250
|
+
{
|
251
|
+
if(minBufLength >= _capacity)
|
252
|
+
SetCapacity(minBufLength + 1);
|
253
|
+
return _chars;
|
254
|
+
}
|
255
|
+
void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
|
256
|
+
void ReleaseBuffer(int newLength)
|
257
|
+
{
|
258
|
+
/*
|
259
|
+
#ifndef _WIN32_WCE
|
260
|
+
if(newLength >= _capacity)
|
261
|
+
throw 282217;
|
262
|
+
#endif
|
263
|
+
*/
|
264
|
+
_chars[newLength] = 0;
|
265
|
+
_length = newLength;
|
266
|
+
}
|
267
|
+
|
268
|
+
CStringBase& operator=(T c)
|
269
|
+
{
|
270
|
+
Empty();
|
271
|
+
SetCapacity(1);
|
272
|
+
_chars[0] = c;
|
273
|
+
_chars[1] = 0;
|
274
|
+
_length = 1;
|
275
|
+
return *this;
|
276
|
+
}
|
277
|
+
CStringBase& operator=(const T *chars)
|
278
|
+
{
|
279
|
+
Empty();
|
280
|
+
int length = MyStringLen(chars);
|
281
|
+
SetCapacity(length);
|
282
|
+
MyStringCopy(_chars, chars);
|
283
|
+
_length = length;
|
284
|
+
return *this;
|
285
|
+
}
|
286
|
+
CStringBase& operator=(const CStringBase& s)
|
287
|
+
{
|
288
|
+
if(&s == this)
|
289
|
+
return *this;
|
290
|
+
Empty();
|
291
|
+
SetCapacity(s._length);
|
292
|
+
MyStringCopy(_chars, s._chars);
|
293
|
+
_length = s._length;
|
294
|
+
return *this;
|
295
|
+
}
|
296
|
+
|
297
|
+
CStringBase& operator+=(T c)
|
298
|
+
{
|
299
|
+
GrowLength(1);
|
300
|
+
_chars[_length] = c;
|
301
|
+
_chars[++_length] = 0;
|
302
|
+
return *this;
|
303
|
+
}
|
304
|
+
CStringBase& operator+=(const T *s)
|
305
|
+
{
|
306
|
+
int len = MyStringLen(s);
|
307
|
+
GrowLength(len);
|
308
|
+
MyStringCopy(_chars + _length, s);
|
309
|
+
_length += len;
|
310
|
+
return *this;
|
311
|
+
}
|
312
|
+
CStringBase& operator+=(const CStringBase &s)
|
313
|
+
{
|
314
|
+
GrowLength(s._length);
|
315
|
+
MyStringCopy(_chars + _length, s._chars);
|
316
|
+
_length += s._length;
|
317
|
+
return *this;
|
318
|
+
}
|
319
|
+
void Empty()
|
320
|
+
{
|
321
|
+
_length = 0;
|
322
|
+
_chars[0] = 0;
|
323
|
+
}
|
324
|
+
int Length() const { return _length; }
|
325
|
+
bool IsEmpty() const { return (_length == 0); }
|
326
|
+
|
327
|
+
CStringBase Mid(int startIndex) const
|
328
|
+
{ return Mid(startIndex, _length - startIndex); }
|
329
|
+
CStringBase Mid(int startIndex, int count ) const
|
330
|
+
{
|
331
|
+
if (startIndex + count > _length)
|
332
|
+
count = _length - startIndex;
|
333
|
+
|
334
|
+
if (startIndex == 0 && startIndex + count == _length)
|
335
|
+
return *this;
|
336
|
+
|
337
|
+
CStringBase<T> result;
|
338
|
+
result.SetCapacity(count);
|
339
|
+
// MyStringNCopy(result._chars, _chars + startIndex, count);
|
340
|
+
for (int i = 0; i < count; i++)
|
341
|
+
result._chars[i] = _chars[startIndex + i];
|
342
|
+
result._chars[count] = 0;
|
343
|
+
result._length = count;
|
344
|
+
return result;
|
345
|
+
}
|
346
|
+
CStringBase Left(int count) const
|
347
|
+
{ return Mid(0, count); }
|
348
|
+
CStringBase Right(int count) const
|
349
|
+
{
|
350
|
+
if (count > _length)
|
351
|
+
count = _length;
|
352
|
+
return Mid(_length - count, count);
|
353
|
+
}
|
354
|
+
|
355
|
+
void MakeUpper()
|
356
|
+
{ MyStringUpper(_chars); }
|
357
|
+
void MakeLower()
|
358
|
+
{ MyStringLower(_chars); }
|
359
|
+
|
360
|
+
int Compare(const CStringBase& s) const
|
361
|
+
{ return MyStringCompare(_chars, s._chars); }
|
362
|
+
|
363
|
+
int CompareNoCase(const CStringBase& s) const
|
364
|
+
{ return MyStringCompareNoCase(_chars, s._chars); }
|
365
|
+
/*
|
366
|
+
int Collate(const CStringBase& s) const
|
367
|
+
{ return MyStringCollate(_chars, s._chars); }
|
368
|
+
int CollateNoCase(const CStringBase& s) const
|
369
|
+
{ return MyStringCollateNoCase(_chars, s._chars); }
|
370
|
+
*/
|
371
|
+
|
372
|
+
int Find(T c) const { return Find(c, 0); }
|
373
|
+
int Find(T c, int startIndex) const
|
374
|
+
{
|
375
|
+
T *p = _chars + startIndex;
|
376
|
+
while (true)
|
377
|
+
{
|
378
|
+
if (*p == c)
|
379
|
+
return (int)(p - _chars);
|
380
|
+
if (*p == 0)
|
381
|
+
return -1;
|
382
|
+
p = GetNextCharPointer(p);
|
383
|
+
}
|
384
|
+
}
|
385
|
+
int Find(const CStringBase &s) const { return Find(s, 0); }
|
386
|
+
int Find(const CStringBase &s, int startIndex) const
|
387
|
+
{
|
388
|
+
if (s.IsEmpty())
|
389
|
+
return startIndex;
|
390
|
+
for (; startIndex < _length; startIndex++)
|
391
|
+
{
|
392
|
+
int j;
|
393
|
+
for (j = 0; j < s._length && startIndex + j < _length; j++)
|
394
|
+
if (_chars[startIndex+j] != s._chars[j])
|
395
|
+
break;
|
396
|
+
if (j == s._length)
|
397
|
+
return startIndex;
|
398
|
+
}
|
399
|
+
return -1;
|
400
|
+
}
|
401
|
+
int ReverseFind(T c) const
|
402
|
+
{
|
403
|
+
if (_length == 0)
|
404
|
+
return -1;
|
405
|
+
T *p = _chars + _length - 1;
|
406
|
+
while (true)
|
407
|
+
{
|
408
|
+
if (*p == c)
|
409
|
+
return (int)(p - _chars);
|
410
|
+
if (p == _chars)
|
411
|
+
return -1;
|
412
|
+
p = GetPrevCharPointer(_chars, p);
|
413
|
+
}
|
414
|
+
}
|
415
|
+
int FindOneOf(const CStringBase &s) const
|
416
|
+
{
|
417
|
+
for(int i = 0; i < _length; i++)
|
418
|
+
if (s.Find(_chars[i]) >= 0)
|
419
|
+
return i;
|
420
|
+
return -1;
|
421
|
+
}
|
422
|
+
|
423
|
+
void TrimLeft(T c)
|
424
|
+
{
|
425
|
+
const T *p = _chars;
|
426
|
+
while (c == *p)
|
427
|
+
p = GetNextCharPointer(p);
|
428
|
+
Delete(0, p - _chars);
|
429
|
+
}
|
430
|
+
private:
|
431
|
+
CStringBase GetTrimDefaultCharSet()
|
432
|
+
{
|
433
|
+
CStringBase<T> charSet;
|
434
|
+
for(int i = 0; i < (int)(sizeof(kTrimDefaultCharSet) /
|
435
|
+
sizeof(kTrimDefaultCharSet[0])); i++)
|
436
|
+
charSet += (T)kTrimDefaultCharSet[i];
|
437
|
+
return charSet;
|
438
|
+
}
|
439
|
+
public:
|
440
|
+
|
441
|
+
void TrimLeft()
|
442
|
+
{
|
443
|
+
TrimLeftWithCharSet(GetTrimDefaultCharSet());
|
444
|
+
}
|
445
|
+
void TrimRight()
|
446
|
+
{
|
447
|
+
TrimRightWithCharSet(GetTrimDefaultCharSet());
|
448
|
+
}
|
449
|
+
void TrimRight(T c)
|
450
|
+
{
|
451
|
+
const T *p = _chars;
|
452
|
+
const T *pLast = NULL;
|
453
|
+
while (*p != 0)
|
454
|
+
{
|
455
|
+
if (*p == c)
|
456
|
+
{
|
457
|
+
if (pLast == NULL)
|
458
|
+
pLast = p;
|
459
|
+
}
|
460
|
+
else
|
461
|
+
pLast = NULL;
|
462
|
+
p = GetNextCharPointer(p);
|
463
|
+
}
|
464
|
+
if(pLast != NULL)
|
465
|
+
{
|
466
|
+
int i = pLast - _chars;
|
467
|
+
Delete(i, _length - i);
|
468
|
+
}
|
469
|
+
}
|
470
|
+
void Trim()
|
471
|
+
{
|
472
|
+
TrimRight();
|
473
|
+
TrimLeft();
|
474
|
+
}
|
475
|
+
|
476
|
+
int Insert(int index, T c)
|
477
|
+
{
|
478
|
+
InsertSpace(index, 1);
|
479
|
+
_chars[index] = c;
|
480
|
+
_length++;
|
481
|
+
return _length;
|
482
|
+
}
|
483
|
+
int Insert(int index, const CStringBase &s)
|
484
|
+
{
|
485
|
+
CorrectIndex(index);
|
486
|
+
if (s.IsEmpty())
|
487
|
+
return _length;
|
488
|
+
int numInsertChars = s.Length();
|
489
|
+
InsertSpace(index, numInsertChars);
|
490
|
+
for(int i = 0; i < numInsertChars; i++)
|
491
|
+
_chars[index + i] = s[i];
|
492
|
+
_length += numInsertChars;
|
493
|
+
return _length;
|
494
|
+
}
|
495
|
+
|
496
|
+
// !!!!!!!!!!!!!!! test it if newChar = '\0'
|
497
|
+
int Replace(T oldChar, T newChar)
|
498
|
+
{
|
499
|
+
if (oldChar == newChar)
|
500
|
+
return 0;
|
501
|
+
int number = 0;
|
502
|
+
int pos = 0;
|
503
|
+
while (pos < Length())
|
504
|
+
{
|
505
|
+
pos = Find(oldChar, pos);
|
506
|
+
if (pos < 0)
|
507
|
+
break;
|
508
|
+
_chars[pos] = newChar;
|
509
|
+
pos++;
|
510
|
+
number++;
|
511
|
+
}
|
512
|
+
return number;
|
513
|
+
}
|
514
|
+
int Replace(const CStringBase &oldString, const CStringBase &newString)
|
515
|
+
{
|
516
|
+
if (oldString.IsEmpty())
|
517
|
+
return 0;
|
518
|
+
if (oldString == newString)
|
519
|
+
return 0;
|
520
|
+
int oldStringLength = oldString.Length();
|
521
|
+
int newStringLength = newString.Length();
|
522
|
+
int number = 0;
|
523
|
+
int pos = 0;
|
524
|
+
while (pos < _length)
|
525
|
+
{
|
526
|
+
pos = Find(oldString, pos);
|
527
|
+
if (pos < 0)
|
528
|
+
break;
|
529
|
+
Delete(pos, oldStringLength);
|
530
|
+
Insert(pos, newString);
|
531
|
+
pos += newStringLength;
|
532
|
+
number++;
|
533
|
+
}
|
534
|
+
return number;
|
535
|
+
}
|
536
|
+
int Delete(int index, int count = 1 )
|
537
|
+
{
|
538
|
+
if (index + count > _length)
|
539
|
+
count = _length - index;
|
540
|
+
if (count > 0)
|
541
|
+
{
|
542
|
+
MoveItems(index, index + count);
|
543
|
+
_length -= count;
|
544
|
+
}
|
545
|
+
return _length;
|
546
|
+
}
|
547
|
+
};
|
548
|
+
|
549
|
+
template <class T>
|
550
|
+
CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
|
551
|
+
{
|
552
|
+
CStringBase<T> result(s1);
|
553
|
+
result += s2;
|
554
|
+
return result;
|
555
|
+
}
|
556
|
+
|
557
|
+
template <class T>
|
558
|
+
CStringBase<T> operator+(const CStringBase<T>& s, T c)
|
559
|
+
{
|
560
|
+
CStringBase<T> result(s);
|
561
|
+
result += c;
|
562
|
+
return result;
|
563
|
+
}
|
564
|
+
|
565
|
+
template <class T>
|
566
|
+
CStringBase<T> operator+(T c, const CStringBase<T>& s)
|
567
|
+
{
|
568
|
+
CStringBase<T> result(c);
|
569
|
+
result += s;
|
570
|
+
return result;
|
571
|
+
}
|
572
|
+
|
573
|
+
template <class T>
|
574
|
+
CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
|
575
|
+
{
|
576
|
+
CStringBase<T> result(s);
|
577
|
+
result += chars;
|
578
|
+
return result;
|
579
|
+
}
|
580
|
+
|
581
|
+
template <class T>
|
582
|
+
CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
|
583
|
+
{
|
584
|
+
CStringBase<T> result(chars);
|
585
|
+
result += s;
|
586
|
+
return result;
|
587
|
+
}
|
588
|
+
|
589
|
+
template <class T>
|
590
|
+
bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
|
591
|
+
{ return (s1.Compare(s2) == 0); }
|
592
|
+
|
593
|
+
template <class T>
|
594
|
+
bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
|
595
|
+
{ return (s1.Compare(s2) < 0); }
|
596
|
+
|
597
|
+
template <class T>
|
598
|
+
bool operator==(const T *s1, const CStringBase<T>& s2)
|
599
|
+
{ return (s2.Compare(s1) == 0); }
|
600
|
+
|
601
|
+
template <class T>
|
602
|
+
bool operator==(const CStringBase<T>& s1, const T *s2)
|
603
|
+
{ return (s1.Compare(s2) == 0); }
|
604
|
+
|
605
|
+
template <class T>
|
606
|
+
bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
|
607
|
+
{ return (s1.Compare(s2) != 0); }
|
608
|
+
|
609
|
+
template <class T>
|
610
|
+
bool operator!=(const T *s1, const CStringBase<T>& s2)
|
611
|
+
{ return (s2.Compare(s1) != 0); }
|
612
|
+
|
613
|
+
template <class T>
|
614
|
+
bool operator!=(const CStringBase<T>& s1, const T *s2)
|
615
|
+
{ return (s1.Compare(s2) != 0); }
|
616
|
+
|
617
|
+
typedef CStringBase<char> AString;
|
618
|
+
typedef CStringBase<wchar_t> UString;
|
619
|
+
|
620
|
+
typedef CObjectVector<AString> AStringVector;
|
621
|
+
typedef CObjectVector<UString> UStringVector;
|
622
|
+
|
623
|
+
#ifdef _UNICODE
|
624
|
+
typedef UString CSysString;
|
625
|
+
#else
|
626
|
+
typedef AString CSysString;
|
627
|
+
#endif
|
628
|
+
|
629
|
+
typedef CObjectVector<CSysString> CSysStringVector;
|
630
|
+
|
631
|
+
#endif
|