-
Notifications
You must be signed in to change notification settings - Fork 23
/
STString.h
200 lines (168 loc) · 5.78 KB
/
STString.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/******************************************************************************
File: STString.h
Description:
VM representation of Smalltalk String class.
N.B. The representation of this class must NOT be changed.
******************************************************************************/
#pragma once
#include "VMPointers.h"
#include "STCollection.h"
// Turn off warning about zero length arrays
#pragma warning ( disable : 4200)
// Declare forward references
namespace ST
{
class String;
class AnsiString;
class Symbol;
class Utf32String;
class Utf16String;
class Utf8String;
};
typedef TOTE<ST::String> StringOTE;
typedef TOTE<ST::AnsiString> AnsiStringOTE;
typedef TOTE<ST::Utf8String> Utf8StringOTE;
typedef TOTE<ST::Utf16String> Utf16StringOTE;
typedef TOTE<ST::Utf32String> Utf32StringOTE;
typedef TOTE<ST::Symbol> SymbolOTE;
namespace ST
{
enum class StringEncoding
{
Ansi,
Utf8,
Utf16,
Utf32
};
class String : public ArrayedCollection
{
public:
template <typename T> static StringEncoding GetEncoding(T* ote)
{
ASSERT(ote->isNullTerminated());
auto strClass = reinterpret_cast<const StringClass*>(ote->m_oteClass->m_location);
return strClass->Encoding;
}
};
template <UINT CP, size_t I, class OTE, class TChar> class ByteStringT : public ArrayedCollection
{
public:
typedef TChar CU;
typedef const TChar * __restrict PCSZ;
static const UINT CodePage = CP;
static const size_t PointersIndex = I;
CU m_characters[1]; // Variable length array of data
typedef ByteStringT<CP, PointersIndex, OTE, TChar> MyType;
typedef OTE* POTE;
static POTE __fastcall New(size_t cch)
{
OTE* stringPointer = reinterpret_cast<OTE*>(ObjectMemory::newUninitializedNullTermObject<MyType>(cch));
ASSERT(stringPointer->isNullTerminated());
return stringPointer;
}
static POTE __fastcall New(LPCCH value, size_t cch)
{
OTE* stringPointer = reinterpret_cast<OTE*>(ObjectMemory::newUninitializedNullTermObject<MyType>(cch));
MyType* __restrict string = stringPointer->m_location;
string->m_characters[cch] = '\0';
memcpy(string->m_characters, value, cch);
ASSERT(stringPointer->isNullTerminated());
return stringPointer;
}
static POTE __fastcall New(LPCSTR sz)
{
size_t cch = strlen(sz);
OTE* stringPointer = reinterpret_cast<OTE*>(ObjectMemory::newUninitializedNullTermObject<MyType>(cch));
MyType* __restrict string = stringPointer->m_location;
// Copy the string and null terminator
memcpy(string->m_characters, sz, cch + sizeof(char));
ASSERT(stringPointer->isNullTerminated());
return stringPointer;
}
// Allocate a new String from a Unicode string
static POTE __fastcall New(LPCWSTR wsz)
{
int cch = ::WideCharToMultiByte(CP, 0, wsz, -1, nullptr, 0, nullptr, nullptr);
// Length includes null terminator since input is null terminated
OTE* stringPointer = reinterpret_cast<OTE*>(ObjectMemory::newUninitializedNullTermObject<MyType>((cch - 1)*sizeof(CU)));
CU* psz = stringPointer->m_location->m_characters;
int cch2 = ::WideCharToMultiByte(CP, 0, wsz, -1, reinterpret_cast<LPSTR>(psz), cch, nullptr, nullptr);
UNREFERENCED_PARAMETER(cch2);
ASSERT(cch2 == cch);
ASSERT(stringPointer->isNullTerminated());
return stringPointer;
}
static POTE __fastcall New(const char16_t* pwch, size_t cwch)
{
int cch = ::WideCharToMultiByte(CP, 0, (LPCWCH)pwch, cwch, nullptr, 0, nullptr, nullptr);
// Length does not include null terminator
OTE* stringPointer = reinterpret_cast<OTE*>(ObjectMemory::newUninitializedNullTermObject<MyType>(cch*sizeof(CU)));
CU* psz = stringPointer->m_location->m_characters;
psz[cch] = '\0';
int cch2 = ::WideCharToMultiByte(CP, 0, (LPCWCH)pwch, cwch, reinterpret_cast<LPSTR>(psz), cch, nullptr, nullptr);
UNREFERENCED_PARAMETER(cch2);
ASSERT(cch2 == cch);
ASSERT(stringPointer->isNullTerminated());
return stringPointer;
}
//static POTE NewLiteral(LPCSTR szValue)
//{
// size_t cch = strlen(szValue);
// if (cch > 0)
// {
// MyOTE* oteLiteral = NewWithLen(szValue, cch);
// oteLiteral->beImmutable();
// return oteLiteral;
// }
// else
// return Pointers.EmptyString;
//}
};
// Indexes into the VM's pointer array
const size_t ClassByteString = 84;
const size_t ClassUtf8String = 104;
const size_t ClassUtf16String = 93;
class Utf8String : public ByteStringT<CP_UTF8, ClassUtf8String, Utf8StringOTE, uint8_t>
{
public:
static POTE __fastcall NewFromAnsi(const char* pChars, size_t len);
static POTE __fastcall NewFromBSTR(BSTR bs)
{
return bs == nullptr ? New("", 0) : New(reinterpret_cast<LPCWSTR>(bs));
}
};
class AnsiString : public ByteStringT<CP_ACP, ClassByteString, AnsiStringOTE, char>
{
public:
static POTE __fastcall NewFromUtf8(const Utf8String::CU* pChars, size_t len);
};
class Symbol : public ArrayedCollection // Really a subclass of Utf8String
{
public:
Utf8String::CU m_characters[];
};
class Utf16String : public ArrayedCollection // Actually a string subclass
{
public:
typedef char16_t CU;
static const size_t PointersIndex = ClassUtf16String;
CU m_characters[];
static Utf16StringOTE* __fastcall New(LPCWSTR wsz);
static Utf16StringOTE* __fastcall New(const WCHAR* pChars, size_t len);
template <UINT CP, class T> static Utf16StringOTE* __fastcall New(const T* pChars, size_t len);
static Utf16StringOTE* __fastcall New(OTE* oteByteString);
static Utf16StringOTE* __fastcall New(size_t cwch);
static Utf16StringOTE * ST::Utf16String::NewFromBSTR(BSTR bs)
{
return New(bs, ::SysStringLen(bs));
}
};
class Utf32String : public ArrayedCollection // Actually a string subclass
{
public:
typedef char32_t CU;
CU m_characters[];
};
}
std::wostream& operator<<(std::wostream& st, const AnsiStringOTE*);
std::wostream& operator<<(std::wostream& st, const SymbolOTE*);