• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/common/indexed_db/indexed_db_key.h"
6 
7 #include <string>
8 #include "base/logging.h"
9 
10 namespace content {
11 
12 using blink::WebIDBKey;
13 using blink::WebIDBKeyType;
14 using blink::WebIDBKeyTypeArray;
15 using blink::WebIDBKeyTypeBinary;
16 using blink::WebIDBKeyTypeDate;
17 using blink::WebIDBKeyTypeInvalid;
18 using blink::WebIDBKeyTypeMin;
19 using blink::WebIDBKeyTypeNull;
20 using blink::WebIDBKeyTypeNumber;
21 using blink::WebIDBKeyTypeString;
22 
23 namespace {
24 
25 // Very rough estimate of minimum key size overhead.
26 const size_t kOverheadSize = 16;
27 
CalculateArraySize(const IndexedDBKey::KeyArray & keys)28 static size_t CalculateArraySize(const IndexedDBKey::KeyArray& keys) {
29   size_t size(0);
30   for (size_t i = 0; i < keys.size(); ++i)
31     size += keys[i].size_estimate();
32   return size;
33 }
34 
35 template <typename T>
CopyKeyArray(const T & array)36 static IndexedDBKey::KeyArray CopyKeyArray(const T& array) {
37   IndexedDBKey::KeyArray result;
38   result.reserve(array.size());
39   for (size_t i = 0; i < array.size(); ++i) {
40     result.push_back(IndexedDBKey(array[i]));
41   }
42   return result;
43 }
44 
45 }  // namespace
46 
IndexedDBKey()47 IndexedDBKey::IndexedDBKey()
48     : type_(WebIDBKeyTypeNull),
49       date_(0),
50       number_(0),
51       size_estimate_(kOverheadSize) {}
52 
IndexedDBKey(WebIDBKeyType type)53 IndexedDBKey::IndexedDBKey(WebIDBKeyType type)
54     : type_(type), date_(0), number_(0), size_estimate_(kOverheadSize) {
55   DCHECK(type == WebIDBKeyTypeNull || type == WebIDBKeyTypeInvalid);
56 }
57 
IndexedDBKey(double number,WebIDBKeyType type)58 IndexedDBKey::IndexedDBKey(double number, WebIDBKeyType type)
59     : type_(type),
60       date_(number),
61       number_(number),
62       size_estimate_(kOverheadSize + sizeof(number)) {
63   DCHECK(type == WebIDBKeyTypeNumber || type == WebIDBKeyTypeDate);
64 }
65 
IndexedDBKey(const KeyArray & keys)66 IndexedDBKey::IndexedDBKey(const KeyArray& keys)
67     : type_(WebIDBKeyTypeArray),
68       array_(CopyKeyArray(keys)),
69       date_(0),
70       number_(0),
71       size_estimate_(kOverheadSize + CalculateArraySize(keys)) {}
72 
IndexedDBKey(const std::string & key)73 IndexedDBKey::IndexedDBKey(const std::string& key)
74     : type_(WebIDBKeyTypeBinary),
75       binary_(key),
76       size_estimate_(kOverheadSize +
77                      (key.length() * sizeof(std::string::value_type))) {}
78 
IndexedDBKey(const base::string16 & key)79 IndexedDBKey::IndexedDBKey(const base::string16& key)
80     : type_(WebIDBKeyTypeString),
81       string_(key),
82       size_estimate_(kOverheadSize +
83                      (key.length() * sizeof(base::string16::value_type))) {}
84 
~IndexedDBKey()85 IndexedDBKey::~IndexedDBKey() {}
86 
Compare(const IndexedDBKey & other) const87 int IndexedDBKey::Compare(const IndexedDBKey& other) const {
88   DCHECK(IsValid());
89   DCHECK(other.IsValid());
90   if (type_ != other.type_)
91     return type_ > other.type_ ? -1 : 1;
92 
93   switch (type_) {
94     case WebIDBKeyTypeArray:
95       for (size_t i = 0; i < array_.size() && i < other.array_.size(); ++i) {
96         if (int result = array_[i].Compare(other.array_[i]))
97           return result;
98       }
99       if (array_.size() < other.array_.size())
100         return -1;
101       if (array_.size() > other.array_.size())
102         return 1;
103       return 0;
104     case WebIDBKeyTypeBinary:
105       return binary_.compare(other.binary_);
106     case WebIDBKeyTypeString:
107       return string_.compare(other.string_);
108     case WebIDBKeyTypeDate:
109       return (date_ < other.date_) ? -1 : (date_ > other.date_) ? 1 : 0;
110     case WebIDBKeyTypeNumber:
111       return (number_ < other.number_) ? -1 : (number_ > other.number_) ? 1 : 0;
112     case WebIDBKeyTypeInvalid:
113     case WebIDBKeyTypeNull:
114     case WebIDBKeyTypeMin:
115     default:
116       NOTREACHED();
117       return 0;
118   }
119   NOTREACHED();
120   return 0;
121 }
122 
IsLessThan(const IndexedDBKey & other) const123 bool IndexedDBKey::IsLessThan(const IndexedDBKey& other) const {
124   return Compare(other) < 0;
125 }
126 
IsEqual(const IndexedDBKey & other) const127 bool IndexedDBKey::IsEqual(const IndexedDBKey& other) const {
128   return !Compare(other);
129 }
130 
IsValid() const131 bool IndexedDBKey::IsValid() const {
132   if (type_ == WebIDBKeyTypeInvalid || type_ == WebIDBKeyTypeNull)
133     return false;
134 
135   if (type_ == WebIDBKeyTypeArray) {
136     for (size_t i = 0; i < array_.size(); i++) {
137       if (!array_[i].IsValid())
138         return false;
139     }
140   }
141 
142   return true;
143 }
144 
145 }  // namespace content
146