diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.cpp
index 825b72c6afe92ea073e44cd9044427f67f540bbf..833063c176fa5532abb81d17d0fe565f63b5bd70 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.cpp
@@ -25,7 +25,7 @@ const size_t BufferWithExtendableBuffer::EXTEND_ADDITIONAL_BUFFER_SIZE_STEP = 12
 
 uint32_t BufferWithExtendableBuffer::readUint(const int size, const int pos) const {
     const bool readingPosIsInAdditionalBuffer = isInAdditionalBuffer(pos);
-    const int posInBuffer = readingPosIsInAdditionalBuffer ? pos - mOriginalBufferSize : pos;
+    const int posInBuffer = readingPosIsInAdditionalBuffer ? pos - mOriginalBuffer.size() : pos;
     return ByteArrayUtils::readUint(getBuffer(readingPosIsInAdditionalBuffer), size, posInBuffer);
 }
 
@@ -40,12 +40,12 @@ void BufferWithExtendableBuffer::readCodePointsAndAdvancePosition(const int maxC
         int *const outCodePoints, int *outCodePointCount, int *const pos) const {
     const bool readingPosIsInAdditionalBuffer = isInAdditionalBuffer(*pos);
     if (readingPosIsInAdditionalBuffer) {
-        *pos -= mOriginalBufferSize;
+        *pos -= mOriginalBuffer.size();
     }
     *outCodePointCount = ByteArrayUtils::readStringAndAdvancePosition(
             getBuffer(readingPosIsInAdditionalBuffer), maxCodePointCount, outCodePoints, pos);
     if (readingPosIsInAdditionalBuffer) {
-        *pos += mOriginalBufferSize;
+        *pos += mOriginalBuffer.size();
     }
 }
 
@@ -69,13 +69,14 @@ bool BufferWithExtendableBuffer::writeUintAndAdvancePosition(const uint32_t data
         return false;
     }
     const bool usesAdditionalBuffer = isInAdditionalBuffer(*pos);
-    uint8_t *const buffer = usesAdditionalBuffer ? &mAdditionalBuffer[0] : mOriginalBuffer;
+    uint8_t *const buffer =
+            usesAdditionalBuffer ? mAdditionalBuffer.data() : mOriginalBuffer.data();
     if (usesAdditionalBuffer) {
-        *pos -= mOriginalBufferSize;
+        *pos -= mOriginalBuffer.size();
     }
     ByteArrayUtils::writeUintAndAdvancePosition(buffer, data, size, pos);
     if (usesAdditionalBuffer) {
-        *pos += mOriginalBufferSize;
+        *pos += mOriginalBuffer.size();
     }
     return true;
 }
@@ -88,14 +89,15 @@ bool BufferWithExtendableBuffer::writeCodePointsAndAdvancePosition(const int *co
         return false;
     }
     const bool usesAdditionalBuffer = isInAdditionalBuffer(*pos);
-    uint8_t *const buffer = usesAdditionalBuffer ? &mAdditionalBuffer[0] : mOriginalBuffer;
+    uint8_t *const buffer =
+            usesAdditionalBuffer ? mAdditionalBuffer.data() : mOriginalBuffer.data();
     if (usesAdditionalBuffer) {
-        *pos -= mOriginalBufferSize;
+        *pos -= mOriginalBuffer.size();
     }
     ByteArrayUtils::writeCodePointsAndAdvancePosition(buffer, codePoints, codePointCount,
             writesTerminator, pos);
     if (usesAdditionalBuffer) {
-        *pos += mOriginalBufferSize;
+        *pos += mOriginalBuffer.size();
     }
     return true;
 }
