| /* | |
| * 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 | |