1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/java/gin_java_bridge_value_converter.h"
7 #include "base/float_util.h"
8 #include "base/values.h"
9 #include "content/common/android/gin_java_bridge_value.h"
10 #include "content/renderer/java/gin_java_bridge_object.h"
11 #include "gin/array_buffer.h"
15 GinJavaBridgeValueConverter::GinJavaBridgeValueConverter()
16 : converter_(V8ValueConverter::create()) {
17 converter_
->SetDateAllowed(false);
18 converter_
->SetRegExpAllowed(false);
19 converter_
->SetFunctionAllowed(true);
20 converter_
->SetStrategy(this);
23 GinJavaBridgeValueConverter::~GinJavaBridgeValueConverter() {
26 v8::Handle
<v8::Value
> GinJavaBridgeValueConverter::ToV8Value(
27 const base::Value
* value
,
28 v8::Handle
<v8::Context
> context
) const {
29 return converter_
->ToV8Value(value
, context
);
32 scoped_ptr
<base::Value
> GinJavaBridgeValueConverter::FromV8Value(
33 v8::Handle
<v8::Value
> value
,
34 v8::Handle
<v8::Context
> context
) const {
35 return make_scoped_ptr(converter_
->FromV8Value(value
, context
));
38 bool GinJavaBridgeValueConverter::FromV8Object(
39 v8::Handle
<v8::Object
> value
,
42 const FromV8ValueCallback
& callback
) const {
43 GinJavaBridgeObject
* unwrapped
;
44 if (!gin::ConvertFromV8(isolate
, value
, &unwrapped
)) {
48 GinJavaBridgeValue::CreateObjectIDValue(unwrapped
->object_id()).release();
54 class TypedArraySerializer
{
56 virtual ~TypedArraySerializer() {}
57 static scoped_ptr
<TypedArraySerializer
> Create(
58 v8::Handle
<v8::TypedArray
> typed_array
);
59 virtual void serializeTo(char* data
,
61 base::ListValue
* out
) = 0;
63 TypedArraySerializer() {}
66 template <typename ElementType
, typename ListType
>
67 class TypedArraySerializerImpl
: public TypedArraySerializer
{
69 static scoped_ptr
<TypedArraySerializer
> Create(
70 v8::Handle
<v8::TypedArray
> typed_array
) {
71 scoped_ptr
<TypedArraySerializerImpl
<ElementType
, ListType
> > result(
72 new TypedArraySerializerImpl
<ElementType
, ListType
>(typed_array
));
73 return result
.template PassAs
<TypedArraySerializer
>();
76 virtual void serializeTo(char* data
,
78 base::ListValue
* out
) OVERRIDE
{
79 DCHECK_EQ(data_length
, typed_array_
->Length() * sizeof(ElementType
));
80 for (ElementType
*element
= reinterpret_cast<ElementType
*>(data
),
81 *end
= element
+ typed_array_
->Length();
84 const ListType list_value
= *element
;
85 out
->Append(new base::FundamentalValue(list_value
));
90 explicit TypedArraySerializerImpl(v8::Handle
<v8::TypedArray
> typed_array
)
91 : typed_array_(typed_array
) {}
93 v8::Handle
<v8::TypedArray
> typed_array_
;
95 DISALLOW_COPY_AND_ASSIGN(TypedArraySerializerImpl
);
99 scoped_ptr
<TypedArraySerializer
> TypedArraySerializer::Create(
100 v8::Handle
<v8::TypedArray
> typed_array
) {
101 if (typed_array
->IsInt8Array() ||
102 typed_array
->IsUint8Array() ||
103 typed_array
->IsUint8ClampedArray()) {
104 return TypedArraySerializerImpl
<char, int>::Create(typed_array
).Pass();
105 } else if (typed_array
->IsInt16Array() || typed_array
->IsUint16Array()) {
106 return TypedArraySerializerImpl
<int16_t, int>::Create(typed_array
).Pass();
107 } else if (typed_array
->IsInt32Array() || typed_array
->IsUint32Array()) {
108 return TypedArraySerializerImpl
<int32_t, int>::Create(typed_array
).Pass();
109 } else if (typed_array
->IsFloat32Array()) {
110 return TypedArraySerializerImpl
<float, double>::Create(typed_array
).Pass();
111 } else if (typed_array
->IsFloat64Array()) {
112 return TypedArraySerializerImpl
<double, double>::Create(typed_array
).Pass();
115 return scoped_ptr
<TypedArraySerializer
>();
120 bool GinJavaBridgeValueConverter::FromV8ArrayBuffer(
121 v8::Handle
<v8::Object
> value
,
123 v8::Isolate
* isolate
) const {
124 if (!value
->IsTypedArray()) {
125 *out
= GinJavaBridgeValue::CreateUndefinedValue().release();
130 size_t data_length
= 0;
131 gin::ArrayBufferView view
;
132 if (ConvertFromV8(isolate
, value
.As
<v8::ArrayBufferView
>(), &view
)) {
133 data
= reinterpret_cast<char*>(view
.bytes());
134 data_length
= view
.num_bytes();
137 *out
= GinJavaBridgeValue::CreateUndefinedValue().release();
141 base::ListValue
* result
= new base::ListValue();
143 scoped_ptr
<TypedArraySerializer
> serializer(
144 TypedArraySerializer::Create(value
.As
<v8::TypedArray
>()));
145 serializer
->serializeTo(data
, data_length
, result
);
149 bool GinJavaBridgeValueConverter::FromV8Number(v8::Handle
<v8::Number
> value
,
150 base::Value
** out
) const {
151 double double_value
= value
->Value();
152 if (base::IsFinite(double_value
))
154 *out
= GinJavaBridgeValue::CreateNonFiniteValue(double_value
).release();
158 bool GinJavaBridgeValueConverter::FromV8Undefined(base::Value
** out
) const {
159 *out
= GinJavaBridgeValue::CreateUndefinedValue().release();
163 } // namespace content