Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fix buffer handling and null detection to match original converter be…
…havior
  • Loading branch information
stvoutsin committed Jul 24, 2025
commit 11d94038c51f4debc5ac718a284d3229f592e1d8
13 changes: 9 additions & 4 deletions astropy/io/votable/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,9 @@ def binparse(self, read):
data = read(8)
if len(data) != 8:
raise EOFError("Unexpected end of file")
return fast_binparse_double(data)
value, _ = fast_binparse_double(data)
is_null = self.is_null(value)
return value, is_null


class Float(FloatingPoint):
Expand Down Expand Up @@ -971,7 +973,9 @@ def binparse(self, read):
data = read(4)
if len(data) != 4:
raise EOFError("Unexpected end of file")
return fast_binparse_int(data)
value, _ = fast_binparse_int(data)
is_null = self.is_null(value)
return value, is_null


class Long(Integer):
Expand All @@ -987,7 +991,9 @@ def binparse(self, read):
data = read(8)
if len(data) != 8:
raise EOFError("Unexpected end of file")
return fast_binparse_long(data)
value, _ = fast_binparse_long(data)
is_null = self.is_null(value)
return value, is_null


class ComplexArrayVarArray(VarArray):
Expand Down Expand Up @@ -1173,7 +1179,6 @@ def binparse(self, read):
def binoutput(self, value, mask):
if np.any(mask):
vo_warn(W39)

return bool_to_bitarray(value)


Expand Down
32 changes: 24 additions & 8 deletions astropy/io/votable/src/fast_converters.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,26 @@ ctypedef cnp.uint8_t bool_t

cdef bint NEED_BYTESWAP = sys.byteorder == 'little'

def fast_bitarray_to_bool(const unsigned char[::1] data, int length):
def fast_bitarray_to_bool(data, int length):
"""Convert packed bits to bool array"""
cdef const unsigned char[::1] byte_data

if hasattr(data, 'tobytes'):
byte_data = memoryview(data.tobytes())
elif isinstance(data, (bytes, bytearray)):
byte_data = memoryview(data)
else:
byte_data = data

cdef cnp.ndarray[bool_t, ndim=1] results = np.empty(length, dtype=np.bool_)
cdef int i = 0
cdef int byte_idx = 0
cdef int bit_no
cdef unsigned char byte_val
cdef bool_t bit_val

while i < length and byte_idx < data.shape[0]:
byte_val = data[byte_idx]
while i < length and byte_idx < byte_data.shape[0]:
byte_val = byte_data[byte_idx]
for bit_no in range(7, -1, -1):
if i >= length:
break
Expand All @@ -50,21 +59,28 @@ def fast_bitarray_to_bool(const unsigned char[::1] data, int length):

return results

def fast_bool_to_bitarray(const bool_t[::1] value):
"""Pack bools into bit array - reverse of above."""
cdef int length = value.shape[0]
def fast_bool_to_bitarray(value):
"""
Cython implementation of bool_to_bitarray.
"""
if np.isscalar(value):
flat_array = np.array([bool(value)], dtype=np.bool_)
else:
value_array = np.asarray(value, dtype=np.bool_)
flat_array = value_array.ravel()

cdef int length = len(flat_array)
cdef int num_bytes = (length + 7) // 8
cdef cnp.ndarray[unsigned char, ndim=1] result = np.zeros(num_bytes, dtype=np.uint8)

cdef int i
cdef int byte_idx
cdef int bit_no
cdef unsigned char byte_val

for i in range(length):
byte_idx = i // 8
bit_no = 7 - (i % 8)
if value[i]:
if flat_array[i]:
result[byte_idx] |= (1 << bit_no)

return result.tobytes()
Expand Down
Loading