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