示例#1
0
 void pp( const char * s , BSONElement e ){
     int len;
     const char * data = e.binData( len );
     cout << s << ":" << e.binDataType() << "\t" << len << endl;
     cout << "\t";
     for ( int i=0; i<len; i++ )
         cout << (int)(data[i]) << " ";
     cout << endl;
 }
示例#2
0
NamespaceStringOrUUID CommandHelpers::parseNsOrUUID(StringData dbname, const BSONObj& cmdObj) {
    BSONElement first = cmdObj.firstElement();
    if (first.type() == BinData && first.binDataType() == BinDataType::newUUID) {
        return uassertStatusOK(UUID::parse(first));
    } else {
        // Ensure collection identifier is not a Command
        const NamespaceString nss(parseNsCollectionRequired(dbname, cmdObj));
        uassert(ErrorCodes::InvalidNamespace,
                str::stream() << "Invalid collection name specified '" << nss.ns() << "'",
                nss.isNormal());
        return nss;
    }
}
示例#3
0
StatusWith<LogicalTimeMetadata> LogicalTimeMetadata::readFromMetadata(
    const BSONElement& metadataElem) {
    if (metadataElem.eoo()) {
        return LogicalTimeMetadata();
    }

    const auto& obj = metadataElem.Obj();

    Timestamp ts;
    Status status = bsonExtractTimestampField(obj, kClusterTimeFieldName, &ts);
    if (!status.isOK()) {
        return status;
    }

    BSONElement signatureElem;
    status = bsonExtractTypedField(obj, kSignatureFieldName, Object, &signatureElem);
    if (!status.isOK()) {
        return status;
    }

    const auto& signatureObj = signatureElem.Obj();

    // Extract BinData type signature hash and construct a SHA1Block instance from it.
    BSONElement hashElem;
    status = bsonExtractTypedField(signatureObj, kSignatureHashFieldName, BinData, &hashElem);
    if (!status.isOK()) {
        return status;
    }

    int hashLength = 0;
    auto rawBinSignature = hashElem.binData(hashLength);
    BSONBinData proofBinData(rawBinSignature, hashLength, hashElem.binDataType());
    auto proofStatus = SHA1Block::fromBinData(proofBinData);

    if (!proofStatus.isOK()) {
        return proofStatus.getStatus();
    }

    long long keyId;
    status = bsonExtractIntegerField(signatureObj, kSignatureKeyIdFieldName, &keyId);
    if (!status.isOK()) {
        return status;
    }

    return LogicalTimeMetadata(
        SignedLogicalTime(LogicalTime(ts), std::move(proofStatus.getValue()), keyId));
}
示例#4
0
NamespaceString Command::parseNsOrUUID(OperationContext* opCtx,
                                       const string& dbname,
                                       const BSONObj& cmdObj) {
    BSONElement first = cmdObj.firstElement();
    if (first.type() == BinData && first.binDataType() == BinDataType::newUUID) {
        StatusWith<UUID> uuidRes = UUID::parse(first);
        uassertStatusOK(uuidRes);
        UUIDCatalog& catalog = UUIDCatalog::get(opCtx);
        return catalog.lookupNSSByUUID(uuidRes.getValue());
    } else {
        // Ensure collection identifier is not a Command
        const NamespaceString nss(parseNsCollectionRequired(dbname, cmdObj));
        uassert(ErrorCodes::InvalidNamespace,
                str::stream() << "Invalid collection name specified '" << nss.ns() << "'",
                nss.isNormal());
        return nss;
    }
}
示例#5
0
 // fromBSON to Key format
 KeyV1Owned::KeyV1Owned(const BSONObj& obj) {
     BSONObj::iterator i(obj);
     unsigned char bits = 0;
     while( 1 ) { 
         BSONElement e = i.next();
         if( i.more() )
             bits |= cHASMORE;
         switch( e.type() ) { 
         case MinKey:
             b.appendUChar(cminkey|bits);
             break;
         case jstNULL:
             b.appendUChar(cnull|bits);
             break;
         case MaxKey:
             b.appendUChar(cmaxkey|bits);
             break;
         case Bool:
             b.appendUChar( (e.boolean()?ctrue:cfalse) | bits );
             break;
         case jstOID:
             b.appendUChar(coid|bits);
             b.appendBuf(&e.__oid(), sizeof(OID));
             break;
         case BinData:
             {
                 int t = e.binDataType();
                 // 0-7 and 0x80 to 0x87 are supported by Key
                 if( (t & 0x78) == 0 && t != ByteArrayDeprecated ) {
                     int len;
                     const char * d = e.binData(len);
                     if( len <= BinDataLenMax ) {
                         int code = BinDataLengthToCode[len];
                         if( code >= 0 ) {
                             if( t >= 128 )
                                 t = (t-128) | 0x08;
                             dassert( (code&t) == 0 );
                             b.appendUChar( cbindata|bits );
                             b.appendUChar( code | t );
                             b.appendBuf(d, len);
                             break;
                         }
                     }
                 }
                 traditional(obj);
                 return;
             }
         case Date:
             b.appendUChar(cdate|bits);
             b.appendStruct(e.date());
             break;
         case String:
             {
                 b.appendUChar(cstring|bits);
                 // note we do not store the terminating null, to save space.
                 unsigned x = (unsigned) e.valuestrsize() - 1;
                 if( x > 255 ) { 
                     traditional(obj);
                     return;
                 }
                 b.appendUChar(x);
                 b.appendBuf(e.valuestr(), x);
                 break;
             }
         case NumberInt:
             b.appendUChar(cint|bits);
             b.appendNum((double) e._numberInt());
             break;
         case NumberLong:
             {
                 long long n = e._numberLong();
                 long long m = 2LL << 52;
                 DEV {
                     long long d = m-1;
                     verify( ((long long) ((double) -d)) == -d );
                 }
                 if( n >= m || n <= -m ) {
                     // can't represent exactly as a double
                     traditional(obj);
                     return;
                 }
                 b.appendUChar(clong|bits);
                 b.appendNum((double) n);
                 break;
             }
         case NumberDouble:
             {
                 double d = e._numberDouble();
                 if( isNaN(d) ) {
                     traditional(obj);
                     return;
                 }
                 b.appendUChar(cdouble|bits);
                 b.appendNum(d);
                 break;
             }
         default:
             // if other types involved, store as traditional BSON
             traditional(obj);
             return;
         }
         if( !i.more() )
             break;
         bits = 0;
     }
     _keyData = (const unsigned char *) b.buf();
     dassert( b.len() == dataSize() ); // check datasize method is correct
     dassert( (*_keyData & cNOTUSED) == 0 );
 }
