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)