1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright 2008 Google Inc. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Author: Lincoln Smith 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Licensed under the Apache License, Version 2.0 (the "License"); 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// you may not use this file except in compliance with the License. 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// You may obtain a copy of the License at 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// http://www.apache.org/licenses/LICENSE-2.0 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Unless required by applicable law or agreed to in writing, software 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// distributed under the License is distributed on an "AS IS" BASIS, 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// See the License for the specific language governing permissions and 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// limitations under the License. 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef OPEN_VCDIFF_HEADERPARSER_H_ 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define OPEN_VCDIFF_HEADERPARSER_H_ 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <config.h> 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stddef.h> // NULL 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdint.h> // int32_t, uint32_t 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "checksum.h" // VCDChecksum 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "vcdiff_defs.h" // VCDiffResult 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace open_vcdiff { 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class contains a contiguous memory buffer with start and end pointers, 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// as well as a position pointer which shows how much of the buffer has been 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// parsed and how much remains. 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Because no virtual destructor is defined for ParseableChunk, a pointer to 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// a child class of ParseableChunk must be destroyed using its specific type, 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// rather than as a ParseableChunk*. 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ParseableChunk { 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ParseableChunk(const char* data_start, size_t data_size) { 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetDataBuffer(data_start, data_size); 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* End() const { return end_; } 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The number of bytes remaining to be parsed. This is not necessarily the 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // same as the initial size of the buffer; it changes with each call to 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Advance(). 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t UnparsedSize() const { 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return end_ - position_; 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The number of bytes that have already been parsed. 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t ParsedSize() const { 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return position_ - start_; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool Empty() const { return 0 == UnparsedSize(); } 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The start of the data remaining to be parsed. 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* UnparsedData() const { return position_; } 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns a pointer to the start of the data remaining to be parsed. 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char** UnparsedDataAddr() { return &position_; } 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Moves the parsing position forward by number_of_bytes. 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Advance(size_t number_of_bytes); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Jumps the parsing position to a new location. 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SetPosition(const char* position); 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Jumps the parsing position to the end of the data chunk. 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Finish() { 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott position_ = end_; 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Jumps the parsing position so that there are now number_of_bytes 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // bytes left to parse. This number should be smaller than the size of data 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to be parsed before the function was called. 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void FinishExcept(size_t number_of_bytes); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SetDataBuffer(const char* data_start, size_t data_size) { 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott start_ = data_start; 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott end_ = data_start + data_size; 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott position_ = start_; 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* start_; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* end_; 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The current parsing position within the data chunk. 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Must always respect start_ <= position_ <= end_. 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* position_; 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Making these private avoids implicit copy constructor & assignment operator 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ParseableChunk(const ParseableChunk&); 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void operator=(const ParseableChunk&); 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Represents one of the three sections in the delta window, as described in 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RFC section 4.3: 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// * Data section for ADDs and RUNs 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// * Instructions and sizes section 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// * Addresses section for COPYs 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// When using the interleaved format, data and addresses are pulled from the 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// instructions and sizes section rather than being stored in separate sections. 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// For that reason, this class allows one DeltaWindowSection to be based on 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// another, such that the same position pointer is shared by both sections; 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// i.e., UnparsedDataAddr() returns the same value for both objects. 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// To achieve this end, one extra level of indirection (a pointer to a 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ParseableChunk object) is added. 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass DeltaWindowSection { 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DeltaWindowSection() : parseable_chunk_(NULL), owned_(true) { } 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~DeltaWindowSection() { 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FreeChunk(); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Init(const char* data_start, size_t data_size) { 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (owned_ && parseable_chunk_) { 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Reuse the already-allocated ParseableChunk object. 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parseable_chunk_->SetDataBuffer(data_start, data_size); 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parseable_chunk_ = new ParseableChunk(data_start, data_size); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott owned_ = true; 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Init(DeltaWindowSection* original) { 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FreeChunk(); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parseable_chunk_ = original->parseable_chunk_; 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott owned_ = false; 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Invalidate() { FreeChunk(); } 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsOwned() const { return owned_; } 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The following functions just pass their arguments to the underlying 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ParseableChunk object. 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* End() const { 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_->End(); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t UnparsedSize() const { 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_->UnparsedSize(); 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t ParsedSize() const { 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_->ParsedSize(); 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool Empty() const { 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_->Empty(); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* UnparsedData() const { 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_->UnparsedData(); 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char** UnparsedDataAddr() { 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_->UnparsedDataAddr(); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Advance(size_t number_of_bytes) { 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_->Advance(number_of_bytes); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void FreeChunk() { 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (owned_) { 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete parseable_chunk_; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parseable_chunk_ = NULL; 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Will be NULL until Init() has been called. If owned_ is true, this will 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // point to a ParseableChunk object that has been allocated with "new" and 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // must be deleted by this DeltaWindowSection object. If owned_ is false, 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this points at the parseable_chunk_ owned by a different DeltaWindowSection 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // object. In this case, it is important to free the DeltaWindowSection which 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // does not own the ParseableChunk before (or simultaneously to) freeing the 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // DeltaWindowSection that owns it, or else deleted memory may be accessed. 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ParseableChunk* parseable_chunk_; 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool owned_; 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Making these private avoids implicit copy constructor & assignment operator 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DeltaWindowSection(const DeltaWindowSection&); 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void operator=(const DeltaWindowSection&); 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Used to parse the bytes and Varints that make up the delta file header 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// or delta window header. 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass VCDiffHeaderParser { 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // header_start should be the start of the header to be parsed; 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // data_end is the position just after the last byte of available data 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (which may extend far past the end of the header.) 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott VCDiffHeaderParser(const char* header_start, const char* data_end); 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // One of these functions should be called for each element of the header. 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // variable_description is a description of the value that we are attempting 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to parse, and will only be used to create descriptive error messages. 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the function returns true, then the element was parsed successfully 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and its value has been placed in *value. If the function returns false, 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // then *value is unchanged, and GetResult() can be called to return the 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // reason that the element could not be parsed, which will be either 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // RESULT_ERROR (an error occurred), or RESULT_END_OF_DATA (the limit data_end 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // was reached before the end of the element to be parsed.) Once one of these 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // functions has returned false, further calls to any of the Parse... 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // functions will also return false without performing any additional actions. 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Typical usage is as follows: 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // int32_t segment_length = 0; 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // if (!header_parser.ParseInt32("segment length", &segment_length)) { 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // return header_parser.GetResult(); 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // } 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The following example takes advantage of the fact that calling a Parse... 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // function after an error or end-of-data condition is legal and does nothing. 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // It can thus parse more than one element in a row and check the status 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // afterwards. If the first call to ParseInt32() fails, the second will have 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no effect: 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // int32_t segment_length = 0, segment_position = 0; 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // header_parser.ParseInt32("segment length", &segment_length)); 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // header_parser.ParseInt32("segment position", &segment_position)); 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // if (RESULT_SUCCESS != header_parser.GetResult()) { 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // return header_parser.GetResult(); 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // } 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseByte(unsigned char* value); 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseInt32(const char* variable_description, int32_t* value); 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseUInt32(const char* variable_description, uint32_t* value); 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseChecksum(const char* variable_description, VCDChecksum* value); 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseSize(const char* variable_description, size_t* value); 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Parses the first three elements of the delta window header: 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Win_Indicator - byte 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // [Source segment size] - integer (VarintBE format) 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // [Source segment position] - integer (VarintBE format) 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the values were parsed successfully and the values were 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // found to be acceptable. Returns false otherwise, in which case 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // GetResult() can be called to return the reason that the two values 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // could not be validated. This will be either RESULT_ERROR (an error 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // occurred and was logged), or RESULT_END_OF_DATA (the limit data_end was 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // reached before the end of the values to be parsed.) If return value is 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // true, then *win_indicator, *source_segment_length, and 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // *source_segment_position are populated with the parsed values. Otherwise, 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the values of these output arguments are undefined. 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // dictionary_size: The size of the dictionary (source) file. Used to 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // validate the limits of source_segment_length and 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // source_segment_position if the source segment is taken from the 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // dictionary (i.e., if the parsed *win_indicator equals VCD_SOURCE.) 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // decoded_target_size: The size of the target data that has been decoded 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // so far, including all target windows. Used to validate the limits of 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // source_segment_length and source_segment_position if the source segment 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // is taken from the target (i.e., if the parsed *win_indicator equals 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // VCD_TARGET.) 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // allow_vcd_target: If this argument is false, and the parsed *win_indicator 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // is VCD_TARGET, then an error is produced; if true, VCD_TARGET is 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // allowed. 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // win_indicator (output): Points to a single unsigned char (not an array) 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // that will receive the parsed value of Win_Indicator. 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // source_segment_length (output): The parsed length of the source segment. 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // source_segment_position (output): The parsed zero-based index in the 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // source/target file from which the source segment is to be taken. 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseWinIndicatorAndSourceSegment(size_t dictionary_size, 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t decoded_target_size, 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool allow_vcd_target, 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char* win_indicator, 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t* source_segment_length, 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t* source_segment_position); 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Parses the following two elements of the delta window header: 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Length of the delta encoding - integer (VarintBE format) 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Size of the target window - integer (VarintBE format) 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Return conditions and values are the same as for 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ParseWinIndicatorAndSourceSegment(), above. 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseWindowLengths(size_t* target_window_length); 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // May only be called after ParseWindowLengths() has returned RESULT_SUCCESS. 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns a pointer to the end of the delta window (which might not point to 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a valid memory location if there is insufficient input data.) 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* EndOfDeltaWindow() const; 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Parses the following element of the delta window header: 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Delta_Indicator - byte 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Because none of the bits in Delta_Indicator are used by this implementation 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of VCDIFF, this function does not have an output argument to return the 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // value of that field. It may return RESULT_SUCCESS, RESULT_ERROR, or 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // RESULT_END_OF_DATA as with the other Parse...() functions. 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseDeltaIndicator(); 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Parses the following 3 elements of the delta window header: 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Length of data for ADDs and RUNs - integer (VarintBE format) 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Length of instructions and sizes - integer (VarintBE format) 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Length of addresses for COPYs - integer (VarintBE format) 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If has_checksum is true, it also looks for the following element: 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adler32 checksum - unsigned 32-bit integer (VarintBE format) 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Return conditions and values are the same as for 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ParseWinIndicatorAndSourceSegment(), above. 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseSectionLengths(bool has_checksum, 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t* add_and_run_data_length, 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t* instructions_and_sizes_length, 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t* addresses_length, 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott VCDChecksum* checksum); 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If one of the Parse... functions returned false, this function 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // can be used to find the result code (RESULT_ERROR or RESULT_END_OF_DATA) 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // describing the reason for the most recent parse failure. If none of the 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Parse... functions has returned false, returns RESULT_SUCCESS. 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott VCDiffResult GetResult() const { 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return return_code_; 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The following functions just pass their arguments to the underlying 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ParseableChunk object. 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* End() const { 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_.End(); 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t UnparsedSize() const { 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_.UnparsedSize(); 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t ParsedSize() const { 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_.ParsedSize(); 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* UnparsedData() const { 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parseable_chunk_.UnparsedData(); 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Parses two variable-length integers representing the source segment length 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and source segment position (== offset.) Checks whether the source segment 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // length and position would cause it to exceed the size of the source file or 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // target file. Returns true if the values were parsed successfully and the 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // values were found to be acceptable. Returns false otherwise, in which case 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // GetResult() can be called to return the reason that the two values could 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // not be validated, which will be either RESULT_ERROR (an error occurred and 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // was logged), or RESULT_END_OF_DATA (the limit data_end was reached before 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the end of the integers to be parsed.) 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // from_size: The requested size of the source segment. 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // from_boundary_name: A NULL-terminated string naming the end of the 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // source or target file, used in error messages. 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // from_name: A NULL-terminated string naming the source or target file, 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // also used in error messages. 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // source_segment_length (output): The parsed length of the source segment. 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // source_segment_position (output): The parsed zero-based index in the 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // source/target file from which the source segment is to be taken. 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ParseSourceSegmentLengthAndPosition(size_t from_size, 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* from_boundary_name, 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* from_name, 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t* source_segment_length, 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t* source_segment_position); 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ParseableChunk parseable_chunk_; 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Contains the result code of the last Parse...() operation that failed 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (RESULT_ERROR or RESULT_END_OF_DATA). If no Parse...() method has been 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // called, or if all calls to Parse...() were successful, then this contains 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // RESULT_SUCCESS. 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott VCDiffResult return_code_; 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Will be zero until ParseWindowLengths() has been called. After 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ParseWindowLengths() has been called successfully, this contains the 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // parsed length of the delta encoding. 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t delta_encoding_length_; 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Will be NULL until ParseWindowLengths() has been called. After 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ParseWindowLengths() has been called successfully, this points to the 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // beginning of the section of the current window titled "The delta encoding" 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in the RFC, i.e., to the position just after the length of the delta 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // encoding. 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* delta_encoding_start_; 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Making these private avoids implicit copy constructor & assignment operator 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott VCDiffHeaderParser(const VCDiffHeaderParser&); 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void operator=(const VCDiffHeaderParser&); 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace open_vcdiff 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // OPEN_VCDIFF_HEADERPARSER_H_ 401