]>
Dogcows Code - chaz/yoink/blob - src/moof/string.cc
2 /*] Copyright (c) 2009-2011, Charles McGarvey [*****************************
3 **] All rights reserved.
5 * Distributable under the terms and conditions of the 2-clause BSD license;
6 * see the file COPYING for a complete text of the license.
8 *****************************************************************************/
12 #include <boost/shared_array.hpp>
14 #include "ConvertUTF.h"
22 wstring
multi_to_wide(const string
& multi
)
24 typedef boost::shared_array
<wchar_t> buffer
;
26 if (sizeof(wchar_t) == 2)
28 size_t length
= multi
.length();
29 buffer
wide(new wchar_t[length
+ 1]);
30 const UTF8
* src1
= (const UTF8
*)multi
.c_str();
31 const UTF8
* src2
= src1
+ length
;
32 UTF16
* dst1
= (UTF16
*)wide
.get();
33 UTF16
* dst2
= dst1
+ length
+ 1;
35 if (ConvertUTF8toUTF16(&src1
, src2
,
37 lenientConversion
) != conversionOK
)
38 throw std::runtime_error("bad string conversion");
41 wstring
str(wide
.get());
44 else if (sizeof(wchar_t) == 4)
46 size_t length
= multi
.length();
47 buffer
wide(new wchar_t[length
+ 1]);
48 const UTF8
* src1
= (const UTF8
*)multi
.c_str();
49 const UTF8
* src2
= src1
+ length
;
50 UTF32
* dst1
= (UTF32
*)wide
.get();
51 UTF32
* dst2
= dst1
+ length
+ 1;
53 if (ConvertUTF8toUTF32(&src1
, src2
,
55 lenientConversion
) != conversionOK
)
56 throw std::runtime_error("bad string conversion");
59 wstring
str(wide
.get());
64 throw std::runtime_error("unknown size of wide characters");
68 string
wide_to_multi(const wstring
& wide
)
70 typedef boost::shared_array
<char> buffer
;
72 if (sizeof(wchar_t) == 2)
74 size_t length
= wide
.length();
75 size_t multi_length
= 3 * length
+ 1;
76 buffer
multi(new char[multi_length
]);
77 const UTF16
* src1
= (const UTF16
*)wide
.c_str();
78 const UTF16
* src2
= src1
+ length
;
79 UTF8
* dst1
= (UTF8
*)multi
.get();
80 UTF8
* dst2
= dst1
+ multi_length
;
82 if (ConvertUTF16toUTF8(&src1
, src2
,
84 lenientConversion
) != conversionOK
)
85 throw std::runtime_error("bad string conversion");
88 string
str(multi
.get());
91 else if (sizeof(wchar_t) == 4)
93 size_t length
= wide
.length();
94 size_t multi_length
= 4 * length
+ 1;
95 buffer
multi(new char[multi_length
]);
96 const UTF32
* src1
= (const UTF32
*)wide
.c_str();
97 const UTF32
* src2
= src1
+ length
;
98 UTF8
* dst1
= (UTF8
*)multi
.get();
99 UTF8
* dst2
= dst1
+ multi_length
;
101 if (ConvertUTF32toUTF8(&src1
, src2
,
103 lenientConversion
) != conversionOK
)
104 throw std::runtime_error("bad string conversion");
107 string
str(multi
.get());
112 throw std::runtime_error("unknown size of wide characters");
117 static script
& pattern_script()
119 static script script
;
120 static bool init
= true;
123 script
.import_string_library();
124 script
.globals().push_field("string").push_field("match");
125 script
.globals().set_field("match");
126 script
.top().push_field("gmatch");
127 script
.globals().set_field("gmatch");
128 script
.top().push_field("gsub");
129 script
.globals().set_field("gsub");
131 script
.globals().set_field("string");
138 pattern::pattern(const std::string
& pattern
)
140 pattern::string(pattern
);
143 pattern::pattern(const std::string
& pattern
, const std::string
& source
)
145 pattern::string(pattern
);
151 script
& script
= pattern_script();
152 script
.push_pointer(this);
154 script
.globals().set_field();
155 script
.push_pointer(this);
157 script
.registry().set_field();
160 std::string
pattern::string() const
162 script
& script
= pattern_script();
163 script
.push_pointer(this);
164 script::slot saved
= script
.registry().push_field();
173 void pattern::string(const std::string
& pattern
)
175 script
& script
= pattern_script();
176 script
.push_pointer(this);
177 script
.push(pattern
);
178 script
.registry().set_field();
181 void pattern::match(const std::string
& source
)
183 script
& script
= pattern_script();
184 script
.push_pointer(this);
186 script
.globals().push_field("gmatch");
188 script
.push_pointer(this);
189 script
.registry().push_field();
192 script
.globals().set_field();
195 bool pattern::get(std::string
& match
)
197 script
& script
= pattern_script();
198 script
.push_pointer(this);
199 script::slot value
= script
.globals().push_field();
200 if (!value
.is_function())
202 script
.clear_stack();
207 bool result
= value
.get(match
);
212 bool pattern::get(std::vector
<std::string
>& captures
)
214 script
& script
= pattern_script();
215 script
.push_pointer(this);
216 script::slot value
= script
.globals().push_field();
217 if (!value
.is_function())
219 script
.clear_stack();
226 while (value
.is_string())
228 captures
.resize(captures
.size() + 1);
229 value
.get(captures
.back());
233 script
.clear_stack();
234 return 0 < captures
.size();
237 bool pattern::match(std::string
& match
,
238 const std::string
& pattern
, const std::string
& source
, int position
)
240 script
& script
= pattern_script();
241 script::slot value
= script
.globals().push_field("match");
243 script
.push(pattern
);
244 ++position
; // lua indices count from one
245 script
.push(position
);
248 bool result
= value
.get(match
);
249 script
.clear_stack();
253 bool pattern::match(std::vector
<std::string
>& captures
,
254 const std::string
& pattern
, const std::string
& source
, int position
)
256 script
& script
= pattern_script();
257 script::slot value
= script
.globals().push_field("match");
259 script
.push(pattern
);
260 ++position
; // lua indices count from one
261 script
.push(position
);
266 while (value
.is_string())
268 captures
.resize(captures
.size() + 1);
269 value
.get(captures
.back());
273 script
.clear_stack();
274 return 0 < captures
.size();
277 int pattern::sub(std::string
& substitution
,
278 const std::string
& pattern
,
279 const std::string
& source
, const std::string
& replacement
)
281 script
& script
= pattern_script();
282 script::slot value
= script
.globals().push_field("gsub");
284 script
.push(pattern
);
285 script
.push(replacement
);
288 value
.get(substitution
);
294 script
.clear_stack();
This page took 0.046495 seconds and 5 git commands to generate.