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