Files
react-native/ReactAndroid/src/main/jni/react/Value.h
Andy Street b0519c8280 Update WebWorkers API to return message object in onmessage
Summary:
public

I wasn't obeying the web workers API correctly: I had missed that the message isn't sent directly but is attached to a message object in a data field.

Reviewed By: lexs

Differential Revision: D2811247

fb-gh-sync-id: 8e51414766e0cfe382ee9bdde8f0d66e269cb83a
2016-01-12 04:52:01 -08:00

218 lines
4.7 KiB
C++

// Copyright 2004-present Facebook. All Rights Reserved.
#pragma once
#include <memory>
#include <sstream>
#include <JavaScriptCore/JSObjectRef.h>
#include <JavaScriptCore/JSRetainPtr.h>
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/JSValueRef.h>
#include <fb/noncopyable.h>
#if WITH_FBJSCEXTENSIONS
#include <jsc_stringref.h>
#endif
namespace facebook {
namespace react {
class Value;
class Context;
class String : public noncopyable {
public:
explicit String(const char* utf8) :
m_string(Adopt, JSStringCreateWithUTF8CString(utf8))
{}
String(String&& other) :
m_string(Adopt, other.m_string.leakRef())
{}
String(const String& other) :
m_string(other.m_string)
{}
operator JSStringRef() const {
return m_string.get();
}
// Length in characters
size_t length() const {
return JSStringGetLength(m_string.get());
}
// Length in bytes of a null-terminated utf8 encoded value
size_t utf8Size() const {
return JSStringGetMaximumUTF8CStringSize(m_string.get());
}
std::string str() const {
size_t reserved = utf8Size();
char* bytes = new char[reserved];
size_t length = JSStringGetUTF8CString(m_string.get(), bytes, reserved) - 1;
std::unique_ptr<char[]> retainedBytes(bytes);
return std::string(bytes, length);
}
// Assumes that utf8 is null terminated
bool equals(const char* utf8) {
return JSStringIsEqualToUTF8CString(m_string.get(), utf8);
}
static String createExpectingAscii(std::string const &utf8) {
#if WITH_FBJSCEXTENSIONS
return String(Adopt, JSStringCreateWithUTF8CStringExpectAscii(utf8.c_str(), utf8.size()));
#else
return String(Adopt, JSStringCreateWithUTF8CString(utf8.c_str()));
#endif
}
static String ref(JSStringRef string) {
return String(string);
}
static String adopt(JSStringRef string) {
return String(Adopt, string);
}
private:
explicit String(JSStringRef string) :
m_string(string)
{}
String(AdoptTag tag, JSStringRef string) :
m_string(tag, string)
{}
JSRetainPtr<JSStringRef> m_string;
};
class Object : public noncopyable {
public:
Object(JSContextRef context, JSObjectRef obj) :
m_context(context),
m_obj(obj)
{}
Object(Object&& other) :
m_context(other.m_context),
m_obj(other.m_obj),
m_isProtected(other.m_isProtected) {
other.m_obj = nullptr;
other.m_isProtected = false;
}
~Object() {
if (m_isProtected && m_obj) {
JSValueUnprotect(m_context, m_obj);
}
}
operator JSObjectRef() const {
return m_obj;
}
operator Value() const;
bool isFunction() const {
return JSObjectIsFunction(m_context, m_obj);
}
Value callAsFunction(int nArgs, JSValueRef args[]);
Value getProperty(const String& propName) const;
Value getProperty(const char *propName) const;
void setProperty(const String& propName, const Value& value) const;
void setProperty(const char *propName, const Value& value) const;
void makeProtected() {
if (!m_isProtected && m_obj) {
JSValueProtect(m_context, m_obj);
m_isProtected = true;
}
}
static Object getGlobalObject(JSContextRef ctx) {
auto globalObj = JSContextGetGlobalObject(ctx);
return Object(ctx, globalObj);
}
/**
* Creates an instance of the default object class.
*/
static Object create(JSContextRef ctx);
private:
JSContextRef m_context;
JSObjectRef m_obj;
bool m_isProtected = false;
};
class Value : public noncopyable {
public:
Value(JSContextRef context, JSValueRef value);
Value(Value&&);
operator JSValueRef() const {
return m_value;
}
bool isBoolean() const {
return JSValueIsBoolean(context(), m_value);
}
bool asBoolean() const {
return JSValueToBoolean(context(), m_value);
}
bool isNumber() const {
return JSValueIsNumber(context(), m_value);
}
bool isNull() const {
return JSValueIsNull(context(), m_value);
}
bool isUndefined() const {
return JSValueIsUndefined(context(), m_value);
}
double asNumber() const {
if (isNumber()) {
return JSValueToNumber(context(), m_value, nullptr);
} else {
return 0.0f;
}
}
int32_t asInteger() const {
return static_cast<int32_t>(asNumber());
}
uint32_t asUnsignedInteger() const {
return static_cast<uint32_t>(asNumber());
}
bool isObject() const {
return JSValueIsObject(context(), m_value);
}
Object asObject();
bool isString() const {
return JSValueIsString(context(), m_value);
}
String toString() {
return String::adopt(JSValueToStringCopy(context(), m_value, nullptr));
}
std::string toJSONString(unsigned indent = 0) const;
static Value fromJSON(JSContextRef ctx, const String& json);
protected:
JSContextRef context() const;
JSContextRef m_context;
JSValueRef m_value;
};
} }