// Copyright 2008 Google Inc.
// Author: Lincoln Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Implements a Decoder for the format described in
// RFC 3284 - The VCDIFF Generic Differencing and Compression Data Format.
// The RFC text can be found at http://www.faqs.org/rfcs/rfc3284.html
//
// The RFC describes the possibility of using a secondary compressor
// to further reduce the size of each section of the VCDIFF output.
// That feature is not supported in this implementation of the encoder
// and decoder.
// No secondary compressor types have been publicly registered with
// the IANA at http://www.iana.org/assignments/vcdiff-comp-ids
// in the more than five years since the registry was created, so there
// is no standard set of compressor IDs which would be generated by other
// encoders or accepted by other decoders.

#include <config.h>
#include "google/vcdecoder.h"
#include <stddef.h>  // size_t, ptrdiff_t
#include <stdint.h>  // int32_t
#include <string.h>  // memcpy, memset
#include <memory>  // auto_ptr
#include <string>
#include "addrcache.h"
#include "checksum.h"
#include "codetable.h"
#include "decodetable.h"
#include "headerparser.h"
#include "logging.h"
#include "google/output_string.h"
#include "varint_bigendian.h"
#include "vcdiff_defs.h"

namespace open_vcdiff {

// This class is used to parse delta file windows as described
// in RFC sections 4.2 and 4.3.  Its methods are not thread-safe.
//
// Here is the window format copied from the RFC:
//
// Window1
//     Win_Indicator                            - byte
//     [Source segment size]                    - integer
//     [Source segment position]                - integer
//     The delta encoding of the target window
//         Length of the delta encoding         - integer
//         The delta encoding
//             Size of the target window        - integer
//             Delta_Indicator                  - byte
//             Length of data for ADDs and RUNs - integer
//             Length of instructions and sizes - integer
//             Length of addresses for COPYs    - integer
//             Data section for ADDs and RUNs   - array of bytes
//             Instructions and sizes section   - array of bytes
//             Addresses section for COPYs      - array of bytes
// Window2
// ...
//
// Sample usage:
//
// VCDiffDeltaFileWindow delta_window_;
// delta_window_.Init(parent);
// ParseableChunk parseable_chunk(input_buffer,
//                                input_size,
//                                leftover_unencoded_bytes);
// switch (delta_window_.DecodeWindows(&parseable_chunk)) {
//   case RESULT_END_OF_DATA:
//     <Read more input and retry DecodeWindows later.>
//   case RESULT_ERROR:
//     <Handle error case.  An error log message has already been generated.>
// }
//
// DecodeWindows consumes as many windows from the input as it can.  It only
// needs to be placed within a loop if the loop is used to obtain more input
// (delta file) data.
//
class VCDiffDeltaFileWindow {
 public:
  VCDiffDeltaFileWindow();
  ~VCDiffDeltaFileWindow();

  // Init() should be called immediately after constructing the
  // VCDiffDeltaFileWindow().  It must be called before DecodeWindows() can be
  // invoked, or an error will occur.
  void Init(VCDiffStreamingDecoderImpl* parent);

  // Resets the pointers to the data sections in the current window.
  void Reset();

  bool UseCodeTable(const VCDiffCodeTableData& code_table_data,
                    unsigned char max_mode) {
    return reader_.UseCodeTable(code_table_data, max_mode);
  }

  // Decodes as many delta windows as possible using the input data from
  // *parseable_chunk.  Appends the decoded target windows to
  // parent_->decoded_target().  Returns RESULT_SUCCESS on success, or
  // RESULT_END_OF_DATA if the end of input was reached before the entire window
  // could be decoded and more input is expected (only possible if
  // IsInterleaved() is true), or RESULT_ERROR if an error occurred during
  // decoding.  In the RESULT_ERROR case, the value of parseable_chunk->pointer_
  // is undefined; otherwise, parseable_chunk->Advance() is called to point to
  // the input data position just after the data that has been decoded.
  //
  // If planned_target_file_size is not set to kUnlimitedBytes, then the decoder
  // expects *exactly* this number of target bytes to be decoded from one or
  // more delta file windows.  If this number is met exactly after finishing a
  // delta window, this function will return RESULT_SUCCESS without processing
  // any more bytes from data_pointer.  If this number is exceeded while
  // decoding a window, but was not met before starting that window,
  // then RESULT_ERROR will be returned.
  //
  VCDiffResult DecodeWindows(ParseableChunk* parseable_chunk);

  bool FoundWindowHeader() const {
    return found_header_;
  }

  bool MoreDataExpected() const {
    // When parsing an interleaved-format delta file,
    // every time DecodeBody() exits, interleaved_bytes_expected_
    // will be decremented by the number of bytes parsed.  If it
    // reaches zero, then there is no more data expected because
    // the size of the interleaved section (given in the window
    // header) has been reached.
    return IsInterleaved() && (interleaved_bytes_expected_ > 0);
  }

  size_t target_window_start_pos() const { return target_window_start_pos_; }

  void set_target_window_start_pos(size_t new_start_pos) {
    target_window_start_pos_ = new_start_pos;
  }

  // Returns the number of bytes remaining to be decoded in the target window.
  // If not in the process of decoding a window, returns 0.
  size_t TargetBytesRemaining();

 private:
  // Reads the header of the window section as described in RFC sections 4.2 and
  // 4.3, up to and including the value "Length of addresses for COPYs".  If the
  // entire header is found, this function sets up the DeltaWindowSections
  // instructions_and_sizes_, data_for_add_and_run_, and addresses_for_copy_ so
  // that the decoder can begin decoding the opcodes in these sections.  Returns
  // RESULT_ERROR if an error occurred, or RESULT_END_OF_DATA if the end of
  // available data was reached before the entire header could be read.  (The
  // latter may be an error condition if there is no more data available.)
  // Otherwise, returns RESULT_SUCCESS and advances parseable_chunk past the
  // parsed header.
  //
  VCDiffResult ReadHeader(ParseableChunk* parseable_chunk);

  // After the window header has been parsed as far as the Delta_Indicator,
  // this function is called to parse the following delta window header fields:
  //
  //     Length of data for ADDs and RUNs - integer (VarintBE format)
  //     Length of instructions and sizes - integer (VarintBE format)
  //     Length of addresses for COPYs    - integer (VarintBE format)
  //
  // If has_checksum_ is true, it also looks for the following element:
  //
  //     Adler32 checksum            - unsigned 32-bit integer (VarintBE format)
  //
  // It sets up the DeltaWindowSections instructions_and_sizes_,
  // data_for_add_and_run_, and addresses_for_copy_.  If the interleaved format
  // is being used, all three sections will include the entire window body; if
  // the standard format is used, three non-overlapping window sections will be
  // defined.  Returns RESULT_ERROR if an error occurred, or RESULT_END_OF_DATA
  // if standard format is being used and there is not enough input data to read
  // the entire window body.  Otherwise, returns RESULT_SUCCESS.
  VCDiffResult SetUpWindowSections(VCDiffHeaderParser* header_parser);