@@ -119,7 +121,7 @@ bool BufferWithExtendableBuffer::checkAndPrepareWriting(const int pos, const int
     const size_t totalRequiredSize = static_cast<size_t>(pos + size);
     if (!isInAdditionalBuffer(pos)) {
         // Here don't need to care about the additional buffer.
-        if (static_cast<size_t>(mOriginalBufferSize) < totalRequiredSize) {
+        if (mOriginalBuffer.size() < totalRequiredSize) {
             // Violate the boundary.
             return false;
         }
@@ -137,7 +139,7 @@ bool BufferWithExtendableBuffer::checkAndPrepareWriting(const int pos, const int
         return false;
     }
     const size_t extendSize = totalRequiredSize -
-            std::min(mAdditionalBuffer.size() + mOriginalBufferSize, totalRequiredSize);
+            std::min(mAdditionalBuffer.size() + mOriginalBuffer.size(), totalRequiredSize);
     if (extendSize > 0 && !extendBuffer(extendSize)) {
         // Failed to extend the buffer.
         return false;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h b/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h
index 5e1362eeee80bc62e28ce8c6969dba8707ccc694..24e2dd4c8b6fa273a2e79823d1cc57f35f7a6eca 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h
@@ -23,6 +23,7 @@
 
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/utils/byte_array_utils.h"
+#include "utils/byte_array_view.h"
 
 namespace latinime {
 
@@ -36,18 +37,17 @@ class BufferWithExtendableBuffer {
 
     BufferWithExtendableBuffer(uint8_t *const originalBuffer, const int originalBufferSize,
             const int maxAdditionalBufferSize)
-            : mOriginalBuffer(originalBuffer), mOriginalBufferSize(originalBufferSize),
+            : mOriginalBuffer(originalBuffer, originalBufferSize),
               mAdditionalBuffer(0), mUsedAdditionalBufferSize(0),
               mMaxAdditionalBufferSize(maxAdditionalBufferSize) {}
 
     // Without original buffer.
     BufferWithExtendableBuffer(const int maxAdditionalBufferSize)
-            : mOriginalBuffer(0), mOriginalBufferSize(0),
-              mAdditionalBuffer(0), mUsedAdditionalBufferSize(0),
+            : mOriginalBuffer(), mAdditionalBuffer(0), mUsedAdditionalBufferSize(0),
               mMaxAdditionalBufferSize(maxAdditionalBufferSize) {}
 
     AK_FORCE_INLINE int getTailPosition() const {
-        return mOriginalBufferSize + mUsedAdditionalBufferSize;
+        return mOriginalBuffer.size() + mUsedAdditionalBufferSize;
     }
 
     AK_FORCE_INLINE int getUsedAdditionalBufferSize() const {
@@ -58,16 +58,16 @@ class BufferWithExtendableBuffer {
      * For reading.
      */
     AK_FORCE_INLINE bool isInAdditionalBuffer(const int position) const {
-        return position >= mOriginalBufferSize;
+        return position >= static_cast<int>(mOriginalBuffer.size());
     }
 
     // TODO: Resolve the issue that the address can be changed when the vector is resized.
     // CAVEAT!: Be careful about array out of bound access with buffers
     AK_FORCE_INLINE const uint8_t *getBuffer(const bool usesAdditionalBuffer) const {
         if (usesAdditionalBuffer) {
-            return &mAdditionalBuffer[0];
+            return mAdditionalBuffer.data();
         } else {
-            return mOriginalBuffer;
+            return mOriginalBuffer.data();
         }
     }
 
@@ -79,7 +79,7 @@ class BufferWithExtendableBuffer {
             int *const outCodePoints, int *outCodePointCount, int *const pos) const;
 
     AK_FORCE_INLINE int getOriginalBufferSize() const {
-        return mOriginalBufferSize;
+        return mOriginalBuffer.size();
     }
 
     AK_FORCE_INLINE bool isNearSizeLimit() const {
@@ -110,8 +110,7 @@ class BufferWithExtendableBuffer {
     static const int NEAR_BUFFER_LIMIT_THRESHOLD_PERCENTILE;
     static const size_t EXTEND_ADDITIONAL_BUFFER_SIZE_STEP;
 
-    uint8_t *const mOriginalBuffer;
-    const int mOriginalBufferSize;
+    const ReadWriteByteArrayView mOriginalBuffer;
     std::vector<uint8_t> mAdditionalBuffer;
     int mUsedAdditionalBufferSize;
     const size_t mMaxAdditionalBufferSize;