Ejemplo n.º 1
0
 void BSONElement::validate() const {
     switch( type() ) {
         case DBRef:
         case Code:
         case Symbol:
         case String:
             massert( "Invalid dbref/code/string/symbol size",
                     valuestrsize() > 0 &&
                     valuestrsize() - 1 == strnlen( valuestr(), valuestrsize() ) );
             break;
         case CodeWScope: {
             int totalSize = *( int * )( value() );
             massert( "Invalid CodeWScope size", totalSize >= 8 );
             int strSizeWNull = *( int * )( value() + 4 );
             massert( "Invalid CodeWScope string size", totalSize >= strSizeWNull + 4 + 4 );
             massert( "Invalid CodeWScope string size",
                     strSizeWNull > 0 &&
                     strSizeWNull - 1 == strnlen( codeWScopeCode(), strSizeWNull ) );
             massert( "Invalid CodeWScope size", totalSize >= strSizeWNull + 4 + 4 + 4 );
             int objSize = *( int * )( value() + 4 + 4 + strSizeWNull );
             massert( "Invalid CodeWScope object size", totalSize == 4 + 4 + strSizeWNull + objSize );
             // Subobject validation handled elsewhere.
         }
         case Object:
             // We expect Object size validation to be handled elsewhere.
         default:
             break;
     }
 }
std::string BSONElement::_asCode() const {
    switch (type()) {
        case mongo::String:
        case Code:
            return std::string(valuestr(), valuestrsize() - 1);
        case CodeWScope:
            return std::string(codeWScopeCode(),
                               ConstDataView(valuestr()).read<LittleEndian<int>>() - 1);
        default:
            log() << "can't convert type: " << (int)(type()) << " to code" << std::endl;
    }
    uassert(10062, "not code", 0);
    return "";
}
Ejemplo n.º 3
0
    string BSONElement::toString( bool includeFieldName ) const {
        stringstream s;
        if ( includeFieldName && type() != EOO )
            s << fieldName() << ": ";
        switch ( type() ) {
        case EOO:
            return "EOO";
        case Date:
            s << "Date(" << hex << date() << ')';
            break;
        case RegEx:
        {
            s << "/" << regex() << '/';
            const char *p = regexFlags();
            if ( p ) s << p;
        }
        break;
        case NumberDouble:
			{
				stringstream tmp;
				tmp.precision( 16 );
				tmp << number();
				string n = tmp.str();
				s << n;
				// indicate this is a double:
				if( strchr(n.c_str(), '.') == 0 && strchr(n.c_str(), 'E') == 0 && strchr(n.c_str(), 'N') == 0 )
					s << ".0";
			}
            break;
        case NumberInt:
            s.precision( 16 );
            s << number();
            //s << "(" << ( type() == NumberInt ? "int" : "double" ) << ")";
            break;
        case Bool:
            s << ( boolean() ? "true" : "false" );
            break;
        case Object:
        case Array:
            s << embeddedObject().toString();
            break;
        case Undefined:
            s << "undefined";
            break;
        case jstNULL:
            s << "null";
            break;
        case MaxKey:
            s << "MaxKey";
            break;
        case MinKey:
            s << "MinKey";
            break;
        case CodeWScope:
            s << "CodeWScope( "
                << codeWScopeCode() << ", " << codeWScopeObject().toString() << ")";
            break;
        case Code:
            if ( valuestrsize() > 80 )
                s << string(valuestr()).substr(0, 70) << "...";
            else {
                s << valuestr();
            }
            break;
        case Symbol:
        case String:
            if ( valuestrsize() > 80 )
                s << '"' << string(valuestr()).substr(0, 70) << "...\"";
            else {
                s << '"' << valuestr() << '"';
            }
            break;
        case DBRef:
            s << "DBRef('" << valuestr() << "',";
            {
                OID *x = (OID *) (valuestr() + valuestrsize());
                s << *x << ')';
            }
            break;
        case jstOID:
            s << "ObjId(";
            s << __oid() << ')';
            break;
        case BinData:
            s << "BinData";
            break;
        case Timestamp:
            s << "Timestamp " << timestampTime() << "|" << timestampInc();
            break;
        default:
            s << "?type=" << type();
            break;
        }
        return s.str();
    }
