Home | History | Annotate | Download | only in src
      1 // Copyright 2008 Google Inc.
      2 // Author: Lincoln Smith
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 // Unit tests for the class VCDiffCodeTableWriter, found in encodetable.h.
     17 
     18 #include <config.h>
     19 #include "encodetable.h"
     20 #include <string.h>  // strlen
     21 #include <algorithm>
     22 #include <string>
     23 #include <vector>
     24 #include "addrcache.h"  // VCDiffAddressCache::kDefaultNearCacheSize
     25 #include "checksum.h"
     26 #include "codetable.h"
     27 #include "google/output_string.h"
     28 #include "testing.h"
     29 #include "vcdiff_defs.h"
     30 
     31 namespace open_vcdiff {
     32 namespace {
     33 
     34 class CodeTableWriterTest : public testing::Test {
     35  protected:
     36   typedef std::string string;
     37 
     38   CodeTableWriterTest()
     39       : standard_writer(false),
     40         interleaved_writer(true),
     41         exercise_writer(true,
     42                         VCDiffAddressCache::kDefaultNearCacheSize,
     43                         VCDiffAddressCache::kDefaultSameCacheSize,
     44                         *g_exercise_code_table_, kLastExerciseMode),
     45         output_string(&out),
     46         out_index(0) { }
     47 
     48   virtual ~CodeTableWriterTest() { }
     49 
     50   static void AddExerciseOpcode(unsigned char inst1,
     51                                 unsigned char mode1,
     52                                 unsigned char size1,
     53                                 unsigned char inst2,
     54                                 unsigned char mode2,
     55                                 unsigned char size2,
     56                                 int opcode) {
     57     g_exercise_code_table_->inst1[opcode] = inst1;
     58     g_exercise_code_table_->mode1[opcode] = mode1;
     59     g_exercise_code_table_->size1[opcode] = (inst1 == VCD_NOOP) ? 0 : size1;
     60     g_exercise_code_table_->inst2[opcode] = inst2;
     61     g_exercise_code_table_->mode2[opcode] = mode2;
     62     g_exercise_code_table_->size2[opcode] = (inst2 == VCD_NOOP) ? 0 : size2;
     63   }
     64 
     65   static void SetUpTestCase() {
     66     g_exercise_code_table_ = new VCDiffCodeTableData;
     67     int opcode = 0;
     68     for (unsigned char inst_mode1 = 0;
     69          inst_mode1 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
     70          ++inst_mode1) {
     71       unsigned char inst1 = inst_mode1;
     72       unsigned char mode1 = 0;
     73       if (inst_mode1 > VCD_COPY) {
     74         inst1 = VCD_COPY;
     75         mode1 = inst_mode1 - VCD_COPY;
     76       }
     77       for (unsigned char inst_mode2 = 0;
     78            inst_mode2 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
     79            ++inst_mode2) {
     80         unsigned char inst2 = inst_mode2;
     81         unsigned char mode2 = 0;
     82         if (inst_mode2 > VCD_COPY) {
     83           inst2 = VCD_COPY;
     84           mode2 = inst_mode2 - VCD_COPY;
     85         }
     86         AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 0, opcode++);
     87         AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 255, opcode++);
     88         AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 0, opcode++);
     89         AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 255, opcode++);
     90       }
     91     }
     92     // This is a CHECK rather than an EXPECT because it validates only
     93     // the logic of the test, not of the code being tested.
     94     CHECK_EQ(VCDiffCodeTableData::kCodeTableSize, opcode);
     95 
     96     EXPECT_TRUE(g_exercise_code_table_->Validate(kLastExerciseMode));
     97   }
     98 
     99   static void TearDownTestCase() {
    100     delete g_exercise_code_table_;
    101   }
    102 
    103   void ExpectByte(unsigned char b) {
    104     EXPECT_EQ(b, static_cast<unsigned char>(out[out_index]));
    105     ++out_index;
    106   }
    107 
    108   void ExpectString(const char* s) {
    109     const size_t size = strlen(s);  // don't include terminating NULL char
    110     EXPECT_EQ(string(s, size),
    111               string(out.data() + out_index, size));
    112     out_index += size;
    113   }
    114 
    115   void ExpectNoMoreBytes() {
    116     EXPECT_EQ(out_index, out.size());
    117   }
    118 
    119   static bool AnyMatch(int match_count) { return match_count != 0; }
    120 
    121   static void ExpectNoMatchesForWriter(const VCDiffCodeTableWriter& writer) {
    122     const std::vector<int>& match_counts = writer.match_counts();
    123     EXPECT_TRUE(find_if(match_counts.begin(), match_counts.end(), AnyMatch)
    124                     == match_counts.end());
    125   }
    126 
    127   void ExpectNoMatches() const {
    128     ExpectNoMatchesForWriter(standard_writer);
    129     ExpectNoMatchesForWriter(interleaved_writer);
    130     ExpectNoMatchesForWriter(exercise_writer);
    131   }
    132 
    133   // This value is designed so that the total number of inst values and modes
    134   // will equal 8 (VCD_NOOP, VCD_ADD, VCD_RUN, VCD_COPY modes 0 - 4).
    135   // Eight combinations of inst and mode, times two possible size values,
    136   // squared (because there are two instructions per opcode), makes
    137   // exactly 256 possible instruction combinations, which fits kCodeTableSize
    138   // (the number of opcodes in the table.)
    139   static const int kLastExerciseMode = 4;
    140 
    141   // A code table that exercises as many combinations as possible:
    142   // 2 instructions, each is a NOOP, ADD, RUN, or one of 5 copy modes
    143   // (== 8 total combinations of inst and mode), and each has
    144   // size == 0 or 255 (2 possibilities.)
    145   static VCDiffCodeTableData* g_exercise_code_table_;
    146 
    147   // The code table writer for standard encoding, default code table.
    148   VCDiffCodeTableWriter standard_writer;
    149 
    150   // The code table writer for interleaved encoding, default code table.
    151   VCDiffCodeTableWriter interleaved_writer;
    152 
    153   // The code table writer corresponding to g_exercise_code_table_
    154   // (interleaved encoding).
    155   VCDiffCodeTableWriter exercise_writer;
    156 
    157   // Destination for VCDiffCodeTableWriter::Output()
    158   string out;
    159   OutputString<string> output_string;
    160   size_t out_index;
    161 };
    162 
    163 VCDiffCodeTableData* CodeTableWriterTest::g_exercise_code_table_;
    164 
    165 #ifdef GTEST_HAS_DEATH_TEST
    166 typedef CodeTableWriterTest CodeTableWriterDeathTest;
    167 #endif  // GTEST_HAS_DEATH_TEST
    168 
    169 #ifdef GTEST_HAS_DEATH_TEST
    170 TEST_F(CodeTableWriterDeathTest, WriterAddWithoutInit) {
    171 #ifndef NDEBUG
    172   // This condition is only checked in the debug build.
    173   EXPECT_DEBUG_DEATH(standard_writer.Add("Hello", 5),
    174                      "Init");
    175 #endif  // !NDEBUG
    176 }
    177 
    178 TEST_F(CodeTableWriterDeathTest, WriterRunWithoutInit) {
    179 #ifndef NDEBUG
    180   // This condition is only checked in the debug build.
    181   EXPECT_DEBUG_DEATH(standard_writer.Run(3, 'a'),
    182                      "Init");
    183 #endif  // !NDEBUG
    184 }
    185 
    186 TEST_F(CodeTableWriterDeathTest, WriterCopyWithoutInit) {
    187 #ifndef NDEBUG
    188   // This condition is only checked in the debug build.
    189   EXPECT_DEBUG_DEATH(standard_writer.Copy(6, 5),
    190                      "Init");
    191 #endif  // !NDEBUG
    192 }
    193 #endif  // GTEST_HAS_DEATH_TEST
    194 
    195 // Output() without Init() is harmless, but will produce no output.
    196 TEST_F(CodeTableWriterTest, WriterOutputWithoutInit) {
    197   standard_writer.Output(&output_string);
    198   EXPECT_TRUE(out.empty());
    199 }
    200 
    201 TEST_F(CodeTableWriterTest, WriterEncodeNothing) {
    202   EXPECT_TRUE(standard_writer.Init(0));
    203   standard_writer.Output(&output_string);
    204   // The writer should know not to append a delta file window
    205   // if nothing was encoded.
    206   EXPECT_TRUE(out.empty());
    207 
    208   out.clear();
    209   EXPECT_TRUE(interleaved_writer.Init(0x10));
    210   interleaved_writer.Output(&output_string);
    211   EXPECT_TRUE(out.empty());
    212 
    213   out.clear();
    214   EXPECT_TRUE(exercise_writer.Init(0x20));
    215   exercise_writer.Output(&output_string);
    216   EXPECT_TRUE(out.empty());
    217 
    218   ExpectNoMatches();
    219 }
    220 
    221 TEST_F(CodeTableWriterTest, StandardWriterEncodeAdd) {
    222   EXPECT_TRUE(standard_writer.Init(0x11));
    223   standard_writer.Add("foo", 3);
    224   standard_writer.Output(&output_string);
    225   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
    226   ExpectByte(0x11);  // Source segment size: dictionary length
    227   ExpectByte(0x00);  // Source segment position: start of dictionary
    228   ExpectByte(0x09);  // Length of the delta encoding
    229   ExpectByte(0x03);  // Size of the target window
    230   ExpectByte(0x00);  // Delta_indicator (no compression)
    231   ExpectByte(0x03);  // length of data for ADDs and RUNs
    232   ExpectByte(0x01);  // length of instructions section
    233   ExpectByte(0x00);  // length of addresses for COPYs
    234   ExpectString("foo");
    235   ExpectByte(0x04);  // ADD(3) opcode
    236   ExpectNoMoreBytes();
    237   ExpectNoMatches();
    238 }
    239 
    240 TEST_F(CodeTableWriterTest, ExerciseWriterEncodeAdd) {
    241   EXPECT_TRUE(exercise_writer.Init(0x11));
    242   exercise_writer.Add("foo", 3);
    243   exercise_writer.Output(&output_string);
    244   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
    245   ExpectByte(0x11);  // Source segment size: dictionary length
    246   ExpectByte(0x00);  // Source segment position: start of dictionary
    247   ExpectByte(0x0A);  // Length of the delta encoding
    248   ExpectByte(0x03);  // Size of the target window
    249   ExpectByte(0x00);  // Delta_indicator (no compression)
    250   ExpectByte(0x00);  // length of data for ADDs and RUNs
    251   ExpectByte(0x05);  // length of instructions section
    252   ExpectByte(0x00);  // length of addresses for COPYs
    253   ExpectByte(0x04);  // Opcode: NOOP + ADD(0)
    254   ExpectByte(0x03);  // Size of ADD (3)
    255   ExpectString("foo");
    256   ExpectNoMatches();
    257 }
    258 
    259 TEST_F(CodeTableWriterTest, StandardWriterEncodeRun) {
    260   EXPECT_TRUE(standard_writer.Init(0x11));
    261   standard_writer.Run(3, 'a');
    262   standard_writer.Output(&output_string);
    263   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
    264   ExpectByte(0x11);  // Source segment size: dictionary length
    265   ExpectByte(0x00);  // Source segment position: start of dictionary
    266   ExpectByte(0x08);  // Length of the delta encoding
    267   ExpectByte(0x03);  // Size of the target window
    268   ExpectByte(0x00);  // Delta_indicator (no compression)
    269   ExpectByte(0x01);  // length of data for ADDs and RUNs
    270   ExpectByte(0x02);  // length of instructions section
    271   ExpectByte(0x00);  // length of addresses for COPYs
    272   ExpectByte('a');
    273   ExpectByte(0x00);  // RUN(0) opcode
    274   ExpectByte(0x03);  // Size of RUN (3)
    275   ExpectNoMoreBytes();
    276   ExpectNoMatches();
    277 }
    278 
    279 TEST_F(CodeTableWriterTest, ExerciseWriterEncodeRun) {
    280   EXPECT_TRUE(exercise_writer.Init(0x11));
    281   exercise_writer.Run(3, 'a');
    282   exercise_writer.Output(&output_string);
    283   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
    284   ExpectByte(0x11);  // Source segment size: dictionary length
    285   ExpectByte(0x00);  // Source segment position: start of dictionary
    286   ExpectByte(0x08);  // Length of the delta encoding
    287   ExpectByte(0x03);  // Size of the target window
    288   ExpectByte(0x00);  // Delta_indicator (no compression)
    289   ExpectByte(0x00);  // length of data for ADDs and RUNs
    290   ExpectByte(0x03);  // length of instructions section
    291   ExpectByte(0x00);  // length of addresses for COPYs
    292   ExpectByte(0x08);  // Opcode: NOOP + RUN(0)
    293   ExpectByte(0x03);  // Size of RUN (3)
    294   ExpectByte('a');
    295   ExpectNoMoreBytes();
    296   ExpectNoMatches();
    297 }
    298 
    299 TEST_F(CodeTableWriterTest, StandardWriterEncodeCopy) {
    300   EXPECT_TRUE(standard_writer.Init(0x11));
    301   standard_writer.Copy(2, 8);
    302   standard_writer.Copy(2, 8);
    303   standard_writer.Output(&output_string);
    304   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
    305   ExpectByte(0x11);  // Source segment size: dictionary length
    306   ExpectByte(0x00);  // Source segment position: start of dictionary
    307   ExpectByte(0x09);  // Length of the delta encoding
    308   ExpectByte(0x10);  // Size of the target window
    309   ExpectByte(0x00);  // Delta_indicator (no compression)
    310   ExpectByte(0x00);  // length of data for ADDs and RUNs
    311   ExpectByte(0x02);  // length of instructions section
    312   ExpectByte(0x02);  // length of addresses for COPYs
    313   ExpectByte(0x18);  // COPY mode SELF, size 8
    314   ExpectByte(0x78);  // COPY mode SAME(0), size 8
    315   ExpectByte(0x02);  // COPY address (2)
    316   ExpectByte(0x02);  // COPY address (2)
    317   ExpectNoMoreBytes();
    318   EXPECT_LE(9U, standard_writer.match_counts().size());
    319   EXPECT_EQ(0, standard_writer.match_counts()[0]);
    320   EXPECT_EQ(0, standard_writer.match_counts()[1]);
    321   EXPECT_EQ(0, standard_writer.match_counts()[2]);
    322   EXPECT_EQ(0, standard_writer.match_counts()[3]);
    323   EXPECT_EQ(0, standard_writer.match_counts()[4]);
    324   EXPECT_EQ(0, standard_writer.match_counts()[5]);
    325   EXPECT_EQ(0, standard_writer.match_counts()[6]);
    326   EXPECT_EQ(0, standard_writer.match_counts()[7]);
    327   EXPECT_EQ(2, standard_writer.match_counts()[8]);
    328 }
    329 
    330 // The exercise code table can't be used to test how the code table
    331 // writer encodes COPY instructions because the code table writer
    332 // always uses the default cache sizes, which exceed the maximum mode
    333 // used in the exercise table.
    334 TEST_F(CodeTableWriterTest, InterleavedWriterEncodeCopy) {
    335   EXPECT_TRUE(interleaved_writer.Init(0x11));
    336   interleaved_writer.Copy(2, 8);
    337   interleaved_writer.Copy(2, 8);
    338   interleaved_writer.Output(&output_string);
    339   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
    340   ExpectByte(0x11);  // Source segment size: dictionary length
    341   ExpectByte(0x00);  // Source segment position: start of dictionary
    342   ExpectByte(0x09);  // Length of the delta encoding
    343   ExpectByte(0x10);  // Size of the target window
    344   ExpectByte(0x00);  // Delta_indicator (no compression)
    345   ExpectByte(0x00);  // length of data for ADDs and RUNs
    346   ExpectByte(0x04);  // length of instructions section
    347   ExpectByte(0x00);  // length of addresses for COPYs
    348   ExpectByte(0x18);  // COPY mode SELF, size 8
    349   ExpectByte(0x02);  // COPY address (2)
    350   ExpectByte(0x78);  // COPY mode SAME(0), size 8
    351   ExpectByte(0x02);  // COPY address (2)
    352   ExpectNoMoreBytes();
    353   EXPECT_LE(9U, interleaved_writer.match_counts().size());
    354   EXPECT_EQ(0, interleaved_writer.match_counts()[0]);
    355   EXPECT_EQ(0, interleaved_writer.match_counts()[1]);
    356   EXPECT_EQ(0, interleaved_writer.match_counts()[2]);
    357   EXPECT_EQ(0, interleaved_writer.match_counts()[3]);
    358   EXPECT_EQ(0, interleaved_writer.match_counts()[4]);
    359   EXPECT_EQ(0, interleaved_writer.match_counts()[5]);
    360   EXPECT_EQ(0, interleaved_writer.match_counts()[6]);
    361   EXPECT_EQ(0, interleaved_writer.match_counts()[7]);
    362   EXPECT_EQ(2, interleaved_writer.match_counts()[8]);
    363 }
    364 
    365 TEST_F(CodeTableWriterTest, StandardWriterEncodeCombo) {
    366   EXPECT_TRUE(standard_writer.Init(0x11));
    367   standard_writer.Add("rayo", 4);
    368   standard_writer.Copy(2, 5);
    369   standard_writer.Copy(0, 4);
    370   standard_writer.Add("X", 1);
    371   standard_writer.Output(&output_string);
    372   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
    373   ExpectByte(0x11);  // Source segment size: dictionary length
    374   ExpectByte(0x00);  // Source segment position: start of dictionary
    375   ExpectByte(0x0E);  // Length of the delta encoding
    376   ExpectByte(0x0E);  // Size of the target window
    377   ExpectByte(0x00);  // Delta_indicator (no compression)
    378   ExpectByte(0x05);  // length of data for ADDs and RUNs
    379   ExpectByte(0x02);  // length of instructions section
    380   ExpectByte(0x02);  // length of addresses for COPYs
    381   ExpectString("rayoX");
    382   ExpectByte(0xAD);  // Combo: Add size 4 + COPY mode SELF, size 5
    383   ExpectByte(0xFD);  // Combo: COPY mode SAME(0), size 4 + Add size 1
    384   ExpectByte(0x02);  // COPY address (2)
    385   ExpectByte(0x00);  // COPY address (0)
    386   ExpectNoMoreBytes();
    387   EXPECT_LE(6U, standard_writer.match_counts().size());
    388   EXPECT_EQ(0, standard_writer.match_counts()[0]);
    389   EXPECT_EQ(0, standard_writer.match_counts()[1]);
    390   EXPECT_EQ(0, standard_writer.match_counts()[2]);
    391   EXPECT_EQ(0, standard_writer.match_counts()[3]);
    392   EXPECT_EQ(1, standard_writer.match_counts()[4]);
    393   EXPECT_EQ(1, standard_writer.match_counts()[5]);
    394 }
    395 
    396 TEST_F(CodeTableWriterTest, InterleavedWriterEncodeCombo) {
    397   EXPECT_TRUE(interleaved_writer.Init(0x11));
    398   interleaved_writer.Add("rayo", 4);
    399   interleaved_writer.Copy(2, 5);
    400   interleaved_writer.Copy(0, 4);
    401   interleaved_writer.Add("X", 1);
    402   interleaved_writer.Output(&output_string);
    403   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
    404   ExpectByte(0x11);  // Source segment size: dictionary length
    405   ExpectByte(0x00);  // Source segment position: start of dictionary
    406   ExpectByte(0x0E);  // Length of the delta encoding
    407   ExpectByte(0x0E);  // Size of the target window
    408   ExpectByte(0x00);  // Delta_indicator (no compression)
    409   ExpectByte(0x00);  // length of data for ADDs and RUNs
    410   ExpectByte(0x09);  // length of instructions section
    411   ExpectByte(0x00);  // length of addresses for COPYs
    412   ExpectByte(0xAD);  // Combo: Add size 4 + COPY mode SELF, size 5
    413   ExpectString("rayo");
    414   ExpectByte(0x02);  // COPY address (2)
    415   ExpectByte(0xFD);  // Combo: COPY mode SAME(0), size 4 + Add size 1
    416   ExpectByte(0x00);  // COPY address (0)
    417   ExpectByte('X');
    418   ExpectNoMoreBytes();
    419   EXPECT_LE(6U, interleaved_writer.match_counts().size());
    420   EXPECT_EQ(0, interleaved_writer.match_counts()[0]);
    421   EXPECT_EQ(0, interleaved_writer.match_counts()[1]);
    422   EXPECT_EQ(0, interleaved_writer.match_counts()[2]);
    423   EXPECT_EQ(0, interleaved_writer.match_counts()[3]);
    424   EXPECT_EQ(1, interleaved_writer.match_counts()[4]);
    425   EXPECT_EQ(1, interleaved_writer.match_counts()[5]);
    426 }
    427 
    428 TEST_F(CodeTableWriterTest, InterleavedWriterEncodeComboWithChecksum) {
    429   EXPECT_TRUE(interleaved_writer.Init(0x11));
    430   const VCDChecksum checksum = 0xFFFFFFFF;  // would be negative if signed
    431   interleaved_writer.AddChecksum(checksum);
    432   interleaved_writer.Add("rayo", 4);
    433   interleaved_writer.Copy(2, 5);
    434   interleaved_writer.Copy(0, 4);
    435   interleaved_writer.Add("X", 1);
    436   interleaved_writer.Output(&output_string);
    437   ExpectByte(VCD_SOURCE | VCD_CHECKSUM);  // Win_Indicator
    438   ExpectByte(0x11);  // Source segment size: dictionary length
    439   ExpectByte(0x00);  // Source segment position: start of dictionary
    440   ExpectByte(0x13);  // Length of the delta encoding
    441   ExpectByte(0x0E);  // Size of the target window
    442   ExpectByte(0x00);  // Delta_indicator (no compression)
    443   ExpectByte(0x00);  // length of data for ADDs and RUNs
    444   ExpectByte(0x09);  // length of instructions section
    445   ExpectByte(0x00);  // length of addresses for COPYs
    446   ExpectByte(0x8F);  // checksum byte 1
    447   ExpectByte(0xFF);  // checksum byte 2
    448   ExpectByte(0xFF);  // checksum byte 3
    449   ExpectByte(0xFF);  // checksum byte 4
    450   ExpectByte(0x7F);  // checksum byte 5
    451   ExpectByte(0xAD);  // Combo: Add size 4 + COPY mode SELF, size 5
    452   ExpectString("rayo");
    453   ExpectByte(0x02);  // COPY address (2)
    454   ExpectByte(0xFD);  // Combo: COPY mode SAME(0), size 4 + Add size 1
    455   ExpectByte(0x00);  // COPY address (0)
    456   ExpectByte('X');
    457   ExpectNoMoreBytes();
    458 }
    459 
    460 TEST_F(CodeTableWriterTest, ReallyBigDictionary) {
    461   EXPECT_TRUE(interleaved_writer.Init(0x3FFFFFFF));
    462   interleaved_writer.Copy(2, 8);
    463   interleaved_writer.Copy(0x3FFFFFFE, 8);
    464   interleaved_writer.Output(&output_string);
    465   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
    466   ExpectByte(0x83);  // Source segment size: dictionary length (1)
    467   ExpectByte(0xFF);  // Source segment size: dictionary length (2)
    468   ExpectByte(0xFF);  // Source segment size: dictionary length (3)
    469   ExpectByte(0xFF);  // Source segment size: dictionary length (4)
    470   ExpectByte(0x7F);  // Source segment size: dictionary length (5)
    471   ExpectByte(0x00);  // Source segment position: start of dictionary
    472   ExpectByte(0x09);  // Length of the delta encoding
    473   ExpectByte(0x10);  // Size of the target window
    474   ExpectByte(0x00);  // Delta_indicator (no compression)
    475   ExpectByte(0x00);  // length of data for ADDs and RUNs
    476   ExpectByte(0x04);  // length of instructions section
    477   ExpectByte(0x00);  // length of addresses for COPYs
    478   ExpectByte(0x18);  // COPY mode SELF, size 8
    479   ExpectByte(0x02);  // COPY address (2)
    480   ExpectByte(0x28);  // COPY mode HERE, size 8
    481   ExpectByte(0x09);  // COPY address (9)
    482   ExpectNoMoreBytes();
    483   EXPECT_LE(9U, interleaved_writer.match_counts().size());
    484   EXPECT_EQ(0, interleaved_writer.match_counts()[0]);
    485   EXPECT_EQ(0, interleaved_writer.match_counts()[1]);
    486   EXPECT_EQ(0, interleaved_writer.match_counts()[2]);
    487   EXPECT_EQ(0, interleaved_writer.match_counts()[3]);
    488   EXPECT_EQ(0, interleaved_writer.match_counts()[4]);
    489   EXPECT_EQ(0, interleaved_writer.match_counts()[5]);
    490   EXPECT_EQ(0, interleaved_writer.match_counts()[6]);
    491   EXPECT_EQ(0, interleaved_writer.match_counts()[7]);
    492   EXPECT_EQ(2, interleaved_writer.match_counts()[8]);
    493 }
    494 
    495 #ifdef GTEST_HAS_DEATH_TEST
    496 TEST_F(CodeTableWriterDeathTest, DictionaryTooBig) {
    497   EXPECT_TRUE(interleaved_writer.Init(0x7FFFFFFF));
    498   interleaved_writer.Copy(2, 8);
    499   EXPECT_DEBUG_DEATH(interleaved_writer.Copy(0x7FFFFFFE, 8),
    500                      "address.*<.*here_address");
    501 }
    502 #endif  // GTEST_HAS_DEATH_TEST
    503 
    504 }  // unnamed namespace
    505 }  // namespace open_vcdiff
    506