Add code point writing methods for updatable dictionaries.
Bug: 6669677 Change-Id: If7ab6fefdb9a7f0d21c397edbb7d9e7fddc0e0db
This commit is contained in:
parent
5901b5e1bd
commit
2a41a35635
3 changed files with 118 additions and 46 deletions
|
@ -22,4 +22,70 @@ const size_t BufferWithExtendableBuffer::INITIAL_ADDITIONAL_BUFFER_SIZE = 16 * 1
|
|||
const size_t BufferWithExtendableBuffer::MAX_ADDITIONAL_BUFFER_SIZE = 1024 * 1024;
|
||||
const size_t BufferWithExtendableBuffer::EXTEND_ADDITIONAL_BUFFER_SIZE_STEP = 16 * 1024;
|
||||
|
||||
bool BufferWithExtendableBuffer::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;
|
||||
}
|
||||
|
||||
bool BufferWithExtendableBuffer::writeCodePointsAndAdvancePosition(const int *const codePoints,
|
||||
const int codePointCount, const bool writesTerminator ,int *const pos) {
|
||||
const size_t size = ByteArrayUtils::calculateRequiredByteCountToStoreCodePoints(
|
||||
codePoints, codePointCount, writesTerminator);
|
||||
if (!checkAndPrepareWriting(*pos, size)) {
|
||||
return false;
|
||||
}
|
||||
const bool usesAdditionalBuffer = isInAdditionalBuffer(*pos);
|
||||
uint8_t *const buffer = usesAdditionalBuffer ? &mAdditionalBuffer[0] : mOriginalBuffer;
|
||||
if (usesAdditionalBuffer) {
|
||||
*pos -= mOriginalBufferSize;
|
||||
}
|
||||
ByteArrayUtils::writeCodePointsAndAdvancePosition(buffer, codePoints, codePointCount,
|
||||
writesTerminator, pos);
|
||||
if (usesAdditionalBuffer) {
|
||||
*pos += mOriginalBufferSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BufferWithExtendableBuffer::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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,27 +66,10 @@ class BufferWithExtendableBuffer {
|
|||
* 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;
|
||||
}
|
||||
bool writeUintAndAdvancePosition(const uint32_t data, const int size, int *const pos);
|
||||
|
||||
bool writeCodePointsAndAdvancePosition(const int *const codePoints, const int codePointCount,
|
||||
const bool writesTerminator, int *const pos);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(BufferWithExtendableBuffer);
|
||||
|
@ -112,29 +95,7 @@ class BufferWithExtendableBuffer {
|
|||
|
||||
// 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;
|
||||
}
|
||||
AK_FORCE_INLINE bool checkAndPrepareWriting(const int pos, const int size);
|
||||
};
|
||||
}
|
||||
#endif /* LATINIME_BUFFER_WITH_EXTENDABLE_BUFFER_H */
|
||||
|
|
|
@ -115,7 +115,7 @@ class ByteArrayUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Code Point
|
||||
* Code Point Reading
|
||||
*
|
||||
* 1 byte = bbbbbbbb match
|
||||
* case 000xxxxx: xxxxx << 16 + next byte << 8 + next byte
|
||||
|
@ -149,7 +149,7 @@ class ByteArrayUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* String (array of code points)
|
||||
* String (array of code points) Reading
|
||||
*
|
||||
* Reads code points until the terminator is found.
|
||||
*/
|
||||
|
@ -176,6 +176,51 @@ class ByteArrayUtils {
|
|||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* String (array of code points) Writing
|
||||
*/
|
||||
static void writeCodePointsAndAdvancePosition(uint8_t *const buffer,
|
||||
const int *const codePoints, const int codePointCount, const bool writesTerminator,
|
||||
int *const pos) {
|
||||
for (int i = 0; i < codePointCount; ++i) {
|
||||
const int codePoint = codePoints[i];
|
||||
if (codePoint == NOT_A_CODE_POINT || codePoint == CHARACTER_ARRAY_TERMINATOR) {
|
||||
break;
|
||||
} else if (codePoint < MINIMAL_ONE_BYTE_CHARACTER_VALUE) {
|
||||
// three bytes character.
|
||||
writeUint24AndAdvancePosition(buffer, codePoint, pos);
|
||||
} else {
|
||||
// one byte character.
|
||||
writeUint8AndAdvancePosition(buffer, codePoint, pos);
|
||||
}
|
||||
}
|
||||
if (writesTerminator) {
|
||||
writeUint8AndAdvancePosition(buffer, CHARACTER_ARRAY_TERMINATOR, pos);
|
||||
}
|
||||
}
|
||||
|
||||
static int calculateRequiredByteCountToStoreCodePoints(const int *const codePoints,
|
||||
const int codePointCount, const bool writesTerminator) {
|
||||
int byteCount = 0;
|
||||
for (int i = 0; i < codePointCount; ++i) {
|
||||
const int codePoint = codePoints[i];
|
||||
if (codePoint == NOT_A_CODE_POINT || codePoint == CHARACTER_ARRAY_TERMINATOR) {
|
||||
break;
|
||||
} else if (codePoint < MINIMAL_ONE_BYTE_CHARACTER_VALUE) {
|
||||
// three bytes character.
|
||||
byteCount += 3;
|
||||
} else {
|
||||
// one byte character.
|
||||
byteCount += 1;
|
||||
}
|
||||
}
|
||||
if (writesTerminator) {
|
||||
// The terminator is one byte.
|
||||
byteCount += 1;
|
||||
}
|
||||
return byteCount;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArrayUtils);
|
||||
|
||||
|
|
Loading…
Reference in a new issue