blob: 95e82a688d86305a6ab3116780519378acef539d [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
Paul Sokolovskye9db8402014-04-10 03:45:38 +030080mp_obj_t mp_binary_get_val_unaligned_le(char typecode, byte **ptr) {
81 machine_int_t val = 0;
82 byte *p = *ptr;
83 switch (typecode) {
84 case 'b':
85 val = (int8_t)*p++;
86 break;
87 case BYTEARRAY_TYPECODE:
88 case 'B':
89 val = *p++;
90 break;
91 case 'h':
92 val = (int16_t)((p[1] << 8) | p[0]);
93 break;
94 case 'H':
95 val = (p[1] << 8) | p[0];
96 break;
97 case 'i':
98 case 'l':
99 val = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
100 *ptr = p + 4;
101 return mp_obj_new_int(val);
102 case 'I':
103 case 'L':
104 val = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
105 *ptr = p + 4;
106 return mp_obj_new_int_from_uint(val);
107#if 0 //TODO
108#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
109 case 'q':
110 case 'Q':
111 // TODO: Explode API more to cover signedness
112 return mp_obj_new_int_from_ll(((long long*)p)[index]);
113#endif
114#if MICROPY_ENABLE_FLOAT
115 case 'f':
116 return mp_obj_new_float(((float*)p)[index]);
117 case 'd':
118 return mp_obj_new_float(((double*)p)[index]);
119#endif
120#endif
121 }
122 *ptr = p;
123 return MP_OBJ_NEW_SMALL_INT(val);
124}
125
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200126void mp_binary_set_val(char typecode, void *p, int index, mp_obj_t val_in) {
127 machine_int_t val = 0;
128 if (MP_OBJ_IS_INT(val_in)) {
129 val = mp_obj_int_get(val_in);
130 }
131
132 switch (typecode) {
133 case 'b':
134 ((int8_t*)p)[index] = val;
135 break;
136 case BYTEARRAY_TYPECODE:
137 case 'B':
138 val = ((uint8_t*)p)[index] = val;
139 break;
140 case 'h':
141 val = ((int16_t*)p)[index] = val;
142 break;
143 case 'H':
144 val = ((uint16_t*)p)[index] = val;
145 break;
146 case 'i':
147 case 'l':
148 ((int32_t*)p)[index] = val;
149 break;
150 case 'I':
151 case 'L':
152 ((uint32_t*)p)[index] = val;
153 break;
154#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
155 case 'q':
156 case 'Q':
157 assert(0);
158 ((long long*)p)[index] = val;
159 break;
160#endif
161#if MICROPY_ENABLE_FLOAT
162 case 'f':
163 ((float*)p)[index] = mp_obj_float_get(val_in);
164 break;
165 case 'd':
166 ((double*)p)[index] = mp_obj_float_get(val_in);
167 break;
168#endif
169 }
170}