// 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.

#ifndef OPEN_VCDIFF_DECODETABLE_H_
#define OPEN_VCDIFF_DECODETABLE_H_

#include <config.h>
#include <stddef.h>     // NULL
#include <stdint.h>     // int32_t
#include <memory>       // auto_ptr
#include "codetable.h"  // VCDiffInstructi...
#include "logging.h"

namespace open_vcdiff {

// This class is used by the decoder.  It can use a standard or
// non-standard code table, and will translate the opcodes in the code table
// into delta instructions.
//
// NOT threadsafe.
//
class VCDiffCodeTableReader {
 public:
  // When constructed, the object will be set up to use the default code table.
  // If a non-default code table is to be used, then UseCodeTable()
  // should be called after the VCDiffCodeTableReader has been constructed.
  // In any case, the Init() method must be called before GetNextInstruction()
  // may be used.
  //
  VCDiffCodeTableReader();

  // Sets up a non-standard code table.  The caller
  // may free the memory occupied by the argument code table after
  // passing it to this method, because the argument code table
  // allocates space to store a copy of it.
  // UseCodeTable() may be called either before or after calling Init().
  // Returns true if the code table was accepted, or false if the
  // argument did not appear to be a valid code table.
  //
  bool UseCodeTable(const VCDiffCodeTableData& code_table_data,
                    unsigned char max_mode);

  // Defines the buffer containing the instructions and sizes.
  // This method must be called before GetNextInstruction() may be used.
  // Init() may be called any number of times to reset the state of
  // the object.
  //
  void Init(const char** instructions_and_sizes,
            const char* instructions_and_sizes_end) {
    instructions_and_sizes_ = instructions_and_sizes;
    instructions_and_sizes_end_ = instructions_and_sizes_end;
    last_instruction_start_ = NULL;
    pending_second_instruction_ = kNoOpcode;
    last_pending_second_instruction_ = kNoOpcode;
  }

  // Updates the pointers to the buffer containing the instructions and sizes,
  // but leaves the rest of the reader state intact, so that (for example)
  // any pending second instruction or unread instruction will still be
  // read when requested.  NOTE: UnGetInstruction() will not work immediately
  // after using UpdatePointers(); GetNextInstruction() must be called first.
  //
  void UpdatePointers(const char** instructions_and_sizes,
                      const char* instructions_and_sizes_end) {
    instructions_and_sizes_ = instructions_and_sizes;
    instructions_and_sizes_end_ = instructions_and_sizes_end;
    last_instruction_start_ = *instructions_and_sizes;
    // pending_second_instruction_ is unchanged
    last_pending_second_instruction_ = pending_second_instruction_;
  }

  // Returns the next instruction from the stream of opcodes,
  // or VCD_INSTRUCTION_END_OF_DATA if the end of the opcode stream is reached,
  // or VCD_INSTRUCTION_ERROR if an error occurred.
  // In the first of these cases, increments *instructions_and_sizes_
  // past the values it reads, and populates *size
  // with the corresponding size for the returned instruction;
  // otherwise, the value of *size is undefined, and is not
  // guaranteed to be preserved.
  // If the instruction returned is VCD_COPY, *mode will
  // be populated with the copy mode; otherwise, the value of *mode
  // is undefined, and is not guaranteed to be preserved.
  // Any occurrences of VCD_NOOP in the opcode stream
  // are skipped over and ignored, not returned.
  // If Init() was not called before calling this method, then
  // VCD_INSTRUCTION_ERROR will be returned.
  //
  VCDiffInstructionType GetNextInstruction(int32_t* size, unsigned char* mode);

  // Puts a single instruction back onto the front of the
  // instruction stream.  The next call to GetNextInstruction()
  // will return the same value that was returned by the last
  // call.  Calling UnGetInstruction() more than once before calling
  // GetNextInstruction() will have no additional effect; you can
  // only rewind one instruction.
  //
  void UnGetInstruction() {
    if (last_instruction_start_) {
      if (last_instruction_start_ > *instructions_and_sizes_) {
        LOG(DFATAL) << "Internal error: last_instruction_start past end of "
                       "instructions_and_sizes in UnGetInstruction" << LOG_ENDL;
      }
      *instructions_and_sizes_ = last_instruction_start_;
      if ((pending_second_instruction_ != kNoOpcode) &&
          (last_pending_second_instruction_ != kNoOpcode)) {
        LOG(DFATAL) << "Internal error: two pending instructions in a row "
                       "in UnGetInstruction" << LOG_ENDL;
      }
      pending_second_instruction_ = last_pending_second_instruction_;
    }
  }

 private:
  // A pointer to the code table.  This is the object that will be used
  // to interpret opcodes in GetNextInstruction().
  const VCDiffCodeTableData* code_table_data_;

  // If the default code table is not being used, then space for the
  // code table data will be allocated using this pointer and freed
  // when the VCDiffCodeTableReader is destroyed.  This will keep the
  // code that uses the object from having to worry about memory
  // management for the non-standard code table, whose contents have
  // been read as part of the encoded data file/stream.
  //
  std::auto_ptr<VCDiffCodeTableData> non_default_code_table_data_;

  const char** instructions_and_sizes_;
  const char* instructions_and_sizes_end_;
  const char* last_instruction_start_;
  OpcodeOrNone pending_second_instruction_;
  OpcodeOrNone last_pending_second_instruction_;

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

};  // namespace open_vcdiff

#endif  // OPEN_VCDIFF_DECODETABLE_H_
