static Variant dynamic_to_variant(const folly::dynamic& v) { switch (v.type()) { case folly::dynamic::Type::NULLT: return init_null(); case folly::dynamic::Type::BOOL: return v.asBool(); case folly::dynamic::Type::DOUBLE: return v.asDouble(); case folly::dynamic::Type::INT64: return v.asInt(); case folly::dynamic::Type::STRING: return v.data(); case folly::dynamic::Type::ARRAY: case folly::dynamic::Type::OBJECT: ArrayInit arr_init(v.size(), ArrayInit::Mixed{}); for (auto& item : v.items()) { arr_init.add(dynamic_to_variant(item.first), dynamic_to_variant(item.second)); } Array ret = arr_init.toArray(); // Sort the array since folly::dynamic has a tendency to iterate from // back to front. This way a var_dump of the array, for example, looks // ordered. ret.sort(Array::SortNaturalAscending, true, false); return ret; } not_reached(); }
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;"; }
static std::string dynamic_to_std_string(const folly::dynamic& v) { switch (v.type()) { case folly::dynamic::Type::NULLT: case folly::dynamic::Type::ARRAY: case folly::dynamic::Type::OBJECT: return ""; case folly::dynamic::Type::BOOL: return std::to_string(v.asBool()); case folly::dynamic::Type::DOUBLE: return std::to_string(v.asDouble()); case folly::dynamic::Type::INT64: return std::to_string(v.asInt()); case folly::dynamic::Type::STRING: return v.data(); } not_reached(); }
static Variant dynamic_to_variant(const folly::dynamic& v) { switch (v.type()) { case folly::dynamic::Type::NULLT: return init_null_variant; case folly::dynamic::Type::BOOL: return v.asBool(); case folly::dynamic::Type::DOUBLE: return v.asDouble(); case folly::dynamic::Type::INT64: return v.asInt(); case folly::dynamic::Type::STRING: return v.data(); case folly::dynamic::Type::ARRAY: case folly::dynamic::Type::OBJECT: ArrayInit ret(v.size(), ArrayInit::Mixed{}); for (auto& item : v.items()) { ret.add(dynamic_to_variant(item.first), dynamic_to_variant(item.second)); } return ret.toArray(); } not_reached(); }