Skip to content

Commit cb3570c

Browse files
committed
Add more value casting functions
1 parent dba78e7 commit cb3570c

File tree

4 files changed

+360
-14
lines changed

4 files changed

+360
-14
lines changed

include/scratchcpp/value_functions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,14 @@ extern "C"
3636
LIBSCRATCHCPP_EXPORT double value_toDouble(const ValueData *v);
3737
LIBSCRATCHCPP_EXPORT bool value_toBool(const ValueData *v);
3838
LIBSCRATCHCPP_EXPORT void value_toString(const ValueData *v, std::string *dst);
39+
LIBSCRATCHCPP_EXPORT char *value_toCString(const ValueData *v);
3940
LIBSCRATCHCPP_EXPORT void value_toUtf16(const ValueData *v, std::u16string *dst);
4041

42+
LIBSCRATCHCPP_EXPORT char *value_doubleToCString(double v);
43+
LIBSCRATCHCPP_EXPORT const char *value_boolToCString(bool v);
44+
LIBSCRATCHCPP_EXPORT double value_stringToDouble(const char *s);
45+
LIBSCRATCHCPP_EXPORT bool value_stringToBool(const char *s);
46+
4147
LIBSCRATCHCPP_EXPORT void value_add(const ValueData *v1, const ValueData *v2, ValueData *dst);
4248
LIBSCRATCHCPP_EXPORT void value_subtract(const ValueData *v1, const ValueData *v2, ValueData *dst);
4349
LIBSCRATCHCPP_EXPORT void value_multiply(const ValueData *v1, const ValueData *v2, ValueData *dst);

src/scratch/value_functions.cpp

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ extern "C"
330330
} else if (v->type == ValueType::Number) {
331331
return v->numberValue != 0;
332332
} else if (v->type == ValueType::String) {
333-
return strlen(v->stringValue) != 0 && !value_stringsEqual(v->stringValue, "false") && strcmp(v->stringValue, "0") != 0;
333+
return value_stringToBool(v->stringValue);
334334
} else if (v->type == ValueType::Infinity || v->type == ValueType::NegativeInfinity) {
335335
return true;
336336
} else if (v->type == ValueType::NaN) {
@@ -346,7 +346,7 @@ extern "C"
346346
if (v->type == ValueType::String)
347347
dst->assign(v->stringValue);
348348
else if (v->type == ValueType::Number)
349-
dst->assign(value_doubleToString(v->numberValue));
349+
value_doubleToString(v->numberValue, dst);
350350
else if (v->type == ValueType::Bool)
351351
dst->assign(v->boolValue ? "true" : "false");
352352
else if (v->type == ValueType::Infinity)
@@ -359,6 +359,19 @@ extern "C"
359359
dst->clear();
360360
}
361361

362+
/*!
363+
* Returns the string representation of the given value.
364+
* \note It is the caller's responsibility to free allocated memory.
365+
*/
366+
char *value_toCString(const ValueData *v)
367+
{
368+
std::string out;
369+
value_toString(v, &out);
370+
char *ret = (char *)malloc((out.size() + 1) * sizeof(char));
371+
strncpy(ret, out.c_str(), out.size() + 1);
372+
return ret;
373+
}
374+
362375
/*! Writes the UTF-16 representation of the given value to dst. */
363376
void value_toUtf16(const libscratchcpp::ValueData *v, std::u16string *dst)
364377
{
@@ -367,6 +380,51 @@ extern "C"
367380
dst->assign(utf8::utf8to16(s));
368381
}
369382

