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 */
16c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
17c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin#ifndef ANDROID_UTIL_ENCODED_BUFFER_H
18c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin#define ANDROID_UTIL_ENCODED_BUFFER_H
19c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
20c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin#include <stdint.h>
21c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin#include <vector>
22c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
23c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinnamespace android {
24c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinnamespace util {
25c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
26c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin/**
27c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * A stream of bytes containing a read pointer and a write pointer,
28c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * backed by a set of fixed-size buffers.  There are write functions for the
29c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * primitive types stored by protocol buffers, but none of the logic
30c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * for tags, inner objects, or any of that.
31c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin *
32c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin * Terminology:
33c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin *      *Pos:       Position in the whole data set (as if it were a single buffer).
34c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin *      *Index:     Index of a buffer within the mBuffers list.
35c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin *      *Offset:    Position within a buffer.
36c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin */
37c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinclass EncodedBuffer
38c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin{
39c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinpublic:
40c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    EncodedBuffer();
41c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    EncodedBuffer(size_t chunkSize);
42c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    ~EncodedBuffer();
43c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
44c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    class Pointer {
45c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    public:
46c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        Pointer();
47c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        Pointer(size_t chunkSize);
48c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
49c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size_t pos() const;
50c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size_t index() const;
51c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size_t offset() const;
52c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
53974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        Pointer* move(size_t amt);
54974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        inline Pointer* move() { return move(1); };
55974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        Pointer* rewind();
56c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
57c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        Pointer copy() const;
58c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
59c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    private:
60c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size_t mChunkSize;
61c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size_t mIndex;
62c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size_t mOffset;
63c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    };
64c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
657f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin    /**
667f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin     * Clears the buffer by rewinding its write pointer to avoid de/allocate buffers in heap.
677f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin     */
687f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin    void clear();
697f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin
70c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    /******************************** Write APIs ************************************************/
71c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
72c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    /**
73c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     * Returns the number of bytes written in the buffer
74c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     */
75c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    size_t size() const;
76c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
77c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    /**
78c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     * Returns the write pointer.
79c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     */
80c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    Pointer* wp();
81c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
82c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    /**
83c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     * Returns the current position of write pointer, if the write buffer is full, it will automatically
84c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     * rotate to a new buffer with given chunkSize. If NULL is returned, it means NO_MEMORY
85c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     */
86c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    uint8_t* writeBuffer();
87c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
88c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    /**
89c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     * Returns the writeable size in the current write buffer .
90c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     */
91c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    size_t currentToWrite();
92c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
93c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    /**
94974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Write a single byte to the buffer.
95c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     */
96974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    void writeRawByte(uint8_t val);
97974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
98974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
99974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Write a varint32 into the buffer. Return the size of the varint.
100974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
101974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    size_t writeRawVarint32(uint32_t val);
102974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
103974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
104974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Write a varint64 into the buffer. Return the size of the varint.
105974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
106974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    size_t writeRawVarint64(uint64_t val);
107974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
108974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
109974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Write Fixed32 into the buffer.
110974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
111974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    void writeRawFixed32(uint32_t val);
112974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
113974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
114974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Write Fixed64 into the buffer.
115974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
116974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    void writeRawFixed64(uint64_t val);
117c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
118c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    /**
119c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     * Write a protobuf header. Return the size of the header.
120c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     */
121c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    size_t writeHeader(uint32_t fieldId, uint8_t wireType);
122c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
123974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /********************************* Edit APIs ************************************************/
124974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
125974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Returns the edit pointer.
126974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
127974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    Pointer* ep();
128974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
129974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
130974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Read a single byte at ep, and move ep to next byte;
131974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
132974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint8_t readRawByte();
133974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
134974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
135974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Read varint starting at ep, ep will move to pos of next byte.
136974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
137974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint64_t readRawVarint();
138974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
139974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
140974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Read 4 bytes starting at ep, ep will move to pos of next byte.
141974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
142974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint32_t readRawFixed32();
143974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
144974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
145974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Read 8 bytes starting at ep, ep will move to pos of next byte.
146974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
147974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    uint64_t readRawFixed64();
148974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
149974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
150974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     * Edit 4 bytes starting at pos.
151974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
152974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    void editRawFixed32(size_t pos, uint32_t val);
153974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
154974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    /**
1551a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin     * Copy _size_ bytes of data starting at __srcPos__ to wp, srcPos must be larger than wp.pos().
156974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin     */
157974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    void copy(size_t srcPos, size_t size);
158974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
159c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    /********************************* Read APIs ************************************************/
160c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    class iterator;
161c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    friend class iterator;
162c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    class iterator {
163c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    public:
164c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        iterator(const EncodedBuffer& buffer);
165c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
166c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        /**
167c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         * Returns the number of bytes written in the buffer
168c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         */
169c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size_t size() const;
170c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
171c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        /**
172c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         * Returns the size of total bytes read.
173c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         */
174c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size_t bytesRead() const;
175c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
176c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        /**
177c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         * Returns the read pointer.
178c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         */
179c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        Pointer* rp();
180c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
181c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        /**
182c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         * Returns the current position of read pointer, if NULL is returned, it reaches end of buffer.
183c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         */
184c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        uint8_t const* readBuffer();
185c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
186c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        /**
187c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         * Returns the readable size in the current read buffer.
188c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         */
189c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        size_t currentToRead();
190c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
191c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        /**
192c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         * Returns true if next bytes is available for read.
193c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         */
194c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        bool hasNext();
195c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
196c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        /**
197c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         * Reads the current byte and moves pointer 1 bit.
198c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         */
199c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        uint8_t next();
200c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
201c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        /**
202c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         * Read varint from iterator, the iterator will point to next available byte.
203c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin         */
204974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin        uint64_t readRawVarint();
205c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
206c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    private:
207c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        const EncodedBuffer& mData;
208c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        Pointer mRp;
209c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    };
210c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
211c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    /**
212c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     * Returns the iterator of EncodedBuffer so it guarantees consumers won't be able to modified the buffer.
213c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin     */
214c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    iterator begin() const;
215c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
216c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jinprivate:
217c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    size_t mChunkSize;
2186cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin    std::vector<uint8_t*> mBuffers;
219c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
220c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    Pointer mWp;
221974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin    Pointer mEp;
222c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
223c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    inline uint8_t* at(const Pointer& p) const; // helper function to get value
224c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin};
225c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
226c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin} // util
227c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin} // android
228c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
229974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin#endif // ANDROID_UTIL_ENCODED_BUFFER_H
230974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin
231