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 <android/util/ProtoReader.h> 21 22 #include <utils/Errors.h> 23 #include <utils/RefBase.h> 24 25 #include <stdint.h> 26 #include <vector> 27 28 namespace android { 29 namespace util { 30 31 /** 32 * A stream of bytes containing a read pointer and a write pointer, 33 * backed by a set of fixed-size buffers. There are write functions for the 34 * primitive types stored by protocol buffers, but none of the logic 35 * for tags, inner objects, or any of that. 36 * 37 * Terminology: 38 * *Pos: Position in the whole data set (as if it were a single buffer). 39 * *Index: Index of a buffer within the mBuffers list. 40 * *Offset: Position within a buffer. 41 */ 42 class EncodedBuffer : public virtual RefBase 43 { 44 public: 45 EncodedBuffer(); 46 explicit EncodedBuffer(size_t chunkSize); 47 virtual ~EncodedBuffer(); 48 49 class Pointer { 50 public: 51 Pointer(); 52 explicit Pointer(size_t chunkSize); 53 54 size_t pos() const; 55 size_t index() const; 56 size_t offset() const; 57 58 Pointer* move(size_t amt); move()59 inline Pointer* move() { return move(1); }; 60 Pointer* rewind(); 61 62 Pointer copy() const; 63 64 private: 65 size_t mChunkSize; 66 size_t mIndex; 67 size_t mOffset; 68 }; 69 70 /** 71 * Clears the buffer by rewinding its write pointer to avoid de/allocate buffers in heap. 72 */ 73 void clear(); 74 75 /******************************** Write APIs ************************************************/ 76 77 /** 78 * Returns the number of bytes written in the buffer 79 */ 80 size_t size() const; 81 82 /** 83 * Returns the write pointer. 84 */ 85 Pointer* wp(); 86 87 /** 88 * Returns the current position of write pointer, if the write buffer is full, it will 89 * automatically rotate to a new buffer with given chunkSize. If NULL is returned, it 90 * means NO_MEMORY. 91 */ 92 uint8_t* writeBuffer(); 93 94 /** 95 * Returns the writeable size in the current write buffer . 96 */ 97 size_t currentToWrite(); 98 99 /** 100 * Write a single byte to the buffer. 101 */ 102 void writeRawByte(uint8_t val); 103 104 /** 105 * Write a varint32 into the buffer. Return the size of the varint. 106 */ 107 size_t writeRawVarint32(uint32_t val); 108 109 /** 110 * Write a varint64 into the buffer. Return the size of the varint. 111 */ 112 size_t writeRawVarint64(uint64_t val); 113 114 /** 115 * Write Fixed32 into the buffer. 116 */ 117 void writeRawFixed32(uint32_t val); 118 119 /** 120 * Write Fixed64 into the buffer. 121 */ 122 void writeRawFixed64(uint64_t val); 123 124 /** 125 * Write a protobuf header. Return the size of the header. 126 */ 127 size_t writeHeader(uint32_t fieldId, uint8_t wireType); 128 129 /** 130 * Copy the contents of the parameter into the write buffer. 131 */ 132 status_t writeRaw(uint8_t const* buf, size_t size); 133 134 /** 135 * Copy the entire contents of the ProtoReader into the write buffer. 136 */ 137 status_t writeRaw(const sp<ProtoReader>& that); 138 139 /** 140 * Copy the size bytes of contents of the ProtoReader into the write buffer. 141 */ 142 status_t writeRaw(const sp<ProtoReader>& that, size_t size); 143 144 /********************************* Edit APIs ************************************************/ 145 /** 146 * Returns the edit pointer. 147 */ 148 Pointer* ep(); 149 150 /** 151 * Read a single byte at ep, and move ep to next byte; 152 */ 153 uint8_t readRawByte(); 154 155 /** 156 * Read varint starting at ep, ep will move to pos of next byte. 157 */ 158 uint64_t readRawVarint(); 159 160 /** 161 * Read 4 bytes starting at ep, ep will move to pos of next byte. 162 */ 163 uint32_t readRawFixed32(); 164 165 /** 166 * Read 8 bytes starting at ep, ep will move to pos of next byte. 167 */ 168 uint64_t readRawFixed64(); 169 170 /** 171 * Edit 4 bytes starting at pos. 172 */ 173 void editRawFixed32(size_t pos, uint32_t val); 174 175 /** 176 * Copy _size_ bytes of data starting at __srcPos__ to wp, srcPos must be larger than wp.pos(). 177 */ 178 void copy(size_t srcPos, size_t size); 179 180 /********************************* Read APIs ************************************************/ 181 /** 182 * Returns the Reader of EncodedBuffer so it guarantees consumers won't be able to 183 * modify the buffer. 184 */ 185 sp<ProtoReader> read(); 186 187 private: 188 class Reader; 189 friend class Reader; 190 class Reader : public ProtoReader { 191 public: 192 explicit Reader(const sp<EncodedBuffer>& buffer); 193 virtual ~Reader(); 194 195 virtual ssize_t size() const; 196 virtual size_t bytesRead() const; 197 virtual uint8_t const* readBuffer(); 198 virtual size_t currentToRead(); 199 virtual bool hasNext(); 200 virtual uint8_t next(); 201 virtual uint64_t readRawVarint(); 202 virtual void move(size_t amt); 203 204 private: 205 const sp<EncodedBuffer> mData; 206 Pointer mRp; 207 friend class EncodedBuffer; 208 }; 209 210 size_t mChunkSize; 211 std::vector<uint8_t*> mBuffers; 212 213 Pointer mWp; 214 Pointer mEp; 215 216 inline uint8_t* at(const Pointer& p) const; // helper function to get value 217 }; 218 219 } // util 220 } // android 221 222 #endif // ANDROID_UTIL_ENCODED_BUFFER_H 223 224