  // Decodes the body of the window section as described in RFC sections 4.3,
  // including the sections "Data section for ADDs and RUNs", "Instructions
  // and sizes section", and "Addresses section for COPYs".  These sections
  // must already have been set up by ReadWindowHeader().  Returns a
  // non-negative value on success, or RESULT_END_OF_DATA if the end of input
  // was reached before the entire window could be decoded (only possible if
  // IsInterleaved() is true), or RESULT_ERROR if an error occurred during
  // decoding.  Appends as much of the decoded target window as possible to
  // parent->decoded_target().
  //
  int DecodeBody(ParseableChunk* parseable_chunk);

  // Returns the number of bytes already decoded into the target window.
  size_t TargetBytesDecoded();

  // Decodes a single ADD instruction, updating parent_->decoded_target_.
  VCDiffResult DecodeAdd(size_t size);

  // Decodes a single RUN instruction, updating parent_->decoded_target_.
  VCDiffResult DecodeRun(size_t size);

  // Decodes a single COPY instruction, updating parent_->decoded_target_.
  VCDiffResult DecodeCopy(size_t size, unsigned char mode);

  // When using the interleaved format, this function is called both on parsing
  // the header and on resuming after a RESULT_END_OF_DATA was returned from a
  // previous call to DecodeBody().  It sets up all three section pointers to
  // reference the same interleaved stream of instructions, sizes, addresses,
  // and data.  These pointers must be reset every time that work resumes on a
  // delta window,  because the input data string may have been changed or
  // resized since DecodeBody() last returned.
  void UpdateInterleavedSectionPointers(const char* data_pos,
                                        const char* data_end) {
    const ptrdiff_t available_data = data_end - data_pos;
    // Don't read past the end of currently-available data
    if (available_data > interleaved_bytes_expected_) {
      instructions_and_sizes_.Init(data_pos, interleaved_bytes_expected_);
    } else {
      instructions_and_sizes_.Init(data_pos, available_data);
    }
    data_for_add_and_run_.Init(&instructions_and_sizes_);
    addresses_for_copy_.Init(&instructions_and_sizes_);
  }

  // If true, the interleaved format described in AllowInterleaved() is used
  // for the current delta file.  Only valid after ReadWindowHeader() has been
  // called and returned a positive number (i.e., the whole header was parsed),
  // but before the window has finished decoding.
  //
  bool IsInterleaved() const {
    // If the sections are interleaved, both addresses_for_copy_ and
    // data_for_add_and_run_ should point at instructions_and_sizes_.
    return !addresses_for_copy_.IsOwned();
  }

  // Executes a single COPY or ADD instruction, appending data to
  // parent_->decoded_target().
  void CopyBytes(const char* data, size_t size);

  // Executes a single RUN instruction, appending data to
  // parent_->decoded_target().
  void RunByte(unsigned char byte, size_t size);

  // Advance *parseable_chunk to point to the current position in the
  // instructions/sizes section.  If interleaved format is used, then
  // decrement the number of expected bytes in the instructions/sizes section
  // by the number of instruction/size bytes parsed.
  void UpdateInstructionPointer(ParseableChunk* parseable_chunk);

  // The parent object which was passed to Init().
  VCDiffStreamingDecoderImpl* parent_;

  // This value will be true if VCDiffDeltaFileWindow::ReadDeltaWindowHeader()
  // has been called and succeeded in parsing the delta window header, but the
  // entire window has not yet been decoded.
  bool found_header_;

  // Contents and length of the current source window.  source_segment_ptr_
  // will be non-NULL if (a) the window section header for the current window
  // has been read, but the window has not yet finished decoding; or
  // (b) the window did not specify a source segment.
  const char* source_segment_ptr_;
  size_t source_segment_length_;

  // The delta encoding window sections as defined in RFC section 4.3.
  // The pointer for each section will be incremented as data is consumed and
  // decoded from that section.  If the interleaved format is used,
  // data_for_add_and_run_ and addresses_for_copy_ will both point to
  // instructions_and_sizes_; otherwise, they will be separate data sections.
  //
  DeltaWindowSection instructions_and_sizes_;
  DeltaWindowSection data_for_add_and_run_;
  DeltaWindowSection addresses_for_copy_;

  // The expected bytes left to decode in instructions_and_sizes_.  Only used
  // for the interleaved format.
  int interleaved_bytes_expected_;

  // The expected length of the target window once it has been decoded.
  size_t target_window_length_;

  // The index in decoded_target at which the first byte of the current
  // target window was/will be written.
  size_t target_window_start_pos_;

  // If has_checksum_ is true, then expected_checksum_ contains an Adler32
  // checksum of the target window data.  This is an extension included in the
  // VCDIFF 'S' (SDCH) format, but is not part of the RFC 3284 draft standard.
  bool has_checksum_;
  VCDChecksum expected_checksum_;

  VCDiffCodeTableReader reader_;

  // Making these private avoids implicit copy constructor & assignment operator
  VCDiffDeltaFileWindow(const VCDiffDeltaFileWindow&);  // NOLINT
  void operator=(const VCDiffDeltaFileWindow&);
};

// *** Inline methods for VCDiffDeltaFileWindow

inline VCDiffDeltaFileWindow::VCDiffDeltaFileWindow() : parent_(NULL) {
  Reset();
}

inline VCDiffDeltaFileWindow::~VCDiffDeltaFileWindow() { }

inline void VCDiffDeltaFileWindow::Init(VCDiffStreamingDecoderImpl* parent) {
  parent_ = parent;
}

class VCDiffStreamingDecoderImpl {
 public:
  typedef std::string string;

  // The default maximum target file size (and target window size) if
  // SetMaximumTargetFileSize() is not called.
  static const size_t kDefaultMaximumTargetFileSize = 67108864U;  // 64 MB

  // The largest value that can be passed to SetMaximumTargetWindowSize().
  // Using a larger value will result in an error.
  static const size_t kTargetSizeLimit = 2147483647U;  // INT32_MAX

  // A constant that is the default value for planned_target_file_size_,
  // indicating that the decoder does not have an expected length
  // for the target data.
  static const size_t kUnlimitedBytes = static_cast<size_t>(-3);

  VCDiffStreamingDecoderImpl();
  ~VCDiffStreamingDecoderImpl();

  // Resets all member variables to their initial states.
  void Reset();

  // These functions are identical to their counterparts
  // in VCDiffStreamingDecoder.
  //
  void StartDecoding(const char* dictionary_ptr, size_t dictionary_size);

  bool DecodeChunk(const char* data,
                   size_t len,
                   OutputStringInterface* output_string);

  bool FinishDecoding();

  // If true, the version of VCDIFF used in the current delta file allows
  // for the interleaved format, in which instructions, addresses and data
  // are all sent interleaved in the instructions section of each window
  // rather than being sent in separate sections.  This is not part of
  // the VCDIFF draft standard, so we've defined a special version code
  // 'S' which implies that this feature is available.  Even if interleaving
  // is supported, it is not mandatory; interleaved format will be implied
  // if the address and data sections are both zero-length.
  //
  bool AllowInterleaved() const { return vcdiff_version_code_ == 'S'; }

