int64_t convertDynamicIfIntegral(const folly::dynamic& val) { if (val.isInt()) { return val.getInt(); } double dbl = val.getDouble(); int64_t result = static_cast<int64_t>(dbl); if (dbl != result) { throwNewJavaException( exceptions::gUnexpectedNativeTypeExceptionClass, "Tried to read an int, but got a non-integral double: %f", dbl); } return result; }
JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) { switch (obj.type()) { // For primitive types (and strings), just create and return an equivalent JSValue case folly::dynamic::Type::NULLT: return JSC_JSValueMakeNull(ctx); case folly::dynamic::Type::BOOL: return JSC_JSValueMakeBoolean(ctx, obj.getBool()); case folly::dynamic::Type::DOUBLE: return JSC_JSValueMakeNumber(ctx, obj.getDouble()); case folly::dynamic::Type::INT64: return JSC_JSValueMakeNumber(ctx, obj.asDouble()); case folly::dynamic::Type::STRING: return JSC_JSValueMakeString(ctx, String(ctx, obj.getString().c_str())); case folly::dynamic::Type::ARRAY: { // Collect JSValue for every element in the array JSValueRef vals[obj.size()]; for (size_t i = 0; i < obj.size(); ++i) { vals[i] = fromDynamicInner(ctx, obj[i]); } // Create a JSArray with the values JSValueRef arr = JSC_JSObjectMakeArray(ctx, obj.size(), vals, nullptr); return arr; } case folly::dynamic::Type::OBJECT: { // Create an empty object JSObjectRef jsObj = JSC_JSObjectMake(ctx, nullptr, nullptr); // Create a JSValue for each of the object's children and set them in the object for (auto it = obj.items().begin(); it != obj.items().end(); ++it) { JSC_JSObjectSetProperty( ctx, jsObj, String(ctx, it->first.asString().c_str()), fromDynamicInner(ctx, it->second), kJSPropertyAttributeNone, nullptr); } return jsObj; } default: // Assert not reached LOG(FATAL) << "Trying to convert a folly object of unsupported type."; return JSC_JSValueMakeNull(ctx); } }