aboutsummaryrefslogtreecommitdiff
path: root/src/decodetable.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/decodetable.h')
-rw-r--r--src/decodetable.h152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/decodetable.h b/src/decodetable.h
new file mode 100644
index 0000000..f59fc15
--- /dev/null
+++ b/src/decodetable.h
@@ -0,0 +1,152 @@
+// 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_) {
+ VCD_DFATAL << "Internal error: last_instruction_start past end of "
+ "instructions_and_sizes in UnGetInstruction" << VCD_ENDL;
+ }
+ *instructions_and_sizes_ = last_instruction_start_;
+ if ((pending_second_instruction_ != kNoOpcode) &&
+ (last_pending_second_instruction_ != kNoOpcode)) {
+ VCD_DFATAL << "Internal error: two pending instructions in a row "
+ "in UnGetInstruction" << VCD_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_