  // If true, the version of VCDIFF used in the current delta file allows
  // each delta window to contain an Adler32 checksum of the target window data.
  // If the bit 0x08 (VCD_CHECKSUM) is set in the Win_Indicator flags, then
  // this checksum will appear as a variable-length integer, just after the
  // "length of addresses for COPYs" value and before the window data sections.
  // It is possible for some windows in a delta file to use the checksum feature
  // and for others not to use it (and leave the flag bit set to 0.)
  // Just as with AllowInterleaved(), this extension is not part of the draft
  // standard and is only available when the version code 'S' is specified.
  //
  bool AllowChecksum() const { return vcdiff_version_code_ == 'S'; }

  bool SetMaximumTargetFileSize(size_t new_maximum_target_file_size) {
    maximum_target_file_size_ = new_maximum_target_file_size;
    return true;
  }

  bool SetMaximumTargetWindowSize(size_t new_maximum_target_window_size) {
    if (new_maximum_target_window_size > kTargetSizeLimit) {
      LOG(ERROR) << "Specified maximum target window size "
                 << new_maximum_target_window_size << " exceeds limit of "
                 << kTargetSizeLimit << " bytes" << LOG_ENDL;
      return false;
    }
    maximum_target_window_size_ = new_maximum_target_window_size;
    return true;
  }

  // See description of planned_target_file_size_, below.
  bool HasPlannedTargetFileSize() const {
    return planned_target_file_size_ != kUnlimitedBytes;
  }

  void SetPlannedTargetFileSize(size_t planned_target_file_size) {
    planned_target_file_size_ = planned_target_file_size;
  }

  void AddToTotalTargetWindowSize(size_t window_size) {
    total_of_target_window_sizes_ += window_size;
  }

  // Checks to see whether the decoded target data has reached its planned size.
  bool ReachedPlannedTargetFileSize() const {
    if (!HasPlannedTargetFileSize()) {
      return false;
    }
    // The planned target file size should not have been exceeded.
    // TargetWindowWouldExceedSizeLimits() ensures that the advertised size of
    // each target window would not make the target file exceed that limit, and
    // DecodeBody() will return RESULT_ERROR if the actual decoded output ever
    // exceeds the advertised target window size.
    if (total_of_target_window_sizes_ > planned_target_file_size_) {
      LOG(DFATAL) << "Internal error: Decoded data size "
                  << total_of_target_window_sizes_
                  << " exceeds planned target file size "
                  << planned_target_file_size_ << LOG_ENDL;
      return true;
    }
    return total_of_target_window_sizes_ == planned_target_file_size_;
  }

  // Checks to see whether adding a new target window of the specified size
  // would exceed the planned target file size, the maximum target file size,
  // or the maximum target window size.  If so, logs an error and returns true;
  // otherwise, returns false.
  bool TargetWindowWouldExceedSizeLimits(size_t window_size) const;

  // Returns the amount of input data passed to the last DecodeChunk()
  // that was not consumed by the decoder.  This is essential if
  // SetPlannedTargetFileSize() is being used, in order to preserve the
  // remaining input data stream once the planned target file has been decoded.
  size_t GetUnconsumedDataSize() const {
    return unparsed_bytes_.size();
  }

  // This function will return true if the decoder has parsed a complete delta
  // file header plus zero or more delta file windows, with no data left over.
  // It will also return true if no delta data at all was decoded.  If these
  // conditions are not met, then FinishDecoding() should not be called.
  bool IsDecodingComplete() const {
    if (!FoundFileHeader()) {
      // No complete delta file header has been parsed yet.  DecodeChunk()
      // may have received some data that it hasn't yet parsed, in which case
      // decoding is incomplete.
      return unparsed_bytes_.empty();
    } else if (custom_code_table_decoder_.get()) {
      // The decoder is in the middle of parsing a custom code table.
      return false;
    } else if (delta_window_.FoundWindowHeader()) {
      // The decoder is in the middle of parsing an interleaved format delta
      // window.
      return false;
    } else if (ReachedPlannedTargetFileSize()) {
      // The decoder found exactly the planned number of bytes.  In this case
      // it is OK for unparsed_bytes_ to be non-empty; it contains the leftover
      // data after the end of the delta file.
      return true;
    } else {
      // No complete delta file window has been parsed yet.  DecodeChunk()
      // may have received some data that it hasn't yet parsed, in which case
      // decoding is incomplete.
      return unparsed_bytes_.empty();
    }
  }

  const char* dictionary_ptr() const { return dictionary_ptr_; }

  size_t dictionary_size() const { return dictionary_size_; }

  VCDiffAddressCache* addr_cache() { return addr_cache_.get(); }

  string* decoded_target() { return &decoded_target_; }

  bool allow_vcd_target() const { return allow_vcd_target_; }

  void SetAllowVcdTarget(bool allow_vcd_target) {
    if (start_decoding_was_called_) {
      LOG(DFATAL) << "SetAllowVcdTarget() called after StartDecoding()"
                  << LOG_ENDL;
      return;
    }
    allow_vcd_target_ = allow_vcd_target;
  }

  // Removes the contents of decoded_target_ that precede the beginning of the
  // current window.
  void TruncateToBeginningOfWindow();

 private:
  // Reads the VCDiff delta file header section as described in RFC section 4.1,
  // except the custom code table data.  Returns RESULT_ERROR if an error
  // occurred, or RESULT_END_OF_DATA if the end of available data was reached
  // before the entire header could be read.  (The latter may be an error
  // condition if there is no more data available.)  Otherwise, advances
  // data->position_ past the header and returns RESULT_SUCCESS.
  //
  VCDiffResult ReadDeltaFileHeader(ParseableChunk* data);

  // Indicates whether or not the header has already been read.
  bool FoundFileHeader() const { return addr_cache_.get() != NULL; }

  // If ReadDeltaFileHeader() finds the VCD_CODETABLE flag set within the delta
  // file header, this function parses the custom cache sizes and initializes
  // a nested VCDiffStreamingDecoderImpl object that will be used to parse the
  // custom code table in ReadCustomCodeTable().  Returns RESULT_ERROR if an
  // error occurred, or RESULT_END_OF_DATA if the end of available data was
  // reached before the custom cache sizes could be read.  Otherwise, returns
  // the number of bytes read.
  //
  int InitCustomCodeTable(const char* data_start, const char* data_end);

  // If a custom code table was specified in the header section that was parsed
  // by ReadDeltaFileHeader(), this function makes a recursive call to another
  // VCDiffStreamingDecoderImpl object (custom_code_table_decoder_), since the
  // custom code table is expected to be supplied as an embedded VCDIFF
  // encoding that uses the standard code table.  Returns RESULT_ERROR if an
  // error occurs, or RESULT_END_OF_DATA if the end of available data was
  // reached before the entire custom code table could be read.  Otherwise,
  // returns RESULT_SUCCESS and sets *data_ptr to the position after the encoded
  // custom code table.  If the function returns RESULT_SUCCESS or
  // RESULT_END_OF_DATA, it advances data->position_ past the parsed bytes.
  //
  VCDiffResult ReadCustomCodeTable(ParseableChunk* data);

  // Contents and length of the source (dictionary) data.
  const char* dictionary_ptr_;
  size_t dictionary_size_;

