1// Copyright (c) 2012 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.
4
5#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
6
7#include "base/logging.h"
8#include "ppapi/shared_impl/ppapi_globals.h"
9#include "ppapi/shared_impl/var.h"
10#include "ppapi/shared_impl/var_tracker.h"
11
12namespace ppapi {
13
14PPB_X509Certificate_Fields::PPB_X509Certificate_Fields() {}
15
16PPB_X509Certificate_Fields::PPB_X509Certificate_Fields(
17    const PPB_X509Certificate_Fields& fields) {
18  scoped_ptr<base::ListValue> new_values(fields.values_.DeepCopy());
19  values_.Swap(new_values.get());
20}
21
22void PPB_X509Certificate_Fields::SetField(
23    PP_X509Certificate_Private_Field field,
24    base::Value* value) {
25  uint32_t index = static_cast<uint32_t>(field);
26  bool success = values_.Set(index, value);
27  DCHECK(success);
28}
29
30PP_Var PPB_X509Certificate_Fields::GetFieldAsPPVar(
31    PP_X509Certificate_Private_Field field) const {
32  uint32_t index = static_cast<uint32_t>(field);
33  const base::Value* value;
34  bool success = values_.Get(index, &value);
35  if (!success) {
36    // Our list received might be smaller than the number of fields, so just
37    // return null if the index is OOB.
38    return PP_MakeNull();
39  }
40
41  switch (value->GetType()) {
42    case base::Value::TYPE_NULL:
43      return PP_MakeNull();
44    case base::Value::TYPE_BOOLEAN: {
45      bool val;
46      value->GetAsBoolean(&val);
47      return PP_MakeBool(PP_FromBool(val));
48    }
49    case base::Value::TYPE_INTEGER: {
50      int val;
51      value->GetAsInteger(&val);
52      return PP_MakeInt32(val);
53    }
54    case base::Value::TYPE_DOUBLE: {
55      double val;
56      value->GetAsDouble(&val);
57      return PP_MakeDouble(val);
58    }
59    case base::Value::TYPE_STRING: {
60      std::string val;
61      value->GetAsString(&val);
62      return StringVar::StringToPPVar(val);
63    }
64    case base::Value::TYPE_BINARY: {
65      const base::BinaryValue* binary =
66          static_cast<const base::BinaryValue*>(value);
67      uint32_t size = static_cast<uint32_t>(binary->GetSize());
68      const char* buffer = binary->GetBuffer();
69      PP_Var array_buffer =
70          PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(size,
71                                                                     buffer);
72      return array_buffer;
73    }
74    case base::Value::TYPE_DICTIONARY:
75    case base::Value::TYPE_LIST:
76      // Not handled.
77      break;
78  }
79
80  // Should not reach here.
81  CHECK(false);
82  return PP_MakeUndefined();
83}
84
85//------------------------------------------------------------------------------
86
87PPB_X509Certificate_Private_Shared::PPB_X509Certificate_Private_Shared(
88    ResourceObjectType type,
89    PP_Instance instance)
90    : Resource(type, instance) {}
91
92PPB_X509Certificate_Private_Shared::PPB_X509Certificate_Private_Shared(
93    ResourceObjectType type,
94    PP_Instance instance,
95    const PPB_X509Certificate_Fields& fields)
96    : Resource(type, instance),
97      fields_(new PPB_X509Certificate_Fields(fields)) {
98}
99
100PPB_X509Certificate_Private_Shared::~PPB_X509Certificate_Private_Shared() {
101}
102
103thunk::PPB_X509Certificate_Private_API*
104PPB_X509Certificate_Private_Shared::AsPPB_X509Certificate_Private_API() {
105  return this;
106}
107
108PP_Bool PPB_X509Certificate_Private_Shared::Initialize(const char* bytes,
109                                                       uint32_t length) {
110  // The certificate should be immutable once initialized.
111  if (fields_.get())
112    return PP_FALSE;
113
114  if (!bytes || length == 0)
115    return PP_FALSE;
116
117  std::vector<char> der(bytes, bytes + length);
118  scoped_ptr<PPB_X509Certificate_Fields> fields(
119      new PPB_X509Certificate_Fields());
120  bool success = ParseDER(der, fields.get());
121  if (success) {
122    fields_.swap(fields);
123    return PP_TRUE;
124  }
125  return PP_FALSE;
126}
127
128PP_Var PPB_X509Certificate_Private_Shared::GetField(
129    PP_X509Certificate_Private_Field field) {
130  if (!fields_.get())
131    return PP_MakeUndefined();
132
133  return fields_->GetFieldAsPPVar(field);
134}
135
136bool PPB_X509Certificate_Private_Shared::ParseDER(
137    const std::vector<char>& der,
138    PPB_X509Certificate_Fields* result) {
139  // A concrete PPB_X509Certificate_Private_Shared should only ever be
140  // constructed by passing in PPB_X509Certificate_Fields, in which case it is
141  // already initialized.
142  CHECK(false);
143  return false;
144}
145
146}  // namespace ppapi
147