示例#6
0
Local<v8::Object> mongoToV8( BSONObj & m , bool array ){
    Local<v8::Object> o;
    if ( array )
        o = v8::Array::New();
    else 
        o = v8::Object::New();
    
    mongo::BSONObj sub;
    
    for ( BSONObjIterator i(m); i.more(); ) {
        BSONElement f = i.next();
        if ( f.eoo() )
            break;
        
        Local<Value> v;
        
        switch ( f.type() ){

        case mongo::Code:
            cout << "warning, code saved in database just turned into string right now" << endl;
        case mongo::String: 
            o->Set( v8::String::New( f.fieldName() ) , v8::String::New( f.valuestr() ) );
            break;
            
        case mongo::jstOID: {
            v8::Function * idCons = getObjectIdCons();
            v8::Handle<v8::Value> argv[1];
            argv[0] = v8::String::New( f.__oid().str().c_str() );
            o->Set( v8::String::New( f.fieldName() ) , 
                    idCons->NewInstance( 1 , argv ) );
            break;
        }
            
        case mongo::NumberDouble:
        case mongo::NumberInt:
            o->Set( v8::String::New( f.fieldName() ) , v8::Number::New( f.number() ) );
            break;
            
        case mongo::Array:
        case mongo::Object:
            sub = f.embeddedObject();
            o->Set( v8::String::New( f.fieldName() ) , mongoToV8( sub , f.type() == mongo::Array ) );
            break;
            
        case mongo::Date:
            o->Set( v8::String::New( f.fieldName() ) , v8::Date::New( f.date() ) );
            break;

        case mongo::Bool:
            o->Set( v8::String::New( f.fieldName() ) , v8::Boolean::New( f.boolean() ) );
            break;
            
        case mongo::jstNULL:
            o->Set( v8::String::New( f.fieldName() ) , v8::Null() );
            break;
            
        case mongo::RegEx: {
            v8::Function * regex = getNamedCons( "RegExp" );
            
            v8::Handle<v8::Value> argv[2];
            argv[0] = v8::String::New( f.regex() );
            argv[1] = v8::String::New( f.regexFlags() );
            
            o->Set( v8::String::New( f.fieldName() ) , regex->NewInstance( 2 , argv ) );
            break;
        }
            
        case mongo::BinData: {
            Local<v8::Object> b = v8::Object::New();

            int len;
            f.binData( len );
            
            b->Set( v8::String::New( "subtype" ) , v8::Number::New( f.binDataType() ) );
            b->Set( v8::String::New( "length" ) , v8::Number::New( len ) );
            
            o->Set( v8::String::New( f.fieldName() ) , b );
            break;
        };
            
        case mongo::Timestamp: {
            Local<v8::Object> sub = v8::Object::New();            

            sub->Set( v8::String::New( "time" ) , v8::Date::New( f.timestampTime() ) );
            sub->Set( v8::String::New( "i" ) , v8::Number::New( f.timestampInc() ) );
            
            o->Set( v8::String::New( f.fieldName() ) , sub );
            break;
        }

        default:
            cout << "can't handle type: ";
			cout  << f.type() << " ";
			cout  << f.toString();
			cout  << endl;
            break;
        }
        
    }

    return o;
}
示例#7
0
文件: MongoJS.cpp 项目: alanw/mongo
Handle<v8::Value> mongoToV8Element( const BSONElement &f ) {
    assert( !f.eoo() );
    switch ( f.type() ){
            
        case mongo::Code:
            cout << "warning, code saved in database just turned into string right now" << endl;
        case mongo::String: 
            return v8::String::New( f.valuestr() );
            
        case mongo::jstOID: {
            v8::Function * idCons = getObjectIdCons();
            v8::Handle<v8::Value> argv[1];
            argv[0] = v8::String::New( f.__oid().str().c_str() );
            return idCons->NewInstance( 1 , argv );
        }
            
        case mongo::NumberDouble:
        case mongo::NumberInt:
            return v8::Number::New( f.number() );
            
        case mongo::Array:
        case mongo::Object:
            return mongoToV8( f.embeddedObject() , f.type() == mongo::Array );
            
        case mongo::Date:
            return v8::Date::New( f.date() );
            
        case mongo::Bool:
            return v8::Boolean::New( f.boolean() );
            
        case mongo::jstNULL:
            return v8::Null();
            
        case mongo::RegEx: {
            v8::Function * regex = getNamedCons( "RegExp" );
            
            v8::Handle<v8::Value> argv[2];
            argv[0] = v8::String::New( f.regex() );
            argv[1] = v8::String::New( f.regexFlags() );
            
            return regex->NewInstance( 2 , argv );
            break;
        }
            
        case mongo::BinData: {
            Local<v8::Object> b = v8::Object::New();
            
            int len;
            f.binData( len );
            
            b->Set( v8::String::New( "subtype" ) , v8::Number::New( f.binDataType() ) );
            b->Set( v8::String::New( "length" ) , v8::Number::New( len ) );
            
            return b;
        };
            
        case mongo::Timestamp: {
            Local<v8::Object> sub = v8::Object::New();            
            
            sub->Set( v8::String::New( "time" ) , v8::Date::New( f.timestampTime() ) );
            sub->Set( v8::String::New( "i" ) , v8::Number::New( f.timestampInc() ) );
            
            return sub;
        }
            
        case mongo::MinKey:
            // TODO: make a special type
            return v8::String::New( "MinKey" );
            
        case mongo::MaxKey:
            // TODO: make a special type
            return v8::String::New( "MaxKey" );
            
        case mongo::Undefined:
            return v8::Undefined();
            
        default:
            cout << "can't handle type: ";
			cout  << f.type() << " ";
			cout  << f.toString();
			cout  << endl;
            break;
    }    
    
    return v8::Undefined();
}
示例#8
0
    Handle<v8::Value> mongoToV8Element( const BSONElement &f ) {
        Local< v8::ObjectTemplate > internalFieldObjects = v8::ObjectTemplate::New();
        internalFieldObjects->SetInternalFieldCount( 1 );

        switch ( f.type() ){

        case mongo::Code:
            return newFunction( f.valuestr() );
                
        case CodeWScope:
            if ( f.codeWScopeObject().isEmpty() )
                log() << "warning: CodeWScope doesn't transfer to db.eval" << endl;
            return newFunction( f.codeWScopeCode() );
                
        case mongo::String: 
            return v8::String::New( f.valuestr() );
            
        case mongo::jstOID:
            return newId( f.__oid() );
            
        case mongo::NumberDouble:
        case mongo::NumberInt:
            return v8::Number::New( f.number() );
            
        case mongo::Array:
        case mongo::Object:
            return mongoToV8( f.embeddedObject() , f.type() == mongo::Array );
            
        case mongo::Date:
            return v8::Date::New( f.date() );
            
        case mongo::Bool:
            return v8::Boolean::New( f.boolean() );

        case mongo::EOO:            
        case mongo::jstNULL:
        case mongo::Undefined: // duplicate sm behavior
            return v8::Null();
            
        case mongo::RegEx: {
            v8::Function * regex = getNamedCons( "RegExp" );
            
            v8::Handle<v8::Value> argv[2];
            argv[0] = v8::String::New( f.regex() );
            argv[1] = v8::String::New( f.regexFlags() );
            
            return regex->NewInstance( 2 , argv );
            break;
        }
            
        case mongo::BinData: {
            int len;
            const char *data = f.binData( len );
            
            v8::Function* binData = getNamedCons( "BinData" );
            v8::Handle<v8::Value> argv[3];
            argv[0] = v8::Number::New( len );
            argv[1] = v8::Number::New( f.binDataType() );
            argv[2] = v8::String::New( data, len );
            return binData->NewInstance( 3, argv );
        };
            
        case mongo::Timestamp: {
            Local<v8::Object> sub = internalFieldObjects->NewInstance();
            
            sub->Set( v8::String::New( "time" ) , v8::Date::New( f.timestampTime() ) );
            sub->Set( v8::String::New( "i" ) , v8::Number::New( f.timestampInc() ) );
            sub->SetInternalField( 0, v8::Uint32::New( f.type() ) );

            return sub;
        }
                
        case mongo::NumberLong: {
            Local<v8::Object> sub = internalFieldObjects->NewInstance();
            unsigned long long val = f.numberLong();
            v8::Function* numberLong = getNamedCons( "NumberLong" );
            v8::Handle<v8::Value> argv[2];
            argv[0] = v8::Integer::New( val >> 32 );
            argv[1] = v8::Integer::New( (unsigned long)(val & 0x00000000ffffffff) );
            return numberLong->NewInstance( 2, argv );
        }
            
        case mongo::MinKey: {
            Local<v8::Object> sub = internalFieldObjects->NewInstance();
            sub->Set( v8::String::New( "$MinKey" ), v8::Boolean::New( true ) );
            sub->SetInternalField( 0, v8::Uint32::New( f.type() ) );
            return sub;
        }
            
        case mongo::MaxKey: {
            Local<v8::Object> sub = internalFieldObjects->NewInstance();
            sub->Set( v8::String::New( "$MaxKey" ), v8::Boolean::New( true ) );
            sub->SetInternalField( 0, v8::Uint32::New( f.type() ) );
            return sub;
        }
                
        case mongo::DBRef: {
            v8::Function* dbPointer = getNamedCons( "DBPointer" );
            v8::Handle<v8::Value> argv[2];
            argv[0] = v8::String::New( f.dbrefNS() );
            argv[1] = newId( f.dbrefOID() );
            return dbPointer->NewInstance(2, argv);
        }
                       
        default:
            cout << "can't handle type: ";
			cout  << f.type() << " ";
			cout  << f.toString();
			cout  << endl;
            break;
        }    
        
        return v8::Undefined();
    }
