Status saslExtractPayload(const BSONObj& cmdObj, std::string* payload, BSONType* type) {
        BSONElement payloadElement;
        Status status = bsonExtractField(cmdObj, saslCommandPayloadFieldName, &payloadElement);
        if (!status.isOK())
            return status;

        *type = payloadElement.type();
        if (payloadElement.type() == BinData) {
            const char* payloadData;
            int payloadLen;
            payloadData = payloadElement.binData(payloadLen);
            if (payloadLen < 0)
                return Status(ErrorCodes::InvalidLength, "Negative payload length");
            *payload = std::string(payloadData, payloadData + payloadLen);
        }
        else if (payloadElement.type() == String) {
            try {
                *payload = base64::decode(payloadElement.str());
            } catch (UserException& e) {
                return Status(ErrorCodes::FailedToParse, e.what());
            }
        }
        else {
            return Status(ErrorCodes::TypeMismatch,
                          (str::stream() << "Wrong type for field; expected BinData or String for "
                           << payloadElement));
        }

        return Status::OK();
    }
Exemple #2
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;
 }
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));
}
Exemple #4
0
bool BitTestMatchExpression::matchesSingleElement(const BSONElement& e,
                                                  MatchDetails* details) const {
    // Validate 'e' is a number or a BinData.
    if (!e.isNumber() && e.type() != BSONType::BinData) {
        return false;
    }

    if (e.type() == BSONType::BinData) {
        int eBinaryLen;  // Length of eBinary (in bytes).
        const char* eBinary = e.binData(eBinaryLen);
        return performBitTest(eBinary, eBinaryLen);
    }

    invariant(e.isNumber());

    if (e.type() == BSONType::NumberDouble) {
        double eDouble = e.numberDouble();

        // NaN doubles are rejected.
        if (std::isnan(eDouble)) {
            return false;
        }

        // Integral doubles that are too large or small to be represented as a 64-bit signed
        // integer are treated as 0. We use 'kLongLongMaxAsDouble' because if we just did
        // eDouble > 2^63-1, it would be compared against 2^63. eDouble=2^63 would not get caught
        // that way.
        if (eDouble >= BSONElement::kLongLongMaxPlusOneAsDouble ||
            eDouble < std::numeric_limits<long long>::min()) {
            return false;
        }

        // This checks if e is an integral double.
        if (eDouble != static_cast<double>(static_cast<long long>(eDouble))) {
            return false;
        }
    }

    long long eValue = e.numberLong();
    return performBitTest(eValue);
}
Exemple #5
0
StatusWith<std::vector<BSONObj>> getMetricsFromMetricDoc(const BSONObj& obj,
                                                         FTDCDecompressor* decompressor) {
    if (kDebugBuild) {
        auto swType = getBSONDocumentType(obj);
        dassert(swType.isOK() && swType.getValue() == FTDCType::kMetricChunk);
    }

    BSONElement element;

    Status status = bsonExtractTypedField(obj, kFTDCDataField, BSONType::BinData, &element);
    if (!status.isOK()) {
        return {status};
    }

    int length;
    const char* buffer = element.binData(length);
    if (length < 0) {
        return {ErrorCodes::BadValue,
                str::stream() << "Field " << std::string(kFTDCTypeField) << " is not a BinData."};
    }

    return decompressor->uncompress({buffer, static_cast<std::size_t>(length)});
}
Exemple #6
0
int main() {
    cout << "build bits: " << 8 * sizeof(char *) << '\n' <<  endl;

    /* a bson object defaults on construction to { } */
    bo empty;
    cout << "empty: " << empty << endl;

    /* make a simple { name : 'joe', age : 33.7 } object */
    {
        bob b;
        b.append("name", "joe");
        b.append("age", 33.7);
        bo c = b.obj();
        cout << "c: " << c << endl;
    }

    /* make { name : 'joe', age : 33.7 } with a more compact notation. */
    bo x = bob().append("name", "joe").append("age", 33.7).obj();

    /* convert from bson to json */
    string json = x.toString();
    cout << "json for x:" << json << endl;

    /* access some fields of bson object x */
    cout << "Some x things: " << x["name"] << ' ' << x["age"].Number() << ' ' << x.isEmpty() << endl;

    /* make a bit more complex object with some nesting
       { x : 'asdf', y : true, subobj : { z : 3, q : 4 } }
    */
    bo y = BSON( "x" << "asdf" << "y" << true << "subobj" << BSON( "z" << 3 << "q" << 4 ) );

    /* print it */
    cout << "y: " << y << endl;

    /* reach in and get subobj.z */
    cout << "subobj.z: " << y.getFieldDotted("subobj.z").Number() << endl;

    /* alternate syntax: */
    cout << "subobj.z: " << y["subobj"]["z"].Number() << endl;

    /* fetch all *top level* elements from object y into a vector */
    vector<be> v;
    y.elems(v);
    cout << v[0] << endl;

    /* into an array */
    list<be> L;
    y.elems(L);

    // --------------- MYTEST mytest --------------------
    {
        bob b;
        b.append("name", "joe");
        b.append("age", 33);
//        bo c = b.obj();
//        cout << "c.isOwned: " << c.isOwned() << endl;
//        cout << "c.isEmpty: " << c.isEmpty() << endl;
//        cout << "c.isValid: " << c.isValid() << endl;
//        cout << "c: " << c << endl;

        char binbuf[128];
        unsigned int*  plen  = (unsigned int* )binbuf;
        unsigned char* ptype = (unsigned char*)(&binbuf[1]);
        unsigned int*  puint = (unsigned int*)(&ptype[1]);
        for (int i=0; i<10; i++)
        {
            puint[i] = i;
        }
        for (int i=0; i<10; i++)
        {
            puint[i+10] = i;
        }
        *plen = 10*sizeof(unsigned int);
        *ptype = BinData;
        bo bbtest(binbuf);
        printf("---size: %u orig-len: %u valid:%u\n", bbtest.objsize(), 10*sizeof(unsigned int), bbtest.isValid());

        const char* pstr = bbtest.objdata();
        unsigned int*  pplen  = (unsigned int* )pstr;
        unsigned char* pptype = (unsigned char*)(&pplen[1]);
        unsigned int*  ppuint = (unsigned int*)(&pplen[1]);
        printf("bin-data-len: %u olen: %u type: %u\n", *pplen, *plen, *pptype);
//        assert(*pptype == BinData);
        
//        bo sbb = bob().append("bbtest", bbtest).obj();
//        bo sbbb = bob().append("bbbtest", bbtest).obj();
//        sbb.getOwned();
//        cout << "sbb.isOwned: " << sbb.isOwned() << endl;
//        cout << "sbb.isEmpty: " << sbb.isEmpty() << endl;
//        cout << "sbb.isValid: " << sbb.isValid() << endl;
//        set<string> sss;
//        sss.insert("bbtest");
//
//        set<string> ssss;
//        ssss.insert("bbbtest");

//        b.append("bbtest", bbtest);
        b.appendBinData("bbtest", (int)(20*sizeof(unsigned int)), BinDataGeneral, (char*)puint);
        bo c = b.obj();
        cout << "c.isOwned: " << c.isOwned() << endl;
        cout << "c.isEmpty: " << c.isEmpty() << endl;
        cout << "c.isValid: " << c.isValid() << endl;
        cout << "c[\"age\"]: " << c["age"].Number() << endl;

        char tmpbuf[1280];
        printf("--- c -size: %u valid:%u\n", c.objsize(), c.isValid());
        memmove(tmpbuf, c.objdata(), c.objsize());

        bo cc(tmpbuf);
        cout << "bbtest size: " << cc["bbtest"].objsize() << endl;

        BSONElement be = cc.getField("bbtest");
        printf("be.eoo() = [%u]\n", be.eoo());

        int len = 0;
        const int* pdata = (const int*)be.binData(len);
        printf("len = [%u]\n", len);
        for(int i=0; i<len/sizeof(int); i++)
        {
            printf("[%d] [%d]\n", i, pdata[i]);
        }
        
    }
    // --------------- MYTEST mytest -------- END -------
    bo sub = y["subobj"].Obj();

    /* grab all the int's that were in subobj.  if it had elements that were not ints, we throw an exception
       (capital V on Vals() means exception if wrong type found
       */
    vector<int> myints;
    sub.Vals(myints);
    cout << "my ints: " << myints[0] << ' ' << myints[1] << endl;

    /* grab all the string values from x.  if the field isn't of string type, just skip it --
       lowercase v on vals() indicates skip don't throw.
       */
    vector<string> strs;
    x.vals(strs);
    cout << strs.size() << " strings, first one: " << strs[0] << endl;

    iter(y);
    return 0;
}
Exemple #7
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 );
 }
