Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions atmel-samd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ SRC_SHARED_MODULE = \
os/__init__.c \
random/__init__.c \
storage/__init__.c \
struct/__init__.c \
uheap/__init__.c \
ustack/__init__.c

Expand Down
4 changes: 3 additions & 1 deletion atmel-samd/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
#define MICROPY_PY_IO (0)
#define MICROPY_PY_URANDOM (0)
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0)
#define MICROPY_PY_STRUCT (1)
#define MICROPY_PY_STRUCT (0)
#define MICROPY_PY_SYS (1)
// If you change MICROPY_LONGINT_IMPL, also change MPY_TOOL_LONGINT_IMPL in mpconfigport.mk.
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
Expand Down Expand Up @@ -157,6 +157,7 @@ extern const struct _mp_obj_module_t board_module;
extern const struct _mp_obj_module_t os_module;
extern const struct _mp_obj_module_t random_module;
extern const struct _mp_obj_module_t storage_module;
extern const struct _mp_obj_module_t struct_module;
extern const struct _mp_obj_module_t time_module;
extern const struct _mp_obj_module_t cpy_nvm_module;
extern const struct _mp_obj_module_t neopixel_write_module;
Expand Down Expand Up @@ -219,6 +220,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
{ MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)&microcontroller_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module },
EXTRA_BUILTIN_MODULES

Expand Down
3 changes: 2 additions & 1 deletion esp8266/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ SRC_SHARED_MODULE = \
multiterminal/__init__.c \
os/__init__.c \
random/__init__.c \
storage/__init__.c
storage/__init__.c \
struct/__init__.c

SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
$(addprefix shared-module/, $(SRC_SHARED_MODULE))
Expand Down
4 changes: 3 additions & 1 deletion esp8266/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
#define MICROPY_PY_CMATH (0)
#define MICROPY_PY_IO (1)
#define MICROPY_PY_IO_FILEIO (1)
#define MICROPY_PY_STRUCT (1)
#define MICROPY_PY_STRUCT (0)
#define MICROPY_PY_SYS (1)
#define MICROPY_PY_SYS_MAXSIZE (1)
#define MICROPY_PY_SYS_EXIT (1)
Expand Down Expand Up @@ -159,6 +159,7 @@ extern const struct _mp_obj_module_t network_module;
extern const struct _mp_obj_module_t os_module;
extern const struct _mp_obj_module_t random_module;
extern const struct _mp_obj_module_t storage_module;
extern const struct _mp_obj_module_t struct_module;
extern const struct _mp_obj_module_t mp_module_lwip;
extern const struct _mp_obj_module_t mp_module_machine;
extern const struct _mp_obj_module_t mp_module_onewire;
Expand Down Expand Up @@ -189,6 +190,7 @@ extern const struct _mp_obj_module_t multiterminal_module;
{ MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_storage), (mp_obj_t)&storage_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_multiterminal), (mp_obj_t)&multiterminal_module }, \

Expand Down
1 change: 1 addition & 0 deletions shared-bindings/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Module / Port SAMD21 SAMD21 Express ESP8266
`pulseio` No **Yes** No
`random` **Yes** **Yes** **Yes**
`storage` **Yes** **Yes** **Yes**
`struct` **Yes** **Yes** **Yes**
`time` **Yes** **Yes** **Yes**
`touchio` **Yes** **Yes** No
`uheap` Debug Debug Debug
Expand Down
168 changes: 168 additions & 0 deletions shared-bindings/struct/__init__.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
* Copyright (c) 2014 Paul Sokolovsky
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add yourself here @mrmcwethy

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

* Copyright (c) 2017 Michael McWethy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include <assert.h>
#include <string.h>

#include "py/runtime.h"
#include "py/builtin.h"
#include "py/objtuple.h"
#include "py/binary.h"
#include "py/parsenum.h"
#include "shared-bindings/struct/__init__.h"
#include "shared-module/struct/__init__.h"

//| :mod:`struct` --- manipulation of c-style data
//| ========================================================
//|
//| .. module:: struct
//| :synopsis: byte data control
//| :platform: SAMD21
//|
//| This module implements a subset of the corresponding CPython module,
//| as described below. For more information, refer to the original CPython
//| documentation: struct.
//|
//| Supported size/byte order prefixes: *@*, *<*, *>*, *!*.
//|
//| Supported format codes: *b*, *B*, *h*, *H*, *i*, *I*, *l*, *L*, *q*, *Q*,
//| *s*, *P*, *f*, *d* (the latter 2 depending on the floating-point support).


