Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions cpp/fory/util/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ class Buffer {
memcpy(data_ + offset, data, (size_t)length);
}

FORY_ALWAYS_INLINE void PutInt24(uint32_t offset, int32_t value) {
data_[offset] = static_cast<uint8_t>(value);
data_[offset + 1] = static_cast<uint8_t>(value >> 8);
data_[offset + 2] = static_cast<uint8_t>(value >> 16);
}

template <typename T> FORY_ALWAYS_INLINE T Get(uint32_t relative_offset) {
FORY_CHECK(relative_offset < size_) << "Out of range " << relative_offset
<< " should be less than " << size_;
Expand Down Expand Up @@ -164,6 +170,15 @@ class Buffer {
return Get<int16_t>(offset);
}

FORY_ALWAYS_INLINE int32_t GetInt24(uint32_t offset) {
FORY_CHECK(offset + 3 <= size_)
<< "Out of range " << offset << " should be less than " << size_;
int32_t b0 = data_[offset];
int32_t b1 = data_[offset + 1];
int32_t b2 = data_[offset + 2];
return (b0 & 0xFF) | ((b1 & 0xFF) << 8) | ((b2 & 0xFF) << 16);
}

FORY_ALWAYS_INLINE int32_t GetInt32(uint32_t offset) {
return Get<int32_t>(offset);
}
Expand Down Expand Up @@ -541,6 +556,14 @@ class Buffer {
IncreaseWriterIndex(2);
}

/// Write int24 value as fixed 3 bytes to buffer at current writer index.
/// Automatically grows buffer and advances writer index.
FORY_ALWAYS_INLINE void WriteInt24(int32_t value) {
Grow(3);
PutInt24(writer_index_, value);
IncreaseWriterIndex(3);
}

/// Write int32_t value as fixed 4 bytes to buffer at current writer index.
/// Automatically grows buffer and advances writer index.
FORY_ALWAYS_INLINE void WriteInt32(int32_t value) {
Expand Down Expand Up @@ -713,6 +736,19 @@ class Buffer {
return value;
}

/// Read int24 value from buffer. Sets error on bounds violation.
FORY_ALWAYS_INLINE int32_t ReadInt24(Error &error) {
if (FORY_PREDICT_FALSE(reader_index_ + 3 > size_)) {
error.set_buffer_out_of_bound(reader_index_, 3, size_);
return 0;
}
int32_t b0 = data_[reader_index_];
int32_t b1 = data_[reader_index_ + 1];
int32_t b2 = data_[reader_index_ + 2];
reader_index_ += 3;
return (b0 & 0xFF) | ((b1 & 0xFF) << 8) | ((b2 & 0xFF) << 16);
}

/// Read uint32_t value from buffer (fixed 4 bytes). Sets error on bounds
/// violation.
FORY_ALWAYS_INLINE uint32_t ReadUint32(Error &error) {
Expand Down
13 changes: 6 additions & 7 deletions python/pyfory/buffer.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,28 @@
# cython: annotate = True

from libc.stdint cimport *
from libcpp.memory cimport shared_ptr
from libcpp cimport bool as c_bool
from pyfory.includes.libutil cimport CBuffer
from libcpp.memory cimport shared_ptr
from pyfory.includes.libutil cimport CBuffer, CError


cdef class Buffer:
"""This class implements the Python 'buffer protocol', which allows
us to use it for calls into Python libraries without having to
copy the data."""
cdef:
shared_ptr[CBuffer] c_buffer
CBuffer* c_buffer_ptr
uint8_t* _c_address
int32_t _c_size
CBuffer c_buffer
CError _error
# hold python buffer reference count
object data
Py_ssize_t shape[1]
Py_ssize_t stride[1]
public int32_t reader_index, writer_index

@staticmethod
cdef Buffer wrap(shared_ptr[CBuffer] c_buffer)

cdef void _raise_if_error(self)

cpdef inline check_bound(self, int32_t offset, int32_t length)

cdef getitem(self, int64_t i)
Expand Down
Loading
Loading