blob: 0a8a5aa347bac6ee2be7e7c590375d112cdf69a3 [file] [log] [blame]
Yi Jinc23fad22017-09-15 17:24:59 -07001/*
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
23namespace android {
24namespace util {
25
26using namespace std;
27
28/**
29 * A stream of bytes containing a read pointer and a write pointer,
30 * backed by a set of fixed-size buffers. There are write functions for the
31 * primitive types stored by protocol buffers, but none of the logic
32 * for tags, inner objects, or any of that.
33 *
34 * Terminology:
35 * *Pos: Position in the whole data set (as if it were a single buffer).
36 * *Index: Index of a buffer within the mBuffers list.
37 * *Offset: Position within a buffer.
38 */
39class EncodedBuffer
40{
41public:
42 EncodedBuffer();
43 EncodedBuffer(size_t chunkSize);
44 ~EncodedBuffer();
45
46 class Pointer {
47 public:
48 Pointer();
49 Pointer(size_t chunkSize);
50
51 size_t pos() const;
52 size_t index() const;
53 size_t offset() const;
54
Yi Jin974a9c22017-10-02 18:37:08 -070055 Pointer* move(size_t amt);
56 inline Pointer* move() { return move(1); };
57 Pointer* rewind();
Yi Jinc23fad22017-09-15 17:24:59 -070058
Yi Jinc23fad22017-09-15 17:24:59 -070059 Pointer copy() const;
60
61 private:
62 size_t mChunkSize;
63 size_t mIndex;
64 size_t mOffset;
65 };
66
Yi Jin7f9e63b2018-02-02 16:25:11 -080067 /**
68 * Clears the buffer by rewinding its write pointer to avoid de/allocate buffers in heap.
69 */
70 void clear();
71
Yi Jinc23fad22017-09-15 17:24:59 -070072 /******************************** Write APIs ************************************************/
73
74 /**
75 * Returns the number of bytes written in the buffer
76 */
77 size_t size() const;
78
79 /**
80 * Returns the write pointer.
81 */
82 Pointer* wp();
83
84 /**
85 * Returns the current position of write pointer, if the write buffer is full, it will automatically
86 * rotate to a new buffer with given chunkSize. If NULL is returned, it means NO_MEMORY
87 */
88 uint8_t* writeBuffer();
89
90 /**
91 * Returns the writeable size in the current write buffer .
92 */
93 size_t currentToWrite();
94
95 /**
Yi Jin974a9c22017-10-02 18:37:08 -070096 * Write a single byte to the buffer.
Yi Jinc23fad22017-09-15 17:24:59 -070097 */
Yi Jin974a9c22017-10-02 18:37:08 -070098 void writeRawByte(uint8_t val);
99
100 /**
101 * Write a varint32 into the buffer. Return the size of the varint.
102 */
103 size_t writeRawVarint32(uint32_t val);
104
105 /**
106 * Write a varint64 into the buffer. Return the size of the varint.
107 */
108 size_t writeRawVarint64(uint64_t val);
109
110 /**
111 * Write Fixed32 into the buffer.
112 */
113 void writeRawFixed32(uint32_t val);
114
115 /**
116 * Write Fixed64 into the buffer.
117 */
118 void writeRawFixed64(uint64_t val);
Yi Jinc23fad22017-09-15 17:24:59 -0700119
120 /**
121 * Write a protobuf header. Return the size of the header.
122 */
123 size_t writeHeader(uint32_t fieldId, uint8_t wireType);
124
Yi Jin974a9c22017-10-02 18:37:08 -0700125 /********************************* Edit APIs ************************************************/
126 /**
127 * Returns the edit pointer.
128 */
129 Pointer* ep();
130
131 /**
132 * Read a single byte at ep, and move ep to next byte;
133 */
134 uint8_t readRawByte();
135
136 /**
137 * Read varint starting at ep, ep will move to pos of next byte.
138 */
139 uint64_t readRawVarint();
140
141 /**
142 * Read 4 bytes starting at ep, ep will move to pos of next byte.
143 */
144 uint32_t readRawFixed32();
145
146 /**
147 * Read 8 bytes starting at ep, ep will move to pos of next byte.
148 */
149 uint64_t readRawFixed64();
150
151 /**
152 * Edit 4 bytes starting at pos.
153 */
154 void editRawFixed32(size_t pos, uint32_t val);
155
156 /**
157 * Copy _size_ bytes of data starting at __srcPos__ to wp.
158 */
159 void copy(size_t srcPos, size_t size);
160
Yi Jinc23fad22017-09-15 17:24:59 -0700161 /********************************* Read APIs ************************************************/
162 class iterator;
163 friend class iterator;
164 class iterator {
165 public:
166 iterator(const EncodedBuffer& buffer);
167
168 /**
169 * Returns the number of bytes written in the buffer
170 */
171 size_t size() const;
172
173 /**
174 * Returns the size of total bytes read.
175 */
176 size_t bytesRead() const;
177
178 /**
179 * Returns the read pointer.
180 */
181 Pointer* rp();
182
183 /**
184 * Returns the current position of read pointer, if NULL is returned, it reaches end of buffer.
185 */
186 uint8_t const* readBuffer();
187
188 /**
189 * Returns the readable size in the current read buffer.
190 */
191 size_t currentToRead();
192
193 /**
194 * Returns true if next bytes is available for read.
195 */
196 bool hasNext();
197
198 /**
199 * Reads the current byte and moves pointer 1 bit.
200 */
201 uint8_t next();
202
203 /**
204 * Read varint from iterator, the iterator will point to next available byte.
Yi Jinc23fad22017-09-15 17:24:59 -0700205 */
Yi Jin974a9c22017-10-02 18:37:08 -0700206 uint64_t readRawVarint();
Yi Jinc23fad22017-09-15 17:24:59 -0700207
208 private:
209 const EncodedBuffer& mData;
210 Pointer mRp;
211 };
212
213 /**
214 * Returns the iterator of EncodedBuffer so it guarantees consumers won't be able to modified the buffer.
215 */
216 iterator begin() const;
217
218private:
219 size_t mChunkSize;
220 vector<uint8_t*> mBuffers;
221
222 Pointer mWp;
Yi Jin974a9c22017-10-02 18:37:08 -0700223 Pointer mEp;
Yi Jinc23fad22017-09-15 17:24:59 -0700224
225 inline uint8_t* at(const Pointer& p) const; // helper function to get value
226};
227
228} // util
229} // android
230
Yi Jin974a9c22017-10-02 18:37:08 -0700231#endif // ANDROID_UTIL_ENCODED_BUFFER_H
232