@@ -16,6 +16,7 @@ namespace simdjson {
16
16
//
17
17
// element_result inline implementation
18
18
//
19
+ really_inline document::element_result::element_result () noexcept : simdjson_result<element>() {}
19
20
really_inline document::element_result::element_result (element value) noexcept : simdjson_result<element>(value) {}
20
21
really_inline document::element_result::element_result (error_code error) noexcept : simdjson_result<element>(error) {}
21
22
inline simdjson_result<bool > document::element_result::is_null () const noexcept {
@@ -111,6 +112,7 @@ inline document::element_result::operator document::object() const noexcept(fals
111
112
//
112
113
// array_result inline implementation
113
114
//
115
+ really_inline document::array_result::array_result () noexcept : simdjson_result<array>() {}
114
116
really_inline document::array_result::array_result (array value) noexcept : simdjson_result<array>(value) {}
115
117
really_inline document::array_result::array_result (error_code error) noexcept : simdjson_result<array>(error) {}
116
118
@@ -146,6 +148,7 @@ inline document::element_result document::array_result::at(size_t index) const n
146
148
//
147
149
// object_result inline implementation
148
150
//
151
+ really_inline document::object_result::object_result () noexcept : simdjson_result<object>() {}
149
152
really_inline document::object_result::object_result (object value) noexcept : simdjson_result<object>(value) {}
150
153
really_inline document::object_result::object_result (error_code error) noexcept : simdjson_result<object>(error) {}
151
154
@@ -805,53 +808,38 @@ inline document::element_result document::object::operator[](const char *json_po
805
808
return (*this )[std::string_view (json_pointer)];
806
809
}
807
810
inline document::element_result document::object::at (std::string_view json_pointer) const noexcept {
808
- // Unescape the key
809
- std::string unescaped;
810
- unescaped.reserve (json_pointer.length ());
811
- size_t i;
812
- for (i = 0 ; i < json_pointer.length () && json_pointer[i] != ' /' ; i++) {
813
- switch (json_pointer[i]) {
814
- // Handle ~ escaping: ~0 = ~, ~1 = /
815
- case ' ~' : {
816
- i++;
817
- // ~ at end of string is invalid
818
- if (i >= json_pointer.length ()) { RETURN_ERROR (INVALID_JSON_POINTER, " ~ at end of string in JSON pointer" ); }
819
- switch (json_pointer[i]) {
820
- case ' 0' :
821
- unescaped.push_back (' ~' );
822
- break ;
823
- case ' 1' :
824
- unescaped.push_back (' /' );
825
- break ;
826
- default :
827
- RETURN_ERROR (INVALID_JSON_POINTER, " Unexpected ~ escape character in JSON pointer" );
828
- }
829
- break ;
830
- }
831
- // TODO backslash doesn't appear to be a thing in JSON pointer
832
- case ' \\ ' : {
833
- i++;
834
- // backslash at end of string is invalid
835
- if (i >= json_pointer.length ()) { RETURN_ERROR (INVALID_JSON_POINTER, " ~ at end of string in JSON pointer" ); }
836
- // Check for invalid escape characters
837
- if (json_pointer[i] != ' \\ ' && json_pointer[i] != ' "' && json_pointer[i] > 0x1F ) {
838
- RETURN_ERROR (INVALID_JSON_POINTER, " Invalid backslash escape in JSON pointer" );
839
- }
840
- unescaped.push_back (json_pointer[i]);
841
- break ;
842
- }
843
- default :
844
- unescaped.push_back (json_pointer[i]);
845
- break ;
846
- }
847
- }
811
+ size_t slash = json_pointer.find (' /' );
812
+ std::string_view key = json_pointer.substr (0 , slash);
848
813
849
814
// Grab the child with the given key
850
- auto child = at_key (unescaped);
815
+ document::element_result child;
816
+
817
+ // If there is an escape character in the key, unescape it and then get the child.
818
+ size_t escape = key.find (' ~' );
819
+ if (escape != std::string_view::npos) {
820
+ // Unescape the key
821
+ std::string unescaped (key);
822
+ do {
823
+ switch (unescaped[escape+1 ]) {
824
+ case ' 0' :
825
+ unescaped.replace (escape, 2 , " ~" );
826
+ break ;
827
+ case ' 1' :
828
+ unescaped.replace (escape, 2 , " /" );
829
+ break ;
830
+ default :
831
+ RETURN_ERROR (INVALID_JSON_POINTER, " Unexpected ~ escape character in JSON pointer" );
832
+ }
833
+ escape = unescaped.find (' ~' , escape+1 );
834
+ } while (escape != std::string::npos);
835
+ child = at_key (unescaped);
836
+ } else {
837
+ child = at_key (key);
838
+ }
851
839
852
840
// If there is a /, we have to recurse and look up more of the path
853
- if (i < json_pointer. length () ) {
854
- child = child.at (json_pointer.substr (i +1 ));
841
+ if (slash != std::string_view::npos ) {
842
+ child = child.at (json_pointer.substr (slash +1 ));
855
843
}
856
844
857
845
return child;
0 commit comments