Home | History | Annotate | Download | only in indexed_db
      1 // Copyright (c) 2013 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/browser/indexed_db/indexed_db_leveldb_coding.h"
      6 
      7 #include <limits>
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/strings/string16.h"
     12 #include "base/strings/string_piece.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "content/common/indexed_db/indexed_db_key.h"
     15 #include "content/common/indexed_db/indexed_db_key_path.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 using base::ASCIIToUTF16;
     19 using base::StringPiece;
     20 using blink::WebIDBKeyTypeDate;
     21 using blink::WebIDBKeyTypeNumber;
     22 
     23 namespace content {
     24 
     25 namespace {
     26 
     27 static IndexedDBKey CreateArrayIDBKey() {
     28   return IndexedDBKey(IndexedDBKey::KeyArray());
     29 }
     30 
     31 static IndexedDBKey CreateArrayIDBKey(const IndexedDBKey& key1) {
     32   IndexedDBKey::KeyArray array;
     33   array.push_back(key1);
     34   return IndexedDBKey(array);
     35 }
     36 
     37 static IndexedDBKey CreateArrayIDBKey(const IndexedDBKey& key1,
     38                                       const IndexedDBKey& key2) {
     39   IndexedDBKey::KeyArray array;
     40   array.push_back(key1);
     41   array.push_back(key2);
     42   return IndexedDBKey(array);
     43 }
     44 
     45 static std::string WrappedEncodeByte(char value) {
     46   std::string buffer;
     47   EncodeByte(value, &buffer);
     48   return buffer;
     49 }
     50 
     51 TEST(IndexedDBLevelDBCodingTest, EncodeByte) {
     52   std::string expected;
     53   expected.push_back(0);
     54   unsigned char c;
     55 
     56   c = 0;
     57   expected[0] = c;
     58   EXPECT_EQ(expected, WrappedEncodeByte(c));
     59 
     60   c = 1;
     61   expected[0] = c;
     62   EXPECT_EQ(expected, WrappedEncodeByte(c));
     63 
     64   c = 255;
     65   expected[0] = c;
     66   EXPECT_EQ(expected, WrappedEncodeByte(c));
     67 }
     68 
     69 TEST(IndexedDBLevelDBCodingTest, DecodeByte) {
     70   std::vector<unsigned char> test_cases;
     71   test_cases.push_back(0);
     72   test_cases.push_back(1);
     73   test_cases.push_back(255);
     74 
     75   for (size_t i = 0; i < test_cases.size(); ++i) {
     76     unsigned char n = test_cases[i];
     77     std::string v;
     78     EncodeByte(n, &v);
     79 
     80     unsigned char res;
     81     ASSERT_GT(v.size(), 0u);
     82     StringPiece slice(v);
     83     EXPECT_TRUE(DecodeByte(&slice, &res));
     84     EXPECT_EQ(n, res);
     85     EXPECT_TRUE(slice.empty());
     86   }
     87 
     88   {
     89     StringPiece slice;
     90     unsigned char value;
     91     EXPECT_FALSE(DecodeByte(&slice, &value));
     92   }
     93 }
     94 
     95 static std::string WrappedEncodeBool(bool value) {
     96   std::string buffer;
     97   EncodeBool(value, &buffer);
     98   return buffer;
     99 }
    100 
    101 TEST(IndexedDBLevelDBCodingTest, EncodeBool) {
    102   {
    103     std::string expected;
    104     expected.push_back(1);
    105     EXPECT_EQ(expected, WrappedEncodeBool(true));
    106   }
    107   {
    108     std::string expected;
    109     expected.push_back(0);
    110     EXPECT_EQ(expected, WrappedEncodeBool(false));
    111   }
    112 }
    113 
    114 static int CompareKeys(const std::string& a, const std::string& b) {
    115   DCHECK(!a.empty());
    116   DCHECK(!b.empty());
    117 
    118   StringPiece slice_a(a);
    119   StringPiece slice_b(b);
    120   bool ok;
    121   int result = CompareEncodedIDBKeys(&slice_a, &slice_b, &ok);
    122   EXPECT_TRUE(ok);
    123   return result;
    124 }
    125 
    126 TEST(IndexedDBLevelDBCodingTest, MaxIDBKey) {
    127   std::string max_key = MaxIDBKey();
    128 
    129   std::string min_key = MinIDBKey();
    130   std::string array_key;
    131   EncodeIDBKey(IndexedDBKey(IndexedDBKey::KeyArray()), &array_key);
    132   std::string binary_key;
    133   EncodeIDBKey(IndexedDBKey(std::string("\x00\x01\x02")), &binary_key);
    134   std::string string_key;
    135   EncodeIDBKey(IndexedDBKey(ASCIIToUTF16("Hello world")), &string_key);
    136   std::string number_key;
    137   EncodeIDBKey(IndexedDBKey(3.14, WebIDBKeyTypeNumber), &number_key);
    138   std::string date_key;
    139   EncodeIDBKey(IndexedDBKey(1000000, WebIDBKeyTypeDate), &date_key);
    140 
    141   EXPECT_GT(CompareKeys(max_key, min_key), 0);
    142   EXPECT_GT(CompareKeys(max_key, array_key), 0);
    143   EXPECT_GT(CompareKeys(max_key, binary_key), 0);
    144   EXPECT_GT(CompareKeys(max_key, string_key), 0);
    145   EXPECT_GT(CompareKeys(max_key, number_key), 0);
    146   EXPECT_GT(CompareKeys(max_key, date_key), 0);
    147 }
    148 
    149 TEST(IndexedDBLevelDBCodingTest, MinIDBKey) {
    150   std::string min_key = MinIDBKey();
    151 
    152   std::string max_key = MaxIDBKey();
    153   std::string array_key;
    154   EncodeIDBKey(IndexedDBKey(IndexedDBKey::KeyArray()), &array_key);
    155   std::string binary_key;
    156   EncodeIDBKey(IndexedDBKey(std::string("\x00\x01\x02")), &binary_key);
    157   std::string string_key;
    158   EncodeIDBKey(IndexedDBKey(ASCIIToUTF16("Hello world")), &string_key);
    159   std::string number_key;
    160   EncodeIDBKey(IndexedDBKey(3.14, WebIDBKeyTypeNumber), &number_key);
    161   std::string date_key;
    162   EncodeIDBKey(IndexedDBKey(1000000, WebIDBKeyTypeDate), &date_key);
    163 
    164   EXPECT_LT(CompareKeys(min_key, max_key), 0);
    165   EXPECT_LT(CompareKeys(min_key, array_key), 0);
    166   EXPECT_LT(CompareKeys(min_key, binary_key), 0);
    167   EXPECT_LT(CompareKeys(min_key, string_key), 0);
    168   EXPECT_LT(CompareKeys(min_key, number_key), 0);
    169   EXPECT_LT(CompareKeys(min_key, date_key), 0);
    170 }
    171 
    172 static std::string WrappedEncodeInt(int64 value) {
    173   std::string buffer;
    174   EncodeInt(value, &buffer);
    175   return buffer;
    176 }
    177 
    178 TEST(IndexedDBLevelDBCodingTest, EncodeInt) {
    179   EXPECT_EQ(1u, WrappedEncodeInt(0).size());
    180   EXPECT_EQ(1u, WrappedEncodeInt(1).size());
    181   EXPECT_EQ(1u, WrappedEncodeInt(255).size());
    182   EXPECT_EQ(2u, WrappedEncodeInt(256).size());
    183   EXPECT_EQ(4u, WrappedEncodeInt(0xffffffff).size());
    184 #ifdef NDEBUG
    185   EXPECT_EQ(8u, WrappedEncodeInt(-1).size());
    186 #endif
    187 }
    188 
    189 TEST(IndexedDBLevelDBCodingTest, DecodeBool) {
    190   {
    191     std::string encoded;
    192     encoded.push_back(1);
    193     StringPiece slice(encoded);
    194     bool value;
    195     EXPECT_TRUE(DecodeBool(&slice, &value));
    196     EXPECT_TRUE(value);
    197     EXPECT_TRUE(slice.empty());
    198   }
    199   {
    200     std::string encoded;
    201     encoded.push_back(0);
    202     StringPiece slice(encoded);
    203     bool value;
    204     EXPECT_TRUE(DecodeBool(&slice, &value));
    205     EXPECT_FALSE(value);
    206     EXPECT_TRUE(slice.empty());
    207   }
    208   {
    209     StringPiece slice;
    210     bool value;
    211     EXPECT_FALSE(DecodeBool(&slice, &value));
    212   }
    213 }
    214 
    215 TEST(IndexedDBLevelDBCodingTest, DecodeInt) {
    216   std::vector<int64> test_cases;
    217   test_cases.push_back(0);
    218   test_cases.push_back(1);
    219   test_cases.push_back(255);
    220   test_cases.push_back(256);
    221   test_cases.push_back(65535);
    222   test_cases.push_back(655536);
    223   test_cases.push_back(7711192431755665792ll);
    224   test_cases.push_back(0x7fffffffffffffffll);
    225 #ifdef NDEBUG
    226   test_cases.push_back(-3);
    227 #endif
    228 
    229   for (size_t i = 0; i < test_cases.size(); ++i) {
    230     int64 n = test_cases[i];
    231     std::string v = WrappedEncodeInt(n);
    232     ASSERT_GT(v.size(), 0u);
    233     StringPiece slice(v);
    234     int64 value;
    235     EXPECT_TRUE(DecodeInt(&slice, &value));
    236     EXPECT_EQ(n, value);
    237     EXPECT_TRUE(slice.empty());
    238 
    239     // Verify decoding at an offset, to detect unaligned memory access.
    240     v.insert(v.begin(), 1u, static_cast<char>(0));
    241     slice = StringPiece(&*v.begin() + 1, v.size() - 1);
    242     EXPECT_TRUE(DecodeInt(&slice, &value));
    243     EXPECT_EQ(n, value);
    244     EXPECT_TRUE(slice.empty());
    245   }
    246   {
    247     StringPiece slice;
    248     int64 value;
    249     EXPECT_FALSE(DecodeInt(&slice, &value));
    250   }
    251 }
    252 
    253 static std::string WrappedEncodeVarInt(int64 value) {
    254   std::string buffer;
    255   EncodeVarInt(value, &buffer);
    256   return buffer;
    257 }
    258 
    259 TEST(IndexedDBLevelDBCodingTest, EncodeVarInt) {
    260   EXPECT_EQ(1u, WrappedEncodeVarInt(0).size());
    261   EXPECT_EQ(1u, WrappedEncodeVarInt(1).size());
    262   EXPECT_EQ(2u, WrappedEncodeVarInt(255).size());
    263   EXPECT_EQ(2u, WrappedEncodeVarInt(256).size());
    264   EXPECT_EQ(5u, WrappedEncodeVarInt(0xffffffff).size());
    265   EXPECT_EQ(8u, WrappedEncodeVarInt(0xfffffffffffffLL).size());
    266   EXPECT_EQ(9u, WrappedEncodeVarInt(0x7fffffffffffffffLL).size());
    267 #ifdef NDEBUG
    268   EXPECT_EQ(10u, WrappedEncodeVarInt(-100).size());
    269 #endif
    270 }
    271 
    272 TEST(IndexedDBLevelDBCodingTest, DecodeVarInt) {
    273   std::vector<int64> test_cases;
    274   test_cases.push_back(0);
    275   test_cases.push_back(1);
    276   test_cases.push_back(255);
    277   test_cases.push_back(256);
    278   test_cases.push_back(65535);
    279   test_cases.push_back(655536);
    280   test_cases.push_back(7711192431755665792ll);
    281   test_cases.push_back(0x7fffffffffffffffll);
    282 #ifdef NDEBUG
    283   test_cases.push_back(-3);
    284 #endif
    285 
    286   for (size_t i = 0; i < test_cases.size(); ++i) {
    287     int64 n = test_cases[i];
    288     std::string v = WrappedEncodeVarInt(n);
    289     ASSERT_GT(v.size(), 0u);
    290     StringPiece slice(v);
    291     int64 res;
    292     EXPECT_TRUE(DecodeVarInt(&slice, &res));
    293     EXPECT_EQ(n, res);
    294     EXPECT_TRUE(slice.empty());
    295 
    296     slice = StringPiece(&*v.begin(), v.size() - 1);
    297     EXPECT_FALSE(DecodeVarInt(&slice, &res));
    298 
    299     slice = StringPiece(&*v.begin(), static_cast<size_t>(0));
    300     EXPECT_FALSE(DecodeVarInt(&slice, &res));
    301 
    302     // Verify decoding at an offset, to detect unaligned memory access.
    303     v.insert(v.begin(), 1u, static_cast<char>(0));
    304     slice = StringPiece(&*v.begin() + 1, v.size() - 1);
    305     EXPECT_TRUE(DecodeVarInt(&slice, &res));
    306     EXPECT_EQ(n, res);
    307     EXPECT_TRUE(slice.empty());
    308   }
    309 }
    310 
    311 static std::string WrappedEncodeString(base::string16 value) {
    312   std::string buffer;
    313   EncodeString(value, &buffer);
    314   return buffer;
    315 }
    316 
    317 TEST(IndexedDBLevelDBCodingTest, EncodeString) {
    318   const base::char16 test_string_a[] = {'f', 'o', 'o', '\0'};
    319   const base::char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
    320 
    321   EXPECT_EQ(0u, WrappedEncodeString(ASCIIToUTF16("")).size());
    322   EXPECT_EQ(2u, WrappedEncodeString(ASCIIToUTF16("a")).size());
    323   EXPECT_EQ(6u, WrappedEncodeString(ASCIIToUTF16("foo")).size());
    324   EXPECT_EQ(6u, WrappedEncodeString(base::string16(test_string_a)).size());
    325   EXPECT_EQ(4u, WrappedEncodeString(base::string16(test_string_b)).size());
    326 }
    327 
    328 TEST(IndexedDBLevelDBCodingTest, DecodeString) {
    329   const base::char16 test_string_a[] = {'f', 'o', 'o', '\0'};
    330   const base::char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
    331 
    332   std::vector<base::string16> test_cases;
    333   test_cases.push_back(base::string16());
    334   test_cases.push_back(ASCIIToUTF16("a"));
    335   test_cases.push_back(ASCIIToUTF16("foo"));
    336   test_cases.push_back(test_string_a);
    337   test_cases.push_back(test_string_b);
    338 
    339   for (size_t i = 0; i < test_cases.size(); ++i) {
    340     const base::string16& test_case = test_cases[i];
    341     std::string v = WrappedEncodeString(test_case);
    342 
    343     StringPiece slice;
    344     if (v.size()) {
    345       slice = StringPiece(&*v.begin(), v.size());
    346     }
    347 
    348     base::string16 result;
    349     EXPECT_TRUE(DecodeString(&slice, &result));
    350     EXPECT_EQ(test_case, result);
    351     EXPECT_TRUE(slice.empty());
    352 
    353     // Verify decoding at an offset, to detect unaligned memory access.
    354     v.insert(v.begin(), 1u, static_cast<char>(0));
    355     slice = StringPiece(&*v.begin() + 1, v.size() - 1);
    356     EXPECT_TRUE(DecodeString(&slice, &result));
    357     EXPECT_EQ(test_case, result);
    358     EXPECT_TRUE(slice.empty());
    359   }
    360 }
    361 
    362 static std::string WrappedEncodeStringWithLength(base::string16 value) {
    363   std::string buffer;
    364   EncodeStringWithLength(value, &buffer);
    365   return buffer;
    366 }
    367 
    368 TEST(IndexedDBLevelDBCodingTest, EncodeStringWithLength) {
    369   const base::char16 test_string_a[] = {'f', 'o', 'o', '\0'};
    370   const base::char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
    371 
    372   EXPECT_EQ(1u, WrappedEncodeStringWithLength(base::string16()).size());
    373   EXPECT_EQ(3u, WrappedEncodeStringWithLength(ASCIIToUTF16("a")).size());
    374   EXPECT_EQ(
    375       7u, WrappedEncodeStringWithLength(base::string16(test_string_a)).size());
    376   EXPECT_EQ(
    377       5u, WrappedEncodeStringWithLength(base::string16(test_string_b)).size());
    378 }
    379 
    380 TEST(IndexedDBLevelDBCodingTest, DecodeStringWithLength) {
    381   const base::char16 test_string_a[] = {'f', 'o', 'o', '\0'};
    382   const base::char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
    383 
    384   const int kLongStringLen = 1234;
    385   base::char16 long_string[kLongStringLen + 1];
    386   for (int i = 0; i < kLongStringLen; ++i)
    387     long_string[i] = i;
    388   long_string[kLongStringLen] = 0;
    389 
    390   std::vector<base::string16> test_cases;
    391   test_cases.push_back(ASCIIToUTF16(""));
    392   test_cases.push_back(ASCIIToUTF16("a"));
    393   test_cases.push_back(ASCIIToUTF16("foo"));
    394   test_cases.push_back(base::string16(test_string_a));
    395   test_cases.push_back(base::string16(test_string_b));
    396   test_cases.push_back(base::string16(long_string));
    397 
    398   for (size_t i = 0; i < test_cases.size(); ++i) {
    399     base::string16 s = test_cases[i];
    400     std::string v = WrappedEncodeStringWithLength(s);
    401     ASSERT_GT(v.size(), 0u);
    402     StringPiece slice(v);
    403     base::string16 res;
    404     EXPECT_TRUE(DecodeStringWithLength(&slice, &res));
    405     EXPECT_EQ(s, res);
    406     EXPECT_TRUE(slice.empty());
    407 
    408     slice = StringPiece(&*v.begin(), v.size() - 1);
    409     EXPECT_FALSE(DecodeStringWithLength(&slice, &res));
    410 
    411     slice = StringPiece(&*v.begin(), static_cast<size_t>(0));
    412     EXPECT_FALSE(DecodeStringWithLength(&slice, &res));
    413 
    414     // Verify decoding at an offset, to detect unaligned memory access.
    415     v.insert(v.begin(), 1u, static_cast<char>(0));
    416     slice = StringPiece(&*v.begin() + 1, v.size() - 1);
    417     EXPECT_TRUE(DecodeStringWithLength(&slice, &res));
    418     EXPECT_EQ(s, res);
    419     EXPECT_TRUE(slice.empty());
    420   }
    421 }
    422 
    423 static int CompareStrings(const std::string& p, const std::string& q) {
    424   bool ok;
    425   DCHECK(!p.empty());
    426   DCHECK(!q.empty());
    427   StringPiece slice_p(p);
    428   StringPiece slice_q(q);
    429   int result = CompareEncodedStringsWithLength(&slice_p, &slice_q, &ok);
    430   EXPECT_TRUE(ok);
    431   EXPECT_TRUE(slice_p.empty());
    432   EXPECT_TRUE(slice_q.empty());
    433   return result;
    434 }
    435 
    436 TEST(IndexedDBLevelDBCodingTest, CompareEncodedStringsWithLength) {
    437   const base::char16 test_string_a[] = {0x1000, 0x1000, '\0'};
    438   const base::char16 test_string_b[] = {0x1000, 0x1000, 0x1000, '\0'};
    439   const base::char16 test_string_c[] = {0x1000, 0x1000, 0x1001, '\0'};
    440   const base::char16 test_string_d[] = {0x1001, 0x1000, 0x1000, '\0'};
    441   const base::char16 test_string_e[] = {0xd834, 0xdd1e, '\0'};
    442   const base::char16 test_string_f[] = {0xfffd, '\0'};
    443 
    444   std::vector<base::string16> test_cases;
    445   test_cases.push_back(ASCIIToUTF16(""));
    446   test_cases.push_back(ASCIIToUTF16("a"));
    447   test_cases.push_back(ASCIIToUTF16("b"));
    448   test_cases.push_back(ASCIIToUTF16("baaa"));
    449   test_cases.push_back(ASCIIToUTF16("baab"));
    450   test_cases.push_back(ASCIIToUTF16("c"));
    451   test_cases.push_back(base::string16(test_string_a));
    452   test_cases.push_back(base::string16(test_string_b));
    453   test_cases.push_back(base::string16(test_string_c));
    454   test_cases.push_back(base::string16(test_string_d));
    455   test_cases.push_back(base::string16(test_string_e));
    456   test_cases.push_back(base::string16(test_string_f));
    457 
    458   for (size_t i = 0; i < test_cases.size() - 1; ++i) {
    459     base::string16 a = test_cases[i];
    460     base::string16 b = test_cases[i + 1];
    461 
    462     EXPECT_LT(a.compare(b), 0);
    463     EXPECT_GT(b.compare(a), 0);
    464     EXPECT_EQ(a.compare(a), 0);
    465     EXPECT_EQ(b.compare(b), 0);
    466 
    467     std::string encoded_a = WrappedEncodeStringWithLength(a);
    468     EXPECT_TRUE(encoded_a.size());
    469     std::string encoded_b = WrappedEncodeStringWithLength(b);
    470     EXPECT_TRUE(encoded_a.size());
    471 
    472     EXPECT_LT(CompareStrings(encoded_a, encoded_b), 0);
    473     EXPECT_GT(CompareStrings(encoded_b, encoded_a), 0);
    474     EXPECT_EQ(CompareStrings(encoded_a, encoded_a), 0);
    475     EXPECT_EQ(CompareStrings(encoded_b, encoded_b), 0);
    476   }
    477 }
    478 
    479 static std::string WrappedEncodeBinary(std::string value) {
    480   std::string buffer;
    481   EncodeBinary(value, &buffer);
    482   return buffer;
    483 }
    484 
    485 TEST(IndexedDBLevelDBCodingTest, EncodeBinary) {
    486   const unsigned char binary_data[] = {0x00, 0x01, 0xfe, 0xff};
    487   EXPECT_EQ(
    488       1u,
    489       WrappedEncodeBinary(std::string(binary_data, binary_data + 0)).size());
    490   EXPECT_EQ(
    491       2u,
    492       WrappedEncodeBinary(std::string(binary_data, binary_data + 1)).size());
    493   EXPECT_EQ(
    494       5u,
    495       WrappedEncodeBinary(std::string(binary_data, binary_data + 4)).size());
    496 }
    497 
    498 TEST(IndexedDBLevelDBCodingTest, DecodeBinary) {
    499   const unsigned char binary_data[] = { 0x00, 0x01, 0xfe, 0xff };
    500 
    501   std::vector<std::string> test_cases;
    502   test_cases.push_back(std::string(binary_data, binary_data + 0));
    503   test_cases.push_back(std::string(binary_data, binary_data + 1));
    504   test_cases.push_back(std::string(binary_data, binary_data + 4));
    505 
    506   for (size_t i = 0; i < test_cases.size(); ++i) {
    507     std::string value = test_cases[i];
    508     std::string v = WrappedEncodeBinary(value);
    509     ASSERT_GT(v.size(), 0u);
    510     StringPiece slice(v);
    511     std::string result;
    512     EXPECT_TRUE(DecodeBinary(&slice, &result));
    513     EXPECT_EQ(value, result);
    514     EXPECT_TRUE(slice.empty());
    515 
    516     slice = StringPiece(&*v.begin(), v.size() - 1);
    517     EXPECT_FALSE(DecodeBinary(&slice, &result));
    518 
    519     slice = StringPiece(&*v.begin(), static_cast<size_t>(0));
    520     EXPECT_FALSE(DecodeBinary(&slice, &result));
    521 
    522     // Verify decoding at an offset, to detect unaligned memory access.
    523     v.insert(v.begin(), 1u, static_cast<char>(0));
    524     slice = StringPiece(&*v.begin() + 1, v.size() - 1);
    525     EXPECT_TRUE(DecodeBinary(&slice, &result));
    526     EXPECT_EQ(value, result);
    527     EXPECT_TRUE(slice.empty());
    528   }
    529 }
    530 
    531 static std::string WrappedEncodeDouble(double value) {
    532   std::string buffer;
    533   EncodeDouble(value, &buffer);
    534   return buffer;
    535 }
    536 
    537 TEST(IndexedDBLevelDBCodingTest, EncodeDouble) {
    538   EXPECT_EQ(8u, WrappedEncodeDouble(0).size());
    539   EXPECT_EQ(8u, WrappedEncodeDouble(3.14).size());
    540 }
    541 
    542 TEST(IndexedDBLevelDBCodingTest, DecodeDouble) {
    543   std::vector<double> test_cases;
    544   test_cases.push_back(3.14);
    545   test_cases.push_back(-3.14);
    546 
    547   for (size_t i = 0; i < test_cases.size(); ++i) {
    548     double value = test_cases[i];
    549     std::string v = WrappedEncodeDouble(value);
    550     ASSERT_GT(v.size(), 0u);
    551     StringPiece slice(v);
    552     double result;
    553     EXPECT_TRUE(DecodeDouble(&slice, &result));
    554     EXPECT_EQ(value, result);
    555     EXPECT_TRUE(slice.empty());
    556 
    557     slice = StringPiece(&*v.begin(), v.size() - 1);
    558     EXPECT_FALSE(DecodeDouble(&slice, &result));
    559 
    560     slice = StringPiece(&*v.begin(), static_cast<size_t>(0));
    561     EXPECT_FALSE(DecodeDouble(&slice, &result));
    562 
    563     // Verify decoding at an offset, to detect unaligned memory access.
    564     v.insert(v.begin(), 1u, static_cast<char>(0));
    565     slice = StringPiece(&*v.begin() + 1, v.size() - 1);
    566     EXPECT_TRUE(DecodeDouble(&slice, &result));
    567     EXPECT_EQ(value, result);
    568     EXPECT_TRUE(slice.empty());
    569   }
    570 }
    571 
    572 TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKey) {
    573   IndexedDBKey expected_key;
    574   scoped_ptr<IndexedDBKey> decoded_key;
    575   std::string v;
    576   StringPiece slice;
    577 
    578   std::vector<IndexedDBKey> test_cases;
    579   test_cases.push_back(IndexedDBKey(1234, WebIDBKeyTypeNumber));
    580   test_cases.push_back(IndexedDBKey(7890, WebIDBKeyTypeDate));
    581   test_cases.push_back(IndexedDBKey(ASCIIToUTF16("Hello World!")));
    582   test_cases.push_back(IndexedDBKey(std::string("\x01\x02")));
    583   test_cases.push_back(IndexedDBKey(IndexedDBKey::KeyArray()));
    584 
    585   IndexedDBKey::KeyArray array;
    586   array.push_back(IndexedDBKey(1234, WebIDBKeyTypeNumber));
    587   array.push_back(IndexedDBKey(7890, WebIDBKeyTypeDate));
    588   array.push_back(IndexedDBKey(ASCIIToUTF16("Hello World!")));
    589   array.push_back(IndexedDBKey(std::string("\x01\x02")));
    590   array.push_back(IndexedDBKey(IndexedDBKey::KeyArray()));
    591   test_cases.push_back(IndexedDBKey(array));
    592 
    593   for (size_t i = 0; i < test_cases.size(); ++i) {
    594     expected_key = test_cases[i];
    595     v.clear();
    596     EncodeIDBKey(expected_key, &v);
    597     slice = StringPiece(&*v.begin(), v.size());
    598     EXPECT_TRUE(DecodeIDBKey(&slice, &decoded_key));
    599     EXPECT_TRUE(decoded_key->Equals(expected_key));
    600     EXPECT_TRUE(slice.empty());
    601 
    602     slice = StringPiece(&*v.begin(), v.size() - 1);
    603     EXPECT_FALSE(DecodeIDBKey(&slice, &decoded_key));
    604 
    605     slice = StringPiece(&*v.begin(), static_cast<size_t>(0));
    606     EXPECT_FALSE(DecodeIDBKey(&slice, &decoded_key));
    607   }
    608 }
    609 
    610 static std::string WrappedEncodeIDBKeyPath(const IndexedDBKeyPath& value) {
    611   std::string buffer;
    612   EncodeIDBKeyPath(value, &buffer);
    613   return buffer;
    614 }
    615 
    616 TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKeyPath) {
    617   std::vector<IndexedDBKeyPath> key_paths;
    618   std::vector<std::string> encoded_paths;
    619 
    620   {
    621     key_paths.push_back(IndexedDBKeyPath());
    622     char expected[] = {0, 0,  // Header
    623                        0      // Type is null
    624     };
    625     encoded_paths.push_back(
    626         std::string(expected, expected + arraysize(expected)));
    627   }
    628 
    629   {
    630     key_paths.push_back(IndexedDBKeyPath(base::string16()));
    631     char expected[] = {0, 0,  // Header
    632                        1,     // Type is string
    633                        0      // Length is 0
    634     };
    635     encoded_paths.push_back(
    636         std::string(expected, expected + arraysize(expected)));
    637   }
    638 
    639   {
    640     key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo")));
    641     char expected[] = {0, 0,                      // Header
    642                        1,                         // Type is string
    643                        3, 0, 'f', 0, 'o', 0, 'o'  // String length 3, UTF-16BE
    644     };
    645     encoded_paths.push_back(
    646         std::string(expected, expected + arraysize(expected)));
    647   }
    648 
    649   {
    650     key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo.bar")));
    651     char expected[] = {0, 0,  // Header
    652                        1,     // Type is string
    653                        7, 0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0,
    654                        'r'  // String length 7, UTF-16BE
    655     };
    656     encoded_paths.push_back(
    657         std::string(expected, expected + arraysize(expected)));
    658   }
    659 
    660   {
    661     std::vector<base::string16> array;
    662     array.push_back(base::string16());
    663     array.push_back(ASCIIToUTF16("foo"));
    664     array.push_back(ASCIIToUTF16("foo.bar"));
    665 
    666     key_paths.push_back(IndexedDBKeyPath(array));
    667     char expected[] = {0, 0,                       // Header
    668                        2, 3,                       // Type is array, length is 3
    669                        0,                          // Member 1 (String length 0)
    670                        3, 0, 'f', 0, 'o', 0, 'o',  // Member 2 (String length 3)
    671                        7, 0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0,
    672                        'r'  // Member 3 (String length 7)
    673     };
    674     encoded_paths.push_back(
    675         std::string(expected, expected + arraysize(expected)));
    676   }
    677 
    678   ASSERT_EQ(key_paths.size(), encoded_paths.size());
    679   for (size_t i = 0; i < key_paths.size(); ++i) {
    680     IndexedDBKeyPath key_path = key_paths[i];
    681     std::string encoded = encoded_paths[i];
    682 
    683     std::string v = WrappedEncodeIDBKeyPath(key_path);
    684     EXPECT_EQ(encoded, v);
    685 
    686     StringPiece slice(encoded);
    687     IndexedDBKeyPath decoded;
    688     EXPECT_TRUE(DecodeIDBKeyPath(&slice, &decoded));
    689     EXPECT_EQ(key_path, decoded);
    690     EXPECT_TRUE(slice.empty());
    691   }
    692 }
    693 
    694 TEST(IndexedDBLevelDBCodingTest, EncodeDecodeBlobJournal) {
    695   std::vector<IndexedDBKeyPath> key_paths;
    696   std::vector<std::string> encoded_paths;
    697 
    698   std::vector<BlobJournalType> journals;
    699 
    700   {  // Empty journal
    701     BlobJournalType journal;
    702     journals.push_back(journal);
    703   }
    704 
    705   {  // One item
    706     BlobJournalType journal;
    707     journal.push_back(std::make_pair(4, 7));
    708     journals.push_back(journal);
    709   }
    710 
    711   {  // kAllBlobsKey
    712     BlobJournalType journal;
    713     journal.push_back(std::make_pair(5, DatabaseMetaDataKey::kAllBlobsKey));
    714     journals.push_back(journal);
    715   }
    716 
    717   {  // A bunch of items
    718     BlobJournalType journal;
    719     journal.push_back(std::make_pair(4, 7));
    720     journal.push_back(std::make_pair(5, 6));
    721     journal.push_back(std::make_pair(4, 5));
    722     journal.push_back(std::make_pair(4, 4));
    723     journal.push_back(std::make_pair(1, 12));
    724     journal.push_back(std::make_pair(4, 3));
    725     journal.push_back(std::make_pair(15, 14));
    726     journals.push_back(journal);
    727   }
    728 
    729   std::vector<BlobJournalType>::const_iterator journal_iter;
    730   for (journal_iter = journals.begin(); journal_iter != journals.end();
    731        ++journal_iter) {
    732     std::string encoding;
    733     EncodeBlobJournal(*journal_iter, &encoding);
    734     StringPiece slice(encoding);
    735     BlobJournalType journal_out;
    736     EXPECT_TRUE(DecodeBlobJournal(&slice, &journal_out));
    737     EXPECT_EQ(*journal_iter, journal_out);
    738   }
    739 
    740   journals.clear();
    741 
    742   {  // Illegal database id
    743     BlobJournalType journal;
    744     journal.push_back(std::make_pair(0, 3));
    745     journals.push_back(journal);
    746   }
    747 
    748   {  // Illegal blob id
    749     BlobJournalType journal;
    750     journal.push_back(std::make_pair(4, 0));
    751     journals.push_back(journal);
    752   }
    753 
    754   for (journal_iter = journals.begin(); journal_iter != journals.end();
    755        ++journal_iter) {
    756     std::string encoding;
    757     EncodeBlobJournal(*journal_iter, &encoding);
    758     StringPiece slice(encoding);
    759     BlobJournalType journal_out;
    760     EXPECT_FALSE(DecodeBlobJournal(&slice, &journal_out));
    761   }
    762 }
    763 
    764 TEST(IndexedDBLevelDBCodingTest, DecodeLegacyIDBKeyPath) {
    765   // Legacy encoding of string key paths.
    766   std::vector<IndexedDBKeyPath> key_paths;
    767   std::vector<std::string> encoded_paths;
    768 
    769   {
    770     key_paths.push_back(IndexedDBKeyPath(base::string16()));
    771     encoded_paths.push_back(std::string());
    772   }
    773   {
    774     key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo")));
    775     char expected[] = {0, 'f', 0, 'o', 0, 'o'};
    776     encoded_paths.push_back(std::string(expected, arraysize(expected)));
    777   }
    778   {
    779     key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo.bar")));
    780     char expected[] = {0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0, 'r'};
    781     encoded_paths.push_back(std::string(expected, arraysize(expected)));
    782   }
    783 
    784   ASSERT_EQ(key_paths.size(), encoded_paths.size());
    785   for (size_t i = 0; i < key_paths.size(); ++i) {
    786     IndexedDBKeyPath key_path = key_paths[i];
    787     std::string encoded = encoded_paths[i];
    788 
    789     StringPiece slice(encoded);
    790     IndexedDBKeyPath decoded;
    791     EXPECT_TRUE(DecodeIDBKeyPath(&slice, &decoded));
    792     EXPECT_EQ(key_path, decoded);
    793     EXPECT_TRUE(slice.empty());
    794   }
    795 }
    796 
    797 TEST(IndexedDBLevelDBCodingTest, ExtractAndCompareIDBKeys) {
    798   std::vector<IndexedDBKey> keys;
    799 
    800   keys.push_back(IndexedDBKey(-10, WebIDBKeyTypeNumber));
    801   keys.push_back(IndexedDBKey(0, WebIDBKeyTypeNumber));
    802   keys.push_back(IndexedDBKey(3.14, WebIDBKeyTypeNumber));
    803 
    804   keys.push_back(IndexedDBKey(0, WebIDBKeyTypeDate));
    805   keys.push_back(IndexedDBKey(100, WebIDBKeyTypeDate));
    806   keys.push_back(IndexedDBKey(100000, WebIDBKeyTypeDate));
    807 
    808   keys.push_back(IndexedDBKey(ASCIIToUTF16("")));
    809   keys.push_back(IndexedDBKey(ASCIIToUTF16("a")));
    810   keys.push_back(IndexedDBKey(ASCIIToUTF16("b")));
    811   keys.push_back(IndexedDBKey(ASCIIToUTF16("baaa")));
    812   keys.push_back(IndexedDBKey(ASCIIToUTF16("baab")));
    813   keys.push_back(IndexedDBKey(ASCIIToUTF16("c")));
    814 
    815   keys.push_back(IndexedDBKey(std::string()));
    816   keys.push_back(IndexedDBKey(std::string("\x01")));
    817   keys.push_back(IndexedDBKey(std::string("\x01\x01")));
    818   keys.push_back(IndexedDBKey(std::string("\x01\x02")));
    819   keys.push_back(IndexedDBKey(std::string("\x02")));
    820   keys.push_back(IndexedDBKey(std::string("\x02\x01")));
    821   keys.push_back(IndexedDBKey(std::string("\x02\x02")));
    822   keys.push_back(IndexedDBKey(std::string("\xff")));
    823 
    824   keys.push_back(CreateArrayIDBKey());
    825   keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKeyTypeNumber)));
    826   keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKeyTypeNumber),
    827                                    IndexedDBKey(3.14, WebIDBKeyTypeNumber)));
    828   keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKeyTypeDate)));
    829   keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKeyTypeDate),
    830                                    IndexedDBKey(0, WebIDBKeyTypeDate)));
    831   keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16(""))));
    832   keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16("")),
    833                                    IndexedDBKey(ASCIIToUTF16("a"))));
    834   keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey()));
    835   keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(), CreateArrayIDBKey()));
    836   keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey())));
    837   keys.push_back(CreateArrayIDBKey(
    838       CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey()))));
    839 
    840   for (size_t i = 0; i < keys.size() - 1; ++i) {
    841     const IndexedDBKey& key_a = keys[i];
    842     const IndexedDBKey& key_b = keys[i + 1];
    843 
    844     EXPECT_TRUE(key_a.IsLessThan(key_b));
    845 
    846     std::string encoded_a;
    847     EncodeIDBKey(key_a, &encoded_a);
    848     EXPECT_TRUE(encoded_a.size());
    849     std::string encoded_b;
    850     EncodeIDBKey(key_b, &encoded_b);
    851     EXPECT_TRUE(encoded_b.size());
    852 
    853     std::string extracted_a;
    854     std::string extracted_b;
    855     StringPiece slice;
    856 
    857     slice = StringPiece(encoded_a);
    858     EXPECT_TRUE(ExtractEncodedIDBKey(&slice, &extracted_a));
    859     EXPECT_TRUE(slice.empty());
    860     EXPECT_EQ(encoded_a, extracted_a);
    861 
    862     slice = StringPiece(encoded_b);
    863     EXPECT_TRUE(ExtractEncodedIDBKey(&slice, &extracted_b));
    864     EXPECT_TRUE(slice.empty());
    865     EXPECT_EQ(encoded_b, extracted_b);
    866 
    867     EXPECT_LT(CompareKeys(extracted_a, extracted_b), 0);
    868     EXPECT_GT(CompareKeys(extracted_b, extracted_a), 0);
    869     EXPECT_EQ(CompareKeys(extracted_a, extracted_a), 0);
    870     EXPECT_EQ(CompareKeys(extracted_b, extracted_b), 0);
    871 
    872     slice = StringPiece(&*encoded_a.begin(), encoded_a.size() - 1);
    873     EXPECT_FALSE(ExtractEncodedIDBKey(&slice, &extracted_a));
    874   }
    875 }
    876 
    877 TEST(IndexedDBLevelDBCodingTest, ComparisonTest) {
    878   std::vector<std::string> keys;
    879   keys.push_back(SchemaVersionKey::Encode());
    880   keys.push_back(MaxDatabaseIdKey::Encode());
    881   keys.push_back(DatabaseFreeListKey::Encode(0));
    882   keys.push_back(DatabaseFreeListKey::EncodeMaxKey());
    883   keys.push_back(DatabaseNameKey::Encode("", ASCIIToUTF16("")));
    884   keys.push_back(DatabaseNameKey::Encode("", ASCIIToUTF16("a")));
    885   keys.push_back(DatabaseNameKey::Encode("a", ASCIIToUTF16("a")));
    886   keys.push_back(
    887       DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::ORIGIN_NAME));
    888   keys.push_back(
    889       DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::DATABASE_NAME));
    890   keys.push_back(
    891       DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_VERSION));
    892   keys.push_back(
    893       DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID));
    894   keys.push_back(
    895       DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_INT_VERSION));
    896   keys.push_back(
    897       ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::NAME));
    898   keys.push_back(
    899       ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::KEY_PATH));
    900   keys.push_back(ObjectStoreMetaDataKey::Encode(
    901       1, 1, ObjectStoreMetaDataKey::AUTO_INCREMENT));
    902   keys.push_back(
    903       ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::EVICTABLE));
    904   keys.push_back(ObjectStoreMetaDataKey::Encode(
    905       1, 1, ObjectStoreMetaDataKey::LAST_VERSION));
    906   keys.push_back(ObjectStoreMetaDataKey::Encode(
    907       1, 1, ObjectStoreMetaDataKey::MAX_INDEX_ID));
    908   keys.push_back(ObjectStoreMetaDataKey::Encode(
    909       1, 1, ObjectStoreMetaDataKey::HAS_KEY_PATH));
    910   keys.push_back(ObjectStoreMetaDataKey::Encode(
    911       1, 1, ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER));
    912   keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 1));
    913   keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 2));
    914   keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1));
    915   keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::NAME));
    916   keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::UNIQUE));
    917   keys.push_back(
    918       IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::KEY_PATH));
    919   keys.push_back(
    920       IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::MULTI_ENTRY));
    921   keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 0));
    922   keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 1));
    923   keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 31));
    924   keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 32));
    925   keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1));
    926   keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 2));
    927   keys.push_back(ObjectStoreFreeListKey::Encode(1, 1));
    928   keys.push_back(ObjectStoreFreeListKey::EncodeMaxKey(1));
    929   keys.push_back(IndexFreeListKey::Encode(1, 1, kMinimumIndexId));
    930   keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 1));
    931   keys.push_back(IndexFreeListKey::Encode(1, 2, kMinimumIndexId));
    932   keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 2));
    933   keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16("")));
    934   keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16("a")));
    935   keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16("")));
    936   keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16("a")));
    937   keys.push_back(IndexNamesKey::Encode(1, 2, ASCIIToUTF16("a")));
    938   keys.push_back(ObjectStoreDataKey::Encode(1, 1, std::string()));
    939   keys.push_back(ObjectStoreDataKey::Encode(1, 1, MinIDBKey()));
    940   keys.push_back(ObjectStoreDataKey::Encode(1, 1, MaxIDBKey()));
    941   keys.push_back(ExistsEntryKey::Encode(1, 1, std::string()));
    942   keys.push_back(ExistsEntryKey::Encode(1, 1, MinIDBKey()));
    943   keys.push_back(ExistsEntryKey::Encode(1, 1, MaxIDBKey()));
    944   keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), std::string(), 0));
    945   keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 0));
    946   keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 1));
    947   keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 0));
    948   keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 1));
    949   keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 0));
    950   keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 1));
    951   keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 0));
    952   keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 1));
    953   keys.push_back(IndexDataKey::Encode(1, 1, 31, MinIDBKey(), MinIDBKey(), 0));
    954   keys.push_back(IndexDataKey::Encode(1, 2, 30, MinIDBKey(), MinIDBKey(), 0));
    955   keys.push_back(
    956       IndexDataKey::EncodeMaxKey(1, 2, std::numeric_limits<int32>::max() - 1));
    957 
    958   for (size_t i = 0; i < keys.size(); ++i) {
    959     EXPECT_EQ(Compare(keys[i], keys[i], false), 0);
    960 
    961     for (size_t j = i + 1; j < keys.size(); ++j) {
    962       EXPECT_LT(Compare(keys[i], keys[j], false), 0);
    963       EXPECT_GT(Compare(keys[j], keys[i], false), 0);
    964     }
    965   }
    966 }
    967 
    968 TEST(IndexedDBLevelDBCodingTest, EncodeVarIntVSEncodeByteTest) {
    969   std::vector<unsigned char> test_cases;
    970   test_cases.push_back(0);
    971   test_cases.push_back(1);
    972   test_cases.push_back(127);
    973 
    974   for (size_t i = 0; i < test_cases.size(); ++i) {
    975     unsigned char n = test_cases[i];
    976 
    977     std::string vA = WrappedEncodeByte(n);
    978     std::string vB = WrappedEncodeVarInt(static_cast<int64>(n));
    979 
    980     EXPECT_EQ(vA.size(), vB.size());
    981     EXPECT_EQ(*vA.begin(), *vB.begin());
    982   }
    983 }
    984 
    985 }  // namespace
    986 
    987 }  // namespace content
    988