Files
react-native/ReactCommon/jsi/jsi/JSIDynamic.cpp
T
Rain ⁣ 14f249178e standardize C-like MIT copyright headers throughout fbsource
Summary:
`/*` is the standard throughout open source code. For example, Firefox uses single /*: https://hg.mozilla.org/mozilla-central/file/21d22b2f541258d3d1cf96c7ba5ad73e96e616b5/gfx/ipc/CompositorWidgetVsyncObserver.cpp#l3

In addition, Rust considers `/**` to be a doc comment (similar to Javadoc) and having such a comment at the beginning of the file causes `rustc` to barf.

Note that some JavaScript tooling requires `/**`. This is OK since JavaScript files were not covered by the linter in the first place, but it would be good to have that tooling fixed too.

Reviewed By: zertosh

Differential Revision: D15640366

fbshipit-source-id: b4ed4599071516364d6109720750d6a43304c089
2019-06-06 19:40:32 -07:00

100 lines
3.1 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*/
#include "JSIDynamic.h"
#include <glog/logging.h>
#include <folly/dynamic.h>
#include <jsi/jsi.h>
using namespace facebook::jsi;
namespace facebook {
namespace jsi {
Value valueFromDynamic(Runtime& runtime, const folly::dynamic& dyn) {
switch (dyn.type()) {
case folly::dynamic::NULLT:
return Value::null();
case folly::dynamic::ARRAY: {
Array ret = Array(runtime, dyn.size());
for (size_t i = 0; i < dyn.size(); ++i) {
ret.setValueAtIndex(runtime, i, valueFromDynamic(runtime, dyn[i]));
}
return std::move(ret);
}
case folly::dynamic::BOOL:
return dyn.getBool();
case folly::dynamic::DOUBLE:
return dyn.getDouble();
case folly::dynamic::INT64:
// Can't use asDouble() here. If the int64 value is too bit to be
// represented precisely as a double, folly will throw an
// exception.
return (double)dyn.getInt();
case folly::dynamic::OBJECT: {
Object ret(runtime);
for (const auto& element : dyn.items()) {
Value value = valueFromDynamic(runtime, element.second);
if (element.first.isNumber() || element.first.isString()) {
ret.setProperty(runtime, element.first.asString().c_str(), value);
}
}
return std::move(ret);
}
case folly::dynamic::STRING:
return String::createFromUtf8(runtime, dyn.getString());
}
CHECK(false);
}
folly::dynamic dynamicFromValue(Runtime& runtime, const Value& value) {
if (value.isUndefined() || value.isNull()) {
return nullptr;
} else if (value.isBool()) {
return value.getBool();
} else if (value.isNumber()) {
return value.getNumber();
} else if (value.isString()) {
return value.getString(runtime).utf8(runtime);
} else {
Object obj = value.getObject(runtime);
if (obj.isArray(runtime)) {
Array array = obj.getArray(runtime);
folly::dynamic ret = folly::dynamic::array();
for (size_t i = 0; i < array.size(runtime); ++i) {
ret.push_back(dynamicFromValue(runtime, array.getValueAtIndex(runtime, i)));
}
return ret;
} else if (obj.isFunction(runtime)) {
throw JSError(runtime, "JS Functions are not convertible to dynamic");
} else {
folly::dynamic ret = folly::dynamic::object();
Array names = obj.getPropertyNames(runtime);
for (size_t i = 0; i < names.size(runtime); ++i) {
String name = names.getValueAtIndex(runtime, i).getString(runtime);
Value prop = obj.getProperty(runtime, name);
if (prop.isUndefined()) {
continue;
}
// The JSC conversion uses JSON.stringify, which substitutes
// null for a function, so we do the same here. Just dropping
// the pair might also work, but would require more testing.
if (prop.isObject() && prop.getObject(runtime).isFunction(runtime)) {
prop = Value::null();
}
ret.insert(
name.utf8(runtime), dynamicFromValue(runtime, std::move(prop)));
}
return ret;
}
}
}
}
}