@@ -85,10 +85,15 @@ STATIC mp_uint_t get_fmt_num(const char **p) {
8585STATIC uint calcsize_items (const char * fmt ) {
8686 uint cnt = 0 ;
8787 while (* fmt ) {
88- // TODO supports size spec only for "s"
89- if (!unichar_isdigit (* fmt ++ )) {
90- cnt ++ ;
88+ int num = 1 ;
89+ if (unichar_isdigit (* fmt )) {
90+ num = get_fmt_num (& fmt );
91+ if (* fmt == 's' ) {
92+ num = 1 ;
93+ }
9194 }
95+ cnt += num ;
96+ fmt ++ ;
9297 }
9398 return cnt ;
9499}
@@ -103,24 +108,25 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
103108 if (unichar_isdigit (* fmt )) {
104109 cnt = get_fmt_num (& fmt );
105110 }
106- if (cnt > 1 ) {
107- // TODO: count spec support only for string len
108- if (* fmt != 's' ) {
109- mp_not_implemented ("count>1" );
110- }
111- }
112111
113- mp_uint_t sz ;
112+ mp_uint_t sz = 0 ;
114113 if (* fmt == 's' ) {
115114 sz = cnt ;
116- } else {
117- sz = (mp_uint_t )mp_binary_get_size (fmt_type , * fmt , & align );
115+ cnt = 1 ;
116+ }
117+
118+ while (cnt -- ) {
119+ // If we already have size for 's' case, don't set it again
120+ if (sz == 0 ) {
121+ sz = (mp_uint_t )mp_binary_get_size (fmt_type , * fmt , & align );
122+ }
123+ // TODO
124+ assert (sz != (mp_uint_t )- 1 );
125+ // Apply alignment
126+ size = (size + align - 1 ) & ~(align - 1 );
127+ size += sz ;
128+ sz = 0 ;
118129 }
119- // TODO
120- assert (sz != (mp_uint_t )- 1 );
121- // Apply alignment
122- size = (size + align - 1 ) & ~(align - 1 );
123- size += sz ;
124130 }
125131 return MP_OBJ_NEW_SMALL_INT (size );
126132}
@@ -136,26 +142,24 @@ STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) {
136142 mp_get_buffer_raise (data_in , & bufinfo , MP_BUFFER_READ );
137143 byte * p = bufinfo .buf ;
138144
139- for (uint i = 0 ; i < size ; i ++ ) {
145+ for (uint i = 0 ; i < size ;) {
140146 mp_uint_t sz = 1 ;
141147 if (unichar_isdigit (* fmt )) {
142148 sz = get_fmt_num (& fmt );
143149 }
144- if (sz > 1 ) {
145- // TODO: size spec support only for string len
146- if (* fmt != 's' ) {
147- mp_not_implemented ("count>1" );
148- }
149- }
150+
150151 mp_obj_t item ;
151152 if (* fmt == 's' ) {
152153 item = mp_obj_new_bytes (p , sz );
153154 p += sz ;
154- fmt ++ ;
155+ res -> items [ i ++ ] = item ;
155156 } else {
156- item = mp_binary_get_val (fmt_type , * fmt ++ , & p );
157+ while (sz -- ) {
158+ item = mp_binary_get_val (fmt_type , * fmt , & p );
159+ res -> items [i ++ ] = item ;
160+ }
157161 }
158- res -> items [ i ] = item ;
162+ fmt ++ ;
159163 }
160164 return res ;
161165}
@@ -171,32 +175,28 @@ STATIC mp_obj_t struct_pack(mp_uint_t n_args, const mp_obj_t *args) {
171175 byte * p = (byte * )vstr .buf ;
172176 memset (p , 0 , size );
173177
174- for (mp_uint_t i = 1 ; i < n_args ; i ++ ) {
178+ for (mp_uint_t i = 1 ; i < n_args ;) {
175179 mp_uint_t sz = 1 ;
176180 if (unichar_isdigit (* fmt )) {
177181 sz = get_fmt_num (& fmt );
178182 }
179- if (sz > 1 ) {
180- // TODO: size spec support only for string len
181- if (* fmt != 's' ) {
182- mp_not_implemented ("count>1" );
183- }
184- }
185183
186184 if (* fmt == 's' ) {
187185 mp_buffer_info_t bufinfo ;
188- mp_get_buffer_raise (args [i ], & bufinfo , MP_BUFFER_READ );
186+ mp_get_buffer_raise (args [i ++ ], & bufinfo , MP_BUFFER_READ );
189187 mp_uint_t to_copy = sz ;
190188 if (bufinfo .len < to_copy ) {
191189 to_copy = bufinfo .len ;
192190 }
193191 memcpy (p , bufinfo .buf , to_copy );
194192 memset (p + to_copy , 0 , sz - to_copy );
195193 p += sz ;
196- fmt ++ ;
197194 } else {
198- mp_binary_set_val (fmt_type , * fmt ++ , args [i ], & p );
195+ while (sz -- ) {
196+ mp_binary_set_val (fmt_type , * fmt , args [i ++ ], & p );
197+ }
199198 }
199+ fmt ++ ;
200200 }
201201
202202 return mp_obj_new_str_from_vstr (& mp_type_bytes , & vstr );
0 commit comments