blob: 7ffd8874a8fb79b786e81998b0106213bafccfa8 [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 */
Yi Jinad3e6e52018-04-03 15:10:34 -070016#define LOG_TAG "libprotoutil"
17
18#include <stdlib.h>
Yi Jinc23fad22017-09-15 17:24:59 -070019
20#include <android/util/EncodedBuffer.h>
Yi Jin974a9c22017-10-02 18:37:08 -070021#include <android/util/protobuf.h>
Yi Jinad3e6e52018-04-03 15:10:34 -070022#include <cutils/log.h>
Yi Jinc23fad22017-09-15 17:24:59 -070023
24namespace android {
25namespace util {
26
27const size_t BUFFER_SIZE = 8 * 1024; // 8 KB
28
29EncodedBuffer::Pointer::Pointer() : Pointer(BUFFER_SIZE)
30{
31}
32
33EncodedBuffer::Pointer::Pointer(size_t chunkSize)
34 :mIndex(0),
35 mOffset(0)
36{
37 mChunkSize = chunkSize == 0 ? BUFFER_SIZE : chunkSize;
38}
39
40size_t
41EncodedBuffer::Pointer::pos() const
42{
43 return mIndex * mChunkSize + mOffset;
44}
45
46size_t
47EncodedBuffer::Pointer::index() const
48{
49 return mIndex;
50}
51
52size_t
53EncodedBuffer::Pointer::offset() const
54{
55 return mOffset;
56}
57
Yi Jin974a9c22017-10-02 18:37:08 -070058EncodedBuffer::Pointer*
Yi Jinc23fad22017-09-15 17:24:59 -070059EncodedBuffer::Pointer::move(size_t amt)
60{
61 size_t newOffset = mOffset + amt;
62 mIndex += newOffset / mChunkSize;
63 mOffset = newOffset % mChunkSize;
Yi Jin974a9c22017-10-02 18:37:08 -070064 return this;
Yi Jinc23fad22017-09-15 17:24:59 -070065}
66
Yi Jin974a9c22017-10-02 18:37:08 -070067EncodedBuffer::Pointer*
Yi Jinc23fad22017-09-15 17:24:59 -070068EncodedBuffer::Pointer::rewind()
69{
70 mIndex = 0;
71 mOffset = 0;
Yi Jin974a9c22017-10-02 18:37:08 -070072 return this;
Yi Jinc23fad22017-09-15 17:24:59 -070073}
74
75EncodedBuffer::Pointer
76EncodedBuffer::Pointer::copy() const
77{
78 Pointer p = Pointer(mChunkSize);
79 p.mIndex = mIndex;
80 p.mOffset = mOffset;
81 return p;
82}
83
84// ===========================================================
85EncodedBuffer::EncodedBuffer() : EncodedBuffer(0)
86{
87}
88
89EncodedBuffer::EncodedBuffer(size_t chunkSize)
90 :mBuffers()
91{
92 mChunkSize = chunkSize == 0 ? BUFFER_SIZE : chunkSize;
93 mWp = Pointer(mChunkSize);
Yi Jin974a9c22017-10-02 18:37:08 -070094 mEp = Pointer(mChunkSize);
Yi Jinc23fad22017-09-15 17:24:59 -070095}
96
97EncodedBuffer::~EncodedBuffer()
98{
99 for (size_t i=0; i<mBuffers.size(); i++) {
100 uint8_t* buf = mBuffers[i];
101 free(buf);
102 }
103}
104
105inline uint8_t*
106EncodedBuffer::at(const Pointer& p) const
107{
108 return mBuffers[p.index()] + p.offset();
109}
110
Yi Jin7f9e63b2018-02-02 16:25:11 -0800111void
112EncodedBuffer::clear()
113{
114 mWp.rewind();
115 mEp.rewind();
116}
117
Yi Jinc23fad22017-09-15 17:24:59 -0700118/******************************** Write APIs ************************************************/
119size_t
120EncodedBuffer::size() const
121{
122 return mWp.pos();
123}
124
125EncodedBuffer::Pointer*
126EncodedBuffer::wp()
127{
128 return &mWp;
129}
130
131uint8_t*
132EncodedBuffer::writeBuffer()
133{
134 // This prevents write pointer move too fast than allocating the buffer.
135 if (mWp.index() > mBuffers.size()) return NULL;
136 uint8_t* buf = NULL;
137 if (mWp.index() == mBuffers.size()) {
138 buf = (uint8_t*)malloc(mChunkSize);
139
140 if (buf == NULL) return NULL; // This indicates NO_MEMORY
141
142 mBuffers.push_back(buf);
143 }
144 return at(mWp);
145}
146
147size_t
148EncodedBuffer::currentToWrite()
149{
150 return mChunkSize - mWp.offset();
151}
152
Yi Jin974a9c22017-10-02 18:37:08 -0700153void
154EncodedBuffer::writeRawByte(uint8_t val)
155{
156 *writeBuffer() = val;
157 mWp.move();
158}
159
Yi Jinc23fad22017-09-15 17:24:59 -0700160size_t
Yi Jin974a9c22017-10-02 18:37:08 -0700161EncodedBuffer::writeRawVarint64(uint64_t val)
Yi Jinc23fad22017-09-15 17:24:59 -0700162{
163 size_t size = 0;
164 while (true) {
165 size++;
166 if ((val & ~0x7F) == 0) {
Yi Jin974a9c22017-10-02 18:37:08 -0700167 writeRawByte((uint8_t) val);
Yi Jinc23fad22017-09-15 17:24:59 -0700168 return size;
169 } else {
Yi Jin974a9c22017-10-02 18:37:08 -0700170 writeRawByte((uint8_t)((val & 0x7F) | 0x80));
Yi Jinc23fad22017-09-15 17:24:59 -0700171 val >>= 7;
172 }
173 }
174}
175
176size_t
Yi Jin974a9c22017-10-02 18:37:08 -0700177EncodedBuffer::writeRawVarint32(uint32_t val)
178{
179 uint64_t v =(uint64_t)val;
180 return writeRawVarint64(v);
181}
182
183void
184EncodedBuffer::writeRawFixed32(uint32_t val)
185{
186 writeRawByte((uint8_t) val);
187 writeRawByte((uint8_t) (val>>8));
188 writeRawByte((uint8_t) (val>>16));
189 writeRawByte((uint8_t) (val>>24));
190}
191
192void
193EncodedBuffer::writeRawFixed64(uint64_t val)
194{
195 writeRawByte((uint8_t) val);
196 writeRawByte((uint8_t) (val>>8));
197 writeRawByte((uint8_t) (val>>16));
198 writeRawByte((uint8_t) (val>>24));
199 writeRawByte((uint8_t) (val>>32));
200 writeRawByte((uint8_t) (val>>40));
201 writeRawByte((uint8_t) (val>>48));
202 writeRawByte((uint8_t) (val>>56));
203}
204
205size_t
Yi Jinc23fad22017-09-15 17:24:59 -0700206EncodedBuffer::writeHeader(uint32_t fieldId, uint8_t wireType)
207{
Yi Jin974a9c22017-10-02 18:37:08 -0700208 return writeRawVarint32((fieldId << FIELD_ID_SHIFT) | wireType);
209}
210
Joe Onorato99598ee2019-02-11 15:55:13 +0000211status_t
212EncodedBuffer::writeRaw(uint8_t const* buf, size_t size)
213{
214 while (size > 0) {
215 uint8_t* target = writeBuffer();
216 if (target == NULL) {
217 return -ENOMEM;
218 }
219 size_t chunk = currentToWrite();
220 if (chunk > size) {
221 chunk = size;
222 }
223 memcpy(target, buf, chunk);
224 size -= chunk;
225 buf += chunk;
226 mWp.move(chunk);
227 }
228 return NO_ERROR;
229}
230
231status_t
232EncodedBuffer::writeRaw(const sp<ProtoReader>& reader)
233{
234 status_t err;
235 uint8_t const* buf;
236 while ((buf = reader->readBuffer()) != nullptr) {
237 size_t amt = reader->currentToRead();
238 err = writeRaw(buf, amt);
239 reader->move(amt);
240 if (err != NO_ERROR) {
241 return err;
242 }
243 }
244 return NO_ERROR;
245}
246
247status_t
248EncodedBuffer::writeRaw(const sp<ProtoReader>& reader, size_t size)
249{
250 status_t err;
251 uint8_t const* buf;
252 while (size > 0 && (buf = reader->readBuffer()) != nullptr) {
253 size_t amt = reader->currentToRead();
254 if (size < amt) {
255 amt = size;
256 }
257 err = writeRaw(buf, amt);
258 reader->move(amt);
259 size -= amt;
260 if (err != NO_ERROR) {
261 return err;
262 }
263 }
264 return size == 0 ? NO_ERROR : NOT_ENOUGH_DATA;
265}
266
267
Yi Jin974a9c22017-10-02 18:37:08 -0700268/******************************** Edit APIs ************************************************/
269EncodedBuffer::Pointer*
270EncodedBuffer::ep()
271{
272 return &mEp;
273}
274
275uint8_t
276EncodedBuffer::readRawByte()
277{
278 uint8_t val = *at(mEp);
279 mEp.move();
280 return val;
281}
282
283uint64_t
284EncodedBuffer::readRawVarint()
285{
286 uint64_t val = 0, shift = 0;
287 size_t start = mEp.pos();
288 while (true) {
289 uint8_t byte = readRawByte();
Yi Jinad3e6e52018-04-03 15:10:34 -0700290 val |= (UINT64_C(0x7F) & byte) << shift;
Yi Jin974a9c22017-10-02 18:37:08 -0700291 if ((byte & 0x80) == 0) break;
292 shift += 7;
293 }
294 return val;
295}
296
297uint32_t
298EncodedBuffer::readRawFixed32()
299{
300 uint32_t val = 0;
301 for (auto i=0; i<32; i+=8) {
302 val += (uint32_t)readRawByte() << i;
303 }
304 return val;
305}
306
307uint64_t
308EncodedBuffer::readRawFixed64()
309{
310 uint64_t val = 0;
311 for (auto i=0; i<64; i+=8) {
312 val += (uint64_t)readRawByte() << i;
313 }
314 return val;
315}
316
317void
318EncodedBuffer::editRawFixed32(size_t pos, uint32_t val)
319{
320 size_t oldPos = mEp.pos();
321 mEp.rewind()->move(pos);
322 for (auto i=0; i<32; i+=8) {
323 *at(mEp) = (uint8_t) (val >> i);
324 mEp.move();
325 }
326 mEp.rewind()->move(oldPos);
327}
328
329void
330EncodedBuffer::copy(size_t srcPos, size_t size)
331{
332 if (size == 0) return;
333 Pointer cp(mChunkSize);
334 cp.move(srcPos);
335
336 while (cp.pos() < srcPos + size) {
337 writeRawByte(*at(cp));
338 cp.move();
339 }
Yi Jinc23fad22017-09-15 17:24:59 -0700340}
341
342/********************************* Read APIs ************************************************/
Joe Onorato99598ee2019-02-11 15:55:13 +0000343sp<ProtoReader>
344EncodedBuffer::read()
Yi Jinc23fad22017-09-15 17:24:59 -0700345{
Joe Onorato99598ee2019-02-11 15:55:13 +0000346 return new EncodedBuffer::Reader(this);
Yi Jinc23fad22017-09-15 17:24:59 -0700347}
348
Joe Onorato99598ee2019-02-11 15:55:13 +0000349EncodedBuffer::Reader::Reader(const sp<EncodedBuffer>& buffer)
Yi Jinc23fad22017-09-15 17:24:59 -0700350 :mData(buffer),
Joe Onorato99598ee2019-02-11 15:55:13 +0000351 mRp(buffer->mChunkSize)
Yi Jinc23fad22017-09-15 17:24:59 -0700352{
353}
354
Joe Onorato99598ee2019-02-11 15:55:13 +0000355EncodedBuffer::Reader::~Reader() {
356}
357
358ssize_t
359EncodedBuffer::Reader::size() const
Yi Jinc23fad22017-09-15 17:24:59 -0700360{
Joe Onorato99598ee2019-02-11 15:55:13 +0000361 return (ssize_t)mData->size();
Yi Jinc23fad22017-09-15 17:24:59 -0700362}
363
364size_t
Joe Onorato99598ee2019-02-11 15:55:13 +0000365EncodedBuffer::Reader::bytesRead() const
Yi Jinc23fad22017-09-15 17:24:59 -0700366{
367 return mRp.pos();
368}
369
Yi Jinc23fad22017-09-15 17:24:59 -0700370uint8_t const*
Joe Onorato99598ee2019-02-11 15:55:13 +0000371EncodedBuffer::Reader::readBuffer()
Yi Jinc23fad22017-09-15 17:24:59 -0700372{
Joe Onorato99598ee2019-02-11 15:55:13 +0000373 return hasNext() ? const_cast<uint8_t const*>(mData->at(mRp)) : NULL;
Yi Jinc23fad22017-09-15 17:24:59 -0700374}
375
376size_t
Joe Onorato99598ee2019-02-11 15:55:13 +0000377EncodedBuffer::Reader::currentToRead()
Yi Jinc23fad22017-09-15 17:24:59 -0700378{
Joe Onorato99598ee2019-02-11 15:55:13 +0000379 return (mData->mWp.index() > mRp.index()) ?
380 mData->mChunkSize - mRp.offset() :
381 mData->mWp.offset() - mRp.offset();
Yi Jinc23fad22017-09-15 17:24:59 -0700382}
383
384bool
Joe Onorato99598ee2019-02-11 15:55:13 +0000385EncodedBuffer::Reader::hasNext()
Yi Jinc23fad22017-09-15 17:24:59 -0700386{
Joe Onorato99598ee2019-02-11 15:55:13 +0000387 return mRp.pos() < mData->mWp.pos();
Yi Jinc23fad22017-09-15 17:24:59 -0700388}
389
390uint8_t
Joe Onorato99598ee2019-02-11 15:55:13 +0000391EncodedBuffer::Reader::next()
Yi Jinc23fad22017-09-15 17:24:59 -0700392{
Joe Onorato99598ee2019-02-11 15:55:13 +0000393 uint8_t res = *(mData->at(mRp));
Yi Jinc23fad22017-09-15 17:24:59 -0700394 mRp.move();
395 return res;
396}
397
Yi Jin974a9c22017-10-02 18:37:08 -0700398uint64_t
Joe Onorato99598ee2019-02-11 15:55:13 +0000399EncodedBuffer::Reader::readRawVarint()
Yi Jinc23fad22017-09-15 17:24:59 -0700400{
Yi Jin974a9c22017-10-02 18:37:08 -0700401 uint64_t val = 0, shift = 0;
Yi Jinc23fad22017-09-15 17:24:59 -0700402 while (true) {
403 uint8_t byte = next();
Yi Jinad3e6e52018-04-03 15:10:34 -0700404 val |= (INT64_C(0x7F) & byte) << shift;
Yi Jinc23fad22017-09-15 17:24:59 -0700405 if ((byte & 0x80) == 0) break;
406 shift += 7;
407 }
408 return val;
409}
410
Joe Onorato99598ee2019-02-11 15:55:13 +0000411void
412EncodedBuffer::Reader::move(size_t amt)
413{
414 mRp.move(amt);
415}
416
Yi Jinc23fad22017-09-15 17:24:59 -0700417} // util
418} // android