am 75d1cb66: Add buffer writing methods.

* commit '75d1cb667d30e7009ecdbe8c3f1af08749ca554c':
  Add buffer writing methods.
main
Keisuke Kuroyanagi 2013-09-02 03:35:06 -07:00 committed by Android Git Automerger
commit 9cb0f9df34
2 changed files with 111 additions and 1 deletions

View File

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

View File

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