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