void BSONElement::toString(
    StringBuilder& s, bool includeFieldName, bool full, bool redactValues, int depth) const {
    if (depth > BSONObj::maxToStringRecursionDepth) {
        // check if we want the full/complete string
        if (full) {
            StringBuilder s;
            s << "Reached maximum recursion depth of ";
            s << BSONObj::maxToStringRecursionDepth;
            uassert(16150, s.str(), full != true);
        }
        s << "...";
        return;
    }

    if (includeFieldName && type() != EOO)
        s << fieldName() << ": ";

    switch (type()) {
        case Object:
            return embeddedObject().toString(s, false, full, redactValues, depth + 1);
        case mongo::Array:
            return embeddedObject().toString(s, true, full, redactValues, depth + 1);
        default:
            break;
    }

    if (redactValues) {
        s << "\"###\"";
        return;
    }

    switch (type()) {
        case EOO:
            s << "EOO";
            break;
        case mongo::Date:
            s << "new Date(" << date().toMillisSinceEpoch() << ')';
            break;
        case RegEx: {
            s << "/" << regex() << '/';
            const char* p = regexFlags();
            if (p)
                s << p;
        } break;
        case NumberDouble:
            s.appendDoubleNice(number());
            break;
        case NumberLong:
            s << _numberLong();
            break;
        case NumberInt:
            s << _numberInt();
            break;
        case NumberDecimal:
            s << _numberDecimal().toString();
            break;
        case mongo::Bool:
            s << (boolean() ? "true" : "false");
            break;
        case Undefined:
            s << "undefined";
            break;
        case jstNULL:
            s << "null";
            break;
        case MaxKey:
            s << "MaxKey";
            break;
        case MinKey:
            s << "MinKey";
            break;
        case CodeWScope:
            s << "CodeWScope( " << codeWScopeCode() << ", " << codeWScopeObject().toString() << ")";
            break;
        case Code:
            if (!full && valuestrsize() > 80) {
                s.write(valuestr(), 70);
                s << "...";
            } else {
                s.write(valuestr(), valuestrsize() - 1);
            }
            break;
        case Symbol:
        case mongo::String:
            s << '"';
            if (!full && valuestrsize() > 160) {
                s.write(valuestr(), 150);
                s << "...\"";
            } else {
                s.write(valuestr(), valuestrsize() - 1);
                s << '"';
            }
            break;
        case DBRef:
            s << "DBRef('" << valuestr() << "',";
            s << mongo::OID::from(valuestr() + valuestrsize()) << ')';
            break;
        case jstOID:
            s << "ObjectId('";
            s << __oid() << "')";
            break;
        case BinData: {
            int len;
            const char* data = binDataClean(len);
            // If the BinData is a correctly sized newUUID, display it as such.
            if (binDataType() == newUUID && len == 16) {
                // 4 Octets - 2 Octets - 2 Octets - 2 Octets - 6 Octets
                s << "UUID(\"";
                s << toHexLower(&data[0], 4);
                s << "-";
                s << toHexLower(&data[4], 2);
                s << "-";
                s << toHexLower(&data[6], 2);
                s << "-";
                s << toHexLower(&data[8], 2);
                s << "-";
                s << toHexLower(&data[10], 6);
                s << "\")";
                break;
            }
            s << "BinData(" << binDataType() << ", ";
            if (!full && len > 80) {
                s << toHex(data, 70) << "...)";
            } else {
                s << toHex(data, len) << ")";
            }
        } break;

        case bsonTimestamp: {
            // Convert from Milliseconds to Seconds for consistent Timestamp printing.
            auto secs = duration_cast<Seconds>(timestampTime().toDurationSinceEpoch());
            s << "Timestamp(" << secs.count() << ", " << timestampInc() << ")";
        } break;
        default:
            s << "?type=" << type();
            break;
    }
}