diff options
Diffstat (limited to 'db/json.cpp')
-rw-r--r-- | db/json.cpp | 75 |
1 files changed, 53 insertions, 22 deletions
diff --git a/db/json.cpp b/db/json.cpp index 7645b6b..185a8ca 100644 --- a/db/json.cpp +++ b/db/json.cpp @@ -16,17 +16,44 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "stdafx.h" +#include "pch.h" + +#define BOOST_SPIRIT_THREADSAFE +#if BOOST_VERSION >= 103800 +#define BOOST_SPIRIT_USE_OLD_NAMESPACE +#include <boost/spirit/include/classic_core.hpp> +#include <boost/spirit/include/classic_loops.hpp> +#include <boost/spirit/include/classic_lists.hpp> +#else +#include <boost/spirit/core.hpp> +#include <boost/spirit/utility/loops.hpp> +#include <boost/spirit/utility/lists.hpp> +#endif +#undef assert +#define assert MONGO_assert + #include "json.h" -#include "../util/builder.h" +#include "../bson/util/builder.h" #include "../util/base64.h" #include "../util/hex.h" + using namespace boost::spirit; namespace mongo { - struct ObjectBuilder { + struct ObjectBuilder : boost::noncopyable { + ~ObjectBuilder(){ + unsigned i = builders.size(); + if ( i ){ + i--; + for ( ; i>=1; i-- ){ + if ( builders[i] ){ + builders[i]->done(); + } + } + } + } BSONObjBuilder *back() { return builders.back().get(); } @@ -426,20 +453,20 @@ public: array = ch_p( '[' )[ arrayStart( self.b ) ] >> !elements >> ']'; elements = list_p(value, ch_p(',')[arrayNext( self.b )]); value = - oid[ oidEnd( self.b ) ] | - dbref[ dbrefEnd( self.b ) ] | - bindata[ binDataEnd( self.b ) ] | - date[ dateEnd( self.b ) ] | - regex[ regexEnd( self.b ) ] | str[ stringEnd( self.b ) ] | - singleQuoteStr[ stringEnd( self.b ) ] | number | integer | - object[ subobjectEnd( self.b ) ] | array[ arrayEnd( self.b ) ] | lexeme_d[ str_p( "true" ) ][ trueValue( self.b ) ] | lexeme_d[ str_p( "false" ) ][ falseValue( self.b ) ] | - lexeme_d[ str_p( "null" ) ][ nullValue( self.b ) ]; + lexeme_d[ str_p( "null" ) ][ nullValue( self.b ) ] | + singleQuoteStr[ stringEnd( self.b ) ] | + date[ dateEnd( self.b ) ] | + oid[ oidEnd( self.b ) ] | + bindata[ binDataEnd( self.b ) ] | + dbref[ dbrefEnd( self.b ) ] | + regex[ regexEnd( self.b ) ] | + object[ subobjectEnd( self.b ) ] ; // NOTE lexeme_d and rules don't mix well, so we have this mess. // NOTE We use range_p rather than cntrl_p, because the latter is locale dependent. str = lexeme_d[ ch_p( '"' )[ chClear( self.b ) ] >> @@ -530,21 +557,25 @@ public: ObjectBuilder &b; }; - BSONObj fromjson( const char *str ) { - if ( ! strlen(str) ) + BSONObj fromjson( const char *str , int* len) { + if ( str[0] == '\0' ){ + if (len) *len = 0; return BSONObj(); + } + ObjectBuilder b; JsonGrammar parser( b ); parse_info<> result = parse( str, parser, space_p ); - if ( !result.full ) { - int len = strlen( result.stop ); - if ( len > 10 ) - len = 10; - stringstream ss; - ss << "Failure parsing JSON string near: " << string( result.stop, len ); - massert( 10340 , ss.str(), false ); - } - return b.pop(); + if (len) { + *len = result.stop - str; + } else if ( !result.full ) { + int limit = strnlen(result.stop , 10); + if (limit == -1) limit = 10; + msgasserted(10340, "Failure parsing JSON string near: " + string( result.stop, limit )); + } + BSONObj ret = b.pop(); + assert( b.empty() ); + return ret; } BSONObj fromjson( const string &str ) { |