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/common/android/gin_java_bridge_value.h"
11 // The magic value is only used to prevent accidental attempts of reading
12 // GinJavaBridgeValue from a random BinaryValue. GinJavaBridgeValue is not
13 // intended for scenarios where with BinaryValues are being used for anything
14 // else than holding GinJavaBridgeValues. If a need for such scenario ever
15 // emerges, the best solution would be to extend GinJavaBridgeValue to be able
16 // to wrap raw BinaryValues.
17 const uint32 kHeaderMagic
= 0xBEEFCAFE;
20 struct Header
: public base::Pickle::Header
{
29 scoped_ptr
<base::BinaryValue
> GinJavaBridgeValue::CreateUndefinedValue() {
30 GinJavaBridgeValue
gin_value(TYPE_UNDEFINED
);
31 return make_scoped_ptr(gin_value
.SerializeToBinaryValue());
35 scoped_ptr
<base::BinaryValue
> GinJavaBridgeValue::CreateNonFiniteValue(
37 GinJavaBridgeValue
gin_value(TYPE_NONFINITE
);
38 gin_value
.pickle_
.WriteFloat(in_value
);
39 return make_scoped_ptr(gin_value
.SerializeToBinaryValue());
43 scoped_ptr
<base::BinaryValue
> GinJavaBridgeValue::CreateNonFiniteValue(
45 return CreateNonFiniteValue(static_cast<float>(in_value
)).Pass();
49 scoped_ptr
<base::BinaryValue
> GinJavaBridgeValue::CreateObjectIDValue(
51 GinJavaBridgeValue
gin_value(TYPE_OBJECT_ID
);
52 gin_value
.pickle_
.WriteInt(in_value
);
53 return make_scoped_ptr(gin_value
.SerializeToBinaryValue());
57 bool GinJavaBridgeValue::ContainsGinJavaBridgeValue(const base::Value
* value
) {
58 if (!value
->IsType(base::Value::TYPE_BINARY
))
60 const base::BinaryValue
* binary_value
=
61 reinterpret_cast<const base::BinaryValue
*>(value
);
62 if (binary_value
->GetSize() < sizeof(Header
))
64 base::Pickle
pickle(binary_value
->GetBuffer(), binary_value
->GetSize());
65 // Broken binary value: payload or header size is wrong
66 if (!pickle
.data() || pickle
.size() - pickle
.payload_size() != sizeof(Header
))
68 Header
* header
= pickle
.headerT
<Header
>();
69 return (header
->magic
== kHeaderMagic
&&
70 header
->type
>= TYPE_FIRST_VALUE
&& header
->type
< TYPE_LAST_VALUE
);
74 scoped_ptr
<const GinJavaBridgeValue
> GinJavaBridgeValue::FromValue(
75 const base::Value
* value
) {
76 return scoped_ptr
<const GinJavaBridgeValue
>(
77 value
->IsType(base::Value::TYPE_BINARY
)
78 ? new GinJavaBridgeValue(
79 reinterpret_cast<const base::BinaryValue
*>(value
))
83 GinJavaBridgeValue::Type
GinJavaBridgeValue::GetType() const {
84 const Header
* header
= pickle_
.headerT
<Header
>();
85 DCHECK(header
->type
>= TYPE_FIRST_VALUE
&& header
->type
< TYPE_LAST_VALUE
);
86 return static_cast<Type
>(header
->type
);
89 bool GinJavaBridgeValue::IsType(Type type
) const {
90 return GetType() == type
;
93 bool GinJavaBridgeValue::GetAsNonFinite(float* out_value
) const {
94 if (GetType() == TYPE_NONFINITE
) {
95 base::PickleIterator
iter(pickle_
);
96 return iter
.ReadFloat(out_value
);
102 bool GinJavaBridgeValue::GetAsObjectID(int32
* out_object_id
) const {
103 if (GetType() == TYPE_OBJECT_ID
) {
104 base::PickleIterator
iter(pickle_
);
105 return iter
.ReadInt(out_object_id
);
111 GinJavaBridgeValue::GinJavaBridgeValue(Type type
) :
112 pickle_(sizeof(Header
)) {
113 Header
* header
= pickle_
.headerT
<Header
>();
114 header
->magic
= kHeaderMagic
;
118 GinJavaBridgeValue::GinJavaBridgeValue(const base::BinaryValue
* value
)
119 : pickle_(value
->GetBuffer(), value
->GetSize()) {
120 DCHECK(ContainsGinJavaBridgeValue(value
));
123 base::BinaryValue
* GinJavaBridgeValue::SerializeToBinaryValue() {
124 return base::BinaryValue::CreateWithCopiedBuffer(
125 reinterpret_cast<const char*>(pickle_
.data()), pickle_
.size());
128 } // namespace content