Home | History | Annotate | Download | only in indexed_db
      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 
     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>
     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 
     47 IndexedDBKey::IndexedDBKey()
     48     : type_(WebIDBKeyTypeNull),
     49       date_(0),
     50       number_(0),
     51       size_estimate_(kOverheadSize) {}
     52 
     53 IndexedDBKey::IndexedDBKey(WebIDBKeyType type)
     54     : type_(type), date_(0), number_(0), size_estimate_(kOverheadSize) {
     55   DCHECK(type == WebIDBKeyTypeNull || type == WebIDBKeyTypeInvalid);
     56 }
     57 
     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 
     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 
     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 
     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 
     85 IndexedDBKey::~IndexedDBKey() {}
     86 
     87 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 
    123 bool IndexedDBKey::IsLessThan(const IndexedDBKey& other) const {
    124   return Compare(other) < 0;
    125 }
    126 
    127 bool IndexedDBKey::IsEqual(const IndexedDBKey& other) const {
    128   return !Compare(other);
    129 }
    130 
    131 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