summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/jsobj.cpp45
-rw-r--r--db/jsobj.h11
-rw-r--r--dbtests/jsobjtests.cpp30
-rw-r--r--tools/import.cpp47
4 files changed, 87 insertions, 46 deletions
diff --git a/db/jsobj.cpp b/db/jsobj.cpp
index 65200ad582d..e4fae9de18d 100644
--- a/db/jsobj.cpp
+++ b/db/jsobj.cpp
@@ -1579,5 +1579,50 @@ namespace mongo {
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
};
+ bool BSONObjBuilder::appendAsNumber( const string& fieldName , const string& data ){
+ if ( data.size() == 0 )
+ return false;
+
+ unsigned int pos=0;
+ if ( data[0] == '-' )
+ pos++;
+
+ bool hasDec = false;
+
+ for ( ; pos<data.size(); pos++ ){
+ if ( isdigit(data[pos]) )
+ continue;
+
+ if ( data[pos] == '.' ){
+ if ( hasDec )
+ return false;
+ hasDec = true;
+ continue;
+ }
+
+ return false;
+ }
+
+ if ( hasDec ){
+ double d = atof( data.c_str() );
+ append( fieldName.c_str() , d );
+ return true;
+ }
+
+ if ( data.size() < 8 ){
+ append( fieldName , atoi( data.c_str() ) );
+ return true;
+ }
+
+ try {
+ long long num = boost::lexical_cast<long long>( data );
+ append( fieldName , num );
+ return true;
+ }
+ catch(bad_lexical_cast &){
+ return false;
+ }
+
+ }
} // namespace mongo
diff --git a/db/jsobj.h b/db/jsobj.h
index 2f0058a636a..131322826ce 100644
--- a/db/jsobj.h
+++ b/db/jsobj.h
@@ -1207,6 +1207,12 @@ namespace mongo {
b.append(n);
}
+ /** Append a NumberLong */
+ void append(const string& fieldName, long long n) {
+ append( fieldName.c_str() , n );
+ }
+
+
/** Append a double element */
BSONObjBuilder& append(const char *fieldName, double n) {
b.append((char) NumberDouble);
@@ -1215,6 +1221,11 @@ namespace mongo {
return *this;
}
+ /** tries to append the data as a number
+ * @return true if the data was able to be converted to a number
+ */
+ bool appendAsNumber( const string& fieldName , const string& data );
+
/** Append a BSON Object ID (OID type). */
void appendOID(const char *fieldName, OID *oid = 0 , bool generateIfBlank = false ) {
b.append((char) jstOID);
diff --git a/dbtests/jsobjtests.cpp b/dbtests/jsobjtests.cpp
index c92866807a5..d3f15dd6b74 100644
--- a/dbtests/jsobjtests.cpp
+++ b/dbtests/jsobjtests.cpp
@@ -1156,6 +1156,35 @@ namespace JsobjTests {
}
};
+ class NumberParsing {
+ public:
+ void run(){
+ BSONObjBuilder a;
+ BSONObjBuilder b;
+
+ a.append( "a" , (int)1 );
+ ASSERT( b.appendAsNumber( "a" , "1" ) );
+
+ a.append( "b" , 1.1 );
+ ASSERT( b.appendAsNumber( "b" , "1.1" ) );
+
+ a.append( "c" , (int)-1 );
+ ASSERT( b.appendAsNumber( "c" , "-1" ) );
+
+ a.append( "d" , -1.1 );
+ ASSERT( b.appendAsNumber( "d" , "-1.1" ) );
+
+ a.append( "e" , (long long)32131231231232313 );
+ ASSERT( b.appendAsNumber( "e" , "32131231231232313" ) );
+
+ ASSERT( ! b.appendAsNumber( "f" , "zz" ) );
+ ASSERT( ! b.appendAsNumber( "f" , "5zz" ) );
+ ASSERT( ! b.appendAsNumber( "f" , "zz5" ) );
+
+ ASSERT_EQUALS( a.obj() , b.obj() );
+ }
+ };
+
class All : public Suite {
public:
All() : Suite( "jsobj" ){
@@ -1239,6 +1268,7 @@ namespace JsobjTests {
add< NestedDottedConversions >();
add< BSONArrayBuilderTest >();
add< ArrayMacroTest >();
+ add< NumberParsing >();
}
} myall;
diff --git a/tools/import.cpp b/tools/import.cpp
index 93b071ebd7f..9e4c44bf0f9 100644
--- a/tools/import.cpp
+++ b/tools/import.cpp
@@ -39,53 +39,8 @@ class Import : public Tool {
const char * _sep;
bool _ignoreBlanks;
- bool _appendNumber( BSONObjBuilder& b , const string& fieldName , const string& data ){
- if ( data.size() == 0 )
- return false;
-
- unsigned int pos=0;
- if ( data[0] == '-' )
- pos++;
-
- bool hasDec = false;
-
- for ( ; pos<data.size(); pos++ ){
- if ( isdigit(data[pos]) )
- continue;
-
- if ( data[pos] == '.' ){
- if ( hasDec )
- return false;
- hasDec = true;
- continue;
- }
-
- return false;
- }
-
- if ( hasDec ){
- double d = atof( data.c_str() );
- b.append( fieldName.c_str() , d );
- return true;
- }
-
- if ( data.size() < 8 ){
- b.append( fieldName , atoi( data.c_str() ) );
- return true;
- }
-
- try {
- long long num = boost::lexical_cast<long long>( data );
- b.append( fieldName.c_str() , num );
- return true;
- }
- catch(bad_lexical_cast &){
- return false;
- }
- }
-
void _append( BSONObjBuilder& b , const string& fieldName , const string& data ){
- if ( _appendNumber( b , fieldName , data ) )
+ if ( b.appendAsNumber( fieldName , data ) )
return;
if ( _ignoreBlanks && data.size() == 0 )