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#ifndef NVRAM_MESSAGES_IO_H_ 18a715cb1840f9a0c813c90707a351687f7a77950eMattias Nissler#define NVRAM_MESSAGES_IO_H_ 19cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 20cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerextern "C" { 21cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler#include <stddef.h> 22cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler#include <stdint.h> 23cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler} 24cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 25a715cb1840f9a0c813c90707a351687f7a77950eMattias Nissler#include <nvram/messages/blob.h> 26a715cb1840f9a0c813c90707a351687f7a77950eMattias Nissler#include <nvram/messages/compiler.h> 27cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 28cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslernamespace nvram { 29cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 30cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// Abstraction used by the protobuf decoder to read data. The idea here is that 313d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// |InputStreamBuffer| maintains a window of the data to be read. Access to the 323d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// contents of the current window is direct, i.e. doesn't need to go through 333d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// virtual dispatch to subclasses. Whenever the window is exhausted, the next 343d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// window must be set up. This latter operation is left for implementation of 353d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// the virtual |Advance()| member function in subclasses, which is entirely free 363d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// to pull its data from anywhere. 37cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerclass NVRAM_EXPORT InputStreamBuffer { 38cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler public: 393d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler InputStreamBuffer() = default; 40cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler InputStreamBuffer(const void* data, size_t size); 41cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler InputStreamBuffer(const void* start, const void* end); 423d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler virtual ~InputStreamBuffer() = default; 43cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 44cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Checks whether the stream is exhausted; 45cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Done(); 46cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 47cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Consume |size| bytes from the stream and store them in the provided |data| 48cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // buffer. Returns false if insufficient bytes are available. 49cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Read(void* data, size_t size); 50cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 51cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Consume a single byte and place it in |byte|. Returns true if successful, 52cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // i.e. if there was a byte available. 53cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool ReadByte(uint8_t* byte); 54cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 55cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Discard |size| bytes from the stream. Returns false if there are fewer 56cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // bytes available. 57cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Skip(size_t size); 58cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 59cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler protected: 60cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Update the |pos_| and |end_| pointers for the next buffer window. Returns 61cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // true if the window was successfully set up, false on I/O errors or stream 62cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // exhaustion. The default implementation just returns false to signal 63cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // immediate stream exhaustion. Subclasses should override this to pull in 64cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // more data from the underlying data source. 65cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler virtual bool Advance(); 66cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 67cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Pointers to the buffer to read from. |InputStreamBuffer| only advances 68cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |pos_| until reaching |end_|. At this point, |Advance| is called for the 69cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // subclass to initialize the next buffer window and update the pointers. 70cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler const uint8_t* pos_ = nullptr; 71cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler const uint8_t* end_ = nullptr; 72cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 73cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Allow |NestedInputStreamBuffer| to mess with |pos_| and |end_|, also in its 74cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // delegate, which isn't necessarily of type |NestedInputStreamBuffer|. 75cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler friend class NestedInputStreamBuffer; 76cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}; 77cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 78cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// An |InputStreamBuffer| implementation that pulls its data from a delegate, 79cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// but only up to a predetermined limit of bytes. 80cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerclass NVRAM_EXPORT NestedInputStreamBuffer : public InputStreamBuffer { 81cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler public: 82cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Initialize a |NestedInputStreamBuffer| to provide at most |size| bytes from 83cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |delegate|. Note that |delegate| must remain valid throughout the life time 84cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // of this |NestedInputStreamBuffer|. 85cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler NestedInputStreamBuffer(InputStreamBuffer* delegate, size_t size); 863d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler ~NestedInputStreamBuffer() override = default; 87cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 88cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler private: 89cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // InputStreamBuffer: 90cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Advance() override; 91cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 9242455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler // Determine the input window end based on |delegate|'s current window and the 9342455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler // requested |size| to read. If |size| can be satisfied from |delegate|'s 9442455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler // current window, return an end pointer within that window. If size is larger 9542455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler // than the remaining bytes available in |delegate|'s input window, return 9642455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler // |delegate|'s |end_| pointer. 9742455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler static const uint8_t* ClampEnd(InputStreamBuffer* delegate, size_t size); 9842455ff2abfc7ed92a35287d1b3bc6049161adb9Mattias Nissler 99cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler InputStreamBuffer* delegate_; 100cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler size_t remaining_; 101cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}; 102cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 1033d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// Abstraction used by the protobuf decoder to output data. This class maintains 1043d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// a current window of memory to write output to. Access to the current window's 1053d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// bytes is direct and doesn't require virtual dispatch. Once the capacity of 1063d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// the current window is exhausted, the virtual |Advance()| member function is 1073d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// invoked to set up a new window. Subclasses are entirely free to implement 1083d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// this operation as appropriate for their I/O mechanism, for example a 1093d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// socket-based implementations might flush the buffer to the socket and reset 1103d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler// the window pointers to accept more output. 111cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerclass NVRAM_EXPORT OutputStreamBuffer { 112cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler public: 1133d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler OutputStreamBuffer() = default; 114cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler OutputStreamBuffer(void* data, size_t size); 115cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler OutputStreamBuffer(void* data, void* end); 1163d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler virtual ~OutputStreamBuffer() = default; 117cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 118cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Checks whether the stream is exhausted. 119cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Done(); 120cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 121cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Writes a blob of |size| bytes provided in |data| to the underlying buffer. 122cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Returns false if there is not enough space available. 123cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Write(const void* data, size_t size); 124cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 125cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Writes |byte| to the underlying buffer. Returns false if there is not 126cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // enough space available. 127cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool WriteByte(uint8_t byte); 128cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 129cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler protected: 130cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Set up the next data buffer window in |pos_| and |end_|. Returns true on 131cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // success, false on I/O errors or stream exhaustion. The default 132cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // implementation unconditionally returns false, i.e. signaling stream 133cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // exhaustion after the initial window is filled. Subclasses should override 134cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // this to flush buffers to the underlying data sink and set up a fresh buffer 135cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // for more data as appropriate. 136cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler virtual bool Advance(); 137cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 138cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // The |pos_| and |end_| pointers define a window of writable buffer space for 139cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |OutputStreamBuffer| to place data in. |pos_| grows towards |end_| as 140cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // writes occur. Once |pos_| hits |end_|, |OutputStreamBuffer| will call 141cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |Advance|, which subclasses can implement to provide a new buffer window in 142cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |pos_| and |end_|. 143cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler uint8_t* pos_ = nullptr; 144cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler uint8_t* end_ = nullptr; 145cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}; 146cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 147417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler// An |OutputStreamBuffer| backed by a single data buffer. 148417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nisslerclass NVRAM_EXPORT ArrayOutputStreamBuffer : public OutputStreamBuffer { 149417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler public: 150417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler ArrayOutputStreamBuffer() = default; 151417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler ArrayOutputStreamBuffer(void* data, size_t size) 152417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler : OutputStreamBuffer(data, size), data_(pos_) {} 153417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler ArrayOutputStreamBuffer(void* data, void* end) 154417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler : OutputStreamBuffer(data, end), data_(pos_) {} 155417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler ~ArrayOutputStreamBuffer() override = default; 156417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler 157417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler // Returns the number of bytes already written. 158417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler size_t bytes_written() const { return pos_ - data_; } 159417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler 160417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler private: 161417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler uint8_t* data_ = nullptr; 162417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler}; 163417e23fa8c8c8f9dd77a19e60c47b46d5454000dMattias Nissler 164cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// An |OutputStream| implementation that doesn't write anything, but just counts 165cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// the number of bytes written. 166cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerclass NVRAM_EXPORT CountingOutputStreamBuffer : public OutputStreamBuffer { 167cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler public: 168cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler CountingOutputStreamBuffer(); 1693d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler ~CountingOutputStreamBuffer() override = default; 170cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 171cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler size_t bytes_written() const { 172cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler return bytes_written_ + (pos_ - scratch_space_); 173cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler } 174cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 175cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler protected: 176cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // OutputStreamBuffer: 177cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Advance() override; 178cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 179cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler private: 180cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // We share a single scratch buffer that all |CountingOutputStreamBuffer| 181cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // instances use as the destination for writes. Its contents are pretty much 182cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // unpredictable. 1833d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler // 1843d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler // TODO(mnissler): This adds a static 256 bytes memory allocation to each 1853d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler // process linking to this code. If that becomes a problem, we might want to 1863d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler // be smarter here and dynamically allocate a chunk of memory only when it's 1873d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler // needed, or maybe even map some address space that's not even backed by 1883d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler // actual memory (not sure that's possible). 1893d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler static constexpr size_t kScratchSpaceSize = 256; 190cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler static uint8_t scratch_space_[kScratchSpaceSize]; 191cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 192cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Number of bytes that had been written when the last |Advance()| call 193cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // occurred. 194cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler size_t bytes_written_ = 0; 195cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}; 196cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 197cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// An |OutputStreamBuffer| implementation that stores all data to a wrapped 198cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// |Blob|, growing it as necessary. 199cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerclass NVRAM_EXPORT BlobOutputStreamBuffer : public OutputStreamBuffer { 200cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler public: 201cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Construct a |BlobOutputStreamBuffer| that stores all written data to 202cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |blob|, which will get resized as necessary. Note that |blob| must remain 203cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // valid for the life time of the |BlobOutputStreamBuffer| object. 204bb621b95ea636314c87b885107c8d5331992f9bbChih-Hung Hsieh explicit BlobOutputStreamBuffer(Blob* blob); 2053d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler ~BlobOutputStreamBuffer() override = default; 206cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 207cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Truncate the blob to match the current output size. 208cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Truncate(); 209cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 210cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler protected: 211cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // OutputStreamBuffer: 2123d2f13f288feb42f1dfcfe558af27955edefaad3Mattias Nissler bool Advance() override; 213cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 214cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler private: 215cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler Blob* blob_; 216cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}; 217cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 218cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// Protobuf wire types. 219cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerenum class WireType : int8_t { 220cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler kVarint = 0, 221cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler kFixed64 = 1, 222cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler kLengthDelimited = 2, 223cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler kStartGroup = 3, 224cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler kEndGroup = 4, 225cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler kFixed32 = 5, 226cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}; 227cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 228cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// A class implementing a parser for the low-level protobuf wire format. It 229cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// obtains raw data from a wrapped |InputStream| and offers member functions 230cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// that facilitate decoding the data according to the protobuf wire format. 231cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerclass NVRAM_EXPORT ProtoReader { 232cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler public: 233cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Construct a new |ProtoReader| that consumes data from |stream_buffer|. 234cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |stream_buffer| must remain valid throughout the life time of the 235cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |ProtoReader|. 236cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler explicit ProtoReader(InputStreamBuffer* stream_buffer); 237cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 238cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Access to the underlying stream buffer. 239cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler InputStreamBuffer* stream_buffer() { return stream_buffer_; } 240cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 241cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Wire type of the current field. 242cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler WireType wire_type() const { return static_cast<WireType>(wire_type_); } 243cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 244cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Field number of the current field. 245cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler uint64_t field_number() const { return field_number_; } 246cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 247cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Size of the field data, if known in advance. 248cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler size_t field_size() const { return field_size_; } 249cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 250cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Whether all data is consumed. 251cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Done() const { return stream_buffer_->Done(); } 252cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 253cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Reads the next wire tag from the current position in the underlying 254cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |stream_buffer_| and initializes internal fields. Previous state is 255cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // discarded silently. 256cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool ReadWireTag(); 257cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 258cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Read a varint-encoded field and advances to the next field. Returns true if 259cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // successful. 260cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool ReadVarint(uint64_t* value); 261cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 262cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Read field data. Checks that |size| matches |field_size()| and copies out 263cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // the data to the provided |data| buffer. Advances to the next field and 264cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // returns true if successful. 265cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool ReadLengthDelimited(void* data, size_t size); 266cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 267cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Skips over the current field data. 268cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool SkipField(); 269cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 270cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler private: 271cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler static constexpr int8_t kInvalidWireType = -1; 272cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 273cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler InputStreamBuffer* stream_buffer_; 274cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 275cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Information about the current field. |wire_type == kInvalidWireType| 276cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // indicates that there is no current field to be consumed. 277cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler int8_t wire_type_ = kInvalidWireType; 278cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler uint64_t field_number_ = 0; 279cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler size_t field_size_ = 0; 280cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}; 281cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 282cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// |ProtoWriter| contains logic to write raw data according to the protobuf wire 283cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler// format to an |OutputStreamBuffer|. 284cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nisslerclass NVRAM_EXPORT ProtoWriter { 285cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler public: 286cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Construct a |ProtoWriter| which will send its output to |stream_buffer|. 287cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |stream_buffer| must remain valid for the life time of the |ProtoWriter|. 288cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler explicit ProtoWriter(OutputStreamBuffer* stream_buffer); 289cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 290cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Access to the underlying stream buffer. 291cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler OutputStreamBuffer* stream_buffer() { return stream_buffer_; } 292cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 293cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Sets the field number to use when emitting a tag. 294cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler void set_field_number(uint64_t field_number) { field_number_ = field_number; } 295cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 296cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Whether the writer has exhausted the underlying |OutputStream|'s capacity. 297cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool Done() const { return stream_buffer_->Done(); } 298cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 299cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Write |value| as a varint-encoded field. Returns true if successful, i.e. 300cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // the data was successfully written to |stream_buffer_|. 301cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool WriteVarint(uint64_t value); 302cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 303cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Write |size| bytes stored at |data| to |stream_buffer_|. Returns true if 304cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // successful, i.e. the data was successfully written to |stream_buffer_|. 305cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool WriteLengthDelimited(const void* data, size_t size); 306cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 307cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // Writes a wire tag for a length-delimited field, followed by a length 308cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // indication for |size| data bytes. It is up to the caller to emit exactly 309cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // |size| bytes to |stream_buffer()|, otherwise the encoded data will be 310cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // malformed. 311cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool WriteLengthHeader(size_t size); 312cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 313cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler private: 314cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // A helper to write a wire tag using the current field number and the 315cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler // provided wire type. 316cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler bool WriteWireTag(WireType wire_type); 317cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 318cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler OutputStreamBuffer* stream_buffer_; 319cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler uint64_t field_number_ = 0; 320cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler}; 321cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 322cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler} // namespace nvram 323cdab12349a989828ccc9698bd9f6a0f1687453f9Mattias Nissler 324a715cb1840f9a0c813c90707a351687f7a77950eMattias Nissler#endif // NVRAM_MESSAGES_IO_H_ 325