1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
/*
* 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
|