  // This string will be used to store any unparsed bytes left over when
  // DecodeChunk() reaches the end of its input and returns RESULT_END_OF_DATA.
  // It will also be used to concatenate those unparsed bytes with the data
  // supplied to the next call to DecodeChunk(), so that they appear in
  // contiguous memory.
  string unparsed_bytes_;

  // The portion of the target file that has been decoded so far.  This will be
  // used to fill the output string for DecodeChunk(), and will also be used to
  // execute COPY instructions that reference target data.  Since the source
  // window can come from a range of addresses in the previously decoded target
  // data, the entire target file needs to be available to the decoder, not just
  // the current target window.
  string decoded_target_;

  // The VCDIFF version byte (also known as "header4") from the
  // delta file header.
  unsigned char vcdiff_version_code_;

  VCDiffDeltaFileWindow delta_window_;

  std::auto_ptr<VCDiffAddressCache> addr_cache_;

  // Will be NULL unless a custom code table has been defined.
  std::auto_ptr<VCDiffCodeTableData> custom_code_table_;

  // Used to receive the decoded custom code table.
  string custom_code_table_string_;

  // If a custom code table is specified, it will be expressed
  // as an embedded VCDIFF delta file which uses the default code table
  // as the source file (dictionary).  Use a child decoder object
  // to decode that delta file.
  std::auto_ptr<VCDiffStreamingDecoderImpl> custom_code_table_decoder_;

  // If set, then the decoder is expecting *exactly* this number of
  // target bytes to be decoded from one or more delta file windows.
  // If this number is exceeded while decoding a window, but was not met
  // before starting on that window, an error will be reported.
  // If FinishDecoding() is called before this number is met, an error
  // will also be reported.  This feature is used for decoding the
  // embedded code table data within a VCDIFF delta file; we want to
  // stop processing the embedded data once the entire code table has
  // been decoded, and treat the rest of the available data as part
  // of the enclosing delta file.
  size_t planned_target_file_size_;

  size_t maximum_target_file_size_;

  size_t maximum_target_window_size_;

  // Contains the sum of the decoded sizes of all target windows seen so far,
  // including the expected total size of the current target window in progress
  // (even if some of the current target window has not yet been decoded.)
  size_t total_of_target_window_sizes_;

  // This value is used to ensure the correct order of calls to the interface
  // functions, i.e., a single call to StartDecoding(), followed by zero or
  // more calls to DecodeChunk(), followed by a single call to
  // FinishDecoding().
  bool start_decoding_was_called_;

  // If this value is true then the VCD_TARGET flag can be specified to allow
  // the source segment to be chosen from the previously-decoded target data.
  // (This is the default behavior.)  If it is false, then specifying the
  // VCD_TARGET flag is considered an error, and the decoder does not need to
  // keep in memory any decoded target data prior to the current window.
  bool allow_vcd_target_;

