1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 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
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenFundamentalValue* Value::CreateBooleanValue(bool in_value) {
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new FundamentalValue(in_value);
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenFundamentalValue* Value::CreateIntegerValue(int in_value) {
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new FundamentalValue(in_value);
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenFundamentalValue* Value::CreateDoubleValue(double in_value) {
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new FundamentalValue(in_value);
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenStringValue* Value::CreateStringValue(const std::string& in_value) {
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new StringValue(in_value);
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenStringValue* 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
11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool Value::GetAsDouble(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
12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool Value::GetAsList(ListValue** out_value) {
12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return false;
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottValue* Value::DeepCopy() const {
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This method should only be getting called for null Values--all subclasses
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // need to provide their own implementation;.
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(IsType(TYPE_NULL));
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return CreateNullValue();
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Value::Equals(const Value* other) const {
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This method should only be getting called for null Values--all subclasses
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // need to provide their own implementation;.
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(IsType(TYPE_NULL));
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return other->IsType(TYPE_NULL);
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool Value::Equals(const Value* a, const Value* b) {
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if ((a == NULL) && (b == NULL)) return true;
14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if ((a == NULL) ^  (b == NULL)) return false;
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return a->Equals(b);
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochValue::Value(ValueType type) : type_(type) {
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// FundamentalValue ////////////////////
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFundamentalValue::FundamentalValue(bool in_value)
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFundamentalValue::FundamentalValue(int in_value)
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : Value(TYPE_INTEGER), integer_value_(in_value) {
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFundamentalValue::FundamentalValue(double in_value)
16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : Value(TYPE_DOUBLE), double_value_(in_value) {
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFundamentalValue::~FundamentalValue() {
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FundamentalValue::GetAsBoolean(bool* out_value) const {
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value && IsType(TYPE_BOOLEAN))
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = boolean_value_;
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (IsType(TYPE_BOOLEAN));
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FundamentalValue::GetAsInteger(int* out_value) const {
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value && IsType(TYPE_INTEGER))
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = integer_value_;
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (IsType(TYPE_INTEGER));
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool FundamentalValue::GetAsDouble(double* out_value) const {
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (out_value && IsType(TYPE_DOUBLE))
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    *out_value = double_value_;
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return (IsType(TYPE_DOUBLE));
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenFundamentalValue* FundamentalValue::DeepCopy() const {
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  switch (GetType()) {
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_BOOLEAN:
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return CreateBooleanValue(boolean_value_);
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_INTEGER:
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return CreateIntegerValue(integer_value_);
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case TYPE_DOUBLE:
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return CreateDoubleValue(double_value_);
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    default:
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      NOTREACHED();
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return NULL;
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FundamentalValue::Equals(const Value* other) const {
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other->GetType() != GetType())
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  switch (GetType()) {
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_BOOLEAN: {
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      bool lhs, rhs;
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TYPE_INTEGER: {
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      int lhs, rhs;
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case TYPE_DOUBLE: {
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      double lhs, rhs;
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    default:
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      NOTREACHED();
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// StringValue ////////////////////
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottStringValue::StringValue(const std::string& in_value)
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : Value(TYPE_STRING),
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      value_(in_value) {
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(IsStringUTF8(in_value));
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottStringValue::StringValue(const string16& in_value)
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : Value(TYPE_STRING),
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      value_(UTF16ToUTF8(in_value)) {
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottStringValue::~StringValue() {
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool StringValue::GetAsString(std::string* out_value) const {
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = value_;
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool StringValue::GetAsString(string16* out_value) const {
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = UTF8ToUTF16(value_);
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenStringValue* StringValue::DeepCopy() const {
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return CreateStringValue(value_);
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool StringValue::Equals(const Value* other) const {
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other->GetType() != GetType())
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string lhs, rhs;
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// BinaryValue ////////////////////
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2663f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenBinaryValue::~BinaryValue() {
2673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK(buffer_);
2683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (buffer_)
2693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    delete[] buffer_;
2703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBinaryValue* BinaryValue::Create(char* buffer, size_t size) {
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!buffer)
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new BinaryValue(buffer, size);
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                 size_t size) {
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!buffer)
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* buffer_copy = new char[size];
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(buffer_copy, buffer, size);
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new BinaryValue(buffer_copy, size);
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenBinaryValue* BinaryValue::DeepCopy() const {
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return CreateWithCopiedBuffer(buffer_, size_);
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BinaryValue::Equals(const Value* other) const {
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other->GetType() != GetType())
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other_binary->size_ != size_)
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return !memcmp(buffer_, other_binary->buffer_, size_);
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3043f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenBinaryValue::BinaryValue(char* buffer, size_t size)
3053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  : Value(TYPE_BINARY),
3063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    buffer_(buffer),
3073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    size_(size) {
3083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK(buffer_);
3093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
3103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// DictionaryValue ////////////////////
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDictionaryValue::DictionaryValue()
3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : Value(TYPE_DICTIONARY) {
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottDictionaryValue::~DictionaryValue() {
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Clear();
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::HasKey(const std::string& key) const {
3223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(key));
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ValueMap::const_iterator current_entry = dictionary_.find(key);
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK((current_entry == dictionary_.end()) || current_entry->second);
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return current_entry != dictionary_.end();
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DictionaryValue::Clear() {
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ValueMap::iterator dict_iterator = dictionary_.begin();
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (dict_iterator != dictionary_.end()) {
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete dict_iterator->second;
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ++dict_iterator;
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  dictionary_.clear();
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::Set(const std::string& path, Value* in_value) {
3393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(path));
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(in_value);
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string current_path(path);
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DictionaryValue* current_dictionary = this;
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t delimiter_position = current_path.find('.');
3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick       delimiter_position != std::string::npos;
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       delimiter_position = current_path.find('.')) {
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Assume that we're indexing into a dictionary.
3483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::string key(current_path, 0, delimiter_position);
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DictionaryValue* child_dictionary = NULL;
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      child_dictionary = new DictionaryValue;
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_dictionary = child_dictionary;
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_path.erase(0, delimiter_position + 1);
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  current_dictionary->SetWithoutPathExpansion(current_path, in_value);
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Set(path, CreateBooleanValue(in_value));
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetInteger(const std::string& path, int in_value) {
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Set(path, CreateIntegerValue(in_value));
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
37072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid DictionaryValue::SetDouble(const std::string& path, double in_value) {
37172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Set(path, CreateDoubleValue(in_value));
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetString(const std::string& path,
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                const std::string& in_value) {
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Set(path, CreateStringValue(in_value));
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetString(const std::string& path,
3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                const string16& in_value) {
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Set(path, CreateStringValue(in_value));
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DictionaryValue::SetWithoutPathExpansion(const std::string& key,
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                              Value* in_value) {
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If there's an existing value here, we need to delete it, because
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // we own all our children.
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (HasKey(key)) {
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(dictionary_[key] != in_value);  // This would be bogus
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete dictionary_[key];
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  dictionary_[key] = in_value;
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::Get(const std::string& path, Value** out_value) const {
3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(path));
3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string current_path(path);
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const DictionaryValue* current_dictionary = this;
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t delimiter_position = current_path.find('.');
4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick       delimiter_position != std::string::npos;
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       delimiter_position = current_path.find('.')) {
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DictionaryValue* child_dictionary = NULL;
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!current_dictionary->GetDictionary(
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            current_path.substr(0, delimiter_position), &child_dictionary))
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_dictionary = child_dictionary;
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_path.erase(0, delimiter_position + 1);
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetBoolean(const std::string& path,
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 bool* bool_value) const {
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsBoolean(bool_value);
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetInteger(const std::string& path,
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 int* out_value) const {
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsInteger(out_value);
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
43372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool DictionaryValue::GetDouble(const std::string& path,
43472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                double* out_value) const {
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return value->GetAsDouble(out_value);
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DictionaryValue::GetString(const std::string& path,
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                std::string* out_value) const {
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetString(const std::string& path,
4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                string16* out_value) const {
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(path, &value))
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetStringASCII(const std::string& path,
4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     std::string* out_value) const {
4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string out;
4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!GetString(path, &out))
4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return false;
4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!IsStringASCII(out)) {
4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NOTREACHED();
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  out_value->assign(out);
4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return true;
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetBinary(const std::string& path,
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                BinaryValue** out_value) const {
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(path, &value);
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_BINARY))
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<BinaryValue*>(value);
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetDictionary(const std::string& path,
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                    DictionaryValue** out_value) const {
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(path, &value);
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_DICTIONARY))
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<DictionaryValue*>(value);
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetList(const std::string& path,
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              ListValue** out_value) const {
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(path, &value);
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_LIST))
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<ListValue*>(value);
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                              Value** out_value) const {
5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(key));
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ValueMap::const_iterator entry_iterator = dictionary_.find(key);
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (entry_iterator == dictionary_.end())
519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* entry = entry_iterator->second;
522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = entry;
524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                     int* out_value) const {
529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!GetWithoutPathExpansion(key, &value))
531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsInteger(out_value);
534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
53672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
53772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                    double* out_value) const {
538731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Value* value;
539731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!GetWithoutPathExpansion(key, &value))
540731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return false;
541731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
54272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return value->GetAsDouble(out_value);
543731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
544731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool DictionaryValue::GetStringWithoutPathExpansion(
5463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& key,
547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* out_value) const {
548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
5493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!GetWithoutPathExpansion(key, &value))
550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool DictionaryValue::GetStringWithoutPathExpansion(
5563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& key,
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    string16* out_value) const {
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
5593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!GetWithoutPathExpansion(key, &value))
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return value->GetAsString(out_value);
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool DictionaryValue::GetDictionaryWithoutPathExpansion(
5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& key,
567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DictionaryValue** out_value) const {
568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
5693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool result = GetWithoutPathExpansion(key, &value);
570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_DICTIONARY))
571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<DictionaryValue*>(value);
575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                  ListValue** out_value) const {
581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool result = GetWithoutPathExpansion(key, &value);
583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_LIST))
584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<ListValue*>(value);
588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::Remove(const std::string& path, Value** out_value) {
5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(path));
5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string current_path(path);
595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DictionaryValue* current_dictionary = this;
596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t delimiter_position = current_path.rfind('.');
5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (delimiter_position != std::string::npos) {
598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!GetDictionary(current_path.substr(0, delimiter_position),
599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                       &current_dictionary))
600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    current_path.erase(0, delimiter_position + 1);
602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return current_dictionary->RemoveWithoutPathExpansion(current_path,
605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                        out_value);
606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
6083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                 Value** out_value) {
6103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(IsStringUTF8(key));
611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ValueMap::iterator entry_iterator = dictionary_.find(key);
612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (entry_iterator == dictionary_.end())
613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* entry = entry_iterator->second;
616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = entry;
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  else
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete entry;
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  dictionary_.erase(entry_iterator);
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottDictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* copy = CopyWithoutEmptyChildren(this);
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (DictionaryValue::key_iterator key(dictionary->begin_keys());
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       key != dictionary->end_keys(); ++key) {
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Value* merge_value;
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (dictionary->GetWithoutPathExpansion(*key, &merge_value)) {
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Check whether we have to merge dictionaries.
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DictionaryValue* sub_dict;
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (GetDictionaryWithoutPathExpansion(*key, &sub_dict)) {
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          sub_dict->MergeDictionary(
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              static_cast<const DictionaryValue*>(merge_value));
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          continue;
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // All other cases: Make a copy and hook it up.
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SetWithoutPathExpansion(*key, merge_value->DeepCopy());
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenDictionaryValue* DictionaryValue::DeepCopy() const {
6503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DictionaryValue* result = new DictionaryValue;
6513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
6523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  for (ValueMap::const_iterator current_entry(dictionary_.begin());
6533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen       current_entry != dictionary_.end(); ++current_entry) {
6543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    result->SetWithoutPathExpansion(current_entry->first,
6553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                    current_entry->second->DeepCopy());
6563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
6573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
6583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return result;
6593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
6603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
6613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool DictionaryValue::Equals(const Value* other) const {
6623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (other->GetType() != GetType())
6633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return false;
6643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
6653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  const DictionaryValue* other_dict =
6663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      static_cast<const DictionaryValue*>(other);
6673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  key_iterator lhs_it(begin_keys());
6683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  key_iterator rhs_it(other_dict->begin_keys());
6693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) {
6703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    Value* lhs;
6713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    Value* rhs;
6723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (*lhs_it != *rhs_it ||
6733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        !GetWithoutPathExpansion(*lhs_it, &lhs) ||
6743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) ||
6753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        !lhs->Equals(rhs)) {
6763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return false;
6773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
6783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    ++lhs_it;
6793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    ++rhs_it;
6803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
6813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (lhs_it != end_keys() || rhs_it != other_dict->end_keys())
6823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return false;
6833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
6843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return true;
6853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
6863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///////////////////// ListValue ////////////////////
688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochListValue::ListValue() : Value(TYPE_LIST) {
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottListValue::~ListValue() {
693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Clear();
694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ListValue::Clear() {
697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete *i;
699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  list_.clear();
700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Set(size_t index, Value* in_value) {
703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!in_value)
704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (index >= list_.size()) {
707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Pad out any intermediate indexes with null settings
708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    while (index > list_.size())
709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      Append(CreateNullValue());
710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Append(in_value);
711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(list_[index] != in_value);
713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete list_[index];
714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    list_[index] = in_value;
715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Get(size_t index, Value** out_value) const {
720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (index >= list_.size())
721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = list_[index];
725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetBoolean(size_t index, bool* bool_value) const {
730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsBoolean(bool_value);
735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetInteger(size_t index, int* out_value) const {
738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsInteger(out_value);
743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
74572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool ListValue::GetDouble(size_t index, double* out_value) const {
746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
75072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return value->GetAsDouble(out_value);
751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetString(size_t index, std::string* out_value) const {
754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ListValue::GetString(size_t index, string16* out_value) const {
762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!Get(index, &value))
764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return value->GetAsString(out_value);
767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetBinary(size_t index, BinaryValue** out_value) const {
770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(index, &value);
772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_BINARY))
773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<BinaryValue*>(value);
777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) const {
782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(index, &value);
784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_DICTIONARY))
785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<DictionaryValue*>(value);
789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::GetList(size_t index, ListValue** out_value) const {
794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Value* value;
795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool result = Get(index, &value);
796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result || !value->IsType(TYPE_LIST))
797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = static_cast<ListValue*>(value);
801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Remove(size_t index, Value** out_value) {
806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (index >= list_.size())
807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (out_value)
810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *out_value = list_[index];
811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  else
812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete list_[index];
813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  list_.erase(list_.begin() + index);
815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ListValue::Remove(const Value& value) {
819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if ((*i)->Equals(&value)) {
821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      size_t index = i - list_.begin();
822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delete *i;
823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      list_.erase(i);
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // TODO(anyone): Returning a signed int type here is just wrong.
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Change this interface to return a size_t.
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(index <= INT_MAX);
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int return_index = static_cast<int>(index);
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return return_index;
830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return -1;
833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ListValue::Append(Value* in_value) {
836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(in_value);
837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  list_.push_back(in_value);
838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ListValue::AppendIfNotPresent(Value* in_value) {
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(in_value);
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
843ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if ((*i)->Equals(in_value)) {
844ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      delete in_value;
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
846ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  list_.push_back(in_value);
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Insert(size_t index, Value* in_value) {
853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(in_value);
854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (index > list_.size())
855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  list_.insert(list_.begin() + index, in_value);
858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
86121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool ListValue::GetAsList(ListValue** out_value) {
86221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (out_value)
86321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    *out_value = this;
86421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return true;
86521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
86621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
86772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenListValue* ListValue::DeepCopy() const {
868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ListValue* result = new ListValue;
869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result->Append((*i)->DeepCopy());
872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return result;
874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ListValue::Equals(const Value* other) const {
877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (other->GetType() != GetType())
878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const ListValue* other_list =
881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      static_cast<const ListValue*>(other);
882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const_iterator lhs_it, rhs_it;
883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (lhs_it = begin(), rhs_it = other_list->begin();
884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       lhs_it != end() && rhs_it != other_list->end();
885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       ++lhs_it, ++rhs_it) {
886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!(*lhs_it)->Equals(*rhs_it))
887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (lhs_it != end() || rhs_it != other_list->end())
890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochValueSerializer::~ValueSerializer() {
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
897