Skip to content

Commit b41cbe9

Browse files
mrmcwethytannewt
authored andcommitted
CircuitPython now has struct instead of ustruct (micropython#302)
Added struct module to shared-bindings and shared-module. removed ustruct
1 parent 88c6d23 commit b41cbe9

File tree

10 files changed

+439
-6
lines changed

10 files changed

+439
-6
lines changed

atmel-samd/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ SRC_SHARED_MODULE = \
292292
os/__init__.c \
293293
random/__init__.c \
294294
storage/__init__.c \
295+
struct/__init__.c \
295296
uheap/__init__.c \
296297
ustack/__init__.c
297298

atmel-samd/mpconfigport.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
#define MICROPY_PY_IO (0)
5757
#define MICROPY_PY_URANDOM (0)
5858
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0)
59-
#define MICROPY_PY_STRUCT (1)
59+
#define MICROPY_PY_STRUCT (0)
6060
#define MICROPY_PY_SYS (1)
6161
// If you change MICROPY_LONGINT_IMPL, also change MPY_TOOL_LONGINT_IMPL in mpconfigport.mk.
6262
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
@@ -161,6 +161,7 @@ extern const struct _mp_obj_module_t board_module;
161161
extern const struct _mp_obj_module_t os_module;
162162
extern const struct _mp_obj_module_t random_module;
163163
extern const struct _mp_obj_module_t storage_module;
164+
extern const struct _mp_obj_module_t struct_module;
164165
extern const struct _mp_obj_module_t time_module;
165166
extern const struct _mp_obj_module_t cpy_nvm_module;
166167
extern const struct _mp_obj_module_t neopixel_write_module;
@@ -223,6 +224,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
223224
{ MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)&microcontroller_module }, \
224225
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, \
225226
{ MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \
227+
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \
226228
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module },
227229
EXTRA_BUILTIN_MODULES
228230

esp8266/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ SRC_SHARED_MODULE = \
143143
multiterminal/__init__.c \
144144
os/__init__.c \
145145
random/__init__.c \
146-
storage/__init__.c
146+
storage/__init__.c \
147+
struct/__init__.c
147148

148149
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
149150
$(addprefix shared-module/, $(SRC_SHARED_MODULE))

