Skip to content

Commit 4b6b8e2

Browse files
committed
Use StringPtr in list to string conversion
1 parent f1944da commit 4b6b8e2

File tree

6 files changed

+89
-62
lines changed

6 files changed

+89
-62
lines changed

include/scratchcpp/list.h

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
#pragma once
44

55
#include <string>
6-
#include <scratchcpp/veque.h>
76

87
#include "value.h"
98
#include "entity.h"
9+
#include "string_pool.h"
10+
#include "string_functions.h"
11+
#include "stringptr.h"
12+
#include "veque.h"
1013

1114
namespace libscratchcpp
1215
{
@@ -143,21 +146,21 @@ class LIBSCRATCHCPP_EXPORT List : public Entity
143146
return m_dataPtr->operator[](index);
144147
}
145148

146-
/*! Joins the list items with spaces or without any separator if there are only digits and stores the result in dst. */
147-
inline void toString(std::string &dst) const
149+
/*! Joins the list items with spaces or without any separator if there are only digits and returns the result as StringPtr. */
150+
inline StringPtr *toStringPtr() const
148151
{
149-
dst.clear();
150-
veque::veque<std::string> strings;
152+
veque::veque<StringPtr *> strings;
153+
size_t size = 0;
151154
strings.reserve(m_size);
152155
bool digits = true;
153156
size_t i;
154157

155158
for (i = 0; i < m_size; i++) {
156159
const ValueData *item = &m_dataPtr->operator[](i);
157-
strings.push_back(std::string());
158-
value_toString(item, &strings.back());
160+
strings.push_back(value_toStringPtr(item));
161+
size += strings.back()->size;
159162

160-
if (value_isValidNumber(item) && !value_isBool(item) && !strings.back().empty()) {
163+
if (value_isValidNumber(item) && !value_isBool(item) && strings.back()->size > 0) {
161164
double doubleNum = value_toDouble(item);
162165
long num = value_toLong(item);
163166

@@ -176,42 +179,58 @@ class LIBSCRATCHCPP_EXPORT List : public Entity
176179
}
177180
}
178181

179-
std::string s;
182+
StringPtr *ret = string_pool_new();
183+
size_t offset = 0;
180184

181185
if (digits) {
182-
for (i = 0; i < strings.size(); i++)
183-
dst.append(strings[i]);
186+
string_alloc(ret, size);
187+
188+
for (i = 0; i < strings.size(); i++) {
189+
memcpy(ret->data + offset, strings[i]->data, strings[i]->size * sizeof(char16_t));
190+
offset += strings[i]->size;
191+
string_pool_free(strings[i]);
192+
}
184193

185194
for (; i < m_size; i++) {
186-
value_toString(&m_dataPtr->operator[](i), &s);
187-
dst.append(s);
195+
StringPtr *item = value_toStringPtr(&m_dataPtr->operator[](i));
196+
size += item->size + 1;
197+
string_alloc(ret, size);
198+
memcpy(ret->data + offset, item->data, item->size * sizeof(char16_t));
199+
offset += item->size;
200+
string_pool_free(item);
188201
}
189202
} else {
203+
size += strings.size() - 1;
204+
string_alloc(ret, size);
205+
190206
for (i = 0; i < strings.size(); i++) {
191-
dst.append(strings[i]);
207+
memcpy(ret->data + offset, strings[i]->data, strings[i]->size * sizeof(char16_t));
208+
offset += strings[i]->size;
209+
string_pool_free(strings[i]);
192210

193211
if (i + 1 < m_size)
194-
dst.push_back(' ');
212+
ret->data[offset++] = u' ';
195213
}
196214

197215
for (; i < m_size; i++) {
198-
value_toString(&m_dataPtr->operator[](i), &s);
199-
dst.append(s);
216+
StringPtr *item = value_toStringPtr(&m_dataPtr->operator[](i));
217+
size += item->size + 1;
218+
string_alloc(ret, size);
219+
memcpy(ret->data + offset, item->data, item->size * sizeof(char16_t));
220+
offset += item->size;
221+
string_pool_free(item);
200222

201223
if (i + 1 < m_size)
202-
dst.push_back(' ');
224+
ret->data[offset++] = u' ';
203225
}
204226
}
205-
}
206227

207-
/*! Same as the other method, but returns the result directly. */
208-
inline std::string toString() const
209-
{
210-
std::string ret;
211-
toString(ret);
228+
ret->data[offset] = u'\0';
212229
return ret;
213230
}
214231

232+
std::string toString() const;
233+
215234
std::shared_ptr<List> clone();
216235

217236
private:

src/scratch/list.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: Apache-2.0
22

33
#include <scratchcpp/list.h>
4-
#include <algorithm>
4+
#include <utf8.h>
55

66
#include "list_p.h"
77

@@ -58,6 +58,15 @@ void List::setMonitor(Monitor *monitor)
5858
impl->monitor = monitor;
5959
}
6060

