void mongoDateToBSON(const Object& value, const char* key, bson_t* bson) { int64_t mili = (value->o_get("sec").toInt64() * 1000) + (value->o_get("usec").toInt64() / 1000); bson_append_date_time(bson, key, -1, mili); }
void VariantToBsonConverter::_convertRegex(bson_t *bson, const char *key, Object v) { String regex = v.o_get(s_MongoBsonRegex_pattern, false, s_MongoBsonRegex_className).toString(); String flags = v.o_get(s_MongoBsonRegex_flags, false, s_MongoBsonRegex_className).toString(); bson_append_regex(bson, key, -1, regex.c_str(), flags.c_str()); }
bool TestExtVariable::test_unserialize() { { // this was crashing unserialize_from_string(StringUtil::HexDecode("53203a20224c612072756f74612067697261207065722074757474692220204d203a20227365636f6e646f206d6520736920c3a820696e6361737472617461206461207175616c6368652070617274652122")); } { Variant v = unserialize_from_string("O:8:\"stdClass\":1:{s:4:\"name\";s:5:\"value\";}"); VERIFY(v.is(KindOfObject)); Object obj = v.toObject(); VS(obj->o_getClassName(), "stdClass"); VS(obj.o_get("name"), "value"); } { Variant v = unserialize_from_string(String("O:8:\"stdClass\":1:{s:7:\"\0*\0name\";s:5:\"value\";}", 45, AttachLiteral)); VERIFY(v.is(KindOfObject)); Object obj = v.toObject(); VS(obj->o_getClassName(), "stdClass"); VS(obj.o_get("name"), uninit_null()); } { Variant v1 = CREATE_MAP3("a","apple","b",2,"c",CREATE_VECTOR3(1,"y",3)); Variant v2 = unserialize_from_string("a:3:{s:1:\"a\";s:5:\"apple\";s:1:\"b\";i:2;s:1:\"c\";a:3:{i:0;i:1;i:1;s:1:\"y\";i:2;i:3;}}"); VS(v1, v2); } return Count(true); }
/* {{{ MongoDriver\BSON\Binary */ void VariantToBsonConverter::_convertBinary(bson_t *bson, const char *key, Object v) { String data = v.o_get(s_MongoBsonBinary_data, false, s_MongoBsonBinary_className).toString(); int64_t type = v.o_get(s_MongoBsonBinary_type, false, s_MongoBsonBinary_className).toInt64(); bson_append_binary(bson, key, -1, (bson_subtype_t) type, (const unsigned char*) data.c_str(), data.length()); }
void mongoBinDataToBSON(const Object& value, const char* key, bson_t* bson) { const String& binary = value->o_get("bin").toString(); bson_append_binary(bson, key, -1, (bson_subtype_t) value->o_get("type").toInt32(), (const uint8_t*) binary.c_str(), binary.size() ); }
void mongoCodeToBSON(const Object& value, const char* key, bson_t* bson) { bson_t child; bson_init(&child); fillBSONWithArray( value->o_get("scope", true, s_MongoCode.get()).toArray(), &child ); bson_append_code_with_scope(bson, key, -1, value->o_get("code", true, s_MongoCode.get()).toString().c_str(), &child ); }
/* {{{ MongoDriver\BSON\Timestamp */ void VariantToBsonConverter::_convertTimestamp(bson_t *bson, const char *key, Object v) { int32_t timestamp = v.o_get(s_MongoBsonTimestamp_timestamp, false, s_MongoBsonTimestamp_className).toInt32(); int32_t increment = v.o_get(s_MongoBsonTimestamp_increment, false, s_MongoBsonTimestamp_className).toInt32(); bson_append_timestamp(bson, key, -1, timestamp, increment); }
void binary_serialize_spec(const Object& zthis, PHPOutputTransport& transport, const Array& spec) { for (ArrayIter key_ptr = spec.begin(); !key_ptr.end(); ++key_ptr) { Variant key = key_ptr.first(); if (!key.isInteger()) { throw_tprotocolexception("Bad keytype in TSPEC (expected 'long')", INVALID_DATA); return; } unsigned long fieldno = key.toInt64(); Array fieldspec = key_ptr.second().toArray(); // field name String varname = fieldspec.rvalAt(PHPTransport::s_var, AccessFlags::Error_Key).toString(); // thrift type int8_t ttype = fieldspec.rvalAt(PHPTransport::s_type, AccessFlags::Error_Key).toByte(); Variant prop = zthis->o_get(varname, true, zthis->getClassName()); if (!prop.isNull()) { transport.writeI8(ttype); transport.writeI16(fieldno); binary_serialize(ttype, transport, prop, fieldspec); } } transport.writeI8(T_STOP); // struct end }
/* {{{ MongoDriver\BSON\Javascript */ void VariantToBsonConverter::_convertJavascript(bson_t *bson, const char *key, Object v) { bson_t *scope_bson; String code = v.o_get(s_MongoBsonJavascript_code, false, s_MongoBsonJavascript_className).toString(); auto scope = v.o_get(s_MongoBsonJavascript_scope, false, s_MongoBsonJavascript_className); if (scope.isObject() || scope.isArray()) { /* Convert scope to document */ VariantToBsonConverter converter(scope, HIPPO_BSON_NO_FLAGS); scope_bson = bson_new(); converter.convert(scope_bson); bson_append_code_with_scope(bson, key, -1, (const char*) code.c_str(), scope_bson); } else { bson_append_code(bson, key, -1, (const char*) code.c_str()); } }
bool TestExtVariable::test_unserialize() { { Variant v = f_unserialize("O:8:\"stdClass\":1:{s:4:\"name\";s:5:\"value\";}"); VERIFY(v.is(KindOfObject)); Object obj = v.toObject(); VS(obj->o_getClassName(), "stdClass"); VS(obj.o_get("name"), "value"); } { Variant v = f_unserialize(String("O:8:\"stdClass\":1:{s:7:\"\0*\0name\";s:5:\"value\";}", 45, AttachLiteral)); VERIFY(v.is(KindOfObject)); Object obj = v.toObject(); VS(obj->o_getClassName(), "stdClass"); VS(obj.o_get("name"), "value"); } { Variant v1 = CREATE_MAP3("a","apple","b",2,"c",CREATE_VECTOR3(1,"y",3)); Variant v2 = f_unserialize("a:3:{s:1:\"a\";s:5:\"apple\";s:1:\"b\";i:2;s:1:\"c\";a:3:{i:0;i:1;i:1;s:1:\"y\";i:2;i:3;}}"); VS(v1, v2); } return Count(true); }
Object HHVM_METHOD(MongoDBDriverServer, executeCommand, const String &db, const Object &command, const Variant &readPreference) { bson_t *bson; MongoDBDriverServerData* data = Native::data<MongoDBDriverServerData>(this_); auto zquery = command->o_get(s_command, false, s_MongoDriverCommand_className); VariantToBsonConverter converter(zquery, HIPPO_BSON_NO_FLAGS); bson = bson_new(); converter.convert(bson); return MongoDriver::Utils::doExecuteCommand( db.c_str(), data->m_client, data->m_server_id, bson, readPreference ); }
/** * invokeHandler returns true if any autoload handlers were executed, * false otherwise. When this function returns true, it is the caller's * responsibility to check if the given class or interface exists. */ bool AutoloadHandler::invokeHandler(const String& className, bool forceSplStack /* = false */) { if (className.empty()) { return false; } if (!m_map.isNull()) { ClassExistsChecker ce; Result res = loadFromMap(className, s_class, true, ce); if (res == ContinueAutoloading) { if (ce(className)) return true; } else { if (res != Failure) return res == Success; } } // If we end up in a recursive autoload loop where we try to load the // same class twice, just fail the load to mimic PHP as many frameworks // rely on it unless we are forcing a restart (due to spl_autoload_call) // in which case autoload is allowed to be reentrant. if (!forceSplStack) { if (m_loading.exists(className)) { return false; } m_loading.add(className, className); } else { // We can still overflow the stack if there is a loop when using // spl_autoload_call directly, but this behavior matches the reference // implementation. m_loading.append(className); } // Make sure state is cleaned up from this load; autoloading of arbitrary // code below can throw SCOPE_EXIT { String l_className = m_loading.pop(); assert(l_className == className); }; Array params = PackedArrayInit(1).append(className).toArray(); if (!m_spl_stack_inited && !forceSplStack) { if (function_exists(s___autoload)) { invoke(s___autoload, params, -1, true, false); return true; } return false; } if (!m_spl_stack_inited || m_handlers.empty()) { return false; } Object autoloadException; for (const HandlerBundle& hb : m_handlers) { try { vm_call_user_func_cufiter(*hb.m_cufIter, params); } catch (Object& ex) { assert(ex.instanceof(SystemLib::s_ExceptionClass)); if (autoloadException.isNull()) { autoloadException = ex; } else { Object cur = ex; Variant next = cur->o_get(s_previous, false, s_exception); while (next.isObject()) { cur = next.toObject(); next = cur->o_get(s_previous, false, s_exception); } cur->o_set(s_previous, autoloadException, s_exception); autoloadException = ex; } } if (Unit::lookupClass(className.get()) != nullptr) { break; } } if (!autoloadException.isNull()) { throw autoloadException; } return true; }
/** * invokeHandler returns true if any autoload handlers were executed, * false otherwise. When this function returns true, it is the caller's * responsibility to check if the given class or interface exists. */ bool AutoloadHandler::invokeHandler(const String& className, bool forceSplStack /* = false */) { if (!m_map.isNull()) { ClassExistsChecker ce; Result res = loadFromMap(className, s_class, true, ce); if (res == ContinueAutoloading) { if (ce(className)) return true; } else { if (res != Failure) return res == Success; } } // If we end up in a recursive autoload loop where we try to load the same // class twice, just fail the load to mimic PHP as many frameworks rely on it if (m_loading.valueExists(className)) { return false; } m_loading.append(className); // The below code can throw so make sure we clean up the state from this load SCOPE_EXIT { String l_className = m_loading.pop(); assert(l_className == className); }; Array params = PackedArrayInit(1).append(className).toArray(); if (!m_spl_stack_inited && !forceSplStack) { if (function_exists(s___autoload)) { invoke(s___autoload, params, -1, true, false); return true; } return false; } if (!m_spl_stack_inited || m_handlers.empty()) { return false; } Object autoloadException; for (const HandlerBundle& hb : m_handlers) { try { vm_call_user_func_cufiter(*hb.m_cufIter, params); } catch (Object& ex) { assert(ex.instanceof(SystemLib::s_ExceptionClass)); if (autoloadException.isNull()) { autoloadException = ex; } else { Object cur = ex; Variant next = cur->o_get(s_previous, false, s_exception); while (next.isObject()) { cur = next.toObject(); next = cur->o_get(s_previous, false, s_exception); } cur->o_set(s_previous, autoloadException, s_exception); autoloadException = ex; } } if (Unit::lookupClass(className.get()) != nullptr) { break; } } if (!autoloadException.isNull()) { throw autoloadException; } return true; }
/* {{{ MongoDriver\BSON\UTCDateTime */ void VariantToBsonConverter::_convertUTCDateTime(bson_t *bson, const char *key, Object v) { int64_t milliseconds = v.o_get(s_MongoBsonUTCDateTime_milliseconds, false, s_MongoBsonUTCDateTime_className).toInt64(); bson_append_date_time(bson, key, -1, milliseconds); }
void mongoTimestampToBSON(const Object& value, const char* key, bson_t* bson) { bson_append_timestamp(bson, key, -1, value->o_get("sec").toInt64(), value->o_get("inc").toInt64() ); }
void mongoRegexToBSON(const Object& value, const char* key, bson_t* bson) { bson_append_regex(bson, key, -1, value->o_get("regex").toString().c_str(), value->o_get("flags").toString().c_str() ); }
void mongoIdToBSON(const Object& value, const char* key, bson_t* bson) { bson_oid_t oid; bson_oid_init_from_string(&oid, value->o_get("$id").toString().c_str()); bson_append_oid(bson, key, -1, &oid); }
// Find a symbol given by string key of the specified symbol type. Context // information can be specified through ctx, sym, and ar. // // StaticRoot, StaticProp // * Search for a static property given by key in class ctx // * A class name may be encoded with the property as *classname*propname // to indicate a class that should be used as the visibility context for // loading the property static Variant xdebug_lookup_symbol(SymbolType type, String key, Class*& ctx, Variant& sym, ActRec* ar) { char* name = key.get()->mutableData(); char* end = key.get()->mutableData() + key.size(); assert(name != end); switch (type) { case SymbolType::StaticRoot: case SymbolType::StaticProp: { TypedValue* ret = nullptr; if (!ctx) return uninit_null(); Class* newCtx = nullptr; char* secStar; bool vis, acc; if ((ret = ctx->getSProp(ctx, key.get(), vis, acc))) { return tvAsVariant(ret); } for (secStar = name + 1; secStar != end && *secStar != '*'; ++secStar); if (secStar != end && *name == '*' && *secStar == '*') { String clsKey(name + 1, secStar - name - 1, CopyStringMode()); String newKey(secStar + 1, end - secStar - 1, CopyStringMode()); newCtx = Unit::lookupClass(clsKey.get()); if (newCtx && (ret = ctx->getSProp(newCtx, newKey.get(), vis, acc))) { return tvAsVariant(ret); } } return uninit_null(); } break; case SymbolType::Root: { const Func* func = ar->func(); if (key.size() == 4 && strncmp(name, "this", 4) == 0) { return ar->hasThis() ? ar->getThis() : nullptr; } Id localId = func->lookupVarId(key.get()); if (localId != kInvalidId) { TypedValue* tv = frame_local(ar, localId); return tv ? tvAsVariant(tv) : uninit_null(); } Class* tmp = Unit::lookupClass(key.get()); if (tmp) ctx = tmp; return uninit_null(); } break; case SymbolType::ArrayIndexAssoc: { return sym.isArray() ? sym.asArrRef().rvalAt(key) : sym.isObject() ? sym.asObjRef().o_get(key, false) : uninit_null(); } case SymbolType::ArrayIndexNum: { int64_t iKey = key.toInt64(); return sym.isArray() ? sym.asArrRef().rvalAt(iKey) : uninit_null(); } case SymbolType::ObjProp: { char* secStar; if (!sym.is(KindOfObject)) return uninit_null(); Object obj = sym.toObject(); Variant v = obj->o_get(key, false); if(!v.isNull()) return v; for (secStar = name + 1; secStar != end && *secStar != '*'; ++secStar); if (secStar != end && *name == '*' && *secStar == '*') { String clsKey(name + 1, secStar - name - 1, CopyStringMode()); String newKey(secStar + 1, end - secStar - 1, CopyStringMode()); v = obj.o_get(key, false, clsKey); } return v; } } not_reached(); }
void mongoInt64ToBSON(const Object& value, const char* key, bson_t* bson) { bson_append_int64(bson, key, -1, value->o_get("value").toInt64()); }