1311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Copyright 2008 Google Inc. 2311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Author: Lincoln Smith 3311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 4311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Licensed under the Apache License, Version 2.0 (the "License"); 5311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// you may not use this file except in compliance with the License. 6311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// You may obtain a copy of the License at 7311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 8311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// http://www.apache.org/licenses/LICENSE-2.0 9311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 10311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Unless required by applicable law or agreed to in writing, software 11311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// distributed under the License is distributed on an "AS IS" BASIS, 12311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// See the License for the specific language governing permissions and 14311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// limitations under the License. 15311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 16311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifndef OPEN_VCDIFF_HEADERPARSER_H_ 17311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define OPEN_VCDIFF_HEADERPARSER_H_ 18311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 19311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <config.h> 2028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#include <stddef.h> // NULL 21311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <stdint.h> // int32_t, uint32_t 22311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "checksum.h" // VCDChecksum 23311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "vcdiff_defs.h" // VCDiffResult 24311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 25311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffnamespace open_vcdiff { 26311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 27311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// This class contains a contiguous memory buffer with start and end pointers, 28311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// as well as a position pointer which shows how much of the buffer has been 29311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// parsed and how much remains. 30311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 31311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Because no virtual destructor is defined for ParseableChunk, a pointer to 32311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// a child class of ParseableChunk must be destroyed using its specific type, 33311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// rather than as a ParseableChunk*. 34311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass ParseableChunk { 35311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff public: 36311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ParseableChunk(const char* data_start, size_t data_size) { 37311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SetDataBuffer(data_start, data_size); 38311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 39311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 40311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* End() const { return end_; } 41311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 42311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The number of bytes remaining to be parsed. This is not necessarily the 43311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // same as the initial size of the buffer; it changes with each call to 44311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Advance(). 45311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t UnparsedSize() const { 46311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return end_ - position_; 47311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 48311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 49311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The number of bytes that have already been parsed. 50311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t ParsedSize() const { 51311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return position_ - start_; 52311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 53311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 54311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool Empty() const { return 0 == UnparsedSize(); } 55311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 56311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The start of the data remaining to be parsed. 57311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* UnparsedData() const { return position_; } 58311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 59311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Returns a pointer to the start of the data remaining to be parsed. 60311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char** UnparsedDataAddr() { return &position_; } 61311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 62311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Moves the parsing position forward by number_of_bytes. 63311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void Advance(size_t number_of_bytes); 64311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 65311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Jumps the parsing position to a new location. 66311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void SetPosition(const char* position); 67311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 68311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Jumps the parsing position to the end of the data chunk. 69311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void Finish() { 70311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff position_ = end_; 71311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 72311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 73311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Jumps the parsing position so that there are now number_of_bytes 74311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // bytes left to parse. This number should be smaller than the size of data 75311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // to be parsed before the function was called. 76311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void FinishExcept(size_t number_of_bytes); 77311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 78311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void SetDataBuffer(const char* data_start, size_t data_size) { 79311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff start_ = data_start; 80311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff end_ = data_start + data_size; 81311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff position_ = start_; 82311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 83311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 84311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff private: 85311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* start_; 86311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* end_; 87311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 88311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The current parsing position within the data chunk. 89311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Must always respect start_ <= position_ <= end_. 90311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* position_; 91311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 92311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Making these private avoids implicit copy constructor & assignment operator 93311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ParseableChunk(const ParseableChunk&); 94311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void operator=(const ParseableChunk&); 95311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}; 96311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 97311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Represents one of the three sections in the delta window, as described in 98311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// RFC section 4.3: 99311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// * Data section for ADDs and RUNs 100311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// * Instructions and sizes section 101311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// * Addresses section for COPYs 102311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// When using the interleaved format, data and addresses are pulled from the 103311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// instructions and sizes section rather than being stored in separate sections. 104311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// For that reason, this class allows one DeltaWindowSection to be based on 105311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// another, such that the same position pointer is shared by both sections; 106311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// i.e., UnparsedDataAddr() returns the same value for both objects. 107311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// To achieve this end, one extra level of indirection (a pointer to a 108311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// ParseableChunk object) is added. 109311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass DeltaWindowSection { 110311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff public: 111311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff DeltaWindowSection() : parseable_chunk_(NULL), owned_(true) { } 112311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 113311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ~DeltaWindowSection() { 114311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FreeChunk(); 115311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 116311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 117311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void Init(const char* data_start, size_t data_size) { 118311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (owned_ && parseable_chunk_) { 119311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Reuse the already-allocated ParseableChunk object. 120311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff parseable_chunk_->SetDataBuffer(data_start, data_size); 121311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } else { 122311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff parseable_chunk_ = new ParseableChunk(data_start, data_size); 123311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff owned_ = true; 124311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 125311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 126311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 127311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void Init(DeltaWindowSection* original) { 128311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FreeChunk(); 129311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff parseable_chunk_ = original->parseable_chunk_; 130311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff owned_ = false; 131311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 132311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 133311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void Invalidate() { FreeChunk(); } 134311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 135311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool IsOwned() const { return owned_; } 136311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 137311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The following functions just pass their arguments to the underlying 138311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // ParseableChunk object. 139311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 140311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* End() const { 141311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_->End(); 142311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 143311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 144311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t UnparsedSize() const { 145311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_->UnparsedSize(); 146311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 147311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 148311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t ParsedSize() const { 149311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_->ParsedSize(); 150311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 151311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 152311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool Empty() const { 153311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_->Empty(); 154311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 155311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 156311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* UnparsedData() const { 157311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_->UnparsedData(); 158311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 159311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 160311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char** UnparsedDataAddr() { 161311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_->UnparsedDataAddr(); 162311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 163311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 164311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void Advance(size_t number_of_bytes) { 165311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_->Advance(number_of_bytes); 166311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 167311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff private: 168311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void FreeChunk() { 169311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (owned_) { 170311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delete parseable_chunk_; 171311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 172311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff parseable_chunk_ = NULL; 173311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 174311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 175311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Will be NULL until Init() has been called. If owned_ is true, this will 176311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // point to a ParseableChunk object that has been allocated with "new" and 177311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // must be deleted by this DeltaWindowSection object. If owned_ is false, 178311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // this points at the parseable_chunk_ owned by a different DeltaWindowSection 179311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // object. In this case, it is important to free the DeltaWindowSection which 180311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // does not own the ParseableChunk before (or simultaneously to) freeing the 181311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // DeltaWindowSection that owns it, or else deleted memory may be accessed. 182311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ParseableChunk* parseable_chunk_; 183311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool owned_; 184311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 185311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Making these private avoids implicit copy constructor & assignment operator 186311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff DeltaWindowSection(const DeltaWindowSection&); 187311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void operator=(const DeltaWindowSection&); 188311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}; 189311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 190311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Used to parse the bytes and Varints that make up the delta file header 191311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// or delta window header. 192311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass VCDiffHeaderParser { 193311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff public: 194311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // header_start should be the start of the header to be parsed; 195311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // data_end is the position just after the last byte of available data 196311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // (which may extend far past the end of the header.) 197311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff VCDiffHeaderParser(const char* header_start, const char* data_end); 198311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 199311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // One of these functions should be called for each element of the header. 200311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // variable_description is a description of the value that we are attempting 201311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // to parse, and will only be used to create descriptive error messages. 202311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // If the function returns true, then the element was parsed successfully 203311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // and its value has been placed in *value. If the function returns false, 204311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // then *value is unchanged, and GetResult() can be called to return the 205311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // reason that the element could not be parsed, which will be either 206311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // RESULT_ERROR (an error occurred), or RESULT_END_OF_DATA (the limit data_end 207311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // was reached before the end of the element to be parsed.) Once one of these 208311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // functions has returned false, further calls to any of the Parse... 209311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // functions will also return false without performing any additional actions. 210311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Typical usage is as follows: 211311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // int32_t segment_length = 0; 212311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // if (!header_parser.ParseInt32("segment length", &segment_length)) { 213311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // return header_parser.GetResult(); 214311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // } 215311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 216311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The following example takes advantage of the fact that calling a Parse... 217311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // function after an error or end-of-data condition is legal and does nothing. 218311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It can thus parse more than one element in a row and check the status 219311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // afterwards. If the first call to ParseInt32() fails, the second will have 220311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // no effect: 221311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 222311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // int32_t segment_length = 0, segment_position = 0; 223311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // header_parser.ParseInt32("segment length", &segment_length)); 224311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // header_parser.ParseInt32("segment position", &segment_position)); 225311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // if (RESULT_SUCCESS != header_parser.GetResult()) { 226311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // return header_parser.GetResult(); 227311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // } 228311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 229311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseByte(unsigned char* value); 230311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseInt32(const char* variable_description, int32_t* value); 231311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseUInt32(const char* variable_description, uint32_t* value); 232311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseChecksum(const char* variable_description, VCDChecksum* value); 233311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseSize(const char* variable_description, size_t* value); 234311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 235311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Parses the first three elements of the delta window header: 236311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 237311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Win_Indicator - byte 238311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // [Source segment size] - integer (VarintBE format) 239311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // [Source segment position] - integer (VarintBE format) 240311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 241311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Returns true if the values were parsed successfully and the values were 242311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // found to be acceptable. Returns false otherwise, in which case 243311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // GetResult() can be called to return the reason that the two values 244311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // could not be validated. This will be either RESULT_ERROR (an error 245311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // occurred and was logged), or RESULT_END_OF_DATA (the limit data_end was 246311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // reached before the end of the values to be parsed.) If return value is 247311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // true, then *win_indicator, *source_segment_length, and 248311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // *source_segment_position are populated with the parsed values. Otherwise, 249311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // the values of these output arguments are undefined. 250311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 251311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // dictionary_size: The size of the dictionary (source) file. Used to 252311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // validate the limits of source_segment_length and 253311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // source_segment_position if the source segment is taken from the 254311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // dictionary (i.e., if the parsed *win_indicator equals VCD_SOURCE.) 255311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // decoded_target_size: The size of the target data that has been decoded 256311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // so far, including all target windows. Used to validate the limits of 257311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // source_segment_length and source_segment_position if the source segment 258311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // is taken from the target (i.e., if the parsed *win_indicator equals 259311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // VCD_TARGET.) 260baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff // allow_vcd_target: If this argument is false, and the parsed *win_indicator 261baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff // is VCD_TARGET, then an error is produced; if true, VCD_TARGET is 262baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff // allowed. 263311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // win_indicator (output): Points to a single unsigned char (not an array) 264311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // that will receive the parsed value of Win_Indicator. 265311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // source_segment_length (output): The parsed length of the source segment. 266311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // source_segment_position (output): The parsed zero-based index in the 267311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // source/target file from which the source segment is to be taken. 268311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseWinIndicatorAndSourceSegment(size_t dictionary_size, 269311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t decoded_target_size, 270baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff bool allow_vcd_target, 271311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff unsigned char* win_indicator, 272311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t* source_segment_length, 273311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t* source_segment_position); 274311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 275311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Parses the following two elements of the delta window header: 276311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 277311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Length of the delta encoding - integer (VarintBE format) 278311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Size of the target window - integer (VarintBE format) 279311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 280311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Return conditions and values are the same as for 281311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // ParseWinIndicatorAndSourceSegment(), above. 282311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 283311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseWindowLengths(size_t* target_window_length); 284311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 285311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // May only be called after ParseWindowLengths() has returned RESULT_SUCCESS. 286311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Returns a pointer to the end of the delta window (which might not point to 287311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // a valid memory location if there is insufficient input data.) 288311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 289311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* EndOfDeltaWindow() const; 290311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 291311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Parses the following element of the delta window header: 292311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 293311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Delta_Indicator - byte 294311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 295311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Because none of the bits in Delta_Indicator are used by this implementation 296311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // of VCDIFF, this function does not have an output argument to return the 297311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // value of that field. It may return RESULT_SUCCESS, RESULT_ERROR, or 298311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // RESULT_END_OF_DATA as with the other Parse...() functions. 299311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 300311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseDeltaIndicator(); 301311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 302311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Parses the following 3 elements of the delta window header: 303311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 304311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Length of data for ADDs and RUNs - integer (VarintBE format) 305311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Length of instructions and sizes - integer (VarintBE format) 306311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Length of addresses for COPYs - integer (VarintBE format) 307311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 308311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // If has_checksum is true, it also looks for the following element: 309311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 310311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Adler32 checksum - unsigned 32-bit integer (VarintBE format) 311311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 312311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Return conditions and values are the same as for 313311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // ParseWinIndicatorAndSourceSegment(), above. 314311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 315311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseSectionLengths(bool has_checksum, 316311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t* add_and_run_data_length, 317311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t* instructions_and_sizes_length, 318311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t* addresses_length, 319311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff VCDChecksum* checksum); 320311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 321311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // If one of the Parse... functions returned false, this function 322311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // can be used to find the result code (RESULT_ERROR or RESULT_END_OF_DATA) 323311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // describing the reason for the most recent parse failure. If none of the 324311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Parse... functions has returned false, returns RESULT_SUCCESS. 325311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff VCDiffResult GetResult() const { 326311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return return_code_; 327311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 328311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 329311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The following functions just pass their arguments to the underlying 330311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // ParseableChunk object. 331311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 332311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* End() const { 333311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_.End(); 334311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 335311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 336311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t UnparsedSize() const { 337311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_.UnparsedSize(); 338311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 339311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 340311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t ParsedSize() const { 341311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_.ParsedSize(); 342311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 343311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 344311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* UnparsedData() const { 345311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return parseable_chunk_.UnparsedData(); 346311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 347311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 348311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff private: 349311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Parses two variable-length integers representing the source segment length 350311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // and source segment position (== offset.) Checks whether the source segment 351311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // length and position would cause it to exceed the size of the source file or 352311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // target file. Returns true if the values were parsed successfully and the 353311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // values were found to be acceptable. Returns false otherwise, in which case 354311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // GetResult() can be called to return the reason that the two values could 355311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // not be validated, which will be either RESULT_ERROR (an error occurred and 356311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // was logged), or RESULT_END_OF_DATA (the limit data_end was reached before 357311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // the end of the integers to be parsed.) 358311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // from_size: The requested size of the source segment. 359311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // from_boundary_name: A NULL-terminated string naming the end of the 360311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // source or target file, used in error messages. 361311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // from_name: A NULL-terminated string naming the source or target file, 362311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // also used in error messages. 363311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // source_segment_length (output): The parsed length of the source segment. 364311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // source_segment_position (output): The parsed zero-based index in the 365311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // source/target file from which the source segment is to be taken. 366311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 367311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool ParseSourceSegmentLengthAndPosition(size_t from_size, 368311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* from_boundary_name, 369311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* from_name, 370311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t* source_segment_length, 371311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t* source_segment_position); 372311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 373311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ParseableChunk parseable_chunk_; 374311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 375311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Contains the result code of the last Parse...() operation that failed 376311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // (RESULT_ERROR or RESULT_END_OF_DATA). If no Parse...() method has been 377311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // called, or if all calls to Parse...() were successful, then this contains 378311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // RESULT_SUCCESS. 379311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff VCDiffResult return_code_; 380311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 381311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Will be zero until ParseWindowLengths() has been called. After 382311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // ParseWindowLengths() has been called successfully, this contains the 383311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // parsed length of the delta encoding. 384311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff size_t delta_encoding_length_; 385311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 386311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Will be NULL until ParseWindowLengths() has been called. After 387311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // ParseWindowLengths() has been called successfully, this points to the 388311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // beginning of the section of the current window titled "The delta encoding" 389311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // in the RFC, i.e., to the position just after the length of the delta 390311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // encoding. 391311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const char* delta_encoding_start_; 392311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 393311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Making these private avoids implicit copy constructor & assignment operator 394311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff VCDiffHeaderParser(const VCDiffHeaderParser&); 395311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void operator=(const VCDiffHeaderParser&); 396311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}; 397311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 398311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} // namespace open_vcdiff 399311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 400311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // OPEN_VCDIFF_HEADERPARSER_H_ 401