12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/indexed_db/indexed_db_key.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content {
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using blink::WebIDBKey;
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing blink::WebIDBKeyType;
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using blink::WebIDBKeyTypeArray;
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using blink::WebIDBKeyTypeBinary;
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using blink::WebIDBKeyTypeDate;
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing blink::WebIDBKeyTypeInvalid;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using blink::WebIDBKeyTypeMin;
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing blink::WebIDBKeyTypeNull;
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing blink::WebIDBKeyTypeNumber;
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using blink::WebIDBKeyTypeString;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace {
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Very rough estimate of minimum key size overhead.
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const size_t kOverheadSize = 16;
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static size_t CalculateArraySize(const IndexedDBKey::KeyArray& keys) {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t size(0);
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  for (size_t i = 0; i < keys.size(); ++i)
31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    size += keys[i].size_estimate();
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return size;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template<typename T>
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int Compare(const T& a, const T& b) {
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Using '<' for both comparisons here is as generic as possible (for e.g.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // objects which only define operator<() and not operator>() or operator==())
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and also allows e.g. floating point NaNs to compare equal.
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (a < b)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return -1;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return (b < a) ? 1 : 0;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename T>
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static IndexedDBKey::KeyArray CopyKeyArray(const T& array) {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IndexedDBKey::KeyArray result;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result.reserve(array.size());
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < array.size(); ++i) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result.push_back(IndexedDBKey(array[i]));
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IndexedDBKey::IndexedDBKey()
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : type_(WebIDBKeyTypeNull),
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      date_(0),
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      number_(0),
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_estimate_(kOverheadSize) {}
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IndexedDBKey::IndexedDBKey(WebIDBKeyType type)
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : type_(type), date_(0), number_(0), size_estimate_(kOverheadSize) {
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(type == WebIDBKeyTypeNull || type == WebIDBKeyTypeInvalid);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IndexedDBKey::IndexedDBKey(double number, WebIDBKeyType type)
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : type_(type),
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      date_(number),
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      number_(number),
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      size_estimate_(kOverheadSize + sizeof(number)) {
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(type == WebIDBKeyTypeNumber || type == WebIDBKeyTypeDate);
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
76116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIndexedDBKey::IndexedDBKey(const KeyArray& array)
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : type_(WebIDBKeyTypeArray),
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      array_(CopyKeyArray(array)),
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      date_(0),
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      number_(0),
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_estimate_(kOverheadSize + CalculateArraySize(array)) {}
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IndexedDBKey::IndexedDBKey(const std::string& binary)
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : type_(WebIDBKeyTypeBinary),
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      binary_(binary),
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      size_estimate_(kOverheadSize +
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     (binary.length() * sizeof(std::string::value_type))) {}
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)IndexedDBKey::IndexedDBKey(const base::string16& string)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : type_(WebIDBKeyTypeString),
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      string_(string),
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      size_estimate_(kOverheadSize +
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                     (string.length() * sizeof(base::string16::value_type))) {}
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IndexedDBKey::~IndexedDBKey() {}
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool IndexedDBKey::IsValid() const {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (type_ == WebIDBKeyTypeInvalid || type_ == WebIDBKeyTypeNull)
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (type_ == WebIDBKeyTypeArray) {
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    for (size_t i = 0; i < array_.size(); i++) {
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (!array_[i].IsValid())
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        return false;
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IndexedDBKey::IsLessThan(const IndexedDBKey& other) const {
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return CompareTo(other) < 0;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IndexedDBKey::Equals(const IndexedDBKey& other) const {
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !CompareTo(other);
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int IndexedDBKey::CompareTo(const IndexedDBKey& other) const {
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsValid());
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(other.IsValid());
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type_ != other.type_)
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return type_ > other.type_ ? -1 : 1;
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (type_) {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebIDBKeyTypeArray:
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (size_t i = 0; i < array_.size() && i < other.array_.size(); ++i) {
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        int result = array_[i].CompareTo(other.array_[i]);
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (result != 0)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return result;
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return Compare(array_.size(), other.array_.size());
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebIDBKeyTypeBinary:
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return binary_.compare(other.binary_);
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebIDBKeyTypeString:
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return string_.compare(other.string_);
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebIDBKeyTypeDate:
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return Compare(date_, other.date_);
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebIDBKeyTypeNumber:
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return Compare(number_, other.number_);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebIDBKeyTypeInvalid:
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebIDBKeyTypeNull:
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebIDBKeyTypeMin:
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NOTREACHED();
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return 0;
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace content
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)