1c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin/* 2c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Copyright (C) 2017 The Android Open Source Project 3c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * 4c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Licensed under the Apache License, Version 2.0 (the "License"); 5c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * you may not use this file except in compliance with the License. 6c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * You may obtain a copy of the License at 7c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * 8c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * http://www.apache.org/licenses/LICENSE-2.0 9c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * 10c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Unless required by applicable law or agreed to in writing, software 11c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * distributed under the License is distributed on an "AS IS" BASIS, 12c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * See the License for the specific language governing permissions and 14c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * limitations under the License. 15c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 16c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 17c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin#ifndef ANDROID_UTIL_ENCODED_BUFFER_H 18c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin#define ANDROID_UTIL_ENCODED_BUFFER_H 19c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 20c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin#include <stdint.h> 21c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin#include <vector> 22c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 23c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinnamespace android { 24c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinnamespace util { 25c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 26c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin/** 27c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * A stream of bytes containing a read pointer and a write pointer, 28c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * backed by a set of fixed-size buffers. There are write functions for the 29c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * primitive types stored by protocol buffers, but none of the logic 30c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * for tags, inner objects, or any of that. 31c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * 32c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Terminology: 33c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * *Pos: Position in the whole data set (as if it were a single buffer). 34c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * *Index: Index of a buffer within the mBuffers list. 35c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * *Offset: Position within a buffer. 36c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 37c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinclass EncodedBuffer 38c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{ 39c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinpublic: 40c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin EncodedBuffer(); 41c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin EncodedBuffer(size_t chunkSize); 42c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin ~EncodedBuffer(); 43c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 44c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin class Pointer { 45c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin public: 46c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin Pointer(); 47c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin Pointer(size_t chunkSize); 48c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 49c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t pos() const; 50c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t index() const; 51c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t offset() const; 52c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 53974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin Pointer* move(size_t amt); 54974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline Pointer* move() { return move(1); }; 55974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin Pointer* rewind(); 56c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 57c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin Pointer copy() const; 58c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 59c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin private: 60c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t mChunkSize; 61c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t mIndex; 62c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t mOffset; 63c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin }; 64c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 657f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin /** 667f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin * Clears the buffer by rewinding its write pointer to avoid de/allocate buffers in heap. 677f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin */ 687f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin void clear(); 697f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin 70c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /******************************** Write APIs ************************************************/ 71c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 72c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 73c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the number of bytes written in the buffer 74c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 75c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t size() const; 76c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 77c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 78c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the write pointer. 79c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 80c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin Pointer* wp(); 81c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 82c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 83c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the current position of write pointer, if the write buffer is full, it will automatically 84c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * rotate to a new buffer with given chunkSize. If NULL is returned, it means NO_MEMORY 85c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 86c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin uint8_t* writeBuffer(); 87c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 88c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 89c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the writeable size in the current write buffer . 90c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 91c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t currentToWrite(); 92c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 93c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 94974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Write a single byte to the buffer. 95c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 96974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin void writeRawByte(uint8_t val); 97974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 98974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 99974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Write a varint32 into the buffer. Return the size of the varint. 100974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 101974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin size_t writeRawVarint32(uint32_t val); 102974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 103974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 104974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Write a varint64 into the buffer. Return the size of the varint. 105974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 106974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin size_t writeRawVarint64(uint64_t val); 107974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 108974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 109974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Write Fixed32 into the buffer. 110974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 111974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin void writeRawFixed32(uint32_t val); 112974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 113974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 114974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Write Fixed64 into the buffer. 115974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 116974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin void writeRawFixed64(uint64_t val); 117c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 118c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 119c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Write a protobuf header. Return the size of the header. 120c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 121c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t writeHeader(uint32_t fieldId, uint8_t wireType); 122c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 123974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /********************************* Edit APIs ************************************************/ 124974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 125974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Returns the edit pointer. 126974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 127974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin Pointer* ep(); 128974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 129974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 130974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Read a single byte at ep, and move ep to next byte; 131974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 132974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin uint8_t readRawByte(); 133974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 134974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 135974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Read varint starting at ep, ep will move to pos of next byte. 136974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 137974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin uint64_t readRawVarint(); 138974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 139974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 140974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Read 4 bytes starting at ep, ep will move to pos of next byte. 141974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 142974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin uint32_t readRawFixed32(); 143974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 144974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 145974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Read 8 bytes starting at ep, ep will move to pos of next byte. 146974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 147974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin uint64_t readRawFixed64(); 148974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 149974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 150974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Edit 4 bytes starting at pos. 151974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 152974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin void editRawFixed32(size_t pos, uint32_t val); 153974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 154974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 1551a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin * Copy _size_ bytes of data starting at __srcPos__ to wp, srcPos must be larger than wp.pos(). 156974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 157974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin void copy(size_t srcPos, size_t size); 158974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 159c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /********************************* Read APIs ************************************************/ 160c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin class iterator; 161c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin friend class iterator; 162c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin class iterator { 163c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin public: 164c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin iterator(const EncodedBuffer& buffer); 165c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 166c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 167c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the number of bytes written in the buffer 168c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 169c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t size() const; 170c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 171c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 172c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the size of total bytes read. 173c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 174c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t bytesRead() const; 175c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 176c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 177c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the read pointer. 178c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 179c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin Pointer* rp(); 180c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 181c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 182c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the current position of read pointer, if NULL is returned, it reaches end of buffer. 183c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 184c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin uint8_t const* readBuffer(); 185c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 186c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 187c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the readable size in the current read buffer. 188c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 189c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t currentToRead(); 190c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 191c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 192c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns true if next bytes is available for read. 193c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 194c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin bool hasNext(); 195c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 196c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 197c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Reads the current byte and moves pointer 1 bit. 198c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 199c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin uint8_t next(); 200c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 201c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 202c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Read varint from iterator, the iterator will point to next available byte. 203c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 204974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin uint64_t readRawVarint(); 205c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 206c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin private: 207c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin const EncodedBuffer& mData; 208c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin Pointer mRp; 209c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin }; 210c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 211c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin /** 212c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Returns the iterator of EncodedBuffer so it guarantees consumers won't be able to modified the buffer. 213c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */ 214c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin iterator begin() const; 215c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 216c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinprivate: 217c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin size_t mChunkSize; 2186cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin std::vector<uint8_t*> mBuffers; 219c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 220c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin Pointer mWp; 221974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin Pointer mEp; 222c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 223c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin inline uint8_t* at(const Pointer& p) const; // helper function to get value 224c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}; 225c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 226c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin} // util 227c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin} // android 228c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin 229974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin#endif // ANDROID_UTIL_ENCODED_BUFFER_H 230974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 231