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