@@ -33,14 +33,22 @@ cdef class BaseArrayCodec(BaseCodec):
33
33
cdef encode(self , WriteBuffer buf, object obj):
34
34
cdef:
35
35
WriteBuffer elem_data
36
+ WriteBuffer tuple_elem_data
36
37
int32_t ndims = 1
37
38
Py_ssize_t objlen
38
39
Py_ssize_t i
39
40
40
41
if not isinstance (
41
42
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
+ )
44
52
):
45
53
raise TypeError (
46
54
' only arrays of scalars are supported (got type {!r})' .format(
@@ -67,7 +75,20 @@ cdef class BaseArrayCodec(BaseCodec):
67
75
)
68
76
else :
69
77
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
+
71
92
except TypeError as e:
72
93
raise ValueError (
73
94
' invalid array element: {}' .format(
@@ -121,8 +142,27 @@ cdef class BaseArrayCodec(BaseCodec):
121
142
if elem_len == - 1 :
122
143
elem = None
123
144
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
+
126
166
if frb_get_len(& elem_buf):
127
167
raise RuntimeError (
128
168
f' unexpected trailing data in buffer after '
0 commit comments