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