esp8266/mpconfigport.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
#define MICROPY_PY_CMATH (0)
5656
#define MICROPY_PY_IO (1)
5757
#define MICROPY_PY_IO_FILEIO (1)
58-
#define MICROPY_PY_STRUCT (1)
58+
#define MICROPY_PY_STRUCT (0)
5959
#define MICROPY_PY_SYS (1)
6060
#define MICROPY_PY_SYS_MAXSIZE (1)
6161
#define MICROPY_PY_SYS_EXIT (1)
@@ -159,6 +159,7 @@ extern const struct _mp_obj_module_t network_module;
159159
extern const struct _mp_obj_module_t os_module;
160160
extern const struct _mp_obj_module_t random_module;
161161
extern const struct _mp_obj_module_t storage_module;
162+
extern const struct _mp_obj_module_t struct_module;
162163
extern const struct _mp_obj_module_t mp_module_lwip;
163164
extern const struct _mp_obj_module_t mp_module_machine;
164165
extern const struct _mp_obj_module_t mp_module_onewire;
@@ -189,6 +190,7 @@ extern const struct _mp_obj_module_t multiterminal_module;
189190
{ MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \
190191
{ MP_OBJ_NEW_QSTR(MP_QSTR_storage), (mp_obj_t)&storage_module }, \
191192
{ MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \
193+
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \
192194
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
193195
{ MP_OBJ_NEW_QSTR(MP_QSTR_multiterminal), (mp_obj_t)&multiterminal_module }, \
194196

shared-bindings/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Module / Port SAMD21 SAMD21 Express ESP8266
3030
`pulseio` No **Yes** No
3131
`random` **Yes** **Yes** **Yes**
3232
`storage` **Yes** **Yes** **Yes**
33+
`struct` **Yes** **Yes** **Yes**
3334
`time` **Yes** **Yes** **Yes**
3435
`touchio` **Yes** **Yes** No
3536
`uheap` Debug Debug Debug

shared-bindings/struct/__init__.c

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013, 2014 Damien P. George
7+
* Copyright (c) 2014 Paul Sokolovsky
8+
* Copyright (c) 2017 Michael McWethy
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* in the Software without restriction, including without limitation the rights
13+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
* copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in
18+
* all copies or substantial portions of the Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26+
* THE SOFTWARE.
27+
*/
28+
29+
#include <assert.h>
30+
#include <string.h>
31+
32+
#include "py/runtime.h"
33+
#include "py/builtin.h"
34+
#include "py/objtuple.h"
35+
#include "py/binary.h"
36+
#include "py/parsenum.h"
37+
#include "shared-bindings/struct/__init__.h"
38+
#include "shared-module/struct/__init__.h"
39+
40+
//| :mod:`struct` --- manipulation of c-style data
41+
//| ========================================================
42+
//|
43+
//| .. module:: struct
44+
//| :synopsis: byte data control
45+
//| :platform: SAMD21
46+
//|
47+
//| This module implements a subset of the corresponding CPython module,
48+
//| as described below. For more information, refer to the original CPython
49+
//| documentation: struct.
50+
//|
51+
//| Supported size/byte order prefixes: *@*, *<*, *>*, *!*.
52+
//|
53+
//| Supported format codes: *b*, *B*, *h*, *H*, *i*, *I*, *l*, *L*, *q*, *Q*,
54+
//| *s*, *P*, *f*, *d* (the latter 2 depending on the floating-point support).
55+
56+
57+
//| .. function:: calcsize(fmt)
58+
//|
59+
//| Return the number of bytes needed to store the given fmt.
60+
//|
61+
62+
STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
63+
64+
return MP_OBJ_NEW_SMALL_INT(shared_modules_struct_calcsize(fmt_in));
65+
}
66+
MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize);
67+
68+
//| .. function:: pack(fmt, v1, v2, ...)
69+
//|
70+
//| Pack the values v1, v2, ... according to the format string fmt.
71+
//| The return value is a bytes object encoding the values.
72+
//|
73+
74+
STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) {
75+
// TODO: "The arguments must match the values required by the format exactly."
76+
mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0]));
77+
vstr_t vstr;
78+
vstr_init_len(&vstr, size);
79+
byte *p = (byte*)vstr.buf;
80+
memset(p, 0, size);
81+
byte *end_p = &p[size];
82+
shared_modules_struct_pack_into(args[0], p, end_p, n_args - 1, &args[1]);
83+
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
84+
}
85+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack);
86+
87+
88+
//| .. function:: pack_into(fmt, buffer, offset, v1, v2, ...)
89+
//|
90+
//| Pack the values v1, v2, ... according to the format string fmt into a buffer
91+
//| starting at offset. offset may be negative to count from the end of buffer.
92+
//|
93+
94+
STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) {
95+
mp_buffer_info_t bufinfo;
96+
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
97+
mp_int_t offset = mp_obj_get_int(args[2]);
98+
if (offset < 0) {
99+
// negative offsets are relative to the end of the buffer
100+
offset = (mp_int_t)bufinfo.len + offset;
101+
if (offset < 0) {
102+
mp_raise_RuntimeError("buffer too small");
103+
}
104+
}
105+
byte *p = (byte *)bufinfo.buf;
106+
byte *end_p = &p[bufinfo.len];
107+
p += offset;
108+
109+
shared_modules_struct_pack_into(args[0], p, end_p, n_args - 3, &args[3]);
110+
return mp_const_none;
111+
}
112+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_into_obj, 3, MP_OBJ_FUN_ARGS_MAX, struct_pack_into);
113+
114+
//| .. function:: unpack(fmt, data)
115+
//|
116+
//| Unpack from the data according to the format string fmt. The return value
117+
//| is a tuple of the unpacked values.
118+
//|
119+
120+
//| .. function:: unpack_from(fmt, data, offset)
121+
//|
122+
//| Unpack from the data starting at offset according to the format string fmt.
123+
//| offset may be negative to count from the end of buffer. The return value is
124+
//| a tuple of the unpacked values.
125+
//|
126+
127+
STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
128+
// unpack requires that the buffer be exactly the right size.
129+
// unpack_from requires that the buffer be "big enough".
130+
// Since we implement unpack and unpack_from using the same function
131+
// we relax the "exact" requirement, and only implement "big enough".
132+
mp_buffer_info_t bufinfo;
133+
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
134+
byte *p = bufinfo.buf;
135+
byte *end_p = &p[bufinfo.len];
136+
137+
if (n_args > 2) {
138+
mp_int_t offset = mp_obj_get_int(args[2]);
139+
// offset arg provided
140+
if (offset < 0) {
141+
// negative offsets are relative to the end of the buffer
142+
offset = bufinfo.len + offset;
143+
if (offset < 0) {
144+
mp_raise_RuntimeError("buffer too small");
145+
}
146+
}
147+
p += offset;
148+
}
149+
150+
return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[0] , p, end_p));
151+
}
152+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_from_obj, 2, 3, struct_unpack_from);
153+
154+
STATIC const mp_rom_map_elem_t mp_module_struct_globals_table[] = {
155+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_struct) },
156+
{ MP_ROM_QSTR(MP_QSTR_calcsize), MP_ROM_PTR(&struct_calcsize_obj) },
157+
{ MP_ROM_QSTR(MP_QSTR_pack), MP_ROM_PTR(&struct_pack_obj) },
158+
{ MP_ROM_QSTR(MP_QSTR_pack_into), MP_ROM_PTR(&struct_pack_into_obj) },
159+
{ MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&struct_unpack_from_obj) },
160+
{ MP_ROM_QSTR(MP_QSTR_unpack_from), MP_ROM_PTR(&struct_unpack_from_obj) },
161+
};
162+
163+
STATIC MP_DEFINE_CONST_DICT(mp_module_struct_globals, mp_module_struct_globals_table);
164+
165+
const mp_obj_module_t struct_module = {
166+
.base = { &mp_type_module },
167+
.globals = (mp_obj_dict_t*)&mp_module_struct_globals,
168+
};

shared-bindings/struct/__init__.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_STRUCT___INIT___H
28+
#define MICROPY_INCLUDED_SHARED_BINDINGS_STRUCT___INIT___H
29+
30+
void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args);
31+
mp_uint_t shared_modules_struct_calcsize(mp_obj_t fmt_in);
32+
mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p);
33+
34+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_RANDOM___INIT___H

0 commit comments

Comments
 (0)