summaryrefslogtreecommitdiff
path: root/db/json.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'db/json.cpp')
-rw-r--r--db/json.cpp75
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 ) {