fbstring phpSerialize(const folly::dynamic& d) { if (d.isNull()) { return "N;"; } if (d.isBool()) { return d.asBool() ? "b:1;" : "b:0;"; } if (d.isInt()) { return "i:" + d.asString() + ";"; } if (d.isDouble()) { return "d:" + d.asString() + ";"; } if (d.isString()) { auto str = d.asString(); return folly::to<fbstring>("s:", str.size(), ":\"", str, "\";"); } if (d.isArray()) { fbstring ret = folly::to<fbstring>("a:", d.size(), ":{"); int i = 0; for (auto &v : d) { ret += folly::to<fbstring>("i:", i, ";", phpSerialize(v)); } return ret + "};"; } if (d.isObject()) { fbstring ret = folly::to<fbstring>("a:", d.size(), ":{"); int nextindex = 0; for (auto &k : d.keys()) { if (k.isNull()) { ret += "i:0;"; if (nextindex <= 0) { nextindex = 1; } } else if (k.isInt() || k.isDouble()) { int i = k.asInt(); ret += folly::to<fbstring>("i:", i, ";"); if (nextindex <= i) { nextindex = i + 1; } } else if (k.isString()) { ret += folly::to<fbstring>("s:", k.size(), ":\"", escapeCpp(k.asString()), "\";"); } else { /* Should never be reached, but cover it to be safe */ ret += folly::to<fbstring>("i:", nextindex++, ";"); } ret += phpSerialize(d[k]); } return ret + "};"; } throw std::logic_error("Unhandled dynamic type in php serialization"); return "N;"; }
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; }
std::function<void(folly::dynamic)> makeCallback( std::weak_ptr<Instance> instance, const folly::dynamic& callbackId) { if (!callbackId.isInt()) { throw std::invalid_argument("Expected callback(s) as final argument"); } auto id = callbackId.getInt(); return [winstance = std::move(instance), id](folly::dynamic args) { if (auto instance = winstance.lock()) { instance->callJSCallback(id, std::move(args)); } }; }
// Infer type from an actual value, e.g. 123, "foo", null, true, etc... static DataType kindOfFromValue(const folly::dynamic& v) { if (v.isNull()) { return KindOfNull; } if (v.isBool()) { return KindOfBoolean; } if (v.isInt()) { return KindOfInt64; } if (v.isDouble()) { return KindOfDouble; } if (v.isString()) { return KindOfString; } if (v.isArray()) { return KindOfArray; } if (v.isObject()) { return KindOfObject; } return KindOfInvalid; }