Exemple #8
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;
}
Exemple #9
0
static void bson2bamboo(const dclass::DistributedType *type,
                        const BSONElement &element,
                        Datagram &dg)
{
    switch(type->get_type()) {
    case dclass::Type::T_INT8: {
        dg.add_int8(element.Int());
    }
    break;
    case dclass::Type::T_INT16: {
        dg.add_int16(element.Int());
    }
    break;
    case dclass::Type::T_INT32: {
        dg.add_int32(element.Int());
    }
    break;
    case dclass::Type::T_INT64: {
        dg.add_int64(element.Int());
    }
    break;
    case dclass::Type::T_UINT8: {
        dg.add_uint8(element.Int());
    }
    break;
    case dclass::Type::T_UINT16: {
        dg.add_uint16(element.Int());
    }
    break;
    case dclass::Type::T_UINT32: {
        dg.add_uint32(element.Int());
    }
    break;
    case dclass::Type::T_UINT64: {
        dg.add_uint64(element.Int());
    }
    break;
    case dclass::Type::T_CHAR: {
        string str = element.String();
        if(str.size() != 1) {
            throw mongo::DBException("Expected single-length string for char field", 0);
        }
        dg.add_uint8(str[0]);
    }
    break;
    case dclass::Type::T_FLOAT32: {
        dg.add_float32(element.Number());
    }
    break;
    case dclass::Type::T_FLOAT64: {
        dg.add_float64(element.Number());
    }
    break;
    case dclass::Type::T_STRING: {
        dg.add_data(element.String());
    }
    break;
    case dclass::Type::T_VARSTRING: {
        dg.add_string(element.String());
    }
    break;
    case dclass::Type::T_BLOB: {
        int len;
        const uint8_t *rawdata = (const uint8_t *)element.binData(len);
        dg.add_data(rawdata, len);
    }
    break;
    case dclass::Type::T_VARBLOB: {
        int len;
        const uint8_t *rawdata = (const uint8_t *)element.binData(len);
        dg.add_blob(rawdata, len);
    }
    break;
    case dclass::Type::T_ARRAY: {
        const dclass::ArrayType *array = type->as_array();
        std::vector<BSONElement> data = element.Array();

        for(auto it = data.begin(); it != data.end(); ++it) {
            bson2bamboo(array->get_element_type(), *it, dg);
        }
    }
    break;
    case dclass::Type::T_VARARRAY: {
        const dclass::ArrayType *array = type->as_array();
        std::vector<BSONElement> data = element.Array();

        DatagramPtr newdg = Datagram::create();

        for(auto it = data.begin(); it != data.end(); ++it) {
            bson2bamboo(array->get_element_type(), *it, *newdg);
        }

        dg.add_blob(newdg->get_data(), newdg->size());
    }
    break;
    case dclass::Type::T_STRUCT: {
        const dclass::Struct *s = type->as_struct();
        size_t fields = s->get_num_fields();
        for(unsigned int i = 0; i < fields; ++i) {
            const dclass::Field *field = s->get_field(i);
            bson2bamboo(field->get_type(), element[field->get_name()], dg);
        }
    }
    break;
    case dclass::Type::T_METHOD: {
        const dclass::Method *m = type->as_method();
        size_t parameters = m->get_num_parameters();
        for(unsigned int i = 0; i < parameters; ++i) {
            const dclass::Parameter *parameter = m->get_parameter(i);
            string name = parameter->get_name();
            if(name.empty() || element[name].eoo()) {
                stringstream n;
                n << "_" << i;
                name = n.str();
            }
            bson2bamboo(parameter->get_type(), element[name], dg);
        }
    }
    break;
    case dclass::Type::T_INVALID:
    default:
        assert(false);
        break;
    }
}
Exemple #10
0
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();
}
Exemple #11
0
void lua_push_value(lua_State *L, const BSONElement &elem) {
    lua_checkstack(L, 2);
    int type = elem.type();

    switch(type) {
    case mongo::Undefined:
        lua_pushnil(L);
        break;
    case mongo::NumberInt:
        lua_pushinteger(L, elem.numberInt());
        break;
    case mongo::NumberLong:
    case mongo::NumberDouble:
        lua_pushnumber(L, elem.number());
        break;
    case mongo::Bool:
        lua_pushboolean(L, elem.boolean());
        break;
    case mongo::String:
        lua_pushstring(L, elem.valuestr());
        break;
    case mongo::Array:
        bson_to_array(L, elem.embeddedObject());
        break;
    case mongo::Object:
        bson_to_table(L, elem.embeddedObject());
        break;
    case mongo::Date:
        push_bsontype_table(L, mongo::Date);
        lua_pushnumber(L, elem.date());
        lua_rawseti(L, -2, 1);
        break;
    case mongo::Timestamp:
        push_bsontype_table(L, mongo::Date);
        lua_pushnumber(L, elem.timestampTime());
        lua_rawseti(L, -2, 1);
        break;
    case mongo::Symbol:
        push_bsontype_table(L, mongo::Symbol);
        lua_pushstring(L, elem.valuestr());
        lua_rawseti(L, -2, 1);
        break;
    case mongo::BinData: {
        push_bsontype_table(L, mongo::BinData);
        int l;
        const char* c = elem.binData(l);
        lua_pushlstring(L, c, l);
        lua_rawseti(L, -2, 1);
        break;
    }
    case mongo::RegEx:
        push_bsontype_table(L, mongo::RegEx);
        lua_pushstring(L, elem.regex());
        lua_rawseti(L, -2, 1);
        lua_pushstring(L, elem.regexFlags());
        lua_rawseti(L, -2, 2);
        break;
    case mongo::jstOID:
        push_bsontype_table(L, mongo::jstOID);
        lua_pushstring(L, elem.__oid().str().c_str());
        lua_rawseti(L, -2, 1);
        break;
    case mongo::jstNULL:
        push_bsontype_table(L, mongo::jstNULL);
        break;
    case mongo::EOO:
        break;
    /*default:
        luaL_error(L, LUAMONGO_UNSUPPORTED_BSON_TYPE, bson_name(type));*/
    }
}
Exemple #12
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();
    }
Exemple #13
0
// 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 );
}
Exemple #14
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 );
        }
        }