@@ -33,14 +33,22 @@ cdef class BaseArrayCodec(BaseCodec):
3333 cdef encode(self , WriteBuffer buf, object obj):
3434 cdef:
3535 WriteBuffer elem_data
36+ WriteBuffer tuple_elem_data
3637 int32_t ndims = 1
3738 Py_ssize_t objlen
3839 Py_ssize_t i
3940
4041 if not isinstance (
4142 self .sub_codec,
42- (ScalarCodec, TupleCodec, NamedTupleCodec, EnumCodec,
43- RangeCodec, MultiRangeCodec)
43+ (
44+ ScalarCodec,
45+ TupleCodec,
46+ NamedTupleCodec,
47+ EnumCodec,
48+ RangeCodec,
49+ MultiRangeCodec,
50+ ArrayCodec,
51+ )
4452 ):
4553 raise TypeError (
4654 ' only arrays of scalars are supported (got type {!r})' .format(
@@ -67,7 +75,20 @@ cdef class BaseArrayCodec(BaseCodec):
6775 )
6876 else :
6977 try :
70- self .sub_codec.encode(elem_data, item)
78+ if isinstance (self .sub_codec, ArrayCodec):
79+ # This is an array of array.
80+ # Wrap the inner array with a tuple.
81+ tuple_elem_data = WriteBuffer.new()
82+ self .sub_codec.encode(tuple_elem_data, item)
83+
84+ elem_data.write_int32(4 + 4 + tuple_elem_data.len()) # buffer length
85+ elem_data.write_int32(1 ) # tuple_elem_count
86+ elem_data.write_int32(0 ) # reserved
87+ elem_data.write_buffer(tuple_elem_data)
88+
89+ else :
90+ self .sub_codec.encode(elem_data, item)
91+
7192 except TypeError as e:
7293 raise ValueError (
7394 ' invalid array element: {}' .format(
@@ -121,8 +142,27 @@ cdef class BaseArrayCodec(BaseCodec):
121142 if elem_len == - 1 :
122143 elem = None
123144 else :
124- frb_slice_from(& elem_buf, buf, elem_len)
125- elem = self .sub_codec.decode(& elem_buf)
145+
146+ if isinstance (self .sub_codec, ArrayCodec):
147+ # This is an array of array
148+ # Unwrap the tuple from the inner array.
149+ tuple_elem_count = < Py_ssize_t>< uint32_t> hton.unpack_int32(frb_read(buf, 4 ))
150+ if tuple_elem_count != 1 :
151+ raise RuntimeError (
152+ f' cannot decode inner array: expected 1 '
153+ f' element, got {tuple_elem_count}' )
154+
155+ frb_read(buf, 4 ) # reserved
156+ tuple_elem_len = hton.unpack_int32(frb_read(buf, 4 ))
157+
158+ elem = self .sub_codec.decode(
159+ frb_slice_from(& elem_buf, buf, tuple_elem_len)
160+ )
161+
162+ else :
163+ frb_slice_from(& elem_buf, buf, elem_len)
164+ elem = self .sub_codec.decode(& elem_buf)
165+
126166 if frb_get_len(& elem_buf):
127167 raise RuntimeError (
128168 f' unexpected trailing data in buffer after '
0 commit comments