@@ -16,6 +16,7 @@ namespace simdjson {
1616//
1717// element_result inline implementation
1818//
19+ really_inline document::element_result::element_result () noexcept : simdjson_result<element>() {}
1920really_inline document::element_result::element_result (element value) noexcept : simdjson_result<element>(value) {}
2021really_inline document::element_result::element_result (error_code error) noexcept : simdjson_result<element>(error) {}
2122inline simdjson_result<bool > document::element_result::is_null () const noexcept {
@@ -111,6 +112,7 @@ inline document::element_result::operator document::object() const noexcept(fals
111112//
112113// array_result inline implementation
113114//
115+ really_inline document::array_result::array_result () noexcept : simdjson_result<array>() {}
114116really_inline document::array_result::array_result (array value) noexcept : simdjson_result<array>(value) {}
115117really_inline document::array_result::array_result (error_code error) noexcept : simdjson_result<array>(error) {}
116118
@@ -146,6 +148,7 @@ inline document::element_result document::array_result::at(size_t index) const n
146148//
147149// object_result inline implementation
148150//
151+ really_inline document::object_result::object_result () noexcept : simdjson_result<object>() {}
149152really_inline document::object_result::object_result (object value) noexcept : simdjson_result<object>(value) {}
150153really_inline document::object_result::object_result (error_code error) noexcept : simdjson_result<object>(error) {}
151154
@@ -805,53 +808,38 @@ inline document::element_result document::object::operator[](const char *json_po
805808 return (*this )[std::string_view (json_pointer)];
806809}
807810inline 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);
848813
849814 // 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+ }
851839
852840 // 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 ));
855843 }
856844
857845 return child;
0 commit comments