values.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/values.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h"
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/utf_string_conversions.h"
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make a deep copy of |node|, but don't include empty lists or dictionaries
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// in the copy. It's possible for this function to return NULL and it
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// expects |node| to always be non-NULL.
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* CopyWithoutEmptyChildren(Value* node) {
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(node);
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  switch (node->GetType()) {
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case Value::TYPE_LIST: {
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      ListValue* list = static_cast<ListValue*>(node);
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      ListValue* copy = new ListValue;
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      for (ListValue::const_iterator it = list->begin(); it != list->end();
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott           ++it) {
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        Value* child_copy = CopyWithoutEmptyChildren(*it);
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (child_copy)
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          copy->Append(child_copy);
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (!copy->empty())
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return copy;
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delete copy;
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return NULL;
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case Value::TYPE_DICTIONARY: {
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DictionaryValue* dict = static_cast<DictionaryValue*>(node);
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DictionaryValue* copy = new DictionaryValue;
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      for (DictionaryValue::key_iterator it = dict->begin_keys();
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott           it != dict->end_keys(); ++it) {
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        Value* child = NULL;
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        bool rv = dict->GetWithoutPathExpansion(*it, &child);
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        DCHECK(rv);
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        Value* child_copy = CopyWithoutEmptyChildren(child);
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (child_copy)
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          copy->SetWithoutPathExpansion(*it, child_copy);
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (!copy->empty())
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return copy;
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delete copy;
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return NULL;
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    default:
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // For everything else, just make a copy.
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return node->DeepCopy();
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// Value ////////////////////
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue::~Value() {
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* Value::CreateNullValue() {
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new Value(TYPE_NULL);
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* Value::CreateBooleanValue(bool in_value) {
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new FundamentalValue(in_value);
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* Value::CreateIntegerValue(int in_value) {
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new FundamentalValue(in_value);
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* Value::CreateRealValue(double in_value) {
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new FundamentalValue(in_value);
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* Value::CreateStringValue(const std::string& in_value) {
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new StringValue(in_value);
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickValue* Value::CreateStringValue(const string16& in_value) {
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new StringValue(in_value);
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBinaryValue* Value::CreateBinaryValue(char* buffer, size_t size) {
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return BinaryValue::Create(buffer, size);
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Value::GetAsBoolean(bool* out_value) const {
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Value::GetAsInteger(int* out_value) const {
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Value::GetAsReal(double* out_value) const {
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Value::GetAsString(std::string* out_value) const {
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Value::GetAsString(string16* out_value) const {
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* Value::DeepCopy() const {
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This method should only be getting called for null Values--all subclasses
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // need to provide their own implementation;.
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(IsType(TYPE_NULL));
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return CreateNullValue();
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Value::Equals(const Value* other) const {
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This method should only be getting called for null Values--all subclasses
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // need to provide their own implementation;.
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(IsType(TYPE_NULL));
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return other->IsType(TYPE_NULL);
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochValue::Value(ValueType type) : type_(type) {
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// FundamentalValue ////////////////////
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFundamentalValue::FundamentalValue(bool in_value)
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFundamentalValue::FundamentalValue(int in_value)
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : Value(TYPE_INTEGER), integer_value_(in_value) {
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFundamentalValue::FundamentalValue(double in_value)
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : Value(TYPE_REAL), real_value_(in_value) {
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFundamentalValue::~FundamentalValue() {
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FundamentalValue::GetAsBoolean(bool* out_value) const {
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value && IsType(TYPE_BOOLEAN))
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = boolean_value_;
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (IsType(TYPE_BOOLEAN));
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FundamentalValue::GetAsInteger(int* out_value) const {
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value && IsType(TYPE_INTEGER))
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = integer_value_;
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (IsType(TYPE_INTEGER));
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FundamentalValue::GetAsReal(double* out_value) const {
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value && IsType(TYPE_REAL))
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = real_value_;
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (IsType(TYPE_REAL));
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* FundamentalValue::DeepCopy() const {
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  switch (GetType()) {
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_BOOLEAN:
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return CreateBooleanValue(boolean_value_);
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_INTEGER:
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return CreateIntegerValue(integer_value_);
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_REAL:
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return CreateRealValue(real_value_);
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    default:
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      NOTREACHED();
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return NULL;
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FundamentalValue::Equals(const Value* other) const {
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other->GetType() != GetType())
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  switch (GetType()) {
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_BOOLEAN: {
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      bool lhs, rhs;
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_INTEGER: {
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      int lhs, rhs;
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_REAL: {
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      double lhs, rhs;
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return GetAsReal(&lhs) && other->GetAsReal(&rhs) && lhs == rhs;
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    default:
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      NOTREACHED();
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// StringValue ////////////////////
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottStringValue::StringValue(const std::string& in_value)
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : Value(TYPE_STRING),
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      value_(in_value) {
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(IsStringUTF8(in_value));
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottStringValue::StringValue(const string16& in_value)
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : Value(TYPE_STRING),
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      value_(UTF16ToUTF8(in_value)) {
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottStringValue::~StringValue() {
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool StringValue::GetAsString(std::string* out_value) const {
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = value_;
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool StringValue::GetAsString(string16* out_value) const {
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = UTF8ToUTF16(value_);
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* StringValue::DeepCopy() const {
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return CreateStringValue(value_);
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool StringValue::Equals(const Value* other) const {
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other->GetType() != GetType())
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string lhs, rhs;
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// BinaryValue ////////////////////
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBinaryValue* BinaryValue::Create(char* buffer, size_t size) {
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!buffer)
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new BinaryValue(buffer, size);
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                 size_t size) {
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!buffer)
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* buffer_copy = new char[size];
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(buffer_copy, buffer, size);
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new BinaryValue(buffer_copy, size);
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBinaryValue::BinaryValue(char* buffer, size_t size)
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  : Value(TYPE_BINARY),
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    buffer_(buffer),
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    size_(size) {
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(buffer_);
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBinaryValue::~BinaryValue() {
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(buffer_);
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (buffer_)
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete[] buffer_;
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* BinaryValue::DeepCopy() const {
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return CreateWithCopiedBuffer(buffer_, size_);
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BinaryValue::Equals(const Value* other) const {
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other->GetType() != GetType())
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other_binary->size_ != size_)
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return !memcmp(buffer_, other_binary->buffer_, size_);
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// DictionaryValue ////////////////////
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDictionaryValue::DictionaryValue()
3043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : Value(TYPE_DICTIONARY) {
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottDictionaryValue::~DictionaryValue() {
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Clear();
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* DictionaryValue::DeepCopy() const {
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DictionaryValue* result = new DictionaryValue;
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (ValueMap::const_iterator current_entry(dictionary_.begin());
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       current_entry != dictionary_.end(); ++current_entry) {
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result->SetWithoutPathExpansion(current_entry->first,
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                    current_entry->second->DeepCopy());
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return result;
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool DictionaryValue::Equals(const Value* other) const {
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other->GetType() != GetType())
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const DictionaryValue* other_dict =
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      static_cast<const DictionaryValue*>(other);
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  key_iterator lhs_it(begin_keys());
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  key_iterator rhs_it(other_dict->begin_keys());
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) {
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Value* lhs;
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Value* rhs;
3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (*lhs_it != *rhs_it ||
3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        !GetWithoutPathExpansion(*lhs_it, &lhs) ||
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) ||
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        !lhs->Equals(rhs)) {
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ++lhs_it;
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ++rhs_it;
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (lhs_it != end_keys() || rhs_it != other_dict->end_keys())
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::HasKey(const std::string& key) const {
3503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(key));
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ValueMap::const_iterator current_entry = dictionary_.find(key);
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK((current_entry == dictionary_.end()) || current_entry->second);
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return current_entry != dictionary_.end();
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DictionaryValue::Clear() {
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ValueMap::iterator dict_iterator = dictionary_.begin();
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (dict_iterator != dictionary_.end()) {
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete dict_iterator->second;
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ++dict_iterator;
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  dictionary_.clear();
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::Set(const std::string& path, Value* in_value) {
3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(path));
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(in_value);
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string current_path(path);
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DictionaryValue* current_dictionary = this;
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t delimiter_position = current_path.find('.');
3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick       delimiter_position != std::string::npos;
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       delimiter_position = current_path.find('.')) {
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Assume that we're indexing into a dictionary.
3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::string key(current_path, 0, delimiter_position);
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DictionaryValue* child_dictionary = NULL;
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      child_dictionary = new DictionaryValue;
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_dictionary = child_dictionary;
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_path.erase(0, delimiter_position + 1);
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  current_dictionary->SetWithoutPathExpansion(current_path, in_value);
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Set(path, CreateBooleanValue(in_value));
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetInteger(const std::string& path, int in_value) {
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Set(path, CreateIntegerValue(in_value));
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetReal(const std::string& path, double in_value) {
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Set(path, CreateRealValue(in_value));
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetString(const std::string& path,
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                const std::string& in_value) {
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Set(path, CreateStringValue(in_value));
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetString(const std::string& path,
4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                const string16& in_value) {
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Set(path, CreateStringValue(in_value));
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetWithoutPathExpansion(const std::string& key,
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                              Value* in_value) {
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If there's an existing value here, we need to delete it, because
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // we own all our children.
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (HasKey(key)) {
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(dictionary_[key] != in_value);  // This would be bogus
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete dictionary_[key];
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  dictionary_[key] = in_value;
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::Get(const std::string& path, Value** out_value) const {
4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(path));
4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string current_path(path);
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const DictionaryValue* current_dictionary = this;
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t delimiter_position = current_path.find('.');
4293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick       delimiter_position != std::string::npos;
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       delimiter_position = current_path.find('.')) {
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DictionaryValue* child_dictionary = NULL;
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!current_dictionary->GetDictionary(
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            current_path.substr(0, delimiter_position), &child_dictionary))
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_dictionary = child_dictionary;
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_path.erase(0, delimiter_position + 1);
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetBoolean(const std::string& path,
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 bool* bool_value) const {
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsBoolean(bool_value);
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetInteger(const std::string& path,
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 int* out_value) const {
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsInteger(out_value);
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetReal(const std::string& path,
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              double* out_value) const {
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsReal(out_value);
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DictionaryValue::GetString(const std::string& path,
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                std::string* out_value) const {
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetString(const std::string& path,
4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                string16* out_value) const {
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetStringASCII(const std::string& path,
4893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     std::string* out_value) const {
4903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string out;
4913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!GetString(path, &out))
4923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return false;
4933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!IsStringASCII(out)) {
4953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NOTREACHED();
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  out_value->assign(out);
5003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return true;
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetBinary(const std::string& path,
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                BinaryValue** out_value) const {
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(path, &value);
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_BINARY))
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<BinaryValue*>(value);
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetDictionary(const std::string& path,
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                    DictionaryValue** out_value) const {
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(path, &value);
520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_DICTIONARY))
521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<DictionaryValue*>(value);
525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetList(const std::string& path,
530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              ListValue** out_value) const {
531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(path, &value);
533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_LIST))
534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<ListValue*>(value);
538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                              Value** out_value) const {
5443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(key));
545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ValueMap::const_iterator entry_iterator = dictionary_.find(key);
546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (entry_iterator == dictionary_.end())
547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* entry = entry_iterator->second;
550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = entry;
552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                     int* out_value) const {
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
5583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!GetWithoutPathExpansion(key, &value))
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsInteger(out_value);
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
564731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool DictionaryValue::GetRealWithoutPathExpansion(const std::string& key,
565731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                  double* out_value) const {
566731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Value* value;
567731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!GetWithoutPathExpansion(key, &value))
568731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return false;
569731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
570731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return value->GetAsReal(out_value);
571731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
572731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool DictionaryValue::GetStringWithoutPathExpansion(
5743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& key,
575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* out_value) const {
576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!GetWithoutPathExpansion(key, &value))
578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool DictionaryValue::GetStringWithoutPathExpansion(
5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& key,
585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    string16* out_value) const {
586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!GetWithoutPathExpansion(key, &value))
588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return value->GetAsString(out_value);
591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool DictionaryValue::GetDictionaryWithoutPathExpansion(
5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& key,
595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DictionaryValue** out_value) const {
596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool result = GetWithoutPathExpansion(key, &value);
598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_DICTIONARY))
599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<DictionaryValue*>(value);
603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
6073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                  ListValue** out_value) const {
609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
6103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool result = GetWithoutPathExpansion(key, &value);
611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_LIST))
612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<ListValue*>(value);
616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
6203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::Remove(const std::string& path, Value** out_value) {
6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(path));
6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string current_path(path);
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DictionaryValue* current_dictionary = this;
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t delimiter_position = current_path.rfind('.');
6253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (delimiter_position != std::string::npos) {
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!GetDictionary(current_path.substr(0, delimiter_position),
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                       &current_dictionary))
628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_path.erase(0, delimiter_position + 1);
630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return current_dictionary->RemoveWithoutPathExpansion(current_path,
633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                        out_value);
634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
6363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                 Value** out_value) {
6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(key));
639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ValueMap::iterator entry_iterator = dictionary_.find(key);
640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (entry_iterator == dictionary_.end())
641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* entry = entry_iterator->second;
644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = entry;
646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  else
647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete entry;
648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  dictionary_.erase(entry_iterator);
649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottDictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* copy = CopyWithoutEmptyChildren(this);
654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (DictionaryValue::key_iterator key(dictionary->begin_keys());
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       key != dictionary->end_keys(); ++key) {
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Value* merge_value;
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (dictionary->GetWithoutPathExpansion(*key, &merge_value)) {
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Check whether we have to merge dictionaries.
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DictionaryValue* sub_dict;
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (GetDictionaryWithoutPathExpansion(*key, &sub_dict)) {
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          sub_dict->MergeDictionary(
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              static_cast<const DictionaryValue*>(merge_value));
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          continue;
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // All other cases: Make a copy and hook it up.
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SetWithoutPathExpansion(*key, merge_value->DeepCopy());
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetDifferingPathsHelper(
6783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& path_prefix,
6793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const DictionaryValue* other,
6803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<std::string>* different_paths) const {
6813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool added_path = false;
6823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::map<std::string, Value*>::const_iterator current_this;
6833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::map<std::string, Value*>::const_iterator end_this;
6843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  current_this = dictionary_.begin();
6853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  end_this = dictionary_.end();
6863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!other) {
6873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Recursively add all paths from the |this| dictionary, since they are
6883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // not in |other|.
6893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    for (; current_this != end_this; ++current_this) {
6903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      std::string full_path_for_key(path_prefix.empty() ? current_this->first :
6913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     path_prefix + "." + current_this->first);
6923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      different_paths->push_back(full_path_for_key);
6933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      added_path = true;
6943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (current_this->second->IsType(Value::TYPE_DICTIONARY)) {
6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        const DictionaryValue* dictionary_this =
6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            static_cast<const DictionaryValue*>(current_this->second);
6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        dictionary_this->GetDifferingPathsHelper(full_path_for_key,
6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                 NULL,
6993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                 different_paths);
7003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
7013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
7023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else {
7033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Both the |this| and |other| dictionaries have entries. Iterate over
7043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // both simultaneously. Paths that are in one but not the other are
7053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // added to |different_paths| and DictionaryValues are processed
7063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // recursively.
7073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::map<std::string, Value*>::const_iterator current_other =
7083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        other->dictionary_.begin();
7093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::map<std::string, Value*>::const_iterator end_other =
7103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        other->dictionary_.end();
7113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    while (current_this != end_this || current_other != end_other) {
7123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const Value* recursion_this = NULL;
7133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const Value* recursion_other = NULL;
7143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const std::string* key_name = NULL;
7153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      bool current_value_known_equal = false;
7163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (current_this == end_this ||
7173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          (current_other != end_other &&
7183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              (current_other->first < current_this->first))) {
7193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        key_name = &current_other->first;
7203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (current_other->second->IsType(Value::TYPE_DICTIONARY))
7213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick           recursion_this = current_other->second;
7223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        ++current_other;
7233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      } else {
7243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        key_name = &current_this->first;
7253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (current_other == end_other ||
7263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            current_this->first < current_other->first) {
7273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          if (current_this->second->IsType(Value::TYPE_DICTIONARY))
7283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            recursion_this = current_this->second;
7293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ++current_this;
7303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        } else {
7313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          DCHECK(current_this->first == current_other->first);
7323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          if (current_this->second->IsType(Value::TYPE_DICTIONARY)) {
7333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            recursion_this = current_this->second;
7343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (current_other->second->IsType(Value::TYPE_DICTIONARY)) {
7353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              recursion_other = current_other->second;
7363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            }
7373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          } else {
7383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (current_other->second->IsType(Value::TYPE_DICTIONARY)) {
7393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              recursion_this = current_other->second;
7403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            } else {
7413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              current_value_known_equal =
7423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 current_this->second->Equals(current_other->second);
7433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            }
7443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          }
7453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ++current_this;
7463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ++current_other;
7473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
7483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
7493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const std::string& full_path_for_key(path_prefix.empty() ?
7503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          *key_name : path_prefix + "." + *key_name);
7513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (!current_value_known_equal)
7523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        different_paths->push_back(full_path_for_key);
7533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (recursion_this) {
7543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        const DictionaryValue* dictionary_this =
7553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            static_cast<const DictionaryValue*>(recursion_this);
7563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        bool subtree_changed = dictionary_this->GetDifferingPathsHelper(
7573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            full_path_for_key,
7583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            static_cast<const DictionaryValue*>(recursion_other),
7593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            different_paths);
7603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (subtree_changed) {
7613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          added_path = true;
7623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        } else {
7633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          // In order to maintain lexicographical sorting order, directory
7643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          // paths are pushed "optimistically" assuming that their subtree will
7653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          // contain differences. If in retrospect there were no differences
7663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          // in the subtree, the assumption was false and the dictionary path
7673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          // must be removed.
7683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          different_paths->pop_back();
7693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
7703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      } else {
7713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        added_path |= !current_value_known_equal;
7723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
7733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
7743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
7753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return added_path;
7763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
7773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
7783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::GetDifferingPaths(
7793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const DictionaryValue* other,
7803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<std::string>* different_paths) const {
7813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  different_paths->clear();
7823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetDifferingPathsHelper("", other, different_paths);
7833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
7843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// ListValue ////////////////////
786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochListValue::ListValue() : Value(TYPE_LIST) {
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottListValue::~ListValue() {
791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Clear();
792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ListValue::Clear() {
795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete *i;
797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  list_.clear();
798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Set(size_t index, Value* in_value) {
801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!in_value)
802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (index >= list_.size()) {
805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Pad out any intermediate indexes with null settings
806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    while (index > list_.size())
807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      Append(CreateNullValue());
808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Append(in_value);
809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(list_[index] != in_value);
811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete list_[index];
812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    list_[index] = in_value;
813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Get(size_t index, Value** out_value) const {
818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (index >= list_.size())
819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = list_[index];
823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetBoolean(size_t index, bool* bool_value) const {
828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsBoolean(bool_value);
833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetInteger(size_t index, int* out_value) const {
836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsInteger(out_value);
841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetReal(size_t index, double* out_value) const {
844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsReal(out_value);
849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetString(size_t index, std::string* out_value) const {
852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
8593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ListValue::GetString(size_t index, string16* out_value) const {
860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetBinary(size_t index, BinaryValue** out_value) const {
868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(index, &value);
870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_BINARY))
871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<BinaryValue*>(value);
875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) const {
880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(index, &value);
882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_DICTIONARY))
883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<DictionaryValue*>(value);
887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetList(size_t index, ListValue** out_value) const {
892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(index, &value);
894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_LIST))
895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<ListValue*>(value);
899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Remove(size_t index, Value** out_value) {
904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (index >= list_.size())
905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = list_[index];
909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  else
910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete list_[index];
911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  list_.erase(list_.begin() + index);
913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ListValue::Remove(const Value& value) {
917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if ((*i)->Equals(&value)) {
919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      size_t index = i - list_.begin();
920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delete *i;
921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      list_.erase(i);
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // TODO(anyone): Returning a signed int type here is just wrong.
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Change this interface to return a size_t.
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(index <= INT_MAX);
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int return_index = static_cast<int>(index);
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return return_index;
928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return -1;
931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ListValue::Append(Value* in_value) {
934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(in_value);
935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  list_.push_back(in_value);
936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ListValue::AppendIfNotPresent(Value* in_value) {
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(in_value);
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if ((*i)->Equals(in_value))
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  list_.push_back(in_value);
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Insert(size_t index, Value* in_value) {
949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(in_value);
950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (index > list_.size())
951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  list_.insert(list_.begin() + index, in_value);
954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* ListValue::DeepCopy() const {
958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ListValue* result = new ListValue;
959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result->Append((*i)->DeepCopy());
962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return result;
964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Equals(const Value* other) const {
967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other->GetType() != GetType())
968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const ListValue* other_list =
971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      static_cast<const ListValue*>(other);
972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const_iterator lhs_it, rhs_it;
973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (lhs_it = begin(), rhs_it = other_list->begin();
974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       lhs_it != end() && rhs_it != other_list->end();
975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       ++lhs_it, ++rhs_it) {
976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!(*lhs_it)->Equals(*rhs_it))
977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (lhs_it != end() || rhs_it != other_list->end())
980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochValueSerializer::~ValueSerializer() {
986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
987