61+
/*! Same as the other method, but returns the result as std::string. */
62+
std::string List::toString() const
63+
{
64+
StringPtr *str = toStringPtr();
65+
std::string ret = utf8::utf16to8(std::u16string(str->data));
66+
string_pool_free(str);
67+
return ret;
68+
}
69+
6170
/*! Creates a copy of the list. */
6271
std::shared_ptr<List> List::clone()
6372
{

src/scratch/list_functions.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,8 @@ extern "C"
5353
return list->size();
5454
}
5555

56-
char *list_to_string(List *list)
56+
StringPtr *list_to_string(List *list)
5757
{
58-
std::string str;
59-
list->toString(str);
60-
61-
char *ret = (char *)malloc((str.size() + 1) * sizeof(char));
62-
strncpy(ret, str.c_str(), str.size() + 1);
63-
return ret;
58+
return list->toStringPtr();
6459
}
6560
}

src/scratch/list_functions.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace libscratchcpp
99

1010
class List;
1111
struct ValueData;
12+
struct StringPtr;
1213

1314
extern "C"
1415
{
@@ -24,7 +25,7 @@ extern "C"
2425
const size_t *list_alloc_size_ptr(List *list);
2526
size_t list_size(List *list);
2627

27-
char *list_to_string(List *list);
28+
StringPtr *list_to_string(List *list);
2829
}
2930

3031
} // namespace libscratchcpp

test/scratch_classes/list_functions_test.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <scratchcpp/list.h>
22
#include <scratch/list_functions.h>
3+
#include <utf8.h>
34

45
#include <gtest/gtest.h>
56

@@ -157,9 +158,8 @@ TEST(ListFunctionsTest, ToString)
157158
list.append("sit");
158159
list.append("amet");
159160

160-
char *str = list_to_string(&list);
161-
ASSERT_TRUE(strcmp(str, "Lorem ipsum dolor sit amet") == 0);
162-
free(str);
161+
StringPtr *str = list_to_string(&list);
162+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "Lorem ipsum dolor sit amet");
163163
}
164164

165165
{
@@ -168,8 +168,7 @@ TEST(ListFunctionsTest, ToString)
168168
list.append(2);
169169
list.append(3);
170170

171-
char *str = list_to_string(&list);
172-
ASSERT_TRUE(strcmp(str, "123") == 0);
173-
free(str);
171+
StringPtr *str = list_to_string(&list);
172+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "123");
174173
}
175174
}

test/scratch_classes/list_test.cpp

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <scratchcpp/list.h>
22
#include <scratchcpp/target.h>
33
#include <scratchcpp/monitor.h>
4+
#include <utf8.h>
45

56
#include "../common.h"
67

