blob: 7a8ed46111f22df241cc3123a602b90e9491da8d [file] [log] [blame]
Paul Sokolovsky8bc35162014-02-14 17:16:35 +02001#include <stdint.h>
2#include <assert.h>
3
4#include "misc.h"
5#include "mpconfig.h"
6#include "qstr.h"
7#include "obj.h"
Paul Sokolovsky8bc35162014-02-14 17:16:35 +02008#include "binary.h"
9
10// Helpers to work with binary-encoded data
11
Paul Sokolovskyc2033242014-02-14 20:21:50 +020012int mp_binary_get_size(char typecode) {
13 // This assumes that unsigned and signed types are of the same type,
14 // which is invariant for [u]intN_t.
15 switch (typecode) {
16 case BYTEARRAY_TYPECODE:
17 case 'b':
18 case 'B':
19 return sizeof(int8_t);
20 case 'h':
21 case 'H':
22 return sizeof(int16_t);
23 case 'i':
24 case 'I':
25 return sizeof(int32_t);
26 case 'l':
27 case 'L':
28 return sizeof(int32_t);
29 case 'q':
30 case 'Q':
31 return sizeof(long long);
32#if MICROPY_ENABLE_FLOAT
33 case 'f':
34 return sizeof(float);
35 case 'd':
36 return sizeof(double);
37#endif
38 }
39 return -1;
40}
41
Paul Sokolovsky8bc35162014-02-14 17:16:35 +020042mp_obj_t mp_binary_get_val(char typecode, void *p, int index) {
Paul Sokolovsky76f8ced2014-02-15 00:28:41 +020043 machine_int_t val = 0;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +020044 switch (typecode) {
45 case 'b':
46 val = ((int8_t*)p)[index];
47 break;
48 case BYTEARRAY_TYPECODE:
49 case 'B':
50 val = ((uint8_t*)p)[index];
51 break;
52 case 'h':
53 val = ((int16_t*)p)[index];
54 break;
55 case 'H':
56 val = ((uint16_t*)p)[index];
57 break;
58 case 'i':
59 case 'l':
60 return mp_obj_new_int(((int32_t*)p)[index]);
61 case 'I':
62 case 'L':
63 return mp_obj_new_int_from_uint(((uint32_t*)p)[index]);
Damien George96056a62014-02-15 23:02:00 +000064#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
Paul Sokolovsky8bc35162014-02-14 17:16:35 +020065 case 'q':
66 case 'Q':
67 // TODO: Explode API more to cover signedness
68 return mp_obj_new_int_from_ll(((long long*)p)[index]);
69#endif
70#if MICROPY_ENABLE_FLOAT
71 case 'f':
72 return mp_obj_new_float(((float*)p)[index]);
73 case 'd':
74 return mp_obj_new_float(((double*)p)[index]);
75#endif
76 }
77 return MP_OBJ_NEW_SMALL_INT(val);
78}
79
80void mp_binary_set_val(char typecode, void *p, int index, mp_obj_t val_in) {
81 machine_int_t val = 0;
82 if (MP_OBJ_IS_INT(val_in)) {
83 val = mp_obj_int_get(val_in);
84 }
85
86 switch (typecode) {
87 case 'b':
88 ((int8_t*)p)[index] = val;
89 break;
90 case BYTEARRAY_TYPECODE:
91 case 'B':
92 val = ((uint8_t*)p)[index] = val;
93 break;
94 case 'h':
95 val = ((int16_t*)p)[index] = val;
96 break;
97 case 'H':
98 val = ((uint16_t*)p)[index] = val;
99 break;
100 case 'i':
101 case 'l':
102 ((int32_t*)p)[index] = val;
103 break;
104 case 'I':
105 case 'L':
106 ((uint32_t*)p)[index] = val;
107 break;
108#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
109 case 'q':
110 case 'Q':
111 assert(0);
112 ((long long*)p)[index] = val;
113 break;
114#endif
115#if MICROPY_ENABLE_FLOAT
116 case 'f':
117 ((float*)p)[index] = mp_obj_float_get(val_in);
118 break;
119 case 'd':
120 ((double*)p)[index] = mp_obj_float_get(val_in);
121 break;
122#endif
123 }
124}