1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_UTIL_ENCODED_BUFFER_H 18 #define ANDROID_UTIL_ENCODED_BUFFER_H 19 20 #include <stdint.h> 21 #include <vector> 22 23 namespace android { 24 namespace util { 25 26 /** 27 * A stream of bytes containing a read pointer and a write pointer, 28 * backed by a set of fixed-size buffers. There are write functions for the 29 * primitive types stored by protocol buffers, but none of the logic 30 * for tags, inner objects, or any of that. 31 * 32 * Terminology: 33 * *Pos: Position in the whole data set (as if it were a single buffer). 34 * *Index: Index of a buffer within the mBuffers list. 35 * *Offset: Position within a buffer. 36 */ 37 class EncodedBuffer 38 { 39 public: 40 EncodedBuffer(); 41 EncodedBuffer(size_t chunkSize); 42 ~EncodedBuffer(); 43 44 class Pointer { 45 public: 46 Pointer(); 47 Pointer(size_t chunkSize); 48 49 size_t pos() const; 50 size_t index() const; 51 size_t offset() const; 52 53 Pointer* move(size_t amt); move()54 inline Pointer* move() { return move(1); }; 55 Pointer* rewind(); 56 57 Pointer copy() const; 58 59 private: 60 size_t mChunkSize; 61 size_t mIndex; 62 size_t mOffset; 63 }; 64 65 /** 66 * Clears the buffer by rewinding its write pointer to avoid de/allocate buffers in heap. 67 */ 68 void clear(); 69 70 /******************************** Write APIs ************************************************/ 71 72 /** 73 * Returns the number of bytes written in the buffer 74 */ 75 size_t size() const; 76 77 /** 78 * Returns the write pointer. 79 */ 80 Pointer* wp(); 81 82 /** 83 * Returns the current position of write pointer, if the write buffer is full, it will automatically 84 * rotate to a new buffer with given chunkSize. If NULL is returned, it means NO_MEMORY 85 */ 86 uint8_t* writeBuffer(); 87 88 /** 89 * Returns the writeable size in the current write buffer . 90 */ 91 size_t currentToWrite(); 92 93 /** 94 * Write a single byte to the buffer. 95 */ 96 void writeRawByte(uint8_t val); 97 98 /** 99 * Write a varint32 into the buffer. Return the size of the varint. 100 */ 101 size_t writeRawVarint32(uint32_t val); 102 103 /** 104 * Write a varint64 into the buffer. Return the size of the varint. 105 */ 106 size_t writeRawVarint64(uint64_t val); 107 108 /** 109 * Write Fixed32 into the buffer. 110 */ 111 void writeRawFixed32(uint32_t val); 112 113 /** 114 * Write Fixed64 into the buffer. 115 */ 116 void writeRawFixed64(uint64_t val); 117 118 /** 119 * Write a protobuf header. Return the size of the header. 120 */ 121 size_t writeHeader(uint32_t fieldId, uint8_t wireType); 122 123 /********************************* Edit APIs ************************************************/ 124 /** 125 * Returns the edit pointer. 126 */ 127 Pointer* ep(); 128 129 /** 130 * Read a single byte at ep, and move ep to next byte; 131 */ 132 uint8_t readRawByte(); 133 134 /** 135 * Read varint starting at ep, ep will move to pos of next byte. 136 */ 137 uint64_t readRawVarint(); 138 139 /** 140 * Read 4 bytes starting at ep, ep will move to pos of next byte. 141 */ 142 uint32_t readRawFixed32(); 143 144 /** 145 * Read 8 bytes starting at ep, ep will move to pos of next byte. 146 */ 147 uint64_t readRawFixed64(); 148 149 /** 150 * Edit 4 bytes starting at pos. 151 */ 152 void editRawFixed32(size_t pos, uint32_t val); 153 154 /** 155 * Copy _size_ bytes of data starting at __srcPos__ to wp, srcPos must be larger than wp.pos(). 156 */ 157 void copy(size_t srcPos, size_t size); 158 159 /********************************* Read APIs ************************************************/ 160 class iterator; 161 friend class iterator; 162 class iterator { 163 public: 164 iterator(const EncodedBuffer& buffer); 165 166 /** 167 * Returns the number of bytes written in the buffer 168 */ 169 size_t size() const; 170 171 /** 172 * Returns the size of total bytes read. 173 */ 174 size_t bytesRead() const; 175 176 /** 177 * Returns the read pointer. 178 */ 179 Pointer* rp(); 180 181 /** 182 * Returns the current position of read pointer, if NULL is returned, it reaches end of buffer. 183 */ 184 uint8_t const* readBuffer(); 185 186 /** 187 * Returns the readable size in the current read buffer. 188 */ 189 size_t currentToRead(); 190 191 /** 192 * Returns true if next bytes is available for read. 193 */ 194 bool hasNext(); 195 196 /** 197 * Reads the current byte and moves pointer 1 bit. 198 */ 199 uint8_t next(); 200 201 /** 202 * Read varint from iterator, the iterator will point to next available byte. 203 */ 204 uint64_t readRawVarint(); 205 206 private: 207 const EncodedBuffer& mData; 208 Pointer mRp; 209 }; 210 211 /** 212 * Returns the iterator of EncodedBuffer so it guarantees consumers won't be able to modified the buffer. 213 */ 214 iterator begin() const; 215 216 private: 217 size_t mChunkSize; 218 std::vector<uint8_t*> mBuffers; 219 220 Pointer mWp; 221 Pointer mEp; 222 223 inline uint8_t* at(const Pointer& p) const; // helper function to get value 224 }; 225 226 } // util 227 } // android 228 229 #endif // ANDROID_UTIL_ENCODED_BUFFER_H 230 231