Index: sdch/open_vcdiff/depot/opensource/open-vcdiff/src/headerparser.h |
=================================================================== |
--- sdch/open_vcdiff/depot/opensource/open-vcdiff/src/headerparser.h (revision 2678) |
+++ sdch/open_vcdiff/depot/opensource/open-vcdiff/src/headerparser.h (working copy) |
@@ -1,404 +0,0 @@ |
-// 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_HEADERPARSER_H_ |
-#define OPEN_VCDIFF_HEADERPARSER_H_ |
- |
-#include <config.h> |
-#include <stdint.h> // int32_t, uint32_t |
-#include <cstddef> // NULL |
-#include "checksum.h" // VCDChecksum |
-#include "vcdiff_defs.h" // VCDiffResult |
- |
-namespace open_vcdiff { |
- |
-// This class contains a contiguous memory buffer with start and end pointers, |
-// as well as a position pointer which shows how much of the buffer has been |
-// parsed and how much remains. |
-// |
-// Because no virtual destructor is defined for ParseableChunk, a pointer to |
-// a child class of ParseableChunk must be destroyed using its specific type, |
-// rather than as a ParseableChunk*. |
-class ParseableChunk { |
- public: |
- ParseableChunk(const char* data_start, size_t data_size) { |
- SetDataBuffer(data_start, data_size); |
- } |
- |
- const char* End() const { return end_; } |
- |
- // The number of bytes remaining to be parsed. This is not necessarily the |
- // same as the initial size of the buffer; it changes with each call to |
- // Advance(). |
- size_t UnparsedSize() const { |
- return end_ - position_; |
- } |
- |
- // The number of bytes that have already been parsed. |
- size_t ParsedSize() const { |
- return position_ - start_; |
- } |
- |
- bool Empty() const { return 0 == UnparsedSize(); } |
- |
- // The start of the data remaining to be parsed. |
- const char* UnparsedData() const { return position_; } |
- |
- // Returns a pointer to the start of the data remaining to be parsed. |
- const char** UnparsedDataAddr() { return &position_; } |
- |
- // Moves the parsing position forward by number_of_bytes. |
- void Advance(size_t number_of_bytes); |
- |
- // Jumps the parsing position to a new location. |
- void SetPosition(const char* position); |
- |
- // Jumps the parsing position to the end of the data chunk. |
- void Finish() { |
- position_ = end_; |
- } |
- |
- // Jumps the parsing position so that there are now number_of_bytes |
- // bytes left to parse. This number should be smaller than the size of data |
- // to be parsed before the function was called. |
- void FinishExcept(size_t number_of_bytes); |
- |
- void SetDataBuffer(const char* data_start, size_t data_size) { |
- start_ = data_start; |
- end_ = data_start + data_size; |
- position_ = start_; |
- } |
- |
- private: |
- const char* start_; |
- const char* end_; |
- |
- // The current parsing position within the data chunk. |
- // Must always respect start_ <= position_ <= end_. |
- const char* position_; |
- |
- // Making these private avoids implicit copy constructor & assignment operator |
- ParseableChunk(const ParseableChunk&); |
- void operator=(const ParseableChunk&); |
-}; |
- |
-// Represents one of the three sections in the delta window, as described in |
-// RFC section 4.3: |
-// * Data section for ADDs and RUNs |
-// * Instructions and sizes section |
-// * Addresses section for COPYs |
-// When using the interleaved format, data and addresses are pulled from the |
-// instructions and sizes section rather than being stored in separate sections. |
-// For that reason, this class allows one DeltaWindowSection to be based on |
-// another, such that the same position pointer is shared by both sections; |
-// i.e., UnparsedDataAddr() returns the same value for both objects. |
-// To achieve this end, one extra level of indirection (a pointer to a |
-// ParseableChunk object) is added. |
-class DeltaWindowSection { |
- public: |
- DeltaWindowSection() : parseable_chunk_(NULL), owned_(true) { } |
- |
- ~DeltaWindowSection() { |
- FreeChunk(); |
- } |
- |
- void Init(const char* data_start, size_t data_size) { |
- if (owned_ && parseable_chunk_) { |
- // Reuse the already-allocated ParseableChunk object. |
- parseable_chunk_->SetDataBuffer(data_start, data_size); |
- } else { |
- parseable_chunk_ = new ParseableChunk(data_start, data_size); |
- owned_ = true; |
- } |
- } |
- |
- void Init(DeltaWindowSection* original) { |
- FreeChunk(); |
- parseable_chunk_ = original->parseable_chunk_; |
- owned_ = false; |
- } |
- |
- void Invalidate() { FreeChunk(); } |
- |
- bool IsOwned() const { return owned_; } |
- |
- // The following functions just pass their arguments to the underlying |
- // ParseableChunk object. |
- |
- const char* End() const { |
- return parseable_chunk_->End(); |
- } |
- |
- size_t UnparsedSize() const { |
- return parseable_chunk_->UnparsedSize(); |
- } |
- |
- size_t ParsedSize() const { |
- return parseable_chunk_->ParsedSize(); |
- } |
- |
- bool Empty() const { |
- return parseable_chunk_->Empty(); |
- } |
- |
- const char* UnparsedData() const { |
- return parseable_chunk_->UnparsedData(); |
- } |
- |
- const char** UnparsedDataAddr() { |
- return parseable_chunk_->UnparsedDataAddr(); |
- } |
- |
- void Advance(size_t number_of_bytes) { |
- return parseable_chunk_->Advance(number_of_bytes); |
- } |
- private: |
- void FreeChunk() { |
- if (owned_) { |
- delete parseable_chunk_; |
- } |
- parseable_chunk_ = NULL; |
- } |
- |
- // Will be NULL until Init() has been called. If owned_ is true, this will |
- // point to a ParseableChunk object that has been allocated with "new" and |
- // must be deleted by this DeltaWindowSection object. If owned_ is false, |
- // this points at the parseable_chunk_ owned by a different DeltaWindowSection |
- // object. In this case, it is important to free the DeltaWindowSection which |
- // does not own the ParseableChunk before (or simultaneously to) freeing the |
- // DeltaWindowSection that owns it, or else deleted memory may be accessed. |
- ParseableChunk* parseable_chunk_; |
- bool owned_; |
- |
- // Making these private avoids implicit copy constructor & assignment operator |
- DeltaWindowSection(const DeltaWindowSection&); |
- void operator=(const DeltaWindowSection&); |
-}; |
- |
-// Used to parse the bytes and Varints that make up the delta file header |
-// or delta window header. |
-class VCDiffHeaderParser { |
- public: |
- // The maximum allowable size of a target window. This restricts the amount |
- // of memory that can be allocated by the decoder. A maliciously formulated |
- // delta file can create a target window of any arbitrary size, so the |
- // decoder needs to be sure that it can allocate this much memory using |
- // std::string::reserve(). |
- // |
- static const size_t kMaxTargetWindowSize = 1 << 26; // 64 MB |
- |
- // header_start should be the start of the header to be parsed; |
- // data_end is the position just after the last byte of available data |
- // (which may extend far past the end of the header.) |
- VCDiffHeaderParser(const char* header_start, const char* data_end); |
- |
- // One of these functions should be called for each element of the header. |
- // variable_description is a description of the value that we are attempting |
- // to parse, and will only be used to create descriptive error messages. |
- // If the function returns true, then the element was parsed successfully |
- // and its value has been placed in *value. If the function returns false, |
- // then *value is unchanged, and GetResult() can be called to return the |
- // reason that the element could not be parsed, which will be either |
- // RESULT_ERROR (an error occurred), or RESULT_END_OF_DATA (the limit data_end |
- // was reached before the end of the element to be parsed.) Once one of these |
- // functions has returned false, further calls to any of the Parse... |
- // functions will also return false without performing any additional actions. |
- // Typical usage is as follows: |
- // int32_t segment_length = 0; |
- // if (!header_parser.ParseInt32("segment length", &segment_length)) { |
- // return header_parser.GetResult(); |
- // } |
- // |
- // The following example takes advantage of the fact that calling a Parse... |
- // function after an error or end-of-data condition is legal and does nothing. |
- // It can thus parse more than one element in a row and check the status |
- // afterwards. If the first call to ParseInt32() fails, the second will have |
- // no effect: |
- // |
- // int32_t segment_length = 0, segment_position = 0; |
- // header_parser.ParseInt32("segment length", &segment_length)); |
- // header_parser.ParseInt32("segment position", &segment_position)); |
- // if (RESULT_SUCCESS != header_parser.GetResult()) { |
- // return header_parser.GetResult(); |
- // } |
- // |
- bool ParseByte(unsigned char* value); |
- bool ParseInt32(const char* variable_description, int32_t* value); |
- bool ParseUInt32(const char* variable_description, uint32_t* value); |
- bool ParseChecksum(const char* variable_description, VCDChecksum* value); |
- bool ParseSize(const char* variable_description, size_t* value); |
- |
- // Parses the first three elements of the delta window header: |
- // |
- // Win_Indicator - byte |
- // [Source segment size] - integer (VarintBE format) |
- // [Source segment position] - integer (VarintBE format) |
- // |
- // Returns true if the values were parsed successfully and the values were |
- // found to be acceptable. Returns false otherwise, in which case |
- // GetResult() can be called to return the reason that the two values |
- // could not be validated. This will be either RESULT_ERROR (an error |
- // occurred and was logged), or RESULT_END_OF_DATA (the limit data_end was |
- // reached before the end of the values to be parsed.) If return value is |
- // true, then *win_indicator, *source_segment_length, and |
- // *source_segment_position are populated with the parsed values. Otherwise, |
- // the values of these output arguments are undefined. |
- // |
- // dictionary_size: The size of the dictionary (source) file. Used to |
- // validate the limits of source_segment_length and |
- // source_segment_position if the source segment is taken from the |
- // dictionary (i.e., if the parsed *win_indicator equals VCD_SOURCE.) |
- // decoded_target_size: The size of the target data that has been decoded |
- // so far, including all target windows. Used to validate the limits of |
- // source_segment_length and source_segment_position if the source segment |
- // is taken from the target (i.e., if the parsed *win_indicator equals |
- // VCD_TARGET.) |
- // win_indicator (output): Points to a single unsigned char (not an array) |
- // that will receive the parsed value of Win_Indicator. |
- // source_segment_length (output): The parsed length of the source segment. |
- // source_segment_position (output): The parsed zero-based index in the |
- // source/target file from which the source segment is to be taken. |
- bool ParseWinIndicatorAndSourceSegment(size_t dictionary_size, |
- size_t decoded_target_size, |
- unsigned char* win_indicator, |
- size_t* source_segment_length, |
- size_t* source_segment_position); |
- |
- // Parses the following two elements of the delta window header: |
- // |
- // Length of the delta encoding - integer (VarintBE format) |
- // Size of the target window - integer (VarintBE format) |
- // |
- // Return conditions and values are the same as for |
- // ParseWinIndicatorAndSourceSegment(), above. |
- // |
- bool ParseWindowLengths(size_t* target_window_length); |
- |
- // May only be called after ParseWindowLengths() has returned RESULT_SUCCESS. |
- // Returns a pointer to the end of the delta window (which might not point to |
- // a valid memory location if there is insufficient input data.) |
- // |
- const char* EndOfDeltaWindow() const; |
- |
- // Parses the following element of the delta window header: |
- // |
- // Delta_Indicator - byte |
- // |
- // Because none of the bits in Delta_Indicator are used by this implementation |
- // of VCDIFF, this function does not have an output argument to return the |
- // value of that field. It may return RESULT_SUCCESS, RESULT_ERROR, or |
- // RESULT_END_OF_DATA as with the other Parse...() functions. |
- // |
- bool ParseDeltaIndicator(); |
- |
- // Parses the following 3 elements of the delta window header: |
- // |
- // 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) |
- // |
- // Return conditions and values are the same as for |
- // ParseWinIndicatorAndSourceSegment(), above. |
- // |
- bool ParseSectionLengths(bool has_checksum, |
- size_t* add_and_run_data_length, |
- size_t* instructions_and_sizes_length, |
- size_t* addresses_length, |
- VCDChecksum* checksum); |
- |
- // If one of the Parse... functions returned false, this function |
- // can be used to find the result code (RESULT_ERROR or RESULT_END_OF_DATA) |
- // describing the reason for the most recent parse failure. If none of the |
- // Parse... functions has returned false, returns RESULT_SUCCESS. |
- VCDiffResult GetResult() const { |
- return return_code_; |
- } |
- |
- // The following functions just pass their arguments to the underlying |
- // ParseableChunk object. |
- |
- const char* End() const { |
- return parseable_chunk_.End(); |
- } |
- |
- size_t UnparsedSize() const { |
- return parseable_chunk_.UnparsedSize(); |
- } |
- |
- size_t ParsedSize() const { |
- return parseable_chunk_.ParsedSize(); |
- } |
- |
- const char* UnparsedData() const { |
- return parseable_chunk_.UnparsedData(); |
- } |
- |
- private: |
- // Parses two variable-length integers representing the source segment length |
- // and source segment position (== offset.) Checks whether the source segment |
- // length and position would cause it to exceed the size of the source file or |
- // target file. Returns true if the values were parsed successfully and the |
- // values were found to be acceptable. Returns false otherwise, in which case |
- // GetResult() can be called to return the reason that the two values could |
- // not be validated, which will be either RESULT_ERROR (an error occurred and |
- // was logged), or RESULT_END_OF_DATA (the limit data_end was reached before |
- // the end of the integers to be parsed.) |
- // from_size: The requested size of the source segment. |
- // from_boundary_name: A NULL-terminated string naming the end of the |
- // source or target file, used in error messages. |
- // from_name: A NULL-terminated string naming the source or target file, |
- // also used in error messages. |
- // source_segment_length (output): The parsed length of the source segment. |
- // source_segment_position (output): The parsed zero-based index in the |
- // source/target file from which the source segment is to be taken. |
- // |
- bool ParseSourceSegmentLengthAndPosition(size_t from_size, |
- const char* from_boundary_name, |
- const char* from_name, |
- size_t* source_segment_length, |
- size_t* source_segment_position); |
- |
- ParseableChunk parseable_chunk_; |
- |
- // Contains the result code of the last Parse...() operation that failed |
- // (RESULT_ERROR or RESULT_END_OF_DATA). If no Parse...() method has been |
- // called, or if all calls to Parse...() were successful, then this contains |
- // RESULT_SUCCESS. |
- VCDiffResult return_code_; |
- |
- // Will be zero until ParseWindowLengths() has been called. After |
- // ParseWindowLengths() has been called successfully, this contains the |
- // parsed length of the delta encoding. |
- size_t delta_encoding_length_; |
- |
- // Will be NULL until ParseWindowLengths() has been called. After |
- // ParseWindowLengths() has been called successfully, this points to the |
- // beginning of the section of the current window titled "The delta encoding" |
- // in the RFC, i.e., to the position just after the length of the delta |
- // encoding. |
- const char* delta_encoding_start_; |
- |
- // Making these private avoids implicit copy constructor & assignment operator |
- VCDiffHeaderParser(const VCDiffHeaderParser&); |
- void operator=(const VCDiffHeaderParser&); |
-}; |
- |
-} // namespace open_vcdiff |
- |
-#endif // OPEN_VCDIFF_HEADERPARSER_H_ |