示例#9
0
文件: key.cpp 项目: kzys/mongo
// fromBSON to Key format
KeyV1Owned::KeyV1Owned(const BSONObj& obj) {
    BSONObj::iterator i(obj);
    assert( i.more() );
    unsigned char bits = 0;
    while( 1 ) {
        BSONElement e = i.next();
        if( i.more() )
            bits |= cHASMORE;
        switch( e.type() ) {
        case MinKey:
            b.appendUChar(cminkey|bits);
            break;
        case jstNULL:
            b.appendUChar(cnull|bits);
            break;
        case MaxKey:
            b.appendUChar(cmaxkey|bits);
            break;
        case Bool:
            b.appendUChar( (e.boolean()?ctrue:cfalse) | bits );
            break;
        case jstOID:
            b.appendUChar(coid|bits);
            b.appendBuf(&e.__oid(), sizeof(OID));
            break;
        case BinData:
        {
            int t = e.binDataType();
            // 0-7 and 0x80 to 0x87 are supported by Key
            if( (t & 0x78) == 0 && t != ByteArrayDeprecated ) {
                int len;
                const char * d = e.binData(len);
                int code = BinDataLengthToCode[len];
                if( code >= 0 ) {
                    if( t >= 128 )
                        t = (t-128) | 0x08;
                    dassert( (code&t) == 0 );
                    b.appendUChar( cbindata|bits );
                    b.appendUChar( code | t );
                    b.appendBuf(d, len);
                    break;
                }
            }
            traditional(obj);
            return;
        }
        case Date:
            b.appendUChar(cdate|bits);
            b.appendStruct(e.date());
            break;
        case String:
        {
            b.appendUChar(cstring|bits);
            // note we do not store the terminating null, to save space.
            unsigned x = (unsigned) e.valuestrsize() - 1;
            if( x > 255 ) {
                traditional(obj);
                return;
            }
            b.appendUChar(x);
            b.appendBuf(e.valuestr(), x);
            break;
        }
        case NumberInt:
            b.appendUChar(cint|bits);
            b.appendNum((double) e._numberInt());
            break;
        case NumberLong:
        {
            long long n = e._numberLong();
            double d = (double) n;
            if( d != n ) {
                traditional(obj);
                return;
            }
            b.appendUChar(clong|bits);
            b.appendNum(d);
            break;
        }
        case NumberDouble:
        {
            double d = e._numberDouble();
            bool nan = !( d <= numeric_limits< double >::max() &&
                          d >= -numeric_limits< double >::max() );
            if( !nan ) {
                b.appendUChar(cdouble|bits);
                b.appendNum(d);
                break;
            }
            // else fall through and return a traditional BSON obj so our compressed keys need not check for nan
        }
        default:
            // if other types involved, store as traditional BSON
            traditional(obj);
            return;
        }
        if( !i.more() )
            break;
        bits = 0;
    }
    _keyData = (const unsigned char *) b.buf();
    dassert( b.len() == dataSize() ); // check datasize method is correct
    dassert( (*_keyData & cNOTUSED) == 0 );
}
示例#10
0
    jsval toval( const BSONElement& e ) {

        switch( e.type() ) {
        case EOO:
        case jstNULL:
        case Undefined:
            return JSVAL_NULL;
        case NumberDouble:
        case NumberInt:
            return toval( e.number() );
        case Symbol: // TODO: should we make a special class for this
        case String:
            return toval( e.valuestr() );
        case Bool:
            return e.boolean() ? JSVAL_TRUE : JSVAL_FALSE;
        case Object: {
            BSONObj embed = e.embeddedObject().getOwned();
            return toval( &embed );
        }
        case Array: {

            BSONObj embed = e.embeddedObject().getOwned();

            if ( embed.isEmpty() ) {
                return OBJECT_TO_JSVAL( JS_NewArrayObject( _context , 0 , 0 ) );
            }

            int n = embed.nFields();

            JSObject * array = JS_NewArrayObject( _context , n , 0 );
            assert( array );

            jsval myarray = OBJECT_TO_JSVAL( array );

            for ( int i=0; i<n; i++ ) {
                jsval v = toval( embed[i] );
                assert( JS_SetElement( _context , array , i , &v ) );
            }

            return myarray;
        }
        case jstOID: {
            OID oid = e.__oid();
            JSObject * o = JS_NewObject( _context , &object_id_class , 0 , 0 );
            setProperty( o , "str" , toval( oid.str().c_str() ) );
            return OBJECT_TO_JSVAL( o );
        }
        case RegEx: {
            const char * flags = e.regexFlags();
            uintN flagNumber = 0;
            while ( *flags ) {
                switch ( *flags ) {
                case 'g':
                    flagNumber |= JSREG_GLOB;
                    break;
                case 'i':
                    flagNumber |= JSREG_FOLD;
                    break;
                case 'm':
                    flagNumber |= JSREG_MULTILINE;
                    break;
                //case 'y': flagNumber |= JSREG_STICKY; break;

                default:
                    log() << "warning: unknown regex flag:" << *flags << endl;
                }
                flags++;
            }

            JSObject * r = JS_NewRegExpObject( _context , (char*)e.regex() , strlen( e.regex() ) , flagNumber );
            assert( r );
            return OBJECT_TO_JSVAL( r );
        }
        case Code: {
            JSFunction * func = compileFunction( e.valuestr() );
            return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) );
        }
        case CodeWScope: {
            JSFunction * func = compileFunction( e.codeWScopeCode() );

            BSONObj extraScope = e.codeWScopeObject();
            if ( ! extraScope.isEmpty() ) {
                log() << "warning: CodeWScope doesn't transfer to db.eval" << endl;
            }

            return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) );
        }
        case Date:
            return OBJECT_TO_JSVAL( js_NewDateObjectMsec( _context , (jsdouble) e.date().millis ) );

        case MinKey:
            return OBJECT_TO_JSVAL( JS_NewObject( _context , &minkey_class , 0 , 0 ) );

        case MaxKey:
            return OBJECT_TO_JSVAL( JS_NewObject( _context , &maxkey_class , 0 , 0 ) );

        case Timestamp: {
            JSObject * o = JS_NewObject( _context , &timestamp_class , 0 , 0 );
            setProperty( o , "t" , toval( (double)(e.timestampTime()) ) );
            setProperty( o , "i" , toval( (double)(e.timestampInc()) ) );
            return OBJECT_TO_JSVAL( o );
        }
        case NumberLong: {
            boost::uint64_t val = (boost::uint64_t)e.numberLong();
            JSObject * o = JS_NewObject( _context , &numberlong_class , 0 , 0 );
            setProperty( o , "floatApprox" , toval( (double)(boost::int64_t)( val ) ) );
            if ( (boost::int64_t)val != (boost::int64_t)(double)(boost::int64_t)( val ) ) {
                // using 2 doubles here instead of a single double because certain double
                // bit patterns represent undefined values and sm might trash them
                setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) );
                setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) );
            }
            return OBJECT_TO_JSVAL( o );
        }
        case DBRef: {
            JSObject * o = JS_NewObject( _context , &dbpointer_class , 0 , 0 );
            setProperty( o , "ns" , toval( e.dbrefNS() ) );

            JSObject * oid = JS_NewObject( _context , &object_id_class , 0 , 0 );
            setProperty( oid , "str" , toval( e.dbrefOID().str().c_str() ) );

            setProperty( o , "id" , OBJECT_TO_JSVAL( oid ) );
            return OBJECT_TO_JSVAL( o );
        }
        case BinData: {
            JSObject * o = JS_NewObject( _context , &bindata_class , 0 , 0 );
            int len;
            const char * data = e.binData( len );
            assert( JS_SetPrivate( _context , o , new BinDataHolder( data ) ) );

            setProperty( o , "len" , toval( len ) );
            setProperty( o , "type" , toval( (int)e.binDataType() ) );
            return OBJECT_TO_JSVAL( o );
        }
        }