blob: 3b9679a4c28ff6486f8e9ac439bafb4d4941392a [file] [log] [blame]
Paul Sokolovskye9db8402014-04-10 03:45:38 +03001#include <assert.h>
2#include <string.h>
3#include "misc.h"
4#include "mpconfig.h"
5#include "qstr.h"
6#include "obj.h"
7#include "builtin.h"
8#include "objtuple.h"
9#include "binary.h"
10
11#if MICROPY_ENABLE_MOD_STRUCT
12
13STATIC char get_fmt_type(const char **fmt) {
14 char t = **fmt;
15 switch (t) {
16 case '!':
17 t = '>';
18 break;
19 case '@':
20 case '=':
21 case '<':
22 case '>':
23 break;
24 default:
25 return '@';
26 }
27 // Skip type char
28 (*fmt)++;
29 return t;
30}
31
32STATIC uint calcsize_items(const char *fmt) {
33 // TODO
34 return strlen(fmt);
35}
36
37STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
38 const char *fmt = mp_obj_str_get_str(fmt_in);
39 char fmt_type = get_fmt_type(&fmt);
Paul Sokolovsky0c43cf92014-04-11 03:47:21 +030040 (void)fmt_type;
Damien Georgebf8ae4d2014-04-10 13:53:31 +010041 machine_uint_t size;
Paul Sokolovskye9db8402014-04-10 03:45:38 +030042 for (size = 0; *fmt; fmt++) {
43 int sz = mp_binary_get_size(*fmt);
44 // TODO
45 assert(sz != -1);
46 size += sz;
47 }
48 return MP_OBJ_NEW_SMALL_INT(size);
49}
50MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize);
51
52STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) {
53 // TODO: "The buffer must contain exactly the amount of data required by the format (len(bytes) must equal calcsize(fmt))."
54 const char *fmt = mp_obj_str_get_str(fmt_in);
55 char fmt_type = get_fmt_type(&fmt);
Paul Sokolovskye9db8402014-04-10 03:45:38 +030056 uint size = calcsize_items(fmt);
57 mp_obj_tuple_t *res = mp_obj_new_tuple(size, NULL);
58 buffer_info_t bufinfo;
59 mp_get_buffer_raise(data_in, &bufinfo);
60 byte *p = bufinfo.buf;
61
62 for (uint i = 0; i < size; i++) {
Paul Sokolovsky0c43cf92014-04-11 03:47:21 +030063 mp_obj_t item = mp_binary_get_val(fmt_type, *fmt++, &p);
Paul Sokolovskye9db8402014-04-10 03:45:38 +030064 res->items[i] = item;
65 }
66 return res;
67}
68MP_DEFINE_CONST_FUN_OBJ_2(struct_unpack_obj, struct_unpack);
69
70STATIC const mp_map_elem_t mp_module_struct_globals_table[] = {
71 { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_struct) },
72 { MP_OBJ_NEW_QSTR(MP_QSTR_calcsize), (mp_obj_t)&struct_calcsize_obj },
73 { MP_OBJ_NEW_QSTR(MP_QSTR_unpack), (mp_obj_t)&struct_unpack_obj },
74};
75
76STATIC const mp_obj_dict_t mp_module_struct_globals = {
77 .base = {&mp_type_dict},
78 .map = {
79 .all_keys_are_qstrs = 1,
80 .table_is_fixed_array = 1,
81 .used = sizeof(mp_module_struct_globals_table) / sizeof(mp_map_elem_t),
82 .alloc = sizeof(mp_module_struct_globals_table) / sizeof(mp_map_elem_t),
83 .table = (mp_map_elem_t*)mp_module_struct_globals_table,
84 },
85};
86
87const mp_obj_module_t mp_module_struct = {
88 .base = { &mp_type_module },
89 .name = MP_QSTR_struct,
90 .globals = (mp_obj_dict_t*)&mp_module_struct_globals,
91};
92
93#endif