1cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// Use of this source code is governed by a BSD-style license that can be
3cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// found in the LICENSE file.
4cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
5cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include "base/values.h"
6cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
7cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include <string.h>
8cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
9cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include <algorithm>
10cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include <cmath>
11cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include <ostream>
12674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko#include <utility>
13cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
14cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include "base/json/json_writer.h"
15cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include "base/logging.h"
16cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include "base/move.h"
17cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include "base/strings/string_util.h"
188750b279d610fb21d10a205e28e081832ed837eeVitaly Buka#include "base/strings/utf_string_conversion_utils.h"
19cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
20cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukanamespace base {
21cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
22cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukanamespace {
23cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
24cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukascoped_ptr<Value> CopyWithoutEmptyChildren(const Value& node);
25cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
26cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// Make a deep copy of |node|, but don't include empty lists or dictionaries
27cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// in the copy. It's possible for this function to return NULL and it
28cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// expects |node| to always be non-NULL.
29cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukascoped_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) {
30cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  scoped_ptr<ListValue> copy;
31cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (ListValue::const_iterator it = list.begin(); it != list.end(); ++it) {
32cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    scoped_ptr<Value> child_copy = CopyWithoutEmptyChildren(**it);
33cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    if (child_copy) {
34cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      if (!copy)
35cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka        copy.reset(new ListValue);
36674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko      copy->Append(std::move(child_copy));
37cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
38cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
39cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return copy;
40cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
41cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
42cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukascoped_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren(
43cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const DictionaryValue& dict) {
44cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  scoped_ptr<DictionaryValue> copy;
45cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
46cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    scoped_ptr<Value> child_copy = CopyWithoutEmptyChildren(it.value());
47cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    if (child_copy) {
48cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      if (!copy)
49cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka        copy.reset(new DictionaryValue);
50674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko      copy->SetWithoutPathExpansion(it.key(), std::move(child_copy));
51cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
52cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
53cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return copy;
54cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
55cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
56cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukascoped_ptr<Value> CopyWithoutEmptyChildren(const Value& node) {
57cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  switch (node.GetType()) {
58cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    case Value::TYPE_LIST:
59cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node));
60cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
61cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    case Value::TYPE_DICTIONARY:
62cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return CopyDictionaryWithoutEmptyChildren(
63cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka          static_cast<const DictionaryValue&>(node));
64cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
65cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    default:
66cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return node.CreateDeepCopy();
67cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
68cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
69cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
70cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// A small functor for comparing Values for std::find_if and similar.
71cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukaclass ValueEquals {
72cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka public:
73cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // Pass the value against which all consecutive calls of the () operator will
74cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // compare their argument to. This Value object must not be destroyed while
75cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // the ValueEquals is  in use.
76cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  explicit ValueEquals(const Value* first) : first_(first) { }
77cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
78cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool operator ()(const Value* second) const {
79cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return first_->Equals(second);
80cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
81cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
82cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka private:
83cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* first_;
84cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka};
85cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
86cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}  // namespace
87cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
88cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaValue::~Value() {
89cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
90cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
91cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// static
92cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukascoped_ptr<Value> Value::CreateNullValue() {
93cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return make_scoped_ptr(new Value(TYPE_NULL));
94cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
95cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
96674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool Value::GetAsBinary(const BinaryValue** /* out_value */) const {
97cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
98cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
99cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
100674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool Value::GetAsBoolean(bool* /* out_value */) const {
101cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
102cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
103cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
104674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool Value::GetAsInteger(int* /* out_value */) const {
105cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
106cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
107cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
108674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool Value::GetAsDouble(double* /* out_value */) const {
109cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
110cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
111cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
112674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool Value::GetAsString(std::string* /* out_value */) const {
113cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
114cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
115cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
116cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool Value::GetAsString(const StringValue** out_value) const {
117cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
118cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
119cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
120674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool Value::GetAsList(ListValue** /* out_value */) {
121cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
122cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
123cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
124674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool Value::GetAsList(const ListValue** /* out_value */) const {
125cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
126cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
127cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
128674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool Value::GetAsDictionary(DictionaryValue** /* out_value */) {
129cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
130cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
131cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
132674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool Value::GetAsDictionary(const DictionaryValue** /* out_value */) const {
133cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
134cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
135cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
136cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaValue* Value::DeepCopy() const {
137cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // This method should only be getting called for null Values--all subclasses
138cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // need to provide their own implementation;.
139cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(IsType(TYPE_NULL));
140cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return CreateNullValue().release();
141cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
142cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
143cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukascoped_ptr<Value> Value::CreateDeepCopy() const {
144cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return make_scoped_ptr(DeepCopy());
145cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
146cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
147cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool Value::Equals(const Value* other) const {
148cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // This method should only be getting called for null Values--all subclasses
149cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // need to provide their own implementation;.
150cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(IsType(TYPE_NULL));
151cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return other->IsType(TYPE_NULL);
152cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
153cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
154cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// static
155cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool Value::Equals(const Value* a, const Value* b) {
156cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if ((a == NULL) && (b == NULL)) return true;
157cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if ((a == NULL) ^  (b == NULL)) return false;
158cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return a->Equals(b);
159cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
160cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
161cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaValue::Value(Type type) : type_(type) {}
162cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
163cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaValue::Value(const Value& that) : type_(that.type_) {}
164cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
165cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaValue& Value::operator=(const Value& that) {
166cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  type_ = that.type_;
167cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return *this;
168cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
169cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
170cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka///////////////////// FundamentalValue ////////////////////
171cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
172cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaFundamentalValue::FundamentalValue(bool in_value)
173cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
174cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
175cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
176cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaFundamentalValue::FundamentalValue(int in_value)
177cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    : Value(TYPE_INTEGER), integer_value_(in_value) {
178cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
179cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
180cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaFundamentalValue::FundamentalValue(double in_value)
181cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    : Value(TYPE_DOUBLE), double_value_(in_value) {
182cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!std::isfinite(double_value_)) {
183cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
184cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                 << "values cannot be represented in JSON";
185cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    double_value_ = 0.0;
186cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
187cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
188cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
189cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaFundamentalValue::~FundamentalValue() {
190cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
191cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
192cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool FundamentalValue::GetAsBoolean(bool* out_value) const {
193cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value && IsType(TYPE_BOOLEAN))
194cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = boolean_value_;
195cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return (IsType(TYPE_BOOLEAN));
196cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
197cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
198cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool FundamentalValue::GetAsInteger(int* out_value) const {
199cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value && IsType(TYPE_INTEGER))
200cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = integer_value_;
201cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return (IsType(TYPE_INTEGER));
202cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
203cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
204cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool FundamentalValue::GetAsDouble(double* out_value) const {
205cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value && IsType(TYPE_DOUBLE))
206cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = double_value_;
207cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  else if (out_value && IsType(TYPE_INTEGER))
208cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = integer_value_;
209cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER));
210cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
211cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
212cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaFundamentalValue* FundamentalValue::DeepCopy() const {
213cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  switch (GetType()) {
214cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    case TYPE_BOOLEAN:
215cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return new FundamentalValue(boolean_value_);
216cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
217cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    case TYPE_INTEGER:
218cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return new FundamentalValue(integer_value_);
219cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
220cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    case TYPE_DOUBLE:
221cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return new FundamentalValue(double_value_);
222cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
223cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    default:
224cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      NOTREACHED();
225cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return NULL;
226cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
227cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
228cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
229cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool FundamentalValue::Equals(const Value* other) const {
230cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (other->GetType() != GetType())
231cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
232cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
233cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  switch (GetType()) {
234cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    case TYPE_BOOLEAN: {
235cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      bool lhs, rhs;
236cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
237cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
238cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    case TYPE_INTEGER: {
239cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      int lhs, rhs;
240cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
241cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
242cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    case TYPE_DOUBLE: {
243cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      double lhs, rhs;
244cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
245cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
246cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    default:
247cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      NOTREACHED();
248cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return false;
249cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
250cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
251cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
252cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka///////////////////// StringValue ////////////////////
253cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
254cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaStringValue::StringValue(const std::string& in_value)
255cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    : Value(TYPE_STRING),
256cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      value_(in_value) {
257cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(IsStringUTF8(in_value));
258cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
259cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
260cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaStringValue::~StringValue() {
261cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
262cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
263cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukastd::string* StringValue::GetString() {
264cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return &value_;
265cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
266cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
267cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukaconst std::string& StringValue::GetString() const {
268cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value_;
269cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
270cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
271cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool StringValue::GetAsString(std::string* out_value) const {
272cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
273cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = value_;
274cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
275cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
276cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
277cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool StringValue::GetAsString(const StringValue** out_value) const {
278cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
279cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = this;
280cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
281cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
282cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
283cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaStringValue* StringValue::DeepCopy() const {
284cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return new StringValue(value_);
285cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
286cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
287cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool StringValue::Equals(const Value* other) const {
288cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (other->GetType() != GetType())
289cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
290cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  std::string lhs, rhs;
291cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
292cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
293cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
294cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka///////////////////// BinaryValue ////////////////////
295cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
296cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaBinaryValue::BinaryValue()
297cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    : Value(TYPE_BINARY),
298cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      size_(0) {
299cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
300cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
301cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaBinaryValue::BinaryValue(scoped_ptr<char[]> buffer, size_t size)
302674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko    : Value(TYPE_BINARY), buffer_(std::move(buffer)), size_(size) {}
303cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
304cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaBinaryValue::~BinaryValue() {
305cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
306cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
307cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// static
308cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaBinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
309cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                                 size_t size) {
310cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  char* buffer_copy = new char[size];
311cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  memcpy(buffer_copy, buffer, size);
312cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  scoped_ptr<char[]> scoped_buffer_copy(buffer_copy);
313674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  return new BinaryValue(std::move(scoped_buffer_copy), size);
314cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
315cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
316cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool BinaryValue::GetAsBinary(const BinaryValue** out_value) const {
317cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
318cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = this;
319cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
320cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
321cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
322cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaBinaryValue* BinaryValue::DeepCopy() const {
323cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return CreateWithCopiedBuffer(buffer_.get(), size_);
324cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
325cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
326cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool BinaryValue::Equals(const Value* other) const {
327cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (other->GetType() != GetType())
328cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
329cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
330cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (other_binary->size_ != size_)
331cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
332cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return !memcmp(GetBuffer(), other_binary->GetBuffer(), size_);
333cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
334cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
335cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka///////////////////// DictionaryValue ////////////////////
336cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
337674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko// static
338674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkoscoped_ptr<DictionaryValue> DictionaryValue::From(scoped_ptr<Value> value) {
339674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  DictionaryValue* out;
340674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  if (value && value->GetAsDictionary(&out)) {
341674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko    ignore_result(value.release());
342674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko    return make_scoped_ptr(out);
343674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  }
344674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  return nullptr;
345674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko}
346674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko
347cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaDictionaryValue::DictionaryValue()
348cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    : Value(TYPE_DICTIONARY) {
349cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
350cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
351cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaDictionaryValue::~DictionaryValue() {
352cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Clear();
353cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
354cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
355cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
356cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
357cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = this;
358cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
359cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
360cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
361cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
362cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
363cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = this;
364cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
365cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
366cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
367cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::HasKey(const std::string& key) const {
368cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(IsStringUTF8(key));
369cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  ValueMap::const_iterator current_entry = dictionary_.find(key);
370cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK((current_entry == dictionary_.end()) || current_entry->second);
371cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return current_entry != dictionary_.end();
372cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
373cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
374cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::Clear() {
375cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  ValueMap::iterator dict_iterator = dictionary_.begin();
376cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  while (dict_iterator != dictionary_.end()) {
377cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    delete dict_iterator->second;
378cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    ++dict_iterator;
379cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
380cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
381cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  dictionary_.clear();
382cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
383cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
384cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::Set(const std::string& path, scoped_ptr<Value> in_value) {
385cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(IsStringUTF8(path));
386cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(in_value);
387cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
388cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  std::string current_path(path);
389cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DictionaryValue* current_dictionary = this;
390cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (size_t delimiter_position = current_path.find('.');
391cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka       delimiter_position != std::string::npos;
392cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka       delimiter_position = current_path.find('.')) {
393cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    // Assume that we're indexing into a dictionary.
394cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    std::string key(current_path, 0, delimiter_position);
395cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    DictionaryValue* child_dictionary = NULL;
396cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
397cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      child_dictionary = new DictionaryValue;
398cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
399cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
400cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
401cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    current_dictionary = child_dictionary;
402cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    current_path.erase(0, delimiter_position + 1);
403cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
404cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
405674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  current_dictionary->SetWithoutPathExpansion(current_path,
406674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko                                              std::move(in_value));
407cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
408cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
409cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::Set(const std::string& path, Value* in_value) {
410cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Set(path, make_scoped_ptr(in_value));
411cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
412cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
413cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
414cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Set(path, new FundamentalValue(in_value));
415cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
416cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
417cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetInteger(const std::string& path, int in_value) {
418cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Set(path, new FundamentalValue(in_value));
419cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
420cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
421cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetDouble(const std::string& path, double in_value) {
422cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Set(path, new FundamentalValue(in_value));
423cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
424cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
425cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetString(const std::string& path,
426cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                const std::string& in_value) {
427cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Set(path, new StringValue(in_value));
428cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
429cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
430cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetWithoutPathExpansion(const std::string& key,
431cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                              scoped_ptr<Value> in_value) {
432cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Value* bare_ptr = in_value.release();
433cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // If there's an existing value here, we need to delete it, because
434cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // we own all our children.
435cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  std::pair<ValueMap::iterator, bool> ins_res =
436cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      dictionary_.insert(std::make_pair(key, bare_ptr));
437cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!ins_res.second) {
438cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    DCHECK_NE(ins_res.first->second, bare_ptr);  // This would be bogus
439cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    delete ins_res.first->second;
440cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    ins_res.first->second = bare_ptr;
441cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
442cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
443cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
444cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetWithoutPathExpansion(const std::string& key,
445cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                              Value* in_value) {
446cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  SetWithoutPathExpansion(key, make_scoped_ptr(in_value));
447cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
448cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
449cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetBooleanWithoutPathExpansion(
450cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const std::string& path, bool in_value) {
451cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  SetWithoutPathExpansion(path, new FundamentalValue(in_value));
452cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
453cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
454cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetIntegerWithoutPathExpansion(
455cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const std::string& path, int in_value) {
456cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  SetWithoutPathExpansion(path, new FundamentalValue(in_value));
457cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
458cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
459cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetDoubleWithoutPathExpansion(
460cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const std::string& path, double in_value) {
461cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  SetWithoutPathExpansion(path, new FundamentalValue(in_value));
462cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
463cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
464cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::SetStringWithoutPathExpansion(
465cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const std::string& path, const std::string& in_value) {
466cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  SetWithoutPathExpansion(path, new StringValue(in_value));
467cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
468cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
469674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool DictionaryValue::Get(StringPiece path,
470cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                          const Value** out_value) const {
471cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(IsStringUTF8(path));
472674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  StringPiece current_path(path);
473cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const DictionaryValue* current_dictionary = this;
474cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (size_t delimiter_position = current_path.find('.');
475cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka       delimiter_position != std::string::npos;
476cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka       delimiter_position = current_path.find('.')) {
477cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const DictionaryValue* child_dictionary = NULL;
478674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko    if (!current_dictionary->GetDictionaryWithoutPathExpansion(
479674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko            current_path.substr(0, delimiter_position).as_string(),
480674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko            &child_dictionary)) {
481cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return false;
482674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko    }
483cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
484cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    current_dictionary = child_dictionary;
485674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko    current_path = current_path.substr(delimiter_position + 1);
486cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
487cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
488674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  return current_dictionary->GetWithoutPathExpansion(current_path.as_string(),
489674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko                                                     out_value);
490cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
491cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
492674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool DictionaryValue::Get(StringPiece path, Value** out_value)  {
493cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return static_cast<const DictionaryValue&>(*this).Get(
494cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      path,
495cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      const_cast<const Value**>(out_value));
496cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
497cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
498cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetBoolean(const std::string& path,
499cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                 bool* bool_value) const {
500cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
501cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!Get(path, &value))
502cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
503cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
504cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsBoolean(bool_value);
505cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
506cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
507cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetInteger(const std::string& path,
508cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                 int* out_value) const {
509cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
510cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!Get(path, &value))
511cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
512cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
513cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsInteger(out_value);
514cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
515cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
516cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetDouble(const std::string& path,
517cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                double* out_value) const {
518cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
519cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!Get(path, &value))
520cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
521cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
522cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsDouble(out_value);
523cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
524cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
525cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetString(const std::string& path,
526cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                std::string* out_value) const {
527cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
528cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!Get(path, &value))
529cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
530cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
531cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsString(out_value);
532cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
533cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
534cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetStringASCII(const std::string& path,
535cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                     std::string* out_value) const {
536cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  std::string out;
537cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!GetString(path, &out))
538cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
539cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
540cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!IsStringASCII(out)) {
541cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    NOTREACHED();
542cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
543cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
544cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
545cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  out_value->assign(out);
546cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
547cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
548cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
549cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetBinary(const std::string& path,
550cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                const BinaryValue** out_value) const {
551cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
552cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool result = Get(path, &value);
553cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!result || !value->IsType(TYPE_BINARY))
554cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
555cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
556cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
557cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = static_cast<const BinaryValue*>(value);
558cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
559cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
560cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
561cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
562cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetBinary(const std::string& path,
563cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                BinaryValue** out_value) {
564cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return static_cast<const DictionaryValue&>(*this).GetBinary(
565cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      path,
566cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      const_cast<const BinaryValue**>(out_value));
567cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
568cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
569674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool DictionaryValue::GetDictionary(StringPiece path,
570cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                    const DictionaryValue** out_value) const {
571cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
572cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool result = Get(path, &value);
573cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!result || !value->IsType(TYPE_DICTIONARY))
574cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
575cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
576cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
577cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = static_cast<const DictionaryValue*>(value);
578cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
579cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
580cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
581cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
582674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkobool DictionaryValue::GetDictionary(StringPiece path,
583cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                    DictionaryValue** out_value) {
584cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return static_cast<const DictionaryValue&>(*this).GetDictionary(
585cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      path,
586cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      const_cast<const DictionaryValue**>(out_value));
587cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
588cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
589cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetList(const std::string& path,
590cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                              const ListValue** out_value) const {
591cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
592cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool result = Get(path, &value);
593cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!result || !value->IsType(TYPE_LIST))
594cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
595cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
596cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
597cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = static_cast<const ListValue*>(value);
598cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
599cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
600cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
601cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
602cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetList(const std::string& path, ListValue** out_value) {
603cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return static_cast<const DictionaryValue&>(*this).GetList(
604cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      path,
605cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      const_cast<const ListValue**>(out_value));
606cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
607cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
608cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
609cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                              const Value** out_value) const {
610cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(IsStringUTF8(key));
611cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  ValueMap::const_iterator entry_iterator = dictionary_.find(key);
612cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (entry_iterator == dictionary_.end())
613cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
614cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
615cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* entry = entry_iterator->second;
616cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
617cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = entry;
618cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
619cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
620cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
621cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
622cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                              Value** out_value) {
623cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
624cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      key,
625cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      const_cast<const Value**>(out_value));
626cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
627cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
628cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetBooleanWithoutPathExpansion(const std::string& key,
629cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                                     bool* out_value) const {
630cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
631cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!GetWithoutPathExpansion(key, &value))
632cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
633cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
634cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsBoolean(out_value);
635cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
636cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
637cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
638cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                                     int* out_value) const {
639cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
640cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!GetWithoutPathExpansion(key, &value))
641cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
642cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
643cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsInteger(out_value);
644cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
645cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
646cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
647cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                                    double* out_value) const {
648cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
649cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!GetWithoutPathExpansion(key, &value))
650cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
651cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
652cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsDouble(out_value);
653cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
654cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
655cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetStringWithoutPathExpansion(
656cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const std::string& key,
657cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    std::string* out_value) const {
658cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
659cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!GetWithoutPathExpansion(key, &value))
660cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
661cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
662cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsString(out_value);
663cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
664cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
665cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetDictionaryWithoutPathExpansion(
666cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const std::string& key,
667cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const DictionaryValue** out_value) const {
668cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
669cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool result = GetWithoutPathExpansion(key, &value);
670cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!result || !value->IsType(TYPE_DICTIONARY))
671cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
672cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
673cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
674cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = static_cast<const DictionaryValue*>(value);
675cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
676cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
677cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
678cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
679cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetDictionaryWithoutPathExpansion(
680cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const std::string& key,
681cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    DictionaryValue** out_value) {
682cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const DictionaryValue& const_this =
683cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      static_cast<const DictionaryValue&>(*this);
684cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return const_this.GetDictionaryWithoutPathExpansion(
685cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka          key,
686cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka          const_cast<const DictionaryValue**>(out_value));
687cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
688cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
689cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetListWithoutPathExpansion(
690cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const std::string& key,
691cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const ListValue** out_value) const {
692cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
693cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool result = GetWithoutPathExpansion(key, &value);
694cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!result || !value->IsType(TYPE_LIST))
695cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
696cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
697cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
698cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = static_cast<const ListValue*>(value);
699cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
700cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
701cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
702cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
703cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
704cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                                  ListValue** out_value) {
705cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return
706cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
707cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka          key,
708cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka          const_cast<const ListValue**>(out_value));
709cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
710cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
711cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::Remove(const std::string& path,
712cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                             scoped_ptr<Value>* out_value) {
713cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(IsStringUTF8(path));
714cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  std::string current_path(path);
715cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DictionaryValue* current_dictionary = this;
716cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  size_t delimiter_position = current_path.rfind('.');
717cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (delimiter_position != std::string::npos) {
718cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    if (!GetDictionary(current_path.substr(0, delimiter_position),
719cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                       &current_dictionary))
720cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return false;
721cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    current_path.erase(0, delimiter_position + 1);
722cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
723cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
724cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return current_dictionary->RemoveWithoutPathExpansion(current_path,
725cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                                        out_value);
726cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
727cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
728cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
729cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                                 scoped_ptr<Value>* out_value) {
730cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(IsStringUTF8(key));
731cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  ValueMap::iterator entry_iterator = dictionary_.find(key);
732cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (entry_iterator == dictionary_.end())
733cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
734cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
735cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Value* entry = entry_iterator->second;
736cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
737cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    out_value->reset(entry);
738cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  else
739cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    delete entry;
740cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  dictionary_.erase(entry_iterator);
741cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
742cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
743cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
744cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::RemovePath(const std::string& path,
745cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                 scoped_ptr<Value>* out_value) {
746cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool result = false;
747cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  size_t delimiter_position = path.find('.');
748cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
749cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (delimiter_position == std::string::npos)
750cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return RemoveWithoutPathExpansion(path, out_value);
751cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
752cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const std::string subdict_path = path.substr(0, delimiter_position);
753cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DictionaryValue* subdict = NULL;
754cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!GetDictionary(subdict_path, &subdict))
755cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
756cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  result = subdict->RemovePath(path.substr(delimiter_position + 1),
757cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                               out_value);
758cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (result && subdict->empty())
759cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    RemoveWithoutPathExpansion(subdict_path, NULL);
760cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
761cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return result;
762cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
763cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
764cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukascoped_ptr<DictionaryValue> DictionaryValue::DeepCopyWithoutEmptyChildren()
765cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const {
766cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  scoped_ptr<DictionaryValue> copy = CopyDictionaryWithoutEmptyChildren(*this);
767cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!copy)
768cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    copy.reset(new DictionaryValue);
769cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return copy;
770cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
771cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
772cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
773cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) {
774cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    const Value* merge_value = &it.value();
775cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    // Check whether we have to merge dictionaries.
776cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
777cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      DictionaryValue* sub_dict;
778cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
779cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka        sub_dict->MergeDictionary(
780cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka            static_cast<const DictionaryValue*>(merge_value));
781cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka        continue;
782cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      }
783cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
784cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    // All other cases: Make a copy and hook it up.
785cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    SetWithoutPathExpansion(it.key(), merge_value->DeepCopy());
786cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
787cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
788cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
789cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid DictionaryValue::Swap(DictionaryValue* other) {
790cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  dictionary_.swap(other->dictionary_);
791cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
792cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
793cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaDictionaryValue::Iterator::Iterator(const DictionaryValue& target)
794cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    : target_(target),
795cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      it_(target.dictionary_.begin()) {}
796cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
797cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaDictionaryValue::Iterator::~Iterator() {}
798cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
799cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaDictionaryValue* DictionaryValue::DeepCopy() const {
800cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DictionaryValue* result = new DictionaryValue;
801cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
802cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (ValueMap::const_iterator current_entry(dictionary_.begin());
803cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka       current_entry != dictionary_.end(); ++current_entry) {
804cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    result->SetWithoutPathExpansion(current_entry->first,
805cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                    current_entry->second->DeepCopy());
806cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
807cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
808cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return result;
809cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
810cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
811cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukascoped_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
812cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return make_scoped_ptr(DeepCopy());
813cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
814cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
815cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool DictionaryValue::Equals(const Value* other) const {
816cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (other->GetType() != GetType())
817cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
818cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
819cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const DictionaryValue* other_dict =
820cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      static_cast<const DictionaryValue*>(other);
821cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Iterator lhs_it(*this);
822cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Iterator rhs_it(*other_dict);
823cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  while (!lhs_it.IsAtEnd() && !rhs_it.IsAtEnd()) {
824cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    if (lhs_it.key() != rhs_it.key() ||
825cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka        !lhs_it.value().Equals(&rhs_it.value())) {
826cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return false;
827cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
828cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    lhs_it.Advance();
829cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    rhs_it.Advance();
830cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
831cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!lhs_it.IsAtEnd() || !rhs_it.IsAtEnd())
832cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
833cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
834cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
835cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
836cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
837cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka///////////////////// ListValue ////////////////////
838cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
839674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko// static
840674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenkoscoped_ptr<ListValue> ListValue::From(scoped_ptr<Value> value) {
841674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  ListValue* out;
842674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  if (value && value->GetAsList(&out)) {
843674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko    ignore_result(value.release());
844674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko    return make_scoped_ptr(out);
845674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  }
846674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko  return nullptr;
847674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko}
848674f0eb973b8ebf08f9abcb45b2271dc510aa2cfAlex Vakulenko
849cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaListValue::ListValue() : Value(TYPE_LIST) {
850cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
851cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
852cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaListValue::~ListValue() {
853cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Clear();
854cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
855cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
856cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid ListValue::Clear() {
857cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
858cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    delete *i;
859cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  list_.clear();
860cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
861cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
862cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::Set(size_t index, Value* in_value) {
863cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!in_value)
864cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
865cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
866cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (index >= list_.size()) {
867cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    // Pad out any intermediate indexes with null settings
868cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    while (index > list_.size())
869cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      Append(CreateNullValue());
870cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    Append(in_value);
871cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  } else {
872cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    DCHECK(list_[index] != in_value);
873cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    delete list_[index];
874cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    list_[index] = in_value;
875cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
876cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
877cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
878cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
879cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::Set(size_t index, scoped_ptr<Value> in_value) {
880cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return Set(index, in_value.release());
881cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
882cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
883cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::Get(size_t index, const Value** out_value) const {
884cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (index >= list_.size())
885cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
886cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
887cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
888cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = list_[index];
889cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
890cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
891cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
892cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
893cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::Get(size_t index, Value** out_value) {
894cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return static_cast<const ListValue&>(*this).Get(
895cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      index,
896cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      const_cast<const Value**>(out_value));
897cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
898cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
899cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetBoolean(size_t index, bool* bool_value) const {
900cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
901cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!Get(index, &value))
902cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
903cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
904cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsBoolean(bool_value);
905cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
906cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
907cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetInteger(size_t index, int* out_value) const {
908cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
909cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!Get(index, &value))
910cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
911cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
912cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsInteger(out_value);
913cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
914cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
915cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetDouble(size_t index, double* out_value) const {
916cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
917cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!Get(index, &value))
918cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
919cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
920cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsDouble(out_value);
921cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
922cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
923cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetString(size_t index, std::string* out_value) const {
924cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
925cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!Get(index, &value))
926cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
927cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
928cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return value->GetAsString(out_value);
929cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
930cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
931cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const {
932cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
933cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool result = Get(index, &value);
934cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!result || !value->IsType(TYPE_BINARY))
935cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
936cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
937cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
938cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = static_cast<const BinaryValue*>(value);
939cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
940cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
941cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
942cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
943cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetBinary(size_t index, BinaryValue** out_value) {
944cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return static_cast<const ListValue&>(*this).GetBinary(
945cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      index,
946cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      const_cast<const BinaryValue**>(out_value));
947cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
948cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
949cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetDictionary(size_t index,
950cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                              const DictionaryValue** out_value) const {
951cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
952cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool result = Get(index, &value);
953cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!result || !value->IsType(TYPE_DICTIONARY))
954cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
955cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
956cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
957cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = static_cast<const DictionaryValue*>(value);
958cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
959cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
960cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
961cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
962cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
963cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return static_cast<const ListValue&>(*this).GetDictionary(
964cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      index,
965cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      const_cast<const DictionaryValue**>(out_value));
966cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
967cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
968cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetList(size_t index, const ListValue** out_value) const {
969cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const Value* value;
970cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  bool result = Get(index, &value);
971cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (!result || !value->IsType(TYPE_LIST))
972cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
973cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
974cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
975cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = static_cast<const ListValue*>(value);
976cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
977cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
978cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
979cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
980cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetList(size_t index, ListValue** out_value) {
981cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return static_cast<const ListValue&>(*this).GetList(
982cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      index,
983cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      const_cast<const ListValue**>(out_value));
984cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
985cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
986cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::Remove(size_t index, scoped_ptr<Value>* out_value) {
987cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (index >= list_.size())
988cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
989cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
990cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
991cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    out_value->reset(list_[index]);
992cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  else
993cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    delete list_[index];
994cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
995cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  list_.erase(list_.begin() + index);
996cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
997cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
998cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
999cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::Remove(const Value& value, size_t* index) {
1000cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
1001cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    if ((*i)->Equals(&value)) {
1002cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      size_t previous_index = i - list_.begin();
1003cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      delete *i;
1004cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      list_.erase(i);
1005cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1006cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      if (index)
1007cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka        *index = previous_index;
1008cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return true;
1009cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
1010cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
1011cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return false;
1012cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1013cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1014cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaListValue::iterator ListValue::Erase(iterator iter,
1015cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka                                     scoped_ptr<Value>* out_value) {
1016cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
1017cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    out_value->reset(*iter);
1018cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  else
1019cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    delete *iter;
1020cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1021cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return list_.erase(iter);
1022cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1023cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1024cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid ListValue::Append(scoped_ptr<Value> in_value) {
1025cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Append(in_value.release());
1026cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1027cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1028cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid ListValue::Append(Value* in_value) {
1029cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(in_value);
1030cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  list_.push_back(in_value);
1031cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1032cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1033cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid ListValue::AppendBoolean(bool in_value) {
1034cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Append(new FundamentalValue(in_value));
1035cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1036cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1037cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid ListValue::AppendInteger(int in_value) {
1038cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Append(new FundamentalValue(in_value));
1039cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1040cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1041cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid ListValue::AppendDouble(double in_value) {
1042cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Append(new FundamentalValue(in_value));
1043cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1044cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1045cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid ListValue::AppendString(const std::string& in_value) {
1046cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Append(new StringValue(in_value));
1047cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1048cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1049cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid ListValue::AppendStrings(const std::vector<std::string>& in_values) {
1050cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (std::vector<std::string>::const_iterator it = in_values.begin();
1051cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka       it != in_values.end(); ++it) {
1052cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    AppendString(*it);
1053cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
1054cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1055cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1056cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::AppendIfNotPresent(Value* in_value) {
1057cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(in_value);
1058cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
1059cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    if ((*i)->Equals(in_value)) {
1060cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      delete in_value;
1061cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return false;
1062cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
1063cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
1064cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  list_.push_back(in_value);
1065cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
1066cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1067cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1068cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::Insert(size_t index, Value* in_value) {
1069cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DCHECK(in_value);
1070cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (index > list_.size())
1071cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
1072cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1073cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  list_.insert(list_.begin() + index, in_value);
1074cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
1075cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1076cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1077cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaListValue::const_iterator ListValue::Find(const Value& value) const {
1078cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return std::find_if(list_.begin(), list_.end(), ValueEquals(&value));
1079cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1080cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1081cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukavoid ListValue::Swap(ListValue* other) {
1082cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  list_.swap(other->list_);
1083cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1084cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1085cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetAsList(ListValue** out_value) {
1086cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
1087cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = this;
1088cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
1089cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1090cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1091cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::GetAsList(const ListValue** out_value) const {
1092cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (out_value)
1093cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    *out_value = this;
1094cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
1095cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1096cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1097cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaListValue* ListValue::DeepCopy() const {
1098cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  ListValue* result = new ListValue;
1099cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1100cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
1101cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    result->Append((*i)->DeepCopy());
1102cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1103cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return result;
1104cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1105cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1106cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukascoped_ptr<ListValue> ListValue::CreateDeepCopy() const {
1107cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return make_scoped_ptr(DeepCopy());
1108cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1109cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1110cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukabool ListValue::Equals(const Value* other) const {
1111cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (other->GetType() != GetType())
1112cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
1113cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1114cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const ListValue* other_list =
1115cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      static_cast<const ListValue*>(other);
1116cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  const_iterator lhs_it, rhs_it;
1117cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  for (lhs_it = begin(), rhs_it = other_list->begin();
1118cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka       lhs_it != end() && rhs_it != other_list->end();
1119cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka       ++lhs_it, ++rhs_it) {
1120cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    if (!(*lhs_it)->Equals(*rhs_it))
1121cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      return false;
1122cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
1123cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  if (lhs_it != end() || rhs_it != other_list->end())
1124cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    return false;
1125cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1126cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return true;
1127cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1128cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1129cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukastd::ostream& operator<<(std::ostream& out, const Value& value) {
1130cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  std::string json;
1131cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json);
1132cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  return out << json;
1133cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
1134cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
1135cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}  // namespace base
1136