Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9cb0f9df authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi Committed by Android Git Automerger
Browse files

am 75d1cb66: Add buffer writing methods.

* commit '75d1cb66':
  Add buffer writing methods.
parents 5db202d6 75d1cb66
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -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 */
+54 −1
Original line number Diff line number Diff line
@@ -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 */