15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <string.h>
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ostream>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/float_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/move.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace base {
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make a deep copy of |node|, but don't include empty lists or dictionaries
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the copy. It's possible for this function to return NULL and it
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expects |node| to always be non-NULL.
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Value* CopyWithoutEmptyChildren(const Value* node) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(node);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (node->GetType()) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case Value::TYPE_LIST: {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const ListValue* list = static_cast<const ListValue*>(node);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ListValue* copy = new ListValue;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (ListValue::const_iterator it = list->begin(); it != list->end();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ++it) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Value* child_copy = CopyWithoutEmptyChildren(*it);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (child_copy)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          copy->Append(child_copy);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!copy->empty())
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return copy;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete copy;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case Value::TYPE_DICTIONARY: {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const DictionaryValue* dict = static_cast<const DictionaryValue*>(node);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DictionaryValue* copy = new DictionaryValue;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Value* child_copy = CopyWithoutEmptyChildren(&it.value());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (child_copy)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          copy->SetWithoutPathExpansion(it.key(), child_copy);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!copy->empty())
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return copy;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete copy;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // For everything else, just make a copy.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return node->DeepCopy();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A small functor for comparing Values for std::find_if and similar.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ValueEquals {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pass the value against which all consecutive calls of the () operator will
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // compare their argument to. This Value object must not be destroyed while
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the ValueEquals is  in use.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit ValueEquals(const Value* first) : first_(first) { }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator ()(const Value* second) const {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return first_->Equals(second);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* first_;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Value::~Value() {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Value* Value::CreateNullValue() {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new Value(TYPE_NULL);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::GetAsBoolean(bool* out_value) const {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::GetAsInteger(int* out_value) const {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::GetAsDouble(double* out_value) const {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::GetAsString(std::string* out_value) const {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::GetAsString(string16* out_value) const {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Value::GetAsString(const StringValue** out_value) const {
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::GetAsList(ListValue** out_value) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::GetAsList(const ListValue** out_value) const {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::GetAsDictionary(DictionaryValue** out_value) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Value* Value::DeepCopy() const {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method should only be getting called for null Values--all subclasses
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // need to provide their own implementation;.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsType(TYPE_NULL));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateNullValue();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::Equals(const Value* other) const {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method should only be getting called for null Values--all subclasses
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // need to provide their own implementation;.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsType(TYPE_NULL));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return other->IsType(TYPE_NULL);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Value::Equals(const Value* a, const Value* b) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((a == NULL) && (b == NULL)) return true;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((a == NULL) ^  (b == NULL)) return false;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return a->Equals(b);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Value::Value(Type type) : type_(type) {}
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Value::Value(const Value& that) : type_(that.type_) {}
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Value& Value::operator=(const Value& that) {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  type_ = that.type_;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return *this;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////// FundamentalValue ////////////////////
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FundamentalValue::FundamentalValue(bool in_value)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FundamentalValue::FundamentalValue(int in_value)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Value(TYPE_INTEGER), integer_value_(in_value) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FundamentalValue::FundamentalValue(double in_value)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Value(TYPE_DOUBLE), double_value_(in_value) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsFinite(double_value_)) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << "values cannot be represented in JSON";
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double_value_ = 0.0;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FundamentalValue::~FundamentalValue() {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FundamentalValue::GetAsBoolean(bool* out_value) const {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value && IsType(TYPE_BOOLEAN))
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = boolean_value_;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (IsType(TYPE_BOOLEAN));
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FundamentalValue::GetAsInteger(int* out_value) const {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value && IsType(TYPE_INTEGER))
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = integer_value_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (IsType(TYPE_INTEGER));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FundamentalValue::GetAsDouble(double* out_value) const {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value && IsType(TYPE_DOUBLE))
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = double_value_;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (out_value && IsType(TYPE_INTEGER))
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = integer_value_;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER));
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FundamentalValue* FundamentalValue::DeepCopy() const {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (GetType()) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_BOOLEAN:
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return new FundamentalValue(boolean_value_);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_INTEGER:
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return new FundamentalValue(integer_value_);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_DOUBLE:
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return new FundamentalValue(double_value_);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FundamentalValue::Equals(const Value* other) const {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (other->GetType() != GetType())
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (GetType()) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_BOOLEAN: {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool lhs, rhs;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_INTEGER: {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int lhs, rhs;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_DOUBLE: {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      double lhs, rhs;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////// StringValue ////////////////////
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StringValue::StringValue(const std::string& in_value)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Value(TYPE_STRING),
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      value_(in_value) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsStringUTF8(in_value));
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StringValue::StringValue(const string16& in_value)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Value(TYPE_STRING),
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      value_(UTF16ToUTF8(in_value)) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StringValue::~StringValue() {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string* StringValue::GetString() {
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return &value_;
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& StringValue::GetString() const {
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return value_;
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StringValue::GetAsString(std::string* out_value) const {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = value_;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StringValue::GetAsString(string16* out_value) const {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = UTF8ToUTF16(value_);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool StringValue::GetAsString(const StringValue** out_value) const {
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (out_value)
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *out_value = this;
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StringValue* StringValue::DeepCopy() const {
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return new StringValue(value_);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StringValue::Equals(const Value* other) const {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (other->GetType() != GetType())
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string lhs, rhs;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////// BinaryValue ////////////////////
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BinaryValue::BinaryValue()
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : Value(TYPE_BINARY),
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_(0) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BinaryValue::BinaryValue(scoped_ptr<char[]> buffer, size_t size)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : Value(TYPE_BINARY),
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      buffer_(buffer.Pass()),
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_(size) {
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BinaryValue::~BinaryValue() {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 size_t size) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* buffer_copy = new char[size];
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_copy, buffer, size);
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<char[]> scoped_buffer_copy(buffer_copy);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new BinaryValue(scoped_buffer_copy.Pass(), size);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BinaryValue* BinaryValue::DeepCopy() const {
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CreateWithCopiedBuffer(buffer_.get(), size_);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BinaryValue::Equals(const Value* other) const {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (other->GetType() != GetType())
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (other_binary->size_ != size_)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !memcmp(GetBuffer(), other_binary->GetBuffer(), size_);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////// DictionaryValue ////////////////////
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue::DictionaryValue()
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Value(TYPE_DICTIONARY) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue::~DictionaryValue() {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Clear();
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = this;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = this;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::HasKey(const std::string& key) const {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsStringUTF8(key));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValueMap::const_iterator current_entry = dictionary_.find(key);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK((current_entry == dictionary_.end()) || current_entry->second);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return current_entry != dictionary_.end();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::Clear() {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValueMap::iterator dict_iterator = dictionary_.begin();
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (dict_iterator != dictionary_.end()) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete dict_iterator->second;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++dict_iterator;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary_.clear();
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::Set(const std::string& path, Value* in_value) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsStringUTF8(path));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(in_value);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string current_path(path);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* current_dictionary = this;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t delimiter_position = current_path.find('.');
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       delimiter_position != std::string::npos;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       delimiter_position = current_path.find('.')) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Assume that we're indexing into a dictionary.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string key(current_path, 0, delimiter_position);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* child_dictionary = NULL;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      child_dictionary = new DictionaryValue;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_dictionary = child_dictionary;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_path.erase(0, delimiter_position + 1);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_dictionary->SetWithoutPathExpansion(current_path, in_value);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Set(path, new FundamentalValue(in_value));
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetInteger(const std::string& path, int in_value) {
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Set(path, new FundamentalValue(in_value));
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetDouble(const std::string& path, double in_value) {
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Set(path, new FundamentalValue(in_value));
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetString(const std::string& path,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& in_value) {
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Set(path, new StringValue(in_value));
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetString(const std::string& path,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const string16& in_value) {
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Set(path, new StringValue(in_value));
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              Value* in_value) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there's an existing value here, we need to delete it, because
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we own all our children.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::pair<ValueMap::iterator, bool> ins_res =
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dictionary_.insert(std::make_pair(key, in_value));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ins_res.second) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(ins_res.first->second, in_value);  // This would be bogus
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete ins_res.first->second;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ins_res.first->second = in_value;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetBooleanWithoutPathExpansion(
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path, bool in_value) {
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetWithoutPathExpansion(path, new FundamentalValue(in_value));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetIntegerWithoutPathExpansion(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path, int in_value) {
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetWithoutPathExpansion(path, new FundamentalValue(in_value));
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetDoubleWithoutPathExpansion(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path, double in_value) {
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetWithoutPathExpansion(path, new FundamentalValue(in_value));
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetStringWithoutPathExpansion(
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path, const std::string& in_value) {
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetWithoutPathExpansion(path, new StringValue(in_value));
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::SetStringWithoutPathExpansion(
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path, const string16& in_value) {
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetWithoutPathExpansion(path, new StringValue(in_value));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DictionaryValue::Get(const std::string& path,
459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          const Value** out_value) const {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsStringUTF8(path));
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string current_path(path);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DictionaryValue* current_dictionary = this;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t delimiter_position = current_path.find('.');
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       delimiter_position != std::string::npos;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       delimiter_position = current_path.find('.')) {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DictionaryValue* child_dictionary = NULL;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!current_dictionary->GetDictionary(
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            current_path.substr(0, delimiter_position), &child_dictionary))
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_dictionary = child_dictionary;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_path.erase(0, delimiter_position + 1);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::Get(const std::string& path, Value** out_value)  {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const DictionaryValue&>(*this).Get(
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<const Value**>(out_value));
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetBoolean(const std::string& path,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 bool* bool_value) const {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(path, &value))
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsBoolean(bool_value);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetInteger(const std::string& path,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 int* out_value) const {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(path, &value))
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsInteger(out_value);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetDouble(const std::string& path,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                double* out_value) const {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(path, &value))
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsDouble(out_value);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetString(const std::string& path,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                std::string* out_value) const {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(path, &value))
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsString(out_value);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetString(const std::string& path,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                string16* out_value) const {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(path, &value))
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsString(out_value);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetStringASCII(const std::string& path,
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     std::string* out_value) const {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string out;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetString(path, &out))
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsStringASCII(out)) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out_value->assign(out);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetBinary(const std::string& path,
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const BinaryValue** out_value) const {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = Get(path, &value);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result || !value->IsType(TYPE_BINARY))
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = static_cast<const BinaryValue*>(value);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetBinary(const std::string& path,
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                BinaryValue** out_value) {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const DictionaryValue&>(*this).GetBinary(
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<const BinaryValue**>(out_value));
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetDictionary(const std::string& path,
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const DictionaryValue** out_value) const {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = Get(path, &value);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result || !value->IsType(TYPE_DICTIONARY))
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = static_cast<const DictionaryValue*>(value);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetDictionary(const std::string& path,
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    DictionaryValue** out_value) {
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const DictionaryValue&>(*this).GetDictionary(
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path,
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<const DictionaryValue**>(out_value));
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetList(const std::string& path,
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const ListValue** out_value) const {
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = Get(path, &value);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result || !value->IsType(TYPE_LIST))
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = static_cast<const ListValue*>(value);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetList(const std::string& path, ListValue** out_value) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const DictionaryValue&>(*this).GetList(
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path,
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<const ListValue**>(out_value));
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const Value** out_value) const {
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsStringUTF8(key));
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValueMap::const_iterator entry_iterator = dictionary_.find(key);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry_iterator == dictionary_.end())
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* entry = entry_iterator->second;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = entry;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              Value** out_value) {
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<const Value**>(out_value));
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetBooleanWithoutPathExpansion(const std::string& key,
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     bool* out_value) const {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetWithoutPathExpansion(key, &value))
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsBoolean(out_value);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     int* out_value) const {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetWithoutPathExpansion(key, &value))
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsInteger(out_value);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    double* out_value) const {
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetWithoutPathExpansion(key, &value))
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsDouble(out_value);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetStringWithoutPathExpansion(
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* out_value) const {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetWithoutPathExpansion(key, &value))
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsString(out_value);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetStringWithoutPathExpansion(const std::string& key,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    string16* out_value) const {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetWithoutPathExpansion(key, &value))
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsString(out_value);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetDictionaryWithoutPathExpansion(
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DictionaryValue** out_value) const {
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = GetWithoutPathExpansion(key, &value);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result || !value->IsType(TYPE_DICTIONARY))
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = static_cast<const DictionaryValue*>(value);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetDictionaryWithoutPathExpansion(
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue** out_value) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DictionaryValue& const_this =
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const DictionaryValue&>(*this);
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return const_this.GetDictionaryWithoutPathExpansion(
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          key,
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const_cast<const DictionaryValue**>(out_value));
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetListWithoutPathExpansion(
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ListValue** out_value) const {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = GetWithoutPathExpansion(key, &value);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result || !value->IsType(TYPE_LIST))
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = static_cast<const ListValue*>(value);
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  ListValue** out_value) {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          key,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const_cast<const ListValue**>(out_value));
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool DictionaryValue::Remove(const std::string& path,
7163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                             scoped_ptr<Value>* out_value) {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsStringUTF8(path));
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string current_path(path);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* current_dictionary = this;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t delimiter_position = current_path.rfind('.');
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delimiter_position != std::string::npos) {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GetDictionary(current_path.substr(0, delimiter_position),
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       &current_dictionary))
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_path.erase(0, delimiter_position + 1);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return current_dictionary->RemoveWithoutPathExpansion(current_path,
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        out_value);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
7333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                                 scoped_ptr<Value>* out_value) {
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsStringUTF8(key));
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValueMap::iterator entry_iterator = dictionary_.find(key);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry_iterator == dictionary_.end())
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Value* entry = entry_iterator->second;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
7413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    out_value->reset(entry);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete entry;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary_.erase(entry_iterator);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DictionaryValue::RemovePath(const std::string& path,
749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 scoped_ptr<Value>* out_value) {
750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool result = false;
751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t delimiter_position = path.find('.');
752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (delimiter_position == std::string::npos)
754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return RemoveWithoutPathExpansion(path, out_value);
755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string subdict_path = path.substr(0, delimiter_position);
757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DictionaryValue* subdict = NULL;
758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!GetDictionary(subdict_path, &subdict))
759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  result = subdict->RemovePath(path.substr(delimiter_position + 1),
761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               out_value);
762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (result && subdict->empty())
763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RemoveWithoutPathExpansion(subdict_path, NULL);
764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return result;
766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
767f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
76858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() const {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Value* copy = CopyWithoutEmptyChildren(this);
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) {
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Value* merge_value = &it.value();
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check whether we have to merge dictionaries.
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DictionaryValue* sub_dict;
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        sub_dict->MergeDictionary(
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            static_cast<const DictionaryValue*>(merge_value));
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // All other cases: Make a copy and hook it up.
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetWithoutPathExpansion(it.key(), merge_value->DeepCopy());
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DictionaryValue::Swap(DictionaryValue* other) {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary_.swap(other->dictionary_);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : target_(target),
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it_(target.dictionary_.begin()) {}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)DictionaryValue::Iterator::~Iterator() {}
799a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* DictionaryValue::DeepCopy() const {
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* result = new DictionaryValue;
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ValueMap::const_iterator current_entry(dictionary_.begin());
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       current_entry != dictionary_.end(); ++current_entry) {
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->SetWithoutPathExpansion(current_entry->first,
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    current_entry->second->DeepCopy());
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DictionaryValue::Equals(const Value* other) const {
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (other->GetType() != GetType())
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DictionaryValue* other_dict =
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const DictionaryValue*>(other);
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Iterator lhs_it(*this);
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Iterator rhs_it(*other_dict);
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (!lhs_it.IsAtEnd() && !rhs_it.IsAtEnd()) {
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (lhs_it.key() != rhs_it.key() ||
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !lhs_it.value().Equals(&rhs_it.value())) {
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    lhs_it.Advance();
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    rhs_it.Advance();
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!lhs_it.IsAtEnd() || !rhs_it.IsAtEnd())
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////// ListValue ////////////////////
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ListValue::ListValue() : Value(TYPE_LIST) {
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ListValue::~ListValue() {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Clear();
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ListValue::Clear() {
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete *i;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list_.clear();
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::Set(size_t index, Value* in_value) {
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!in_value)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index >= list_.size()) {
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Pad out any intermediate indexes with null settings
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (index > list_.size())
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Append(CreateNullValue());
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Append(in_value);
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(list_[index] != in_value);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete list_[index];
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list_[index] = in_value;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::Get(size_t index, const Value** out_value) const {
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index >= list_.size())
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = list_[index];
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::Get(size_t index, Value** out_value) {
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const ListValue&>(*this).Get(
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index,
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<const Value**>(out_value));
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(index, &value))
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsBoolean(bool_value);
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetInteger(size_t index, int* out_value) const {
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(index, &value))
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsInteger(out_value);
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetDouble(size_t index, double* out_value) const {
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(index, &value))
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsDouble(out_value);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetString(size_t index, std::string* out_value) const {
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(index, &value))
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsString(out_value);
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetString(size_t index, string16* out_value) const {
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Get(index, &value))
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value->GetAsString(out_value);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const {
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = Get(index, &value);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result || !value->IsType(TYPE_BINARY))
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = static_cast<const BinaryValue*>(value);
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetBinary(size_t index, BinaryValue** out_value) {
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const ListValue&>(*this).GetBinary(
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index,
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<const BinaryValue**>(out_value));
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetDictionary(size_t index,
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const DictionaryValue** out_value) const {
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = Get(index, &value);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result || !value->IsType(TYPE_DICTIONARY))
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = static_cast<const DictionaryValue*>(value);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const ListValue&>(*this).GetDictionary(
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index,
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<const DictionaryValue**>(out_value));
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetList(size_t index, const ListValue** out_value) const {
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = Get(index, &value);
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result || !value->IsType(TYPE_LIST))
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out_value = static_cast<const ListValue*>(value);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ListValue::GetList(size_t index, ListValue** out_value) {
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const ListValue&>(*this).GetList(
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index,
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<const ListValue**>(out_value));
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool ListValue::Remove(size_t index, scoped_ptr<Value>* out_value) {
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index >= list_.size())
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_value)
9823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    out_value->reset(list_[index]);
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete list_[index];
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list_.erase(list_.begin() + index);