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