react-native/ReactCommon/jsi/JSIDynamic.cpp
Héctor Ramos 47fb387455 Update copyright headers
Summary: Use MIT License copyright headers in JSI source code.

Reviewed By: axe-fb

Differential Revision: D10454031

fbshipit-source-id: d584073bb885fb7d977df1a45a6666ef6f52dcd6
2018-10-19 11:08:57 -07:00

97 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 <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;
}
}
}
}
}