UNPKG

3.36 kBtext/x-cView Raw
1/*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the LICENSE
5 * file in the root directory of this source tree.
6 */
7#include "JSIDynamic.h"
8
9#include <glog/logging.h>
10
11#include <folly/dynamic.h>
12#include <jsi/jsi.h>
13
14using namespace facebook::jsi;
15
16namespace facebook {
17namespace jsi {
18
19Value valueFromDynamic(Runtime& runtime, const folly::dynamic& dyn) {
20 switch (dyn.type()) {
21 case folly::dynamic::NULLT:
22 return Value::null();
23 case folly::dynamic::ARRAY: {
24 Array ret = Array(runtime, dyn.size());
25 for (size_t i = 0; i < dyn.size(); ++i) {
26 ret.setValueAtIndex(runtime, i, valueFromDynamic(runtime, dyn[i]));
27 }
28 return std::move(ret);
29 }
30 case folly::dynamic::BOOL:
31 return dyn.getBool();
32 case folly::dynamic::DOUBLE:
33 return dyn.getDouble();
34 case folly::dynamic::INT64:
35 // Can't use asDouble() here. If the int64 value is too bit to be
36 // represented precisely as a double, folly will throw an
37 // exception.
38 return (double)dyn.getInt();
39 case folly::dynamic::OBJECT: {
40 Object ret(runtime);
41 for (const auto& element : dyn.items()) {
42 Value value = valueFromDynamic(runtime, element.second);
43 if (element.first.isNumber() || element.first.isString()) {
44 ret.setProperty(
45 runtime,
46 PropNameID::forUtf8(runtime, element.first.asString()),
47 value);
48 }
49 }
50 return std::move(ret);
51 }
52 case folly::dynamic::STRING:
53 return String::createFromUtf8(runtime, dyn.getString());
54 }
55 CHECK(false);
56}
57
58folly::dynamic dynamicFromValue(Runtime& runtime, const Value& value) {
59 if (value.isUndefined() || value.isNull()) {
60 return nullptr;
61 } else if (value.isBool()) {
62 return value.getBool();
63 } else if (value.isNumber()) {
64 return value.getNumber();
65 } else if (value.isString()) {
66 return value.getString(runtime).utf8(runtime);
67 } else {
68 Object obj = value.getObject(runtime);
69 if (obj.isArray(runtime)) {
70 Array array = obj.getArray(runtime);
71 folly::dynamic ret = folly::dynamic::array();
72 for (size_t i = 0; i < array.size(runtime); ++i) {
73 ret.push_back(
74 dynamicFromValue(runtime, array.getValueAtIndex(runtime, i)));
75 }
76 return ret;
77 } else if (obj.isFunction(runtime)) {
78 throw JSError(runtime, "JS Functions are not convertible to dynamic");
79 } else {
80 folly::dynamic ret = folly::dynamic::object();
81 Array names = obj.getPropertyNames(runtime);
82 for (size_t i = 0; i < names.size(runtime); ++i) {
83 String name = names.getValueAtIndex(runtime, i).getString(runtime);
84 Value prop = obj.getProperty(runtime, name);
85 if (prop.isUndefined()) {
86 continue;
87 }
88 // The JSC conversion uses JSON.stringify, which substitutes
89 // null for a function, so we do the same here. Just dropping
90 // the pair might also work, but would require more testing.
91 if (prop.isObject() && prop.getObject(runtime).isFunction(runtime)) {
92 prop = Value::null();
93 }
94 ret.insert(
95 name.utf8(runtime), dynamicFromValue(runtime, std::move(prop)));
96 }
97 return ret;
98 }
99 }
100}
101
102} // namespace jsi
103} // namespace facebook