//| .. function:: calcsize(fmt)
//|
//| Return the number of bytes needed to store the given fmt.
//|

STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {

return MP_OBJ_NEW_SMALL_INT(shared_modules_struct_calcsize(fmt_in));
}
MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize);

//| .. function:: pack(fmt, v1, v2, ...)
//|
//| Pack the values v1, v2, ... according to the format string fmt.
//| The return value is a bytes object encoding the values.
//|

STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) {
// TODO: "The arguments must match the values required by the format exactly."
mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0]));
vstr_t vstr;
vstr_init_len(&vstr, size);
byte *p = (byte*)vstr.buf;
memset(p, 0, size);
byte *end_p = &p[size];
shared_modules_struct_pack_into(args[0], p, end_p, n_args - 1, &args[1]);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack);


//| .. function:: pack_into(fmt, buffer, offset, v1, v2, ...)
//|
//| Pack the values v1, v2, ... according to the format string fmt into a buffer
//| starting at offset. offset may be negative to count from the end of buffer.
//|

STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
mp_int_t offset = mp_obj_get_int(args[2]);
if (offset < 0) {
// negative offsets are relative to the end of the buffer
offset = (mp_int_t)bufinfo.len + offset;
if (offset < 0) {
mp_raise_RuntimeError("buffer too small");
}
}
byte *p = (byte *)bufinfo.buf;
byte *end_p = &p[bufinfo.len];
p += offset;

shared_modules_struct_pack_into(args[0], p, end_p, n_args - 3, &args[3]);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_into_obj, 3, MP_OBJ_FUN_ARGS_MAX, struct_pack_into);

//| .. function:: unpack(fmt, data)
//|
//| Unpack from the data according to the format string fmt. The return value
//| is a tuple of the unpacked values.
//|

//| .. function:: unpack_from(fmt, data, offset)
//|
//| Unpack from the data starting at offset according to the format string fmt.
//| offset may be negative to count from the end of buffer. The return value is
//| a tuple of the unpacked values.
//|

STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
// unpack requires that the buffer be exactly the right size.
// unpack_from requires that the buffer be "big enough".
// Since we implement unpack and unpack_from using the same function
// we relax the "exact" requirement, and only implement "big enough".
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
byte *p = bufinfo.buf;
byte *end_p = &p[bufinfo.len];

if (n_args > 2) {
mp_int_t offset = mp_obj_get_int(args[2]);
// offset arg provided
if (offset < 0) {
// negative offsets are relative to the end of the buffer
offset = bufinfo.len + offset;
if (offset < 0) {
mp_raise_RuntimeError("buffer too small");
}
}
p += offset;
}

return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[0] , p, end_p));
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_from_obj, 2, 3, struct_unpack_from);

STATIC const mp_rom_map_elem_t mp_module_struct_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_struct) },
{ MP_ROM_QSTR(MP_QSTR_calcsize), MP_ROM_PTR(&struct_calcsize_obj) },
{ MP_ROM_QSTR(MP_QSTR_pack), MP_ROM_PTR(&struct_pack_obj) },
{ MP_ROM_QSTR(MP_QSTR_pack_into), MP_ROM_PTR(&struct_pack_into_obj) },
{ MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&struct_unpack_from_obj) },
{ MP_ROM_QSTR(MP_QSTR_unpack_from), MP_ROM_PTR(&struct_unpack_from_obj) },
};

STATIC MP_DEFINE_CONST_DICT(mp_module_struct_globals, mp_module_struct_globals_table);

const mp_obj_module_t struct_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_struct_globals,
};
34 changes: 34 additions & 0 deletions shared-bindings/struct/__init__.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_STRUCT___INIT___H
#define MICROPY_INCLUDED_SHARED_BINDINGS_STRUCT___INIT___H

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);
mp_uint_t shared_modules_struct_calcsize(mp_obj_t fmt_in);
mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p);

#endif // MICROPY_INCLUDED_SHARED_BINDINGS_RANDOM___INIT___H
Loading