383+
/*!
384+
* Converts the given number to string.
385+
* \note It is the caller's responsibility to free allocated memory.
386+
*/
387+
char *value_doubleToCString(double v)
388+
{
389+
std::string out;
390+
value_doubleToString(v, &out);
391+
char *ret = (char *)malloc((out.size() + 1) * sizeof(char));
392+
strncpy(ret, out.c_str(), out.size() + 1);
393+
return ret;
394+
}
395+
396+
/*!
397+
* Converts the given boolean to string.
398+
* \note Do not free allocated memory!
399+
*/
400+
const char *value_boolToCString(bool v)
401+
{
402+
if (v) {
403+
static const char *ret = "true";
404+
return ret;
405+
} else {
406+
static const char *ret = "false";
407+
return ret;
408+
}
409+
}
410+
411+
/*! Converts the given string to double. */
412+
double value_stringToDouble(const char *s)
413+
{
414+
if (strcmp(s, "Infinity") == 0)
415+
return std::numeric_limits<double>::infinity();
416+
else if (strcmp(s, "-Infinity") == 0)
417+
return -std::numeric_limits<double>::infinity();
418+
419+
return value_stringToDoubleImpl(s);
420+
}
421+
422+
/*! Converts the given string to boolean. */
423+
bool value_stringToBool(const char *s)
424+
{
425+
return strlen(s) != 0 && !value_stringsEqual(s, "false") && strcmp(s, "0") != 0;
426+
}
427+
370428
/* operations */
371429

372430
/*! Adds the given values and writes the result to dst. */

src/scratch/value_functions_p.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ extern "C"
227227
}
228228
}
229229

230-
inline double value_stringToDouble(const char *s, bool *ok = nullptr)
230+
inline double value_stringToDoubleImpl(const char *s, bool *ok = nullptr)
231231
{
232232
if (ok)
233233
*ok = false;
@@ -392,7 +392,7 @@ extern "C"
392392

393393
inline long value_stringToLong(const char *s, bool *ok = nullptr)
394394
{
395-
return value_stringToDouble(s, ok);
395+
return value_stringToDoubleImpl(s, ok);
396396
}
397397

398398
inline bool value_stringIsInt(const char *s, int n)
@@ -410,7 +410,7 @@ extern "C"
410410
}
411411
}
412412

413-
inline std::string value_doubleToString(double v)
413+
inline void value_doubleToString(double v, std::string *dst)
414414
{
415415
std::stringstream stream;
416416

@@ -424,22 +424,20 @@ inline std::string value_doubleToString(double v)
424424
} else
425425
stream << std::setprecision(std::max(16u, value_digitCount(v))) << v;
426426

427-
std::string s = stream.str();
427+
dst->assign(stream.str());
428428
std::size_t index;
429429

430430
for (int i = 0; i < 2; i++) {
431431
if (i == 0)
432-
index = s.find("e+");
432+
index = dst->find("e+");
433433
else
434-
index = s.find("e-");
434+
index = dst->find("e-");
435435

436436
if (index != std::string::npos) {
437-
while ((s.size() >= index + 3) && (s[index + 2] == '0'))
438-
s.erase(index + 2, 1);
437+
while ((dst->size() >= index + 3) && ((*dst)[index + 2] == '0'))
438+
dst->erase(index + 2, 1);
439439
}
440440
}
441-
442-
return s;
443441
}
444442

445443
extern "C"
@@ -459,7 +457,7 @@ extern "C"
459457
value_stringToLong(str, &ok);
460458
return ok ? 1 : 0;
461459
} else {
462-
value_stringToDouble(str, &ok);
460+
value_stringToDoubleImpl(str, &ok);
463461
return ok ? 2 : 0;
464462
}
465463
}
@@ -473,7 +471,7 @@ extern "C"
473471
// Since functions calling this already prioritize int, double and bool,
474472
// we can optimize by prioritizing the other types here.
475473
if (v->type == ValueType::String)
476-
return value_stringToDouble(v->stringValue, ok);
474+
return value_stringToDoubleImpl(v->stringValue, ok);
477475
else if (v->type == ValueType::Infinity)
478476
return std::numeric_limits<double>::infinity();
479477
else if (v->type == ValueType::NegativeInfinity)

0 commit comments

Comments
 (0)