@@ -188,10 +189,12 @@ TEST(ListTest, Clear)
188189
TEST(ListTest, Append)
189190
{
190191
List list("", "test list");
192+
Value v1("ipsum");
193+
Value v2("sit");
191194
list.append("Lorem");
192-
list.append(Value("ipsum").data());
195+
list.append(v1.data());
193196
list.append("dolor");
194-
list.append(Value("sit").data());
197+
list.append(v2.data());
195198
list.append("amet");
196199
ASSERT_EQ(list.toString(), "Lorem ipsum dolor sit amet");
197200

@@ -276,80 +279,81 @@ TEST(ListTest, ArrayIndexOperator)
276279
TEST(ListTest, ToString)
277280
{
278281
List list("", "test list");
279-
std::string s;
280-
list.toString(s);
281-
ASSERT_EQ(s, "");
282+
StringPtr *str = list.toStringPtr();
283+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "");
282284
ASSERT_EQ(list.toString(), "");
283285

284286
list.append("");
285-
list.toString(s);
286-
ASSERT_EQ(s, "");
287+
str = list.toStringPtr();
288+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "");
287289
ASSERT_EQ(list.toString(), "");
288290

289291
list.append("");
290292
list.append("");
293+
str = list.toStringPtr();
294+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), " ");
291295
ASSERT_EQ(list.toString(), " ");
292296

293297
list.clear();
294298
list.append("item1");
295299
list.append("i t e m 2");
296300
list.append("item 3");
297-
list.toString(s);
298-
ASSERT_EQ(s, "item1 i t e m 2 item 3");
301+
str = list.toStringPtr();
302+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "item1 i t e m 2 item 3");
299303
ASSERT_EQ(list.toString(), "item1 i t e m 2 item 3");
300304

301305
list.clear();
302306
list.append(" ");
303307
list.append("a ");
304308
list.append(" b");
305309
list.append(" c ");
306-
list.toString(s);
307-
ASSERT_EQ(s, " a b c ");
310+
str = list.toStringPtr();
311+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), " a b c ");
308312
ASSERT_EQ(list.toString(), " a b c ");
309313

310314
list.clear();
311315
list.append("áä");
312316
list.append("ľ š");
313-
list.toString(s);
314-
ASSERT_EQ(s, "áä ľ š");
317+
str = list.toStringPtr();
318+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "áä ľ š");
315319
ASSERT_EQ(list.toString(), "áä ľ š");
316320

317321
list.clear();
318322
list.append(-2);
319323
list.append(5);
320324
list.append(8);
321-
list.toString(s);
322-
ASSERT_EQ(s, "-2 5 8");
325+
str = list.toStringPtr();
326+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "-2 5 8");
323327
ASSERT_EQ(list.toString(), "-2 5 8");
324328

325329
list.clear();
326330
list.append(2);
327331
list.append(10);
328332
list.append(8);
329-
list.toString(s);
330-
ASSERT_EQ(s, "2 10 8");
333+
str = list.toStringPtr();
334+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "2 10 8");
331335
ASSERT_EQ(list.toString(), "2 10 8");
332336

333337
list.clear();
334338
list.append(0);
335339
list.append(9);
336340
list.append(8);
337-
list.toString(s);
338-
ASSERT_EQ(s, "098");
341+
str = list.toStringPtr();
342+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "098");
339343
ASSERT_EQ(list.toString(), "098");
340344

341345
list.clear();
342346
list.append("true");
343347
list.append("false");
344-
list.toString(s);
345-
ASSERT_EQ(s, "true false");
348+
str = list.toStringPtr();
349+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "true false");
346350
ASSERT_EQ(list.toString(), "true false");
347351

348352
list.clear();
349353
list.append(true);
350354
list.append(false);
351-
list.toString(s);
352-
ASSERT_EQ(s, "true false");
355+
str = list.toStringPtr();
356+
ASSERT_EQ(utf8::utf16to8(std::u16string(str->data)), "true false");
353357
ASSERT_EQ(list.toString(), "true false");
354358
}
355359

0 commit comments

Comments
 (0)