  // Making these private avoids implicit copy constructor & assignment operator
  VCDiffStreamingDecoderImpl(const VCDiffStreamingDecoderImpl&);  // NOLINT
  void operator=(const VCDiffStreamingDecoderImpl&);
};

// *** Methods for VCDiffStreamingDecoderImpl

const size_t VCDiffStreamingDecoderImpl::kDefaultMaximumTargetFileSize;
const size_t VCDiffStreamingDecoderImpl::kUnlimitedBytes;

VCDiffStreamingDecoderImpl::VCDiffStreamingDecoderImpl()
    : maximum_target_file_size_(kDefaultMaximumTargetFileSize),
      maximum_target_window_size_(kDefaultMaximumTargetFileSize),
      allow_vcd_target_(true) {
  delta_window_.Init(this);
  Reset();
}

// Reset() will delete the component objects without reallocating them.
VCDiffStreamingDecoderImpl::~VCDiffStreamingDecoderImpl() { Reset(); }

void VCDiffStreamingDecoderImpl::Reset() {
  start_decoding_was_called_ = false;
  dictionary_ptr_ = NULL;
  dictionary_size_ = 0;
  vcdiff_version_code_ = '\0';
  planned_target_file_size_ = kUnlimitedBytes;
  total_of_target_window_sizes_ = 0;
  addr_cache_.reset();
  custom_code_table_.reset();
  custom_code_table_decoder_.reset();
  delta_window_.Reset();
}

void VCDiffStreamingDecoderImpl::TruncateToBeginningOfWindow() {
  // Conserve the data for the current window that has been partially decoded.
  decoded_target_.erase(0, delta_window_.target_window_start_pos());
  delta_window_.set_target_window_start_pos(0);
}

void VCDiffStreamingDecoderImpl::StartDecoding(const char* dictionary_ptr,
                                               size_t dictionary_size) {
  if (start_decoding_was_called_) {
    LOG(DFATAL) << "StartDecoding() called twice without FinishDecoding()"
                << LOG_ENDL;
    return;
  }
  unparsed_bytes_.clear();
  decoded_target_.clear();  // delta_window_.Reset() depends on this
  Reset();
  dictionary_ptr_ = dictionary_ptr;
  dictionary_size_ = dictionary_size;
  start_decoding_was_called_ = true;
}

// Reads the VCDiff delta file header section as described in RFC section 4.1:
//
//     Header1                                  - byte = 0xD6 (ASCII 'V' | 0x80)
//     Header2                                  - byte = 0xC3 (ASCII 'C' | 0x80)
//     Header3                                  - byte = 0xC4 (ASCII 'D' | 0x80)
//     Header4                                  - byte
//     Hdr_Indicator                            - byte
//     [Secondary compressor ID]                - byte
//     [Length of code table data]              - integer
//     [Code table data]
//
// Initializes the code table and address cache objects.  Returns RESULT_ERROR
// if an error occurred, and RESULT_END_OF_DATA if the end of available data was
// reached before the entire header could be read.  (The latter may be an error
// condition if there is no more data available.)  Otherwise, returns
// RESULT_SUCCESS, and removes the header bytes from the data string.
//
// It's relatively inefficient to expect this function to parse any number of
// input bytes available, down to 1 byte, but it is necessary in case the input
// is not a properly formatted VCDIFF delta file.  If the entire input consists
// of two bytes "12", then we should recognize that it does not match the
// initial VCDIFF magic number "VCD" and report an error, rather than waiting
// indefinitely for more input that will never arrive.
//
VCDiffResult VCDiffStreamingDecoderImpl::ReadDeltaFileHeader(
    ParseableChunk* data) {
  if (FoundFileHeader()) {
    return RESULT_SUCCESS;
  }
  size_t data_size = data->UnparsedSize();
  const DeltaFileHeader* header =
      reinterpret_cast<const DeltaFileHeader*>(data->UnparsedData());
  bool wrong_magic_number = false;
  switch (data_size) {
    // Verify only the bytes that are available.
    default:
      // Found header contents up to and including VCDIFF version
      vcdiff_version_code_ = header->header4;
      if ((vcdiff_version_code_ != 0x00) &&  // Draft standard VCDIFF (RFC 3284)
          (vcdiff_version_code_ != 'S')) {   // Enhancements for SDCH protocol
        LOG(ERROR) << "Unrecognized VCDIFF format version" << LOG_ENDL;
        return RESULT_ERROR;
      }
      // fall through
    case 3:
      if (header->header3 != 0xC4) {  // magic value 'D' | 0x80
        wrong_magic_number = true;
      }
      // fall through
    case 2:
      if (header->header2 != 0xC3) {  // magic value 'C' | 0x80
        wrong_magic_number = true;
      }
      // fall through
    case 1:
      if (header->header1 != 0xD6) {  // magic value 'V' | 0x80
        wrong_magic_number = true;
      }
      // fall through
    case 0:
      if (wrong_magic_number) {
        LOG(ERROR) << "Did not find VCDIFF header bytes; "
                      "input is not a VCDIFF delta file" << LOG_ENDL;
        return RESULT_ERROR;
      }
      if (data_size < sizeof(DeltaFileHeader)) return RESULT_END_OF_DATA;
  }
  // Secondary compressor not supported.
  if (header->hdr_indicator & VCD_DECOMPRESS) {
    LOG(ERROR) << "Secondary compression is not supported" << LOG_ENDL;
    return RESULT_ERROR;
  }
  if (header->hdr_indicator & VCD_CODETABLE) {
    int bytes_parsed = InitCustomCodeTable(
        data->UnparsedData() + sizeof(DeltaFileHeader),
        data->End());
    switch (bytes_parsed) {
      case RESULT_ERROR:
        return RESULT_ERROR;
      case RESULT_END_OF_DATA:
        return RESULT_END_OF_DATA;
      default:
        data->Advance(sizeof(DeltaFileHeader) + bytes_parsed);
    }
  } else {
    addr_cache_.reset(new VCDiffAddressCache);
    // addr_cache_->Init() will be called
    // from VCDiffStreamingDecoderImpl::DecodeChunk()
    data->Advance(sizeof(DeltaFileHeader));
  }
  return RESULT_SUCCESS;
}

int VCDiffStreamingDecoderImpl::InitCustomCodeTable(const char* data_start,
                                                    const char* data_end) {
  // A custom code table is being specified.  Parse the variable-length
  // cache sizes and begin parsing the encoded custom code table.
  int32_t near_cache_size = 0, same_cache_size = 0;
  VCDiffHeaderParser header_parser(data_start, data_end);
  if (!header_parser.ParseInt32("size of near cache", &near_cache_size)) {
    return header_parser.GetResult();
  }
  if (!header_parser.ParseInt32("size of same cache", &same_cache_size)) {
    return header_parser.GetResult();
  }
  custom_code_table_.reset(new struct VCDiffCodeTableData);
  memset(custom_code_table_.get(), 0, sizeof(struct VCDiffCodeTableData));
  custom_code_table_string_.clear();
  addr_cache_.reset(new VCDiffAddressCache(near_cache_size, same_cache_size));
  // addr_cache_->Init() will be called
  // from VCDiffStreamingDecoderImpl::DecodeChunk()

  // If we reach this point (the start of the custom code table)
  // without encountering a RESULT_END_OF_DATA condition, then we won't call
  // ReadDeltaFileHeader() again for this delta file.
  //
  // Instantiate a recursive decoder to interpret the custom code table
  // as a VCDIFF encoding of the default code table.
  custom_code_table_decoder_.reset(new VCDiffStreamingDecoderImpl);
  custom_code_table_decoder_->StartDecoding(
      reinterpret_cast<const char*>(
          &VCDiffCodeTableData::kDefaultCodeTableData),
      sizeof(VCDiffCodeTableData::kDefaultCodeTableData));
  custom_code_table_decoder_->SetPlannedTargetFileSize(
      sizeof(*custom_code_table_));
  return static_cast<int>(header_parser.ParsedSize());
}

VCDiffResult VCDiffStreamingDecoderImpl::ReadCustomCodeTable(
    ParseableChunk* data) {
  if (!custom_code_table_decoder_.get()) {
    return RESULT_SUCCESS;
  }
  if (!custom_code_table_.get()) {
    LOG(DFATAL) << "Internal error:  custom_code_table_decoder_ is set,"
                   " but custom_code_table_ is NULL" << LOG_ENDL;
    return RESULT_ERROR;
  }
  OutputString<string> output_string(&custom_code_table_string_);
  if (!custom_code_table_decoder_->DecodeChunk(data->UnparsedData(),
                                               data->UnparsedSize(),
                                               &output_string)) {
    return RESULT_ERROR;
  }
  if (custom_code_table_string_.length() < sizeof(*custom_code_table_)) {
    // Skip over the consumed data.
    data->Finish();
    return RESULT_END_OF_DATA;
  }
  if (!custom_code_table_decoder_->FinishDecoding()) {
    return RESULT_ERROR;
  }
  if (custom_code_table_string_.length() != sizeof(*custom_code_table_)) {
    LOG(DFATAL) << "Decoded custom code table size ("
                << custom_code_table_string_.length()
                << ") does not match size of a code table ("
                << sizeof(*custom_code_table_) << ")" << LOG_ENDL;
    return RESULT_ERROR;
  }
  memcpy(custom_code_table_.get(),
         custom_code_table_string_.data(),
         sizeof(*custom_code_table_));
  custom_code_table_string_.clear();
  // Skip over the consumed data.
  data->FinishExcept(custom_code_table_decoder_->GetUnconsumedDataSize());
  custom_code_table_decoder_.reset();
  delta_window_.UseCodeTable(*custom_code_table_, addr_cache_->LastMode());
  return RESULT_SUCCESS;
}

namespace {

class TrackNewOutputText {
 public:
  typedef std::string string;

  explicit TrackNewOutputText(const string& decoded_target)
      : decoded_target_(decoded_target),
      initial_decoded_target_size_(decoded_target.size()) { }

  void AppendNewOutputText(size_t target_bytes_remaining,
                           OutputStringInterface* output_string) {
    const size_t bytes_decoded_this_chunk =
        decoded_target_.size() - initial_decoded_target_size_;
    if (bytes_decoded_this_chunk > 0) {
      if (target_bytes_remaining > 0) {
        // The decoder is midway through decoding a target window.  Resize
        // output_string to match the expected length.  The interface guarantees
        // not to resize the output_string more than once per target window
        // decoded.
        output_string->ReserveAdditionalBytes(bytes_decoded_this_chunk
                                              + target_bytes_remaining);
      }
      output_string->append(
          decoded_target_.data() + initial_decoded_target_size_,
          bytes_decoded_this_chunk);
    }
  }

