Created
August 14, 2019 03:49
-
-
Save mattytrentini/09885f5aae78590e5d4cce15a18c62dc to your computer and use it in GitHub Desktop.
MicroPython C Module - Class Example to generate a QR Code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "py/obj.h" | |
#include "py/runtime.h" | |
#include "py/builtin.h" | |
#include "string.h" | |
#include "qrcodegen.h" // Project Nayuki C implementation | |
// This example models the following Python class: | |
// ---------------------------------------- | |
// class QrCode: | |
// | |
// ECC_LOW = 0 | |
// ECC_MEDIUM = 1 | |
// ECC_QUARTILE = 2 | |
// ECC_HIGH = 3 | |
// | |
// @static | |
// def encode_text(s: str) -> QrCode: | |
// pass | |
// | |
// def get_size() -> int: | |
// pass | |
// | |
// def get_module(x: int, y: int) -> bool: | |
// pass | |
// ---------------------------------------- | |
typedef struct _mp_obj_qr_t { | |
mp_obj_base_t base; | |
uint8_t qr0[qrcodegen_BUFFER_LEN_MAX]; | |
} mp_obj_qr_t; | |
STATIC const mp_obj_type_t qrcode_type; | |
STATIC mp_obj_t qrcode_encode_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | |
enum { ARG_text, ARG_ecc }; | |
static const mp_arg_t allowed_args[] = { | |
{ MP_QSTR_text, MP_ARG_REQUIRED | MP_ARG_OBJ }, | |
{ MP_QSTR_ecc, MP_ARG_INT, {.u_int = qrcodegen_Ecc_MEDIUM} }, | |
}; | |
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | |
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | |
// Generate QR code | |
mp_obj_qr_t *qr = m_new_obj(mp_obj_qr_t); | |
qr->base.type = &qrcode_type; | |
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX]; | |
mp_uint_t len; | |
bool ok = qrcodegen_encodeText(mp_obj_str_get_data(args[ARG_text].u_obj, &len), | |
tempBuffer, qr->qr0, args[ARG_ecc].u_int, | |
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, | |
qrcodegen_Mask_AUTO, true); | |
if (!ok) { | |
mp_raise_ValueError("Error generating QR code"); // Not quite the right Exception... | |
} | |
return MP_OBJ_FROM_PTR(qr); | |
} | |
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(qrcode_encode_text_fun_obj, 0, qrcode_encode_text); | |
STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(qrcode_encode_text_obj, MP_ROM_PTR(&qrcode_encode_text_fun_obj)); | |
STATIC mp_obj_t qrcode_get_size(mp_obj_t self_in) { | |
mp_obj_qr_t *self = MP_OBJ_TO_PTR(self_in); | |
return mp_obj_new_int(qrcodegen_getSize(self->qr0)); | |
} | |
STATIC MP_DEFINE_CONST_FUN_OBJ_1(qrcode_get_size_obj, qrcode_get_size); | |
STATIC mp_obj_t qrcode_get_module(mp_obj_t self_in, mp_obj_t x, mp_obj_t y) { | |
mp_obj_qr_t *self = MP_OBJ_TO_PTR(self_in); | |
return mp_obj_new_bool(qrcodegen_getModule(self->qr0, mp_obj_get_int(x), mp_obj_get_int(y))); | |
} | |
STATIC MP_DEFINE_CONST_FUN_OBJ_3(qrcode_get_module_obj, qrcode_get_module); | |
STATIC const mp_rom_map_elem_t qrcode_locals_dict_table[] = { | |
{ MP_ROM_QSTR(MP_QSTR_encode_text), MP_ROM_PTR(&qrcode_encode_text_obj) }, | |
{ MP_ROM_QSTR(MP_QSTR_get_size), MP_ROM_PTR(&qrcode_get_size_obj) }, | |
{ MP_ROM_QSTR(MP_QSTR_get_module), MP_ROM_PTR(&qrcode_get_module_obj) }, | |
}; | |
STATIC MP_DEFINE_CONST_DICT(qrcode_locals_dict, qrcode_locals_dict_table); | |
STATIC const mp_obj_type_t qrcode_type = { | |
{ &mp_type_type }, | |
.name = MP_QSTR_QrCode, | |
.locals_dict = (void*)&qrcode_locals_dict, | |
}; | |
// Define the contents of the module | |
STATIC const mp_rom_map_elem_t qr_module_globals_table[] = { | |
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_qr) }, | |
{ MP_ROM_QSTR(MP_QSTR_QrCode), MP_ROM_PTR(&qrcode_type) }, | |
{ MP_ROM_QSTR(MP_QSTR_ECC_LOW), MP_ROM_INT(qrcodegen_Ecc_LOW) }, | |
{ MP_ROM_QSTR(MP_QSTR_ECC_MEDIUM), MP_ROM_INT(qrcodegen_Ecc_MEDIUM) }, | |
{ MP_ROM_QSTR(MP_QSTR_ECC_QUARTILE), MP_ROM_INT(qrcodegen_Ecc_QUARTILE) }, | |
{ MP_ROM_QSTR(MP_QSTR_ECC_HIGH), MP_ROM_INT(qrcodegen_Ecc_HIGH) }, | |
}; | |
STATIC MP_DEFINE_CONST_DICT(qr_module_globals, qr_module_globals_table); | |
// Define module object. | |
const mp_obj_module_t qr_cmodule = { | |
.base = { &mp_type_module }, | |
.globals = (mp_obj_dict_t*)&qr_module_globals, | |
}; | |
// Register the module to make it available to MicroPython | |
MP_REGISTER_MODULE(MP_QSTR_qr, qr_cmodule, MODULE_QR_ENABLED); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment