44
55#include " runtime-common/stdlib/serialization/json-functions.h"
66
7+ #include < cstddef>
8+ #include < optional>
9+ #include < string_view>
10+
711#include " common/algorithms/find.h"
812#include " runtime-common/core/runtime-core.h"
913#include " runtime-common/stdlib/string/string-functions.h"
@@ -316,17 +320,17 @@ bool JsonEncoder::encode(const mixed& v, string_buffer& sb) noexcept {
316320
317321namespace {
318322
319- void json_skip_blanks (const char * s, int & i) noexcept {
323+ void json_skip_blanks (const char * s, size_t & i) noexcept {
320324 while (vk::any_of_equal (s[i], ' ' , ' \t ' , ' \r ' , ' \n ' )) {
321325 i++;
322326 }
323327}
324328
325- bool do_json_decode (const char * s, int s_len, int & i, mixed& v, const char * json_obj_magic_key) noexcept {
329+ bool do_json_decode (std::string_view s, size_t & i, mixed& v, std::string_view json_obj_magic_key) noexcept {
326330 if (!v.is_null ()) {
327331 v.destroy ();
328332 }
329- json_skip_blanks (s, i);
333+ json_skip_blanks (s. data () , i);
330334 switch (s[i]) {
331335 case ' n' :
332336 if (s[i + 1 ] == ' u' && s[i + 2 ] == ' l' && s[i + 3 ] == ' l' ) {
@@ -351,14 +355,14 @@ bool do_json_decode(const char* s, int s_len, int& i, mixed& v, const char* json
351355 case ' "' : {
352356 int j = i + 1 ;
353357 int slashes = 0 ;
354- while (j < s_len && s[j] != ' "' ) {
358+ while (j < s. size () && s[j] != ' "' ) {
355359 if (s[j] == ' \\ ' ) {
356360 slashes++;
357361 j++;
358362 }
359363 j++;
360364 }
361- if (j < s_len ) {
365+ if (j < s. size () ) {
362366 int len = j - i - 1 - slashes;
363367
364368 string value (len, false );
@@ -469,15 +473,15 @@ bool do_json_decode(const char* s, int s_len, int& i, mixed& v, const char* json
469473 case ' [' : {
470474 array<mixed> res;
471475 i++;
472- json_skip_blanks (s, i);
476+ json_skip_blanks (s. data () , i);
473477 if (s[i] != ' ]' ) {
474478 do {
475479 mixed value;
476- if (!do_json_decode (s, s_len, i, value, json_obj_magic_key)) {
480+ if (!do_json_decode (s, i, value, json_obj_magic_key)) {
477481 return false ;
478482 }
479483 res.push_back (value);
480- json_skip_blanks (s, i);
484+ json_skip_blanks (s. data () , i);
481485 } while (s[i++] == ' ,' );
482486
483487 if (s[i - 1 ] != ' ]' ) {
@@ -493,22 +497,22 @@ bool do_json_decode(const char* s, int s_len, int& i, mixed& v, const char* json
493497 case ' {' : {
494498 array<mixed> res;
495499 i++;
496- json_skip_blanks (s, i);
500+ json_skip_blanks (s. data () , i);
497501 if (s[i] != ' }' ) {
498502 do {
499503 mixed key;
500- if (!do_json_decode (s, s_len, i, key, json_obj_magic_key) || !key.is_string ()) {
504+ if (!do_json_decode (s, i, key, json_obj_magic_key) || !key.is_string ()) {
501505 return false ;
502506 }
503- json_skip_blanks (s, i);
507+ json_skip_blanks (s. data () , i);
504508 if (s[i++] != ' :' ) {
505509 return false ;
506510 }
507511
508- if (!do_json_decode (s, s_len, i, res[key], json_obj_magic_key)) {
512+ if (!do_json_decode (s, i, res[key], json_obj_magic_key)) {
509513 return false ;
510514 }
511- json_skip_blanks (s, i);
515+ json_skip_blanks (s. data () , i);
512516 } while (s[i++] == ' ,' );
513517
514518 if (s[i - 1 ] != ' }' ) {
@@ -520,8 +524,8 @@ bool do_json_decode(const char* s, int s_len, int& i, mixed& v, const char* json
520524
521525 // it's impossible to distinguish whether empty php array was an json array or json object;
522526 // to overcome it we add dummy key to php array that make array::is_vector() returning false, so we have difference
523- if (json_obj_magic_key && res.empty ()) {
524- res[string{json_obj_magic_key}] = true ;
527+ if (! json_obj_magic_key. empty () && res.empty ()) {
528+ res[string{json_obj_magic_key. data (), static_cast <string::size_type>(json_obj_magic_key. size ()) }] = true ;
525529 }
526530
527531 new (&v) mixed (res);
@@ -534,15 +538,15 @@ bool do_json_decode(const char* s, int s_len, int& i, mixed& v, const char* json
534538 }
535539 if (j > i) {
536540 int64_t intval = 0 ;
537- if (php_try_to_int (s + i, j - i, &intval)) {
541+ if (php_try_to_int (s. data () + i, j - i, &intval)) {
538542 i = j;
539543 new (&v) mixed (intval);
540544 return true ;
541545 }
542546
543547 char * end_ptr;
544- double floatval = strtod (s + i, &end_ptr);
545- if (end_ptr == s + j) {
548+ double floatval = strtod (s. data () + i, &end_ptr);
549+ if (end_ptr == s. data () + j) {
546550 i = j;
547551 new (&v) mixed (floatval);
548552 return true ;
@@ -557,22 +561,20 @@ bool do_json_decode(const char* s, int s_len, int& i, mixed& v, const char* json
557561
558562} // namespace
559563
560- std::pair<mixed, bool > json_decode (const string& v, const char * json_obj_magic_key) noexcept {
561- mixed result;
562- int i = 0 ;
563- if (do_json_decode (v.c_str (), v.size (), i, result, json_obj_magic_key)) {
564- json_skip_blanks (v.c_str (), i);
565- if (i == static_cast <int >(v.size ())) {
566- bool success = true ;
567- return {result, success};
564+ std::optional<mixed> json_decode (std::string_view v, std::string_view json_obj_magic_key) noexcept {
565+ mixed result{};
566+ size_t i{};
567+ if (do_json_decode (v, i, result, json_obj_magic_key)) {
568+ json_skip_blanks (v.data (), i);
569+ if (i == v.size ()) {
570+ return result;
568571 }
569572 }
570-
571573 return {};
572574}
573575
574576mixed f$json_decode(const string& v, bool assoc) noexcept {
575577 // TODO It was a warning before (in case if assoc is false), but then it was disabled, should we enable it again?
576578 static_cast <void >(assoc);
577- return json_decode (v). first ;
579+ return json_decode ({v. c_str (), v. size ()}, {}). value_or (mixed{}) ;
578580}
0 commit comments