Home | History | Annotate | Download | only in util
      1 /*
      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  */
     16 
     17 #ifndef ANDROID_UTIL_ENCODED_BUFFER_H
     18 #define ANDROID_UTIL_ENCODED_BUFFER_H
     19 
     20 #include <android/util/ProtoReader.h>
     21 
     22 #include <utils/Errors.h>
     23 #include <utils/RefBase.h>
     24 
     25 #include <stdint.h>
     26 #include <vector>
     27 
     28 namespace android {
     29 namespace util {
     30 
     31 /**
     32  * A stream of bytes containing a read pointer and a write pointer,
     33  * backed by a set of fixed-size buffers.  There are write functions for the
     34  * primitive types stored by protocol buffers, but none of the logic
     35  * for tags, inner objects, or any of that.
     36  *
     37  * Terminology:
     38  *      *Pos:       Position in the whole data set (as if it were a single buffer).
     39  *      *Index:     Index of a buffer within the mBuffers list.
     40  *      *Offset:    Position within a buffer.
     41  */
     42 class EncodedBuffer : public virtual RefBase
     43 {
     44 public:
     45     EncodedBuffer();
     46     explicit EncodedBuffer(size_t chunkSize);
     47     virtual ~EncodedBuffer();
     48 
     49     class Pointer {
     50     public:
     51         Pointer();
     52         explicit Pointer(size_t chunkSize);
     53 
     54         size_t pos() const;
     55         size_t index() const;
     56         size_t offset() const;
     57 
     58         Pointer* move(size_t amt);
     59         inline Pointer* move() { return move(1); };
     60         Pointer* rewind();
     61 
     62         Pointer copy() const;
     63 
     64     private:
     65         size_t mChunkSize;
     66         size_t mIndex;
     67         size_t mOffset;
     68     };
     69 
     70     /**
     71      * Clears the buffer by rewinding its write pointer to avoid de/allocate buffers in heap.
     72      */
     73     void clear();
     74 
     75     /******************************** Write APIs ************************************************/
     76 
     77     /**
     78      * Returns the number of bytes written in the buffer
     79      */
     80     size_t size() const;
     81 
     82     /**
     83      * Returns the write pointer.
     84      */
     85     Pointer* wp();
     86 
     87     /**
     88      * Returns the current position of write pointer, if the write buffer is full, it will
     89      * automatically rotate to a new buffer with given chunkSize. If NULL is returned, it
     90      * means NO_MEMORY.
     91      */
     92     uint8_t* writeBuffer();
     93 
     94     /**
     95      * Returns the writeable size in the current write buffer .
     96      */
     97     size_t currentToWrite();
     98 
     99     /**
    100      * Write a single byte to the buffer.
    101      */
    102     void writeRawByte(uint8_t val);
    103 
    104     /**
    105      * Write a varint32 into the buffer. Return the size of the varint.
    106      */
    107     size_t writeRawVarint32(uint32_t val);
    108 
    109     /**
    110      * Write a varint64 into the buffer. Return the size of the varint.
    111      */
    112     size_t writeRawVarint64(uint64_t val);
    113 
    114     /**
    115      * Write Fixed32 into the buffer.
    116      */
    117     void writeRawFixed32(uint32_t val);
    118 
    119     /**
    120      * Write Fixed64 into the buffer.
    121      */
    122     void writeRawFixed64(uint64_t val);
    123 
    124     /**
    125      * Write a protobuf header. Return the size of the header.
    126      */
    127     size_t writeHeader(uint32_t fieldId, uint8_t wireType);
    128 
    129     /**
    130      * Copy the contents of the parameter into the write buffer.
    131      */
    132     status_t writeRaw(uint8_t const* buf, size_t size);
    133 
    134     /**
    135      * Copy the entire contents of the ProtoReader into the write buffer.
    136      */
    137     status_t writeRaw(const sp<ProtoReader>& that);
    138 
    139     /**
    140      * Copy the size bytes of contents of the ProtoReader into the write buffer.
    141      */
    142     status_t writeRaw(const sp<ProtoReader>& that, size_t size);
    143 
    144     /********************************* Edit APIs ************************************************/
    145     /**
    146      * Returns the edit pointer.
    147      */
    148     Pointer* ep();
    149 
    150     /**
    151      * Read a single byte at ep, and move ep to next byte;
    152      */
    153     uint8_t readRawByte();
    154 
    155     /**
    156      * Read varint starting at ep, ep will move to pos of next byte.
    157      */
    158     uint64_t readRawVarint();
    159 
    160     /**
    161      * Read 4 bytes starting at ep, ep will move to pos of next byte.
    162      */
    163     uint32_t readRawFixed32();
    164 
    165     /**
    166      * Read 8 bytes starting at ep, ep will move to pos of next byte.
    167      */
    168     uint64_t readRawFixed64();
    169 
    170     /**
    171      * Edit 4 bytes starting at pos.
    172      */
    173     void editRawFixed32(size_t pos, uint32_t val);
    174 
    175     /**
    176      * Copy _size_ bytes of data starting at __srcPos__ to wp, srcPos must be larger than wp.pos().
    177      */
    178     void copy(size_t srcPos, size_t size);
    179 
    180     /********************************* Read APIs ************************************************/
    181     /**
    182      * Returns the Reader of EncodedBuffer so it guarantees consumers won't be able to
    183      * modify the buffer.
    184      */
    185     sp<ProtoReader> read();
    186 
    187 private:
    188     class Reader;
    189     friend class Reader;
    190     class Reader : public ProtoReader {
    191     public:
    192         explicit Reader(const sp<EncodedBuffer>& buffer);
    193         virtual ~Reader();
    194 
    195         virtual ssize_t size() const;
    196         virtual size_t bytesRead() const;
    197         virtual uint8_t const* readBuffer();
    198         virtual size_t currentToRead();
    199         virtual bool hasNext();
    200         virtual uint8_t next();
    201         virtual uint64_t readRawVarint();
    202         virtual void move(size_t amt);
    203 
    204     private:
    205         const sp<EncodedBuffer> mData;
    206         Pointer mRp;
    207         friend class EncodedBuffer;
    208     };
    209 
    210     size_t mChunkSize;
    211     std::vector<uint8_t*> mBuffers;
    212 
    213     Pointer mWp;
    214     Pointer mEp;
    215 
    216     inline uint8_t* at(const Pointer& p) const; // helper function to get value
    217 };
    218 
    219 } // util
    220 } // android
    221 
    222 #endif // ANDROID_UTIL_ENCODED_BUFFER_H
    223 
    224