1311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Copyright 2007 Google Inc.
2311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Author: Lincoln Smith
3311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
4311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Licensed under the Apache License, Version 2.0 (the "License");
5311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// you may not use this file except in compliance with the License.
6311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// You may obtain a copy of the License at
7311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
8311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//      http://www.apache.org/licenses/LICENSE-2.0
9311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
10311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Unless required by applicable law or agreed to in writing, software
11311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// distributed under the License is distributed on an "AS IS" BASIS,
12311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// See the License for the specific language governing permissions and
14311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// limitations under the License.
15311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
16311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifndef OPEN_VCDIFF_VCENCODER_H_
17311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define OPEN_VCDIFF_VCENCODER_H_
18311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
1928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#include <stddef.h>  // size_t
20732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com#include "google/format_extension_flags.h"
21311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "google/output_string.h"
22311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
23311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffnamespace open_vcdiff {
24311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
25311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass VCDiffEngine;
26311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass VCDiffStreamingEncoderImpl;
27311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
28311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// A HashedDictionary must be constructed from the dictionary data
29311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// in order to use VCDiffStreamingEncoder.  If the same dictionary will
30311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// be used to perform several encoding operations, then the caller should
31311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// create the HashedDictionary once and cache it for reuse.  This object
32311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// is thread-safe: the same const HashedDictionary can be used
33311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// by several threads simultaneously, each with its own VCDiffStreamingEncoder.
34311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
35311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// dictionary_contents is copied into the HashedDictionary, so the
36311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// caller may free that string, if desired, after the constructor returns.
37311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
38311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass HashedDictionary {
39311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff public:
40311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  HashedDictionary(const char* dictionary_contents,
41311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                   size_t dictionary_size);
42311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  ~HashedDictionary();
43311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
44311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Init() must be called before using the HashedDictionary as an argument
45311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // to the VCDiffStreamingEncoder, or for any other purpose except
46311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // destruction.  It returns true if initialization succeeded, or false
47311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // if an error occurred, in which case the caller should destroy the object
48311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // without using it.
49311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool Init();
50311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
51311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  const VCDiffEngine* engine() const { return engine_; }
52311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
53311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff private:
54311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  const VCDiffEngine* engine_;
55d18457863096b3685e56f5a8919959f6afbdb121openvcdiff
56d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  // Make the copy constructor and assignment operator private
57d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  // so that they don't inadvertently get used.
58d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  HashedDictionary(const HashedDictionary&);  // NOLINT
59d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  void operator=(const HashedDictionary&);
60311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff};
61311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
62311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// The standard streaming interface to the VCDIFF (RFC 3284) encoder.
63311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// "Streaming" in this context means that, even though the entire set of
64311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// input data to be encoded may not be available at once, the encoder
65311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// can produce partial output based on what is available.  Of course,
66311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// the caller should try to maximize the sizes of the data chunks passed
67311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// to the encoder.
68311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass VCDiffStreamingEncoder {
69311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff public:
70311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // The HashedDictionary object passed to the constructor must remain valid,
71311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // without being deleted, for the lifetime of the VCDiffStreamingEncoder
72311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // object.
73311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
74311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // format_extensions allows certain open-vcdiff extensions to the VCDIFF
75311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // format to be included in the encoded output.  These extensions are not
76311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // part of the RFC 3284 draft standard, so specifying any extension flags
77311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // will make the output compatible only with open-vcdiff, or with other
78311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // VCDIFF implementations that accept these extensions.  See above for an
79311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // explanation of each possible flag value.
80311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
81311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // *** look_for_target_matches:
82311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // The VCDIFF format allows COPY instruction addresses to reference data from
83311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // the source (dictionary), or from previously encoded target data.
84311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
85311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // If look_for_target_matches is false, then the encoder will only
86311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // produce COPY instructions that reference source data from the dictionary,
87311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // never from previously encoded target data.  This will speed up the encoding
88311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // process, but the encoded data will not be as compact.
89311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
90311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // If this value is true, then the encoder will produce COPY instructions
91311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // that reference either source data or target data.  A COPY instruction from
92311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // the previously encoded target data may even extend into the range of the
93311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // data being produced by that same COPY instruction; for example, if the
94311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // previously encoded target data is "LA", then a single COPY instruction of
95311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // length 10 can produce the additional target data "LALALALALA".
96311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
97311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // There is a third type of COPY instruction that starts within
98311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // the source data and extends from the end of the source data
99311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // into the beginning of the target data.  This VCDIFF encoder will never
100311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // produce a COPY instruction of this third type (regardless of the value of
101311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // look_for_target_matches) because the cost of checking for matches
102311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // across the source-target boundary would not justify its benefits.
103311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
104311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  VCDiffStreamingEncoder(const HashedDictionary* dictionary,
105311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                         VCDiffFormatExtensionFlags format_extensions,
106311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                         bool look_for_target_matches);
107311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  ~VCDiffStreamingEncoder();
108311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
109311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // The client should use these routines as follows:
110311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    HashedDictionary hd(dictionary, dictionary_size);
111311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    if (!hd.Init()) {
112311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      HandleError();
113311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      return;
114311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    }
115311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    string output_string;
116311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    VCDiffStreamingEncoder v(hd, false, false);
117311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    if (!v.StartEncoding(&output_string)) {
118311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      HandleError();
119311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      return;  // No need to call FinishEncoding()
120311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    }
121311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    Process(output_string.data(), output_string.size());
122311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    output_string.clear();
123311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    while (get data_buf) {
124311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      if (!v.EncodeChunk(data_buf, data_len, &output_string)) {
125311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //        HandleError();
126311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //        return;  // No need to call FinishEncoding()
127311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      }
128311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      // The encoding is appended to output_string at each call,
129311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      // so clear output_string once its contents have been processed.
130311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      Process(output_string.data(), output_string.size());
131311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      output_string.clear();
132311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    }
133311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    if (!v.FinishEncoding(&output_string)) {
134311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      HandleError();
135311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //      return;
136311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    }
137311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    Process(output_string.data(), output_string.size());
138311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    output_string.clear();
139311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
140311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // I.e., the allowed pattern of calls is
141311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //    StartEncoding EncodeChunk* FinishEncoding
142311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
143311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // The size of the encoded output depends on the sizes of the chunks
144311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // passed in (i.e. the chunking boundary affects compression).
145311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // However the decoded output is independent of chunk boundaries.
146311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
147311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Sets up the data structures for encoding.
148311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Writes a VCDIFF delta file header (as defined in RFC section 4.1)
149311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // to *output_string.
150311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
151311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Note: we *append*, so the old contents of *output_string stick around.
152311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // This convention differs from the non-streaming Encode/Decode
153311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // interfaces in VCDiffEncoder.
154311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  //
155311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // If an error occurs, this function returns false; otherwise it returns true.
156311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // If this function returns false, the caller does not need to call
157311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // FinishEncoding or to do any cleanup except destroying the
158311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // VCDiffStreamingEncoder object.
159311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  template<class OutputType>
160311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool StartEncoding(OutputType* output) {
161311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    OutputString<OutputType> output_string(output);
162311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    return StartEncodingToInterface(&output_string);
163311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
164311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
165311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool StartEncodingToInterface(OutputStringInterface* output_string);
166311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
167311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Appends compressed encoding for "data" (one complete VCDIFF delta window)
168311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // to *output_string.
169311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // If an error occurs (for example, if StartEncoding was not called
170311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // earlier or StartEncoding returned false), this function returns false;
171311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // otherwise it returns true.  The caller does not need to call FinishEncoding
172311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // or do any cleanup except destroying the VCDiffStreamingEncoder
173311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // if this function returns false.
174311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  template<class OutputType>
175311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool EncodeChunk(const char* data, size_t len, OutputType* output) {
176311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    OutputString<OutputType> output_string(output);
177311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    return EncodeChunkToInterface(data, len, &output_string);
178311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
179311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
180311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool EncodeChunkToInterface(const char* data, size_t len,
181311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                              OutputStringInterface* output_string);
182311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
183311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Finishes encoding and appends any leftover encoded data to *output_string.
184311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // If an error occurs (for example, if StartEncoding was not called
185311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // earlier or StartEncoding returned false), this function returns false;
186311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // otherwise it returns true.  The caller does not need to
187311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // do any cleanup except destroying the VCDiffStreamingEncoder
188311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // if this function returns false.
189311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  template<class OutputType>
190311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool FinishEncoding(OutputType* output) {
191311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    OutputString<OutputType> output_string(output);
192311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    return FinishEncodingToInterface(&output_string);
193311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
194311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
195311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool FinishEncodingToInterface(OutputStringInterface* output_string);
196311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
197311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff private:
198311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  VCDiffStreamingEncoderImpl* const impl_;
199311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
200311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Make the copy constructor and assignment operator private
201311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // so that they don't inadvertently get used.
202311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  VCDiffStreamingEncoder(const VCDiffStreamingEncoder&);  // NOLINT
203311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  void operator=(const VCDiffStreamingEncoder&);
204311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff};
205311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
206311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// A simpler (non-streaming) interface to the VCDIFF encoder that can be used
207311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// if the entire target data string is available.
208311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
209311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass VCDiffEncoder {
210311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff public:
211311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  VCDiffEncoder(const char* dictionary_contents, size_t dictionary_size)
212311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      : dictionary_(dictionary_contents, dictionary_size),
213311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        encoder_(NULL),
214d18457863096b3685e56f5a8919959f6afbdb121openvcdiff        flags_(VCD_STANDARD_FORMAT),
215d18457863096b3685e56f5a8919959f6afbdb121openvcdiff        look_for_target_matches_(true) { }
216311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
217311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  ~VCDiffEncoder() {
218311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    delete encoder_;
219311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
220311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
221311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // By default, VCDiffEncoder uses standard VCDIFF format.  This function
222311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // can be used before calling Encode(), to specify that interleaved format
223311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // and/or checksum format should be used.
224311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  void SetFormatFlags(VCDiffFormatExtensionFlags flags) { flags_ = flags; }
225311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
226d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  // By default, VCDiffEncoder looks for matches in the dictionary and also in
227d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  // the previously encoded target data.  This function can be used before
228d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  // calling Encode(), to specify whether or not target matching should be
229d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  // enabled.
230d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  void SetTargetMatching(bool look_for_target_matches) {
231d18457863096b3685e56f5a8919959f6afbdb121openvcdiff    look_for_target_matches_ = look_for_target_matches;
232d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  }
233d18457863096b3685e56f5a8919959f6afbdb121openvcdiff
234311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Replaces old contents of output_string with the encoded form of
235311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // target_data.
236311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  template<class OutputType>
237311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool Encode(const char* target_data,
238311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff              size_t target_len,
239311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff              OutputType* output) {
240311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    OutputString<OutputType> output_string(output);
241311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    return EncodeToInterface(target_data, target_len, &output_string);
242311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
243311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
244311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff private:
245311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool EncodeToInterface(const char* target_data,
246311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                         size_t target_len,
247311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                         OutputStringInterface* output_string);
248311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
249311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  HashedDictionary dictionary_;
250311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  VCDiffStreamingEncoder* encoder_;
251311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  VCDiffFormatExtensionFlags flags_;
252d18457863096b3685e56f5a8919959f6afbdb121openvcdiff  bool look_for_target_matches_;
253311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
254311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Make the copy constructor and assignment operator private
255311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // so that they don't inadvertently get used.
256311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  VCDiffEncoder(const VCDiffEncoder&);  // NOLINT
257311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  void operator=(const VCDiffEncoder&);
258311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff};
259311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
260311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}  // namespace open_vcdiff
261311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
262311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif  // OPEN_VCDIFF_VCENCODER_H_
263