 private:
  const string& decoded_target_;
  size_t initial_decoded_target_size_;
};

}  // anonymous namespace

bool VCDiffStreamingDecoderImpl::DecodeChunk(
    const char* data,
    size_t len,
    OutputStringInterface* output_string) {
  if (!start_decoding_was_called_) {
    LOG(DFATAL) << "DecodeChunk() called without StartDecoding()" << LOG_ENDL;
    Reset();
    return false;
  }
  ParseableChunk parseable_chunk(data, len);
  if (!unparsed_bytes_.empty()) {
    unparsed_bytes_.append(data, len);
    parseable_chunk.SetDataBuffer(unparsed_bytes_.data(),
                                  unparsed_bytes_.size());
  }
  TrackNewOutputText output_tracker(decoded_target_);
  VCDiffResult result = ReadDeltaFileHeader(&parseable_chunk);
  if (RESULT_SUCCESS == result) {
    result = ReadCustomCodeTable(&parseable_chunk);
  }
  if (RESULT_SUCCESS == result) {
    result = delta_window_.DecodeWindows(&parseable_chunk);
  }
  if (RESULT_ERROR == result) {
    Reset();  // Don't allow further DecodeChunk calls
    return false;
  }
  unparsed_bytes_.assign(parseable_chunk.UnparsedData(),
                         parseable_chunk.UnparsedSize());
  output_tracker.AppendNewOutputText(delta_window_.TargetBytesRemaining(),
                                     output_string);
  if (!allow_vcd_target()) {
    // VCD_TARGET will never be used to reference target data beyond the start
    // of the current window, so throw away any earlier target data.
    TruncateToBeginningOfWindow();
  }
  return true;
}

// Finishes decoding after all data has been received.  Returns true
// if decoding of the entire stream was successful.
bool VCDiffStreamingDecoderImpl::FinishDecoding() {
  bool success = true;
  if (!start_decoding_was_called_) {
    LOG(WARNING) << "FinishDecoding() called before StartDecoding(),"
                    " or called after DecodeChunk() returned false"
                 << LOG_ENDL;
    success = false;
  } else if (!IsDecodingComplete()) {
    LOG(ERROR) << "FinishDecoding() called before parsing entire"
                  " delta file window" << LOG_ENDL;
    success = false;
  }
  // Reset the object state for the next decode operation
  Reset();
  return success;
}

bool VCDiffStreamingDecoderImpl::TargetWindowWouldExceedSizeLimits(
    size_t window_size) const {
  if (window_size > maximum_target_window_size_) {
    LOG(ERROR) << "Length of target window (" << window_size
               << ") exceeds limit of " << maximum_target_window_size_
               << " bytes" << LOG_ENDL;
    return true;
  }
  if (HasPlannedTargetFileSize()) {
    // The logical expression to check would be:
    //
    //   total_of_target_window_sizes_ + window_size > planned_target_file_size_
    //
    // but the addition might cause an integer overflow if target_bytes_to_add
    // is very large.  So it is better to check target_bytes_to_add against
    // the remaining planned target bytes.
    size_t remaining_planned_target_file_size =
        planned_target_file_size_ - total_of_target_window_sizes_;
    if (window_size > remaining_planned_target_file_size) {
      LOG(ERROR) << "Length of target window (" << window_size
                 << " bytes) plus previous windows ("
                 << total_of_target_window_sizes_
                 << " bytes) would exceed planned size of "
                 << planned_target_file_size_ << " bytes" << LOG_ENDL;
      return true;
    }
  }
  size_t remaining_maximum_target_bytes =
      maximum_target_file_size_ - total_of_target_window_sizes_;
  if (window_size > remaining_maximum_target_bytes) {
    LOG(ERROR) << "Length of target window (" << window_size
               << " bytes) plus previous windows ("
               << total_of_target_window_sizes_
               << " bytes) would exceed maximum target file size of "
               << maximum_target_file_size_ << " bytes" << LOG_ENDL;
    return true;
  }
  return false;
}

// *** Methods for VCDiffDeltaFileWindow

void VCDiffDeltaFileWindow::Reset() {
  found_header_ = false;

  // Mark the start of the current target window.
  target_window_start_pos_ = parent_ ? parent_->decoded_target()->size() : 0U;
  target_window_length_ = 0;

  source_segment_ptr_ = NULL;
  source_segment_length_ = 0;

  instructions_and_sizes_.Invalidate();
  data_for_add_and_run_.Invalidate();
  addresses_for_copy_.Invalidate();

  interleaved_bytes_expected_ = 0;

  has_checksum_ = false;
  expected_checksum_ = 0;
}

VCDiffResult VCDiffDeltaFileWindow::SetUpWindowSections(
    VCDiffHeaderParser* header_parser) {
  size_t add_and_run_data_length = 0;
  size_t instructions_and_sizes_length = 0;
  size_t addresses_length = 0;
  if (!header_parser->ParseSectionLengths(has_checksum_,
                                          &add_and_run_data_length,
                                          &instructions_and_sizes_length,
                                          &addresses_length,
                                          &expected_checksum_)) {
    return header_parser->GetResult();
  }
  if (parent_->AllowInterleaved() &&
      (add_and_run_data_length == 0) &&
      (addresses_length == 0)) {
    // The interleaved format is being used.
    interleaved_bytes_expected_ =
        static_cast<int>(instructions_and_sizes_length);
    UpdateInterleavedSectionPointers(header_parser->UnparsedData(),
                                     header_parser->End());
  } else {
    // If interleaved format is not used, then the whole window contents
    // must be available before decoding can begin.  If only part of
    // the current window is available, then report end of data
    // and re-parse the whole header when DecodeChunk() is called again.
    if (header_parser->UnparsedSize() < (add_and_run_data_length +
                                         instructions_and_sizes_length +
                                         addresses_length)) {
      return RESULT_END_OF_DATA;
    }
    data_for_add_and_run_.Init(header_parser->UnparsedData(),
                               add_and_run_data_length);
    instructions_and_sizes_.Init(data_for_add_and_run_.End(),
                                 instructions_and_sizes_length);
    addresses_for_copy_.Init(instructions_and_sizes_.End(), addresses_length);
    if (addresses_for_copy_.End() != header_parser->EndOfDeltaWindow()) {
      LOG(ERROR) << "The end of the instructions section "
                     "does not match the end of the delta window" << LOG_ENDL;
      return RESULT_ERROR;
    }
  }
  reader_.Init(instructions_and_sizes_.UnparsedDataAddr(),
               instructions_and_sizes_.End());
  return RESULT_SUCCESS;
}

// Here are the elements of the delta window header to be parsed,
// from section 4 of the RFC:
//
//     Window1
//         Win_Indicator                            - byte
//         [Source segment size]                    - integer
//         [Source segment position]                - integer
//         The delta encoding of the target window
//             Length of the delta encoding         - integer
//             The delta encoding
//                 Size of the target window        - integer
//                 Delta_Indicator                  - byte
//                 Length of data for ADDs and RUNs - integer
//                 Length of instructions and sizes - integer
//                 Length of addresses for COPYs    - integer
//                 Data section for ADDs and RUNs   - array of bytes
//                 Instructions and sizes section   - array of bytes
//                 Addresses section for COPYs      - array of bytes
//
VCDiffResult VCDiffDeltaFileWindow::ReadHeader(
    ParseableChunk* parseable_chunk) {
  std::string* decoded_target = parent_->decoded_target();
  VCDiffHeaderParser header_parser(parseable_chunk->UnparsedData(),
                                   parseable_chunk->End());
  size_t source_segment_position = 0;
  unsigned char win_indicator = 0;
  if (!header_parser.ParseWinIndicatorAndSourceSegment(
          parent_->dictionary_size(),
          decoded_target->size(),
          parent_->allow_vcd_target(),
          &win_indicator,
          &source_segment_length_,
          &source_segment_position)) {
    return header_parser.GetResult();
  }
  has_checksum_ = parent_->AllowChecksum() && (win_indicator & VCD_CHECKSUM);
  if (!header_parser.ParseWindowLengths(&target_window_length_)) {
    return header_parser.GetResult();
  }
  if (parent_->TargetWindowWouldExceedSizeLimits(target_window_length_)) {
    // An error has been logged by TargetWindowWouldExceedSizeLimits().
    return RESULT_ERROR;
  }
  header_parser.ParseDeltaIndicator();
  VCDiffResult setup_return_code = SetUpWindowSections(&header_parser);
  if (RESULT_SUCCESS != setup_return_code) {
    return setup_return_code;
  }
  // Reserve enough space in the output string for the current target window.
  decoded_target->reserve(target_window_start_pos_ + target_window_length_);
  // Get a pointer to the start of the source segment.
  if (win_indicator & VCD_SOURCE) {
    source_segment_ptr_ = parent_->dictionary_ptr() + source_segment_position;
  } else if (win_indicator & VCD_TARGET) {
    // This assignment must happen after the reserve().
    // decoded_target should not be resized again while processing this window,
    // so source_segment_ptr_ should remain valid.
    source_segment_ptr_ = decoded_target->data() + source_segment_position;
  }
  // The whole window header was found and parsed successfully.
  found_header_ = true;
  parseable_chunk->Advance(header_parser.ParsedSize());
  parent_->AddToTotalTargetWindowSize(target_window_length_);
  return RESULT_SUCCESS;
}

void VCDiffDeltaFileWindow::UpdateInstructionPointer(
    ParseableChunk* parseable_chunk) {
  if (IsInterleaved()) {
    size_t bytes_parsed = instructions_and_sizes_.ParsedSize();
    // Reduce expected instruction segment length by bytes parsed
    interleaved_bytes_expected_ -= static_cast<int>(bytes_parsed);
    parseable_chunk->Advance(bytes_parsed);
  }
}

inline size_t VCDiffDeltaFileWindow::TargetBytesDecoded() {
  return parent_->decoded_target()->size() - target_window_start_pos_;
}

size_t VCDiffDeltaFileWindow::TargetBytesRemaining() {
  if (target_window_length_ == 0) {
    // There is no window being decoded at present
    return 0;
  } else {
    return target_window_length_ - TargetBytesDecoded();
  }
}

inline void VCDiffDeltaFileWindow::CopyBytes(const char* data, size_t size) {
  parent_->decoded_target()->append(data, size);
}

inline void VCDiffDeltaFileWindow::RunByte(unsigned char byte, size_t size) {
  parent_->decoded_target()->append(size, byte);
}

VCDiffResult VCDiffDeltaFileWindow::DecodeAdd(size_t size) {
  if (size > data_for_add_and_run_.UnparsedSize()) {
    return RESULT_END_OF_DATA;
  }
  // Write the next "size" data bytes
  CopyBytes(data_for_add_and_run_.UnparsedData(), size);
  data_for_add_and_run_.Advance(size);
  return RESULT_SUCCESS;
}

VCDiffResult VCDiffDeltaFileWindow::DecodeRun(size_t size) {
  if (data_for_add_and_run_.Empty()) {
    return RESULT_END_OF_DATA;
  }
  // Write "size" copies of the next data byte
  RunByte(*data_for_add_and_run_.UnparsedData(), size);
  data_for_add_and_run_.Advance(1);
  return RESULT_SUCCESS;
}

VCDiffResult VCDiffDeltaFileWindow::DecodeCopy(size_t size,
                                               unsigned char mode) {
  // Keep track of the number of target bytes decoded as a local variable
  // to avoid recalculating it each time it is needed.
  size_t target_bytes_decoded = TargetBytesDecoded();
  const VCDAddress here_address =
      static_cast<VCDAddress>(source_segment_length_ + target_bytes_decoded);
  const VCDAddress decoded_address = parent_->addr_cache()->DecodeAddress(
      here_address,
      mode,
      addresses_for_copy_.UnparsedDataAddr(),
      addresses_for_copy_.End());
  switch (decoded_address) {
    case RESULT_ERROR:
      LOG(ERROR) << "Unable to decode address for COPY" << LOG_ENDL;
      return RESULT_ERROR;
    case RESULT_END_OF_DATA:
      return RESULT_END_OF_DATA;
    default:
      if ((decoded_address < 0) || (decoded_address > here_address)) {
        LOG(DFATAL) << "Internal error: unexpected address " << decoded_address
                    << " returned from DecodeAddress, with here_address = "
                    << here_address << LOG_ENDL;
        return RESULT_ERROR;
      }
      break;
  }
  size_t address = static_cast<size_t>(decoded_address);
  if ((address + size) <= source_segment_length_) {
    // Copy all data from source segment
    CopyBytes(&source_segment_ptr_[address], size);
    return RESULT_SUCCESS;
  }
  // Copy some data from target window...
  if (address < source_segment_length_) {
    // ... plus some data from source segment
    const size_t partial_copy_size = source_segment_length_ - address;
    CopyBytes(&source_segment_ptr_[address], partial_copy_size);
    target_bytes_decoded += partial_copy_size;
    address += partial_copy_size;
    size -= partial_copy_size;
  }
  address -= source_segment_length_;
  // address is now based at start of target window
  const char* const target_segment_ptr = parent_->decoded_target()->data() +
                                         target_window_start_pos_;
  while (size > (target_bytes_decoded - address)) {
    // Recursive copy that extends into the yet-to-be-copied target data
    const size_t partial_copy_size = target_bytes_decoded - address;
    CopyBytes(&target_segment_ptr[address], partial_copy_size);
    target_bytes_decoded += partial_copy_size;
    address += partial_copy_size;
    size -= partial_copy_size;
  }
  CopyBytes(&target_segment_ptr[address], size);
  return RESULT_SUCCESS;
}

int VCDiffDeltaFileWindow::DecodeBody(ParseableChunk* parseable_chunk) {
  if (IsInterleaved() && (instructions_and_sizes_.UnparsedData()
                              != parseable_chunk->UnparsedData())) {
    LOG(DFATAL) << "Internal error: interleaved format is used, but the"
                   " input pointer does not point to the instructions section"
                << LOG_ENDL;
    return RESULT_ERROR;
  }
  while (TargetBytesDecoded() < target_window_length_) {
    int32_t decoded_size = VCD_INSTRUCTION_ERROR;
    unsigned char mode = 0;
    VCDiffInstructionType instruction =
        reader_.GetNextInstruction(&decoded_size, &mode);
    switch (instruction) {
      case VCD_INSTRUCTION_END_OF_DATA:
        UpdateInstructionPointer(parseable_chunk);
        return RESULT_END_OF_DATA;
      case VCD_INSTRUCTION_ERROR:
        return RESULT_ERROR;
      default:
        break;
    }
    const size_t size = static_cast<size_t>(decoded_size);
    // The value of "size" itself could be enormous (say, INT32_MAX)
    // so check it individually against the limit to protect against
    // overflow when adding it to something else.
    if ((size > target_window_length_) ||
        ((size + TargetBytesDecoded()) > target_window_length_)) {
      LOG(ERROR) << VCDiffInstructionName(instruction)
                 << " with size " << size
                 << " plus existing " << TargetBytesDecoded()
                 << " bytes of target data exceeds length of target"
                    " window (" << target_window_length_ << " bytes)"
                 << LOG_ENDL;
      return RESULT_ERROR;
    }
    VCDiffResult result = RESULT_SUCCESS;
    switch (instruction) {
      case VCD_ADD:
        result = DecodeAdd(size);
        break;
      case VCD_RUN:
        result = DecodeRun(size);
        break;
      case VCD_COPY:
        result = DecodeCopy(size, mode);
        break;
      default:
        LOG(DFATAL) << "Unexpected instruction type " << instruction
                    << "in opcode stream" << LOG_ENDL;
        return RESULT_ERROR;
    }
    switch (result) {
      case RESULT_END_OF_DATA:
        reader_.UnGetInstruction();
        UpdateInstructionPointer(parseable_chunk);
        return RESULT_END_OF_DATA;
      case RESULT_ERROR:
        return RESULT_ERROR;
      case RESULT_SUCCESS:
        break;
    }
  }
  if (TargetBytesDecoded() != target_window_length_) {
    LOG(ERROR) << "Decoded target window size (" << TargetBytesDecoded()
               << " bytes) does not match expected size ("
               << target_window_length_ << " bytes)" << LOG_ENDL;
    return RESULT_ERROR;
  }
  const char* const target_window_start =
      parent_->decoded_target()->data() + target_window_start_pos_;
  if (has_checksum_ &&
      (ComputeAdler32(target_window_start, target_window_length_)
           != expected_checksum_)) {
    LOG(ERROR) << "Target data does not match checksum; this could mean "
                  "that the wrong dictionary was used" << LOG_ENDL;
    return RESULT_ERROR;
  }
  if (!instructions_and_sizes_.Empty()) {
    LOG(ERROR) << "Excess instructions and sizes left over "
                  "after decoding target window" << LOG_ENDL;
      return RESULT_ERROR;
  }
  if (!IsInterleaved()) {
    // Standard format is being used, with three separate sections for the
    // instructions, data, and addresses.
    if (!data_for_add_and_run_.Empty()) {
      LOG(ERROR) << "Excess ADD/RUN data left over "
                    "after decoding target window" << LOG_ENDL;
        return RESULT_ERROR;
    }
    if (!addresses_for_copy_.Empty()) {
      LOG(ERROR) << "Excess COPY addresses left over "
                    "after decoding target window" << LOG_ENDL;
        return RESULT_ERROR;
    }
    // Reached the end of the window.  Update the ParseableChunk to point to the
    // end of the addresses section, which is the last section in the window.
    parseable_chunk->SetPosition(addresses_for_copy_.End());
  } else {
    // Interleaved format is being used.
    UpdateInstructionPointer(parseable_chunk);
  }
  return RESULT_SUCCESS;
}

VCDiffResult VCDiffDeltaFileWindow::DecodeWindows(
    ParseableChunk* parseable_chunk) {
  if (!parent_) {
    LOG(DFATAL) << "Internal error: VCDiffDeltaFileWindow::DecodeWindows() "
                   "called before VCDiffDeltaFileWindow::Init()" << LOG_ENDL;
    return RESULT_ERROR;
  }
  while (!parseable_chunk->Empty()) {
    if (!found_header_) {
      switch (ReadHeader(parseable_chunk)) {
        case RESULT_END_OF_DATA:
          return RESULT_END_OF_DATA;
        case RESULT_ERROR:
          return RESULT_ERROR;
        default:
          // Reset address cache between windows (RFC section 5.1)
          if (!parent_->addr_cache()->Init()) {
            LOG(DFATAL) << "Error initializing address cache" << LOG_ENDL;
            return RESULT_ERROR;
          }
      }
    } else {
      // We are resuming a window that was partially decoded before a
      // RESULT_END_OF_DATA was returned.  This can only happen on the first
      // loop iteration, and only if the interleaved format is enabled and used.
      if (!IsInterleaved()) {
        LOG(DFATAL) << "Internal error: Resumed decoding of a delta file window"
                       " when interleaved format is not being used" << LOG_ENDL;
        return RESULT_ERROR;
      }
      UpdateInterleavedSectionPointers(parseable_chunk->UnparsedData(),
                                       parseable_chunk->End());
      reader_.UpdatePointers(instructions_and_sizes_.UnparsedDataAddr(),
                             instructions_and_sizes_.End());
    }
    switch (DecodeBody(parseable_chunk)) {
      case RESULT_END_OF_DATA:
        if (MoreDataExpected()) {
          return RESULT_END_OF_DATA;
        } else {
          LOG(ERROR) << "End of data reached while decoding VCDIFF delta file"
                     << LOG_ENDL;
          // fall through to RESULT_ERROR case
        }
      case RESULT_ERROR:
        return RESULT_ERROR;
      default:
        break;  // DecodeBody succeeded
    }
    // Get ready to read a new delta window
    Reset();
    if (parent_->ReachedPlannedTargetFileSize()) {
      // Found exactly the length we expected.  Stop decoding.
      return RESULT_SUCCESS;
    }
  }
  return RESULT_SUCCESS;
}

// *** Methods for VCDiffStreamingDecoder

VCDiffStreamingDecoder::VCDiffStreamingDecoder()
: impl_(new VCDiffStreamingDecoderImpl) { }

VCDiffStreamingDecoder::~VCDiffStreamingDecoder() { delete impl_; }

void VCDiffStreamingDecoder::StartDecoding(const char* source, size_t len) {
  impl_->StartDecoding(source, len);
}

bool VCDiffStreamingDecoder::DecodeChunkToInterface(
    const char* data,
    size_t len,
    OutputStringInterface* output_string) {
  return impl_->DecodeChunk(data, len, output_string);
}

bool VCDiffStreamingDecoder::FinishDecoding() {
  return impl_->FinishDecoding();
}

bool VCDiffStreamingDecoder::SetMaximumTargetFileSize(
    size_t new_maximum_target_file_size) {
  return impl_->SetMaximumTargetFileSize(new_maximum_target_file_size);
}

bool VCDiffStreamingDecoder::SetMaximumTargetWindowSize(
    size_t new_maximum_target_window_size) {
  return impl_->SetMaximumTargetWindowSize(new_maximum_target_window_size);
}

void VCDiffStreamingDecoder::SetAllowVcdTarget(bool allow_vcd_target) {
  impl_->SetAllowVcdTarget(allow_vcd_target);
}

bool VCDiffDecoder::DecodeToInterface(const char* dictionary_ptr,
                                      size_t dictionary_size,
                                      const string& encoding,
                                      OutputStringInterface* target) {
  target->clear();
  decoder_.StartDecoding(dictionary_ptr, dictionary_size);
  if (!decoder_.DecodeChunkToInterface(encoding.data(),
                                       encoding.size(),
                                       target)) {
    return false;
  }
  return decoder_.FinishDecoding();
}

}  // namespace open_vcdiff
