1c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin/*
2c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Copyright (C) 2017 The Android Open Source Project
3c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin *
4c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Licensed under the Apache License, Version 2.0 (the "License");
5c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * you may not use this file except in compliance with the License.
6c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * You may obtain a copy of the License at
7c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin *
8c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin *      http://www.apache.org/licenses/LICENSE-2.0
9c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin *
10c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Unless required by applicable law or agreed to in writing, software
11c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * distributed under the License is distributed on an "AS IS" BASIS,
12c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * See the License for the specific language governing permissions and
14c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * limitations under the License.
15c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */
16ad3e6e5d5a9746bfe9d4600172798c9d6309b149Yi Jin#define LOG_TAG "libprotoutil"
17ad3e6e5d5a9746bfe9d4600172798c9d6309b149Yi Jin
18ad3e6e5d5a9746bfe9d4600172798c9d6309b149Yi Jin#include <stdlib.h>
19c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
20c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin#include <android/util/EncodedBuffer.h>
21974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin#include <android/util/protobuf.h>
22ad3e6e5d5a9746bfe9d4600172798c9d6309b149Yi Jin#include <cutils/log.h>
23c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
24c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinnamespace android {
25c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinnamespace util {
26c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
27c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinconst size_t BUFFER_SIZE = 8 * 1024; // 8 KB
28c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
29c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer::Pointer() : Pointer(BUFFER_SIZE)
30c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
31c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
32c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
33c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer::Pointer(size_t chunkSize)
34c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        :mIndex(0),
35c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         mOffset(0)
36c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
37c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    mChunkSize = chunkSize == 0 ? BUFFER_SIZE : chunkSize;
38c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
39c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
40c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
41c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer::pos() const
42c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
43c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return mIndex * mChunkSize + mOffset;
44c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
45c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
46c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
47c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer::index() const
48c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
49c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return mIndex;
50c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
51c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
52c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
53c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer::offset() const
54c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
55c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return mOffset;
56c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
57c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
58974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::Pointer*
59c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer::move(size_t amt)
60c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
61c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    size_t newOffset = mOffset + amt;
62c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    mIndex += newOffset / mChunkSize;
63c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    mOffset = newOffset % mChunkSize;
64974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    return this;
65c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
66c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
67974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::Pointer*
68c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer::rewind()
69c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
70c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    mIndex = 0;
71c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    mOffset = 0;
72974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    return this;
73c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
74c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
75c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer
76c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer::copy() const
77c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
78c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    Pointer p = Pointer(mChunkSize);
79c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    p.mIndex = mIndex;
80c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    p.mOffset = mOffset;
81c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return p;
82c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
83c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
84c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin// ===========================================================
85c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::EncodedBuffer() : EncodedBuffer(0)
86c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
87c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
88c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
89c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::EncodedBuffer(size_t chunkSize)
90c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        :mBuffers()
91c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
92c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    mChunkSize = chunkSize == 0 ? BUFFER_SIZE : chunkSize;
93c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    mWp = Pointer(mChunkSize);
94974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    mEp = Pointer(mChunkSize);
95c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
96c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
97c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::~EncodedBuffer()
98c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
99c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    for (size_t i=0; i<mBuffers.size(); i++) {
100c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        uint8_t* buf = mBuffers[i];
101c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        free(buf);
102c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    }
103c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
104c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
105c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jininline uint8_t*
106c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::at(const Pointer& p) const
107c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
108c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return mBuffers[p.index()] + p.offset();
109c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
110c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
1117f9e63b63269baa41a36fc31acd6fc071309c26cYi Jinvoid
1127f9e63b63269baa41a36fc31acd6fc071309c26cYi JinEncodedBuffer::clear()
1137f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin{
1147f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin    mWp.rewind();
1157f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin    mEp.rewind();
1167f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin}
1177f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin
118c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin/******************************** Write APIs ************************************************/
119c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
120c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::size() const
121c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
122c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return mWp.pos();
123c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
124c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
125c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer*
126c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::wp()
127c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
128c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return &mWp;
129c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
130c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
131c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinuint8_t*
132c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::writeBuffer()
133c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
134c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    // This prevents write pointer move too fast than allocating the buffer.
135c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    if (mWp.index() > mBuffers.size()) return NULL;
136c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    uint8_t* buf = NULL;
137c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    if (mWp.index() == mBuffers.size()) {
138c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        buf = (uint8_t*)malloc(mChunkSize);
139c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
140c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        if (buf == NULL) return NULL; // This indicates NO_MEMORY
141c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
142c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        mBuffers.push_back(buf);
143c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    }
144c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return at(mWp);
145c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
146c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
147c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
148c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::currentToWrite()
149c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
150c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return mChunkSize - mWp.offset();
151c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
152c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
153974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinvoid
154974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::writeRawByte(uint8_t val)
155974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
156974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    *writeBuffer() = val;
157974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    mWp.move();
158974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
159974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
160c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
161974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::writeRawVarint64(uint64_t val)
162c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
163c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    size_t size = 0;
164c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    while (true) {
165c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size++;
166c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        if ((val & ~0x7F) == 0) {
167974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin            writeRawByte((uint8_t) val);
168c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            return size;
169c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        } else {
170974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin            writeRawByte((uint8_t)((val & 0x7F) | 0x80));
171c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            val >>= 7;
172c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        }
173c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    }
174c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
175c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
176c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
177974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::writeRawVarint32(uint32_t val)
178974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
179974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint64_t v =(uint64_t)val;
180974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    return writeRawVarint64(v);
181974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
182974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
183974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinvoid
184974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::writeRawFixed32(uint32_t val)
185974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
186974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) val);
187974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>8));
188974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>16));
189974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>24));
190974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
191974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
192974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinvoid
193974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::writeRawFixed64(uint64_t val)
194974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
195974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) val);
196974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>8));
197974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>16));
198974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>24));
199974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>32));
200974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>40));
201974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>48));
202974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    writeRawByte((uint8_t) (val>>56));
203974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
204974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
205974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinsize_t
206c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::writeHeader(uint32_t fieldId, uint8_t wireType)
207c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
208974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    return writeRawVarint32((fieldId << FIELD_ID_SHIFT) | wireType);
209974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
210974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
211974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin/******************************** Edit APIs ************************************************/
212974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::Pointer*
213974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::ep()
214974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
215974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    return &mEp;
216974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
217974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
218974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinuint8_t
219974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::readRawByte()
220974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
221974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint8_t val = *at(mEp);
222974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    mEp.move();
223974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    return val;
224974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
225974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
226974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinuint64_t
227974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::readRawVarint()
228974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
229974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint64_t val = 0, shift = 0;
230974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    size_t start = mEp.pos();
231974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    while (true) {
232974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        uint8_t byte = readRawByte();
233ad3e6e5d5a9746bfe9d4600172798c9d6309b149Yi Jin        val |= (UINT64_C(0x7F) & byte) << shift;
234974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        if ((byte & 0x80) == 0) break;
235974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        shift += 7;
236974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    }
237974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    return val;
238974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
239974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
240974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinuint32_t
241974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::readRawFixed32()
242974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
243974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint32_t val = 0;
244974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    for (auto i=0; i<32; i+=8) {
245974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        val += (uint32_t)readRawByte() << i;
246974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    }
247974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    return val;
248974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
249974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
250974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinuint64_t
251974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::readRawFixed64()
252974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
253974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint64_t val = 0;
254974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    for (auto i=0; i<64; i+=8) {
255974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        val += (uint64_t)readRawByte() << i;
256974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    }
257974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    return val;
258974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
259974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
260974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinvoid
261974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::editRawFixed32(size_t pos, uint32_t val)
262974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
263974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    size_t oldPos = mEp.pos();
264974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    mEp.rewind()->move(pos);
265974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    for (auto i=0; i<32; i+=8) {
266974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        *at(mEp) = (uint8_t) (val >> i);
267974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        mEp.move();
268974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    }
269974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    mEp.rewind()->move(oldPos);
270974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}
271974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
272974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinvoid
273974a9c28853d24ff94f000ae9f5c816d9538897bYi JinEncodedBuffer::copy(size_t srcPos, size_t size)
274974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{
275974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    if (size == 0) return;
276974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    Pointer cp(mChunkSize);
277974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    cp.move(srcPos);
278974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
279974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    while (cp.pos() < srcPos + size) {
280974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        writeRawByte(*at(cp));
281974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        cp.move();
282974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    }
283c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
284c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
285c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin/********************************* Read APIs ************************************************/
286c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator
287c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::begin() const
288c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
289c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return EncodedBuffer::iterator(*this);
290c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
291c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
292c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator::iterator(const EncodedBuffer& buffer)
293c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        :mData(buffer),
294c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         mRp(buffer.mChunkSize)
295c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
296c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
297c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
298c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
299c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator::size() const
300c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
301c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return mData.size();
302c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
303c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
304c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
305c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator::bytesRead() const
306c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
307c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return mRp.pos();
308c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
309c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
310c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::Pointer*
311c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator::rp()
312c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
313c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return &mRp;
314c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
315c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
316c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinuint8_t const*
317c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator::readBuffer()
318c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
319c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return hasNext() ? const_cast<uint8_t const*>(mData.at(mRp)) : NULL;
320c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
321c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
322c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinsize_t
323c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator::currentToRead()
324c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
325c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return (mData.mWp.index() > mRp.index()) ?
326c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            mData.mChunkSize - mRp.offset() :
327c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            mData.mWp.offset() - mRp.offset();
328c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
329c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
330c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinbool
331c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator::hasNext()
332c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
333c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return mRp.pos() < mData.mWp.pos();
334c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
335c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
336c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinuint8_t
337c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator::next()
338c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
339c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    uint8_t res = *(mData.at(mRp));
340c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    mRp.move();
341c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return res;
342c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
343c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
344974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinuint64_t
345c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi JinEncodedBuffer::iterator::readRawVarint()
346c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
347974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint64_t val = 0, shift = 0;
348c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    while (true) {
349c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        uint8_t byte = next();
350ad3e6e5d5a9746bfe9d4600172798c9d6309b149Yi Jin        val |= (INT64_C(0x7F) & byte) << shift;
351c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        if ((byte & 0x80) == 0) break;
352c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        shift += 7;
353c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    }
354c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    return val;
355c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin}
356c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
357c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin} // util
358c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin} // android
359