Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / content / common / android / gin_java_bridge_value.cc
blob465383c993eb27511fb59c6abfff2f52936ecf3c
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"
7 namespace content {
9 namespace {
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;
19 #pragma pack(push, 4)
20 struct Header : public Pickle::Header {
21 uint32 magic;
22 int32 type;
24 #pragma pack(pop)
28 // static
29 scoped_ptr<base::BinaryValue> GinJavaBridgeValue::CreateUndefinedValue() {
30 GinJavaBridgeValue gin_value(TYPE_UNDEFINED);
31 return make_scoped_ptr(gin_value.SerializeToBinaryValue());
34 // static
35 scoped_ptr<base::BinaryValue> GinJavaBridgeValue::CreateNonFiniteValue(
36 float in_value) {
37 GinJavaBridgeValue gin_value(TYPE_NONFINITE);
38 gin_value.pickle_.WriteFloat(in_value);
39 return make_scoped_ptr(gin_value.SerializeToBinaryValue());
42 // static
43 scoped_ptr<base::BinaryValue> GinJavaBridgeValue::CreateNonFiniteValue(
44 double in_value) {
45 return CreateNonFiniteValue(static_cast<float>(in_value)).Pass();
48 // static
49 scoped_ptr<base::BinaryValue> GinJavaBridgeValue::CreateObjectIDValue(
50 int32 in_value) {
51 GinJavaBridgeValue gin_value(TYPE_OBJECT_ID);
52 gin_value.pickle_.WriteInt(in_value);
53 return make_scoped_ptr(gin_value.SerializeToBinaryValue());
56 // static
57 bool GinJavaBridgeValue::ContainsGinJavaBridgeValue(const base::Value* value) {
58 if (!value->IsType(base::Value::TYPE_BINARY))
59 return false;
60 const base::BinaryValue* binary_value =
61 reinterpret_cast<const base::BinaryValue*>(value);
62 if (binary_value->GetSize() < sizeof(Header))
63 return false;
64 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))
67 return false;
68 Header* header = pickle.headerT<Header>();
69 return (header->magic == kHeaderMagic &&
70 header->type >= TYPE_FIRST_VALUE && header->type < TYPE_LAST_VALUE);
73 // static
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))
80 : NULL);
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 PickleIterator iter(pickle_);
96 return iter.ReadFloat(out_value);
97 } else {
98 return false;
102 bool GinJavaBridgeValue::GetAsObjectID(int32* out_object_id) const {
103 if (GetType() == TYPE_OBJECT_ID) {
104 PickleIterator iter(pickle_);
105 return iter.ReadInt(out_object_id);
106 } else {
107 return false;
111 GinJavaBridgeValue::GinJavaBridgeValue(Type type) :
112 pickle_(sizeof(Header)) {
113 Header* header = pickle_.headerT<Header>();
114 header->magic = kHeaderMagic;
115 header->type = type;
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