Skip to content
Snippets Groups Projects
Commit df94b717 authored by Paul Sokolovsky's avatar Paul Sokolovsky
Browse files

modstruct: Implement count specifier for strings (e.g. "100s").

Infra for counts of other types is there, need last mile to be implemented.
parent 147c80bf
Branches
No related tags found
No related merge requests found
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "objtuple.h" #include "objtuple.h"
#include "objstr.h" #include "objstr.h"
#include "binary.h" #include "binary.h"
#include "parsenum.h"
#if MICROPY_ENABLE_MOD_STRUCT #if MICROPY_ENABLE_MOD_STRUCT
...@@ -56,9 +57,26 @@ STATIC char get_fmt_type(const char **fmt) { ...@@ -56,9 +57,26 @@ STATIC char get_fmt_type(const char **fmt) {
return t; return t;
} }
STATIC machine_uint_t get_fmt_num(const char **p) {
const char *num = *p;
uint len = 1;
while (unichar_isdigit(*++num)) {
len++;
}
machine_uint_t val = (machine_uint_t)MP_OBJ_SMALL_INT_VALUE(mp_parse_num_integer(*p, len, 10));
*p = num;
return val;
}
STATIC uint calcsize_items(const char *fmt) { STATIC uint calcsize_items(const char *fmt) {
// TODO uint cnt = 0;
return strlen(fmt); while (*fmt) {
// TODO supports size spec only for "s"
if (!unichar_isdigit(*fmt++)) {
cnt++;
}
}
return cnt;
} }
STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) { STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
...@@ -67,9 +85,23 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) { ...@@ -67,9 +85,23 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
machine_uint_t size; machine_uint_t size;
for (size = 0; *fmt; fmt++) { for (size = 0; *fmt; fmt++) {
uint align; uint align;
int sz = mp_binary_get_size(fmt_type, *fmt, &align); machine_uint_t cnt = 1;
if (unichar_isdigit(*fmt)) {
cnt = get_fmt_num(&fmt);
}
if (cnt > 1) {
// TODO: count spec support only for string len
assert(*fmt == 's');
}
machine_uint_t sz;
if (*fmt == 's') {
sz = cnt;
} else {
sz = (machine_uint_t)mp_binary_get_size(fmt_type, *fmt, &align);
}
// TODO // TODO
assert(sz != -1); assert(sz != (machine_uint_t)-1);
// Apply alignment // Apply alignment
size = (size + align - 1) & ~(align - 1); size = (size + align - 1) & ~(align - 1);
size += sz; size += sz;
...@@ -89,7 +121,22 @@ STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) { ...@@ -89,7 +121,22 @@ STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) {
byte *p = bufinfo.buf; byte *p = bufinfo.buf;
for (uint i = 0; i < size; i++) { for (uint i = 0; i < size; i++) {
mp_obj_t item = mp_binary_get_val(fmt_type, *fmt++, &p); machine_uint_t sz = 1;
if (unichar_isdigit(*fmt)) {
sz = get_fmt_num(&fmt);
}
if (sz > 1) {
// TODO: size spec support only for string len
assert(*fmt == 's');
}
mp_obj_t item;
if (*fmt == 's') {
item = mp_obj_new_bytes(p, sz);
p += sz;
fmt++;
} else {
item = mp_binary_get_val(fmt_type, *fmt++, &p);
}
res->items[i] = item; res->items[i] = item;
} }
return res; return res;
...@@ -106,8 +153,30 @@ STATIC mp_obj_t struct_pack(uint n_args, mp_obj_t *args) { ...@@ -106,8 +153,30 @@ STATIC mp_obj_t struct_pack(uint n_args, mp_obj_t *args) {
memset(p, 0, size); memset(p, 0, size);
for (uint i = 1; i < n_args; i++) { for (uint i = 1; i < n_args; i++) {
machine_uint_t sz = 1;
if (unichar_isdigit(*fmt)) {
sz = get_fmt_num(&fmt);
}
if (sz > 1) {
// TODO: size spec support only for string len
assert(*fmt == 's');
}
if (*fmt == 's') {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[i], &bufinfo, MP_BUFFER_READ);
machine_uint_t to_copy = sz;
if (bufinfo.len < to_copy) {
to_copy = bufinfo.len;
}
memcpy(p, bufinfo.buf, to_copy);
memset(p + to_copy, 0, sz - to_copy);
p += sz;
fmt++;
} else {
mp_binary_set_val(fmt_type, *fmt++, args[i], &p); mp_binary_set_val(fmt_type, *fmt++, args[i], &p);
} }
}
return res; return res;
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack);
......
...@@ -16,3 +16,8 @@ print(struct.pack(">b", 1)) ...@@ -16,3 +16,8 @@ print(struct.pack(">b", 1))
print(struct.pack("<bI", -128, 256)) print(struct.pack("<bI", -128, 256))
print(struct.pack(">bI", -128, 256)) print(struct.pack(">bI", -128, 256))
print(struct.calcsize("100sI"))
print(struct.calcsize("97sI"))
print(struct.unpack("<6sH", b"foo\0\0\0\x12\x34"))
print(struct.pack("<6sH", b"foo", 10000))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment