Add buffer writing methods.
Bug: 6669677 Change-Id: Ic3345e36a7842b77598c21de9b54f7c2863df38f
This commit is contained in:
parent
2660f83a12
commit
75d1cb667d
2 changed files with 111 additions and 1 deletions
|
@ -36,6 +36,10 @@ class BufferWithExtendableBuffer {
|
|||
: mOriginalBuffer(originalBuffer), mOriginalBufferSize(originalBufferSize),
|
||||
mAdditionalBuffer(INITIAL_ADDITIONAL_BUFFER_SIZE), mUsedAdditionalBufferSize(0) {}
|
||||
|
||||
AK_FORCE_INLINE int getTailPosition() const {
|
||||
return mOriginalBufferSize + mUsedAdditionalBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* For reading.
|
||||
*/
|
||||
|
@ -56,6 +60,33 @@ class BufferWithExtendableBuffer {
|
|||
return mOriginalBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* For writing.
|
||||
*
|
||||
* Writing is allowed for original buffer, already written region of additional buffer and the
|
||||
* tail of additional buffer.
|
||||
*/
|
||||
AK_FORCE_INLINE bool writeUintAndAdvancePosition(const uint32_t data, const int size,
|
||||
int *const pos) {
|
||||
if (!(size >= 1 && size <= 4)) {
|
||||
AKLOGI("writeUintAndAdvancePosition() is called with invalid size: %d", size);
|
||||
ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
if (!checkAndPrepareWriting(*pos, size)) {
|
||||
return false;
|
||||
}
|
||||
const bool usesAdditionalBuffer = isInAdditionalBuffer(*pos);
|
||||
uint8_t *const buffer = usesAdditionalBuffer ? &mAdditionalBuffer[0] : mOriginalBuffer;
|
||||
if (usesAdditionalBuffer) {
|
||||
*pos -= mOriginalBufferSize;
|
||||
}
|
||||
ByteArrayUtils::writeUintAndAdvancePosition(buffer, data, size, pos);
|
||||
if (usesAdditionalBuffer) {
|
||||
*pos += mOriginalBufferSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(BufferWithExtendableBuffer);
|
||||
|
@ -78,6 +109,32 @@ class BufferWithExtendableBuffer {
|
|||
mAdditionalBuffer.resize(mAdditionalBuffer.size() + EXTEND_ADDITIONAL_BUFFER_SIZE_STEP);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns if it is possible to write size-bytes from pos. When pos is at the tail position of
|
||||
// the additional buffer, try extending the buffer.
|
||||
AK_FORCE_INLINE bool checkAndPrepareWriting(const int pos, const int size) {
|
||||
if (isInAdditionalBuffer(pos)) {
|
||||
if (pos == mUsedAdditionalBufferSize) {
|
||||
// Append data to the tail.
|
||||
if (pos + size > static_cast<int>(mAdditionalBuffer.size())) {
|
||||
// Need to extend buffer.
|
||||
if (!extendBuffer()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mUsedAdditionalBufferSize += size;
|
||||
} else if (pos + size >= mUsedAdditionalBufferSize) {
|
||||
// The access will beyond the tail of used region.
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (pos < 0 || mOriginalBufferSize < pos + size) {
|
||||
// Invalid position or violate the boundary.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif /* LATINIME_BUFFER_WITH_EXTENDABLE_BUFFER_H */
|
||||
|
|
|
@ -29,7 +29,34 @@ namespace latinime {
|
|||
class ByteArrayUtils {
|
||||
public:
|
||||
/**
|
||||
* Integer
|
||||
* Integer writing
|
||||
*
|
||||
* Each method write a corresponding size integer in a big endian manner.
|
||||
*/
|
||||
static AK_FORCE_INLINE void writeUintAndAdvancePosition(uint8_t *const buffer,
|
||||
const uint32_t data, const int size, int *const pos) {
|
||||
// size must be in 1 to 4.
|
||||
ASSERT(size >= 1 && size <= 4);
|
||||
switch (size) {
|
||||
case 1:
|
||||
ByteArrayUtils::writeUint8AndAdvancePosition(buffer, data, pos);
|
||||
return;
|
||||
case 2:
|
||||
ByteArrayUtils::writeUint16AndAdvancePosition(buffer, data, pos);
|
||||
return;
|
||||
case 3:
|
||||
ByteArrayUtils::writeUint24AndAdvancePosition(buffer, data, pos);
|
||||
return;
|
||||
case 4:
|
||||
ByteArrayUtils::writeUint32AndAdvancePosition(buffer, data, pos);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer reading
|
||||
*
|
||||
* Each method read a corresponding size integer in a big endian manner.
|
||||
*/
|
||||
|
@ -187,6 +214,32 @@ class ByteArrayUtils {
|
|||
|
||||
static const uint8_t MINIMAL_ONE_BYTE_CHARACTER_VALUE;
|
||||
static const uint8_t CHARACTER_ARRAY_TERMINATOR;
|
||||
|
||||
static AK_FORCE_INLINE void writeUint32AndAdvancePosition(uint8_t *const buffer,
|
||||
const uint32_t data, int *const pos) {
|
||||
buffer[(*pos)++] = (data >> 24) & 0xFF;
|
||||
buffer[(*pos)++] = (data >> 16) & 0xFF;
|
||||
buffer[(*pos)++] = (data >> 8) & 0xFF;
|
||||
buffer[(*pos)++] = data & 0xFF;
|
||||
}
|
||||
|
||||
static AK_FORCE_INLINE void writeUint24AndAdvancePosition(uint8_t *const buffer,
|
||||
const uint32_t data, int *const pos) {
|
||||
buffer[(*pos)++] = (data >> 16) & 0xFF;
|
||||
buffer[(*pos)++] = (data >> 8) & 0xFF;
|
||||
buffer[(*pos)++] = data & 0xFF;
|
||||
}
|
||||
|
||||
static AK_FORCE_INLINE void writeUint16AndAdvancePosition(uint8_t *const buffer,
|
||||
const uint16_t data, int *const pos) {
|
||||
buffer[(*pos)++] = (data >> 8) & 0xFF;
|
||||
buffer[(*pos)++] = data & 0xFF;
|
||||
}
|
||||
|
||||
static AK_FORCE_INLINE void writeUint8AndAdvancePosition(uint8_t *const buffer,
|
||||
const uint8_t data, int *const pos) {
|
||||
buffer[(*pos)++] = data & 0xFF;
|
||||
}
|
||||
};
|
||||
} // namespace latinime
|
||||
#endif /* LATINIME_BYTE_ARRAY_UTILS_H */
|
||||
|
|
Loading…
Reference in a new issue