1cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler/*
2cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler * Copyright (C) 2016 The Android Open Source Project
3cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler *
4cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler * Licensed under the Apache License, Version 2.0 (the "License");
5cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler * you may not use this file except in compliance with the License.
6cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler * You may obtain a copy of the License at
7cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler *
8cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler *      http://www.apache.org/licenses/LICENSE-2.0
9cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler *
10cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler * Unless required by applicable law or agreed to in writing, software
11cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler * distributed under the License is distributed on an "AS IS" BASIS,
12cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler * See the License for the specific language governing permissions and
14cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler * limitations under the License.
15cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler */
16cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
17a715cb1840f9a0c813c90707a351687f7a77950eMattias Nissler#include <nvram/messages/io.h>
18cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
19cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerextern "C" {
20cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler#include <string.h>
21cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
22cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
23a715cb1840f9a0c813c90707a351687f7a77950eMattias Nissler#include <nvram/messages/compiler.h>
24cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
25cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslernamespace nvram {
26cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslernamespace {
27cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
28cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslertemplate <typename T>
29cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerT min(T x, T y) {
30cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return x < y ? x : y;
31cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
32cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
33cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslertemplate <typename T>
34cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerT max(T x, T y) {
35cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return x > y ? x : y;
36cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
37cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
38cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// Encodes |value| in varint format and writes the result to |stream|.
39cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool EncodeVarint(OutputStreamBuffer* stream, uint64_t value) {
40cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  do {
41cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    uint8_t byte = (value & 0x7f) | (((value >> 7) == 0) ? 0x00 : 0x80);
42cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    if (!stream->WriteByte(byte)) {
43cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      return false;
44cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    }
45cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    value >>= 7;
46cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  } while (value != 0);
47cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
48cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
49cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
50cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// Read a varint-encoded number from stream, decode it and store the result in
51cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// |value|.
52cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool DecodeVarint(InputStreamBuffer* stream_buffer, uint64_t* value) {
53cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  // Maximum number of bytes required to encode an |uint64_t| as varint. Each
54cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  // byte in a varint has 7 payload bytes, so encoding 64 bits yields at most 10
55cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  // bytes.
56cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  static constexpr int kMaxVarintBytes = 10;
57cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
58cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  *value = 0;
59cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  for (int i = 0; i < kMaxVarintBytes; ++i) {
60cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    uint8_t byte = 0;
61cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    if (!stream_buffer->ReadByte(&byte)) {
62cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      return false;
63cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    }
64cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    *value |= static_cast<uint64_t>(byte & 0x7f) << (i * 7);
65cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    if ((byte & 0x80) == 0) {
66cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      return true;
67cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    }
68cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
69cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return false;
70cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
71cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
72cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}  // namespace
73cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
74cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerInputStreamBuffer::InputStreamBuffer(const void* data, size_t size)
75cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    : InputStreamBuffer(data, static_cast<const uint8_t*>(data) + size) {}
76cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
77cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerInputStreamBuffer::InputStreamBuffer(const void* start, const void* end)
78cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    : pos_(static_cast<const uint8_t*>(start)),
79cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      end_(static_cast<const uint8_t*>(end)) {
80cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  NVRAM_CHECK(pos_ <= end_);
81cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
82cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
83cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool InputStreamBuffer::Done() {
84cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return pos_ >= end_ && !Advance();
85cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
86cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
87cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool InputStreamBuffer::Read(void* data, size_t size) {
88cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  uint8_t* buffer = static_cast<uint8_t*>(data);
89cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  NVRAM_CHECK(pos_ <= end_);
90cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  while (size > static_cast<size_t>(end_ - pos_)) {
91cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    memcpy(buffer, pos_, end_ - pos_);
92cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    buffer += end_ - pos_;
93cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    size -= end_ - pos_;
94cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    pos_ = end_;
95cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    if (!Advance()) {
96cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      return false;
97cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    }
98cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    NVRAM_CHECK(pos_ < end_);
99cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
100cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  memcpy(buffer, pos_, size);
101cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  pos_ += size;
102cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
103cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
104cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
105cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool InputStreamBuffer::ReadByte(uint8_t* byte) {
106cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  if (pos_ >= end_) {
107cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    if (!Advance()) {
108cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      return false;
109cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    }
110cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    NVRAM_CHECK(pos_ < end_);
111cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
112cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  *byte = *pos_;
113cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  ++pos_;
114cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
115cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
116cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
117cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool InputStreamBuffer::Skip(size_t size) {
118cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  NVRAM_CHECK(pos_ <= end_);
119cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  while (size > static_cast<size_t>(end_ - pos_)) {
120cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    size -= end_ - pos_;
121cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    pos_ = end_;
122cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    if (!Advance()) {
123cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      return false;
124cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    }
125cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    NVRAM_CHECK(pos_ < end_);
126cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
127cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  pos_ += size;
128cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
129cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
130cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
131cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool InputStreamBuffer::Advance() {
132cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return false;
133cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
134cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
135cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerNestedInputStreamBuffer::NestedInputStreamBuffer(InputStreamBuffer* delegate,
136cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler                                                 size_t size)
13742455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler    : InputStreamBuffer(delegate->pos_, ClampEnd(delegate, size)),
138cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      delegate_(delegate),
139cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      remaining_(size) {}
140cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
141cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool NestedInputStreamBuffer::Advance() {
142cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  remaining_ -= end_ - delegate_->pos_;
143cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  if (remaining_ == 0) {
144cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    delegate_->pos_ = end_;
145cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    return false;
146cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
147cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  bool status = delegate_->Advance();
148cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  pos_ = delegate_->pos_;
14942455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler  end_ = ClampEnd(delegate_, remaining_);
150cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return status;
151cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
152cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
15342455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler// static
15442455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nisslerconst uint8_t* NestedInputStreamBuffer::ClampEnd(InputStreamBuffer* delegate,
15542455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler                                                 size_t size) {
15642455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler  NVRAM_CHECK(delegate->pos_ <= delegate->end_);
15742455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler  return size < static_cast<size_t>(delegate->end_ - delegate->pos_)
15842455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler             ? delegate->pos_ + size
15942455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler             : delegate->end_;
16042455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler}
16142455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler
162cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerOutputStreamBuffer::OutputStreamBuffer(void* data, size_t size)
163cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    : OutputStreamBuffer(data, static_cast<uint8_t*>(data) + size) {}
164cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
165cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerOutputStreamBuffer::OutputStreamBuffer(void* start, void* end)
166cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    : pos_(static_cast<uint8_t*>(start)), end_(static_cast<uint8_t*>(end)) {
167cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  NVRAM_CHECK(pos_ <= end_);
168cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
169cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
170cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool OutputStreamBuffer::Done() {
171cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return pos_ >= end_ && !Advance();
172cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
173cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
174cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool OutputStreamBuffer::Write(const void* data, size_t size) {
175cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  const uint8_t* buffer = static_cast<const uint8_t*>(data);
176cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  NVRAM_CHECK(pos_ <= end_);
177cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  while (size > static_cast<size_t>(end_ - pos_)) {
178cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    memcpy(pos_, buffer, end_ - pos_);
179cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    buffer += end_ - pos_;
180cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    size -= end_ - pos_;
181cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    pos_ = end_;
182cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    if (!Advance()) {
183cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      return false;
184cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    }
185cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    NVRAM_CHECK(pos_ < end_);
186cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
187cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  memcpy(pos_, buffer, size);
188cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  pos_ += size;
189cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
190cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
191cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
192cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool OutputStreamBuffer::WriteByte(uint8_t byte) {
193cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  if (pos_ >= end_) {
194cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    if (!Advance()) {
195cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      return false;
196cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    }
197cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    NVRAM_CHECK(pos_ < end_);
198cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
199cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  *pos_ = byte;
200cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  ++pos_;
201cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
202cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
203cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
204cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool OutputStreamBuffer::Advance() {
205cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return false;
206cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
207cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
208cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerCountingOutputStreamBuffer::CountingOutputStreamBuffer()
209cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    : OutputStreamBuffer(scratch_space_, kScratchSpaceSize) {}
210cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
211cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool CountingOutputStreamBuffer::Advance() {
212cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  bytes_written_ += pos_ - scratch_space_;
213cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  pos_ = scratch_space_;
214cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  end_ = scratch_space_ + kScratchSpaceSize;
215cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
216cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
217cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
218cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissleruint8_t CountingOutputStreamBuffer::scratch_space_[kScratchSpaceSize];
219cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
220cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerBlobOutputStreamBuffer::BlobOutputStreamBuffer(Blob* blob)
221cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    : OutputStreamBuffer(blob->data(), blob->size()), blob_(blob) {}
222cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
223cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool BlobOutputStreamBuffer::Advance() {
224cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  ptrdiff_t offset = pos_ - blob_->data();
225cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  if (!blob_->Resize(max<size_t>(blob_->size() * 2, 32))) {
226cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    return false;
227cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
228cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  pos_ = blob_->data() + offset;
229cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  end_ = blob_->data() + blob_->size();
230cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
231cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
232cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
233cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool BlobOutputStreamBuffer::Truncate() {
23442455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler  if (!blob_->Resize(pos_ - blob_->data())) {
23542455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler    return false;
23642455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler  }
23742455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler  end_ = blob_->data() + blob_->size();
23842455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler  pos_ = end_;
23942455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler  return true;
240cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
241cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
242cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerProtoReader::ProtoReader(InputStreamBuffer* stream_buffer)
243cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    : stream_buffer_(stream_buffer) {}
244cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
245cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool ProtoReader::ReadWireTag() {
246cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  uint64_t wire_tag;
247cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  if (!DecodeVarint(stream_buffer_, &wire_tag)) {
248cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    return false;
249cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
250cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
251cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  wire_type_ = wire_tag & 0x7;
252cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  field_number_ = wire_tag >> 3;
253cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  switch (wire_type()) {
254cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    case WireType::kLengthDelimited: {
255cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      uint64_t size;
256cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      if (!DecodeVarint(stream_buffer_, &size)) {
257cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler        return false;
258cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      }
259cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      field_size_ = static_cast<size_t>(size);
260cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      if (static_cast<uint64_t>(field_size_) != size) {
261cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler        return false;
262cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      }
263cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      break;
264cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    }
265cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    case WireType::kFixed64:
266cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      field_size_ = sizeof(uint64_t);
267cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      break;
268cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    case WireType::kFixed32:
269cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      field_size_ = sizeof(uint32_t);
270cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      break;
271cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    case WireType::kVarint:
272cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    case WireType::kStartGroup:
273cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    case WireType::kEndGroup:
274cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      field_size_ = 0;
275cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler      break;
276cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
277cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
278cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
279cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
280cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
281cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool ProtoReader::ReadVarint(uint64_t* value) {
282cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  NVRAM_CHECK(wire_type() == WireType::kVarint);
283cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return DecodeVarint(stream_buffer_, value);
284cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
285cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
286cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool ProtoReader::ReadLengthDelimited(void* data, size_t size) {
287cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  NVRAM_CHECK(wire_type() == WireType::kLengthDelimited);
288cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return stream_buffer_->Read(data, size);
289cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
290cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
291cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool ProtoReader::SkipField() {
292cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  if (wire_type() == WireType::kVarint) {
293cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    uint64_t dummy;
294cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    return DecodeVarint(stream_buffer_, &dummy);
295cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  } else if (field_size_ > 0) {
296cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    return stream_buffer_->Skip(field_size_);
297cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  }
298cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
299cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return true;
300cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
301cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
302cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias NisslerProtoWriter::ProtoWriter(OutputStreamBuffer* stream_buffer)
303cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler    : stream_buffer_(stream_buffer) {}
304cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
305cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool ProtoWriter::WriteVarint(uint64_t value) {
306cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return WriteWireTag(WireType::kVarint) &&
307cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler         EncodeVarint(stream_buffer_, value);
308cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
309cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
310cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool ProtoWriter::WriteLengthDelimited(const void* data, size_t size) {
311cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return WriteWireTag(WireType::kLengthDelimited) &&
312cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler         EncodeVarint(stream_buffer_, size) &&
313cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler         stream_buffer_->Write(data, size);
314cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
315cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
316cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool ProtoWriter::WriteLengthHeader(size_t size) {
317cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return WriteWireTag(WireType::kLengthDelimited) &&
318cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler         EncodeVarint(stream_buffer_, size);
319cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
320cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
321cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerbool ProtoWriter::WriteWireTag(WireType wire_type) {
322cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler  return EncodeVarint(stream_buffer_,
323cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler                      (field_number_ << 3) | static_cast<uint64_t>(wire_type));
324cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}
325cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler
326cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}  // namespace nvram
327