@@ -281,44 +281,31 @@ extern "C"
281281 /* ! Writes the string representation of the given value to dst. */
282282 void value_toString (const ValueData *v, std::string *dst)
283283 {
284- StringPtr *str = value_toStringPtr (v);
284+ StringPtr *str = string_pool_new ();
285+ value_toStringPtr (v, str);
285286 dst->assign (utf8::utf16to8 (std::u16string (str->data )));
286287 string_pool_free (str);
287288 }
288289
289- /* !
290- * Returns the string representation of the given value.
291- * \note It is the caller's responsibility to free allocated memory.
292- */
293- StringPtr *value_toStringPtr (const ValueData *v)
290+ /* ! Writes the string representation of the given value to dst. */
291+ void value_toStringPtr (const ValueData *v, StringPtr *dst)
294292 {
295- if (v->type == ValueType::String) {
296- StringPtr *ret = string_pool_new ();
297- string_assign (ret, v->stringValue );
298- return ret;
299- } else if (v->type == ValueType::Number)
300- return value_doubleToStringPtr (v->numberValue );
293+ if (v->type == ValueType::String)
294+ string_assign (dst, v->stringValue );
295+ else if (v->type == ValueType::Number)
296+ value_doubleToStringPtr (v->numberValue , dst);
301297 else if (v->type == ValueType::Bool) {
302- if (v->boolValue ) {
303- StringPtr *ret = string_pool_new ();
304- string_assign (ret, &TRUE_STR);
305- return ret;
306- } else {
307- StringPtr *ret = string_pool_new ();
308- string_assign (ret, &FALSE_STR);
309- return ret;
310- }
311- } else {
312- StringPtr *ret = string_pool_new ();
313- string_assign (ret, &ZERO_STR);
314- return ret;
315- }
298+ const StringPtr *boolStr = value_boolToStringPtr (v->boolValue );
299+ string_assign (dst, boolStr);
300+ } else
301+ string_assign (dst, &ZERO_STR);
316302 }
317303
318304 /* ! Writes the UTF-16 representation of the given value to dst. */
319305 void value_toUtf16 (const libscratchcpp::ValueData *v, std::u16string *dst)
320306 {
321- StringPtr *str = value_toStringPtr (v);
307+ StringPtr *str = string_pool_new ();
308+ value_toStringPtr (v, str);
322309 dst->assign (str->data );
323310 string_pool_free (str);
324311 }
@@ -395,90 +382,76 @@ extern "C"
395382 return v == intpart;
396383 }
397384
398- /* !
399- * Converts the given number to string.
400- * \note It is the caller's responsibility to free the string.
401- */
402- StringPtr *value_doubleToStringPtr (double v)
385+ /* ! Converts the given number to string and stores the result in dst. */
386+ void value_doubleToStringPtr (double v, StringPtr *dst)
403387 {
404- if (v == 0 ) {
405- StringPtr *ret = string_pool_new ();
406- string_assign_cstring (ret, " 0" );
407- return ret;
408- } else if (std::isinf (v)) {
409- if (v > 0 ) {
410- StringPtr *ret = string_pool_new ();
411- string_assign (ret, &INFINITY_STR);
412- return ret;
388+ if (v == 0 )
389+ string_assign_cstring (dst, " 0" );
390+ else if (std::isinf (v)) {
391+ if (v > 0 )
392+ string_assign (dst, &INFINITY_STR);
393+ else
394+ string_assign (dst, &NEGATIVE_INFINITY_STR);
395+ } else if (std::isnan (v))
396+ string_assign (dst, &NAN_STR);
397+ else {
398+ // snprintf() is locale-dependent
399+ std::string oldLocale = std::setlocale (LC_NUMERIC, nullptr );
400+ std::setlocale (LC_NUMERIC, " C" );
401+
402+ const int maxlen = 26 ; // should be enough for any number
403+ char *buffer = (char *)malloc ((maxlen + 1 ) * sizeof (char ));
404+
405+ // Constants for significant digits and thresholds
406+ const int significantDigits = 17 - value_intDigitCount (std::floor (std::fabs (v)));
407+ constexpr double scientificThreshold = 1e21 ;
408+ constexpr double minScientificThreshold = 1e-6 ;
409+
410+ // Use scientific notation if the number is very large or very small
411+ if (std::fabs (v) >= scientificThreshold || std::fabs (v) < minScientificThreshold) {
412+ int ret = snprintf (buffer, maxlen, " %.*g" , significantDigits - 1 , v);
413+ assert (ret >= 0 );
413414 } else {
414- StringPtr *ret = string_pool_new ();
415- string_assign (ret, &NEGATIVE_INFINITY_STR);
416- return ret;
417- }
418- } else if (std::isnan (v)) {
419- StringPtr *ret = string_pool_new ();
420- string_assign (ret, &NAN_STR);
421- return ret;
422- }
423-
424- // snprintf() is locale-dependent
425- std::string oldLocale = std::setlocale (LC_NUMERIC, nullptr );
426- std::setlocale (LC_NUMERIC, " C" );
427-
428- const int maxlen = 26 ; // should be enough for any number
429- char *buffer = (char *)malloc ((maxlen + 1 ) * sizeof (char ));
430-
431- // Constants for significant digits and thresholds
432- const int significantDigits = 17 - value_intDigitCount (std::floor (std::fabs (v)));
433- constexpr double scientificThreshold = 1e21 ;
434- constexpr double minScientificThreshold = 1e-6 ;
435-
436- // Use scientific notation if the number is very large or very small
437- if (std::fabs (v) >= scientificThreshold || std::fabs (v) < minScientificThreshold) {
438- int ret = snprintf (buffer, maxlen, " %.*g" , significantDigits - 1 , v);
439- assert (ret >= 0 );
440- } else {
441- snprintf (buffer, maxlen, " %.*f" , significantDigits - 1 , v);
442-
443- // Remove trailing zeros from the fractional part
444- char *dot = std::strchr (buffer, ' .' );
445-
446- if (dot) {
447- char *end = buffer + std::strlen (buffer) - 1 ;
448- while (end > dot && *end == ' 0' ) {
449- *end-- = ' \0 ' ;
450- }
451- if (*end == ' .' ) {
452- *end = ' \0 ' ; // Remove trailing dot
415+ snprintf (buffer, maxlen, " %.*f" , significantDigits - 1 , v);
416+
417+ // Remove trailing zeros from the fractional part
418+ char *dot = std::strchr (buffer, ' .' );
419+
420+ if (dot) {
421+ char *end = buffer + std::strlen (buffer) - 1 ;
422+ while (end > dot && *end == ' 0' ) {
423+ *end-- = ' \0 ' ;
424+ }
425+ if (*end == ' .' ) {
426+ *end = ' \0 ' ; // Remove trailing dot
427+ }
453428 }
454429 }
455- }
456430
457- // Remove leading zeros after e+/e-
458- for (int i = 0 ; i < 2 ; i++) {
459- const char *target = (i == 0 ) ? " e+" : " e-" ;
460- char *index = strstr (buffer, target);
461-
462- if (index != nullptr ) {
463- char *ptr = index + 2 ;
464- while (*(ptr + 1 ) != ' \0 ' && *ptr == ' 0' ) {
465- // Shift the characters left to erase '0'
466- char *shiftPtr = ptr;
467- do {
468- *shiftPtr = *(shiftPtr + 1 );
469- shiftPtr++;
470- } while (*shiftPtr != ' \0 ' );
431+ // Remove leading zeros after e+/e-
432+ for (int i = 0 ; i < 2 ; i++) {
433+ const char *target = (i == 0 ) ? " e+" : " e-" ;
434+ char *index = strstr (buffer, target);
435+
436+ if (index != nullptr ) {
437+ char *ptr = index + 2 ;
438+ while (*(ptr + 1 ) != ' \0 ' && *ptr == ' 0' ) {
439+ // Shift the characters left to erase '0'
440+ char *shiftPtr = ptr;
441+ do {
442+ *shiftPtr = *(shiftPtr + 1 );
443+ shiftPtr++;
444+ } while (*shiftPtr != ' \0 ' );
445+ }
471446 }
472447 }
473- }
474448
475- // Restore old locale
476- std::setlocale (LC_NUMERIC, oldLocale.c_str ());
449+ // Restore old locale
450+ std::setlocale (LC_NUMERIC, oldLocale.c_str ());
477451
478- StringPtr *ret = string_pool_new ();
479- string_assign_cstring (ret, buffer);
480- free (buffer);
481- return ret;
452+ string_assign_cstring (dst, buffer);
453+ free (buffer);
454+ }
482455 }
483456
484457 /* !
0 commit comments