Branch data Line data Source code
1 : : // Copyright 2019-2026 David Robillard <d@drobilla.net>
2 : : // SPDX-License-Identifier: ISC
3 : :
4 : : #include "big_decimal.h"
5 : : #include "result.h"
6 : : #include "write_utils.h"
7 : :
8 : : #include <exess/exess.h>
9 : :
10 : : #include <stdbool.h>
11 : : #include <stdint.h>
12 : : #include <string.h>
13 : :
14 : : static inline ExessVariableResult
15 : 1016 : fixed(const ExessResult result, const size_t write_count)
16 : : {
17 [ + + ]: 1016 : return VRESULT(result.status, result.count, result.status ? 0U : write_count);
18 : : }
19 : :
20 : : static inline ExessVariableResult
21 : 43 : integer(const ExessVariableResult result,
22 : : const void* const value,
23 : : const BigDecimalKind kind,
24 : : const bool equals)
25 : : {
26 : 43 : const BigDecimal* const decimal = (const BigDecimal*)value;
27 : :
28 [ + + ]: 39 : return (!result.status && ((decimal->kind == kind) == equals)
29 : 7 : ? VRESULT(EXESS_OUT_OF_RANGE, result.read_count, 0U)
30 [ + + ]: 82 : : result);
31 : : }
32 : :
33 : : EXESS_NONBLOCKING ExessVariableResult
34 : 1299 : exess_read_value(const ExessDatatype datatype,
35 : : const char* const str,
36 : : const size_t out_size,
37 : : void* const out)
38 : : {
39 : 1299 : ExessVariableResult r = {EXESS_UNSUPPORTED, 0, 0};
40 : :
41 [ + + ]: 1299 : if (out_size < exess_value_sizes[datatype]) {
42 : 1 : return VRESULT(EXESS_NO_SPACE, 0U, 0U);
43 : : }
44 : :
45 [ + + + + : 1298 : switch (datatype) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - ]
46 : 6 : case EXESS_NOTHING:
47 : 6 : break;
48 : 54 : case EXESS_BOOLEAN:
49 : 1292 : return fixed(exess_read_boolean(str, (bool*)out), sizeof(bool));
50 : 150 : case EXESS_DOUBLE:
51 : 150 : return fixed(exess_read_double(str, (double*)out), sizeof(double));
52 : 150 : case EXESS_FLOAT:
53 : 150 : return fixed(exess_read_float(str, (float*)out), sizeof(float));
54 : 58 : case EXESS_LONG:
55 : 58 : return fixed(exess_read_long(str, (int64_t*)out), sizeof(int64_t));
56 : 19 : case EXESS_INT:
57 : 19 : return fixed(exess_read_int(str, (int32_t*)out), sizeof(int32_t));
58 : 15 : case EXESS_SHORT:
59 : 15 : return fixed(exess_read_short(str, (int16_t*)out), sizeof(int16_t));
60 : 15 : case EXESS_BYTE:
61 : 15 : return fixed(exess_read_byte(str, (int8_t*)out), sizeof(int8_t));
62 : 45 : case EXESS_ULONG:
63 : 45 : return fixed(exess_read_ulong(str, (uint64_t*)out), sizeof(uint64_t));
64 : 14 : case EXESS_UINT:
65 : 14 : return fixed(exess_read_uint(str, (uint32_t*)out), sizeof(uint32_t));
66 : 14 : case EXESS_USHORT:
67 : 14 : return fixed(exess_read_ushort(str, (uint16_t*)out), sizeof(uint16_t));
68 : 14 : case EXESS_UBYTE:
69 : 14 : return fixed(exess_read_ubyte(str, (uint8_t*)out), sizeof(uint8_t));
70 : :
71 : 175 : case EXESS_DECIMAL:
72 : 175 : return exess_read_decimal(str, out_size, out);
73 : 8 : case EXESS_INTEGER:
74 : 8 : return exess_read_integer(str, out_size, out);
75 : :
76 : 9 : case EXESS_NON_POSITIVE_INTEGER:
77 : 9 : return integer(
78 : : exess_read_integer(str, out_size, out), out, EXESS_POSITIVE, true);
79 : :
80 : 9 : case EXESS_NEGATIVE_INTEGER:
81 : 9 : return integer(
82 : : exess_read_integer(str, out_size, out), out, EXESS_NEGATIVE, false);
83 : :
84 : 12 : case EXESS_NON_NEGATIVE_INTEGER:
85 : 12 : return integer(
86 : : exess_read_integer(str, out_size, out), out, EXESS_NEGATIVE, true);
87 : :
88 : 13 : case EXESS_POSITIVE_INTEGER:
89 : 13 : return integer(
90 : : exess_read_integer(str, out_size, out), out, EXESS_POSITIVE, false);
91 : :
92 : 118 : case EXESS_DURATION:
93 : 118 : return fixed(exess_read_duration(str, (ExessDuration*)out),
94 : : sizeof(ExessDuration));
95 : :
96 : 5 : case EXESS_YEAR_MONTH_DURATION:
97 : 5 : r = fixed(exess_read_duration(str, (ExessDuration*)out),
98 : : sizeof(ExessDuration));
99 [ + + ]: 4 : return (!r.status && (((const ExessDuration*)out)->seconds ||
100 [ + + ]: 2 : ((const ExessDuration*)out)->nanoseconds))
101 : 3 : ? VRESULT(EXESS_BAD_VALUE, r.read_count, 0U)
102 [ + + ]: 9 : : r;
103 : :
104 : 3 : case EXESS_DAY_TIME_DURATION:
105 : 3 : r = fixed(exess_read_duration(str, (ExessDuration*)out),
106 : : sizeof(ExessDuration));
107 [ + + ]: 2 : return (!r.status && ((const ExessDuration*)out)->months)
108 : 1 : ? VRESULT(EXESS_BAD_VALUE, r.read_count, 0U)
109 [ + + ]: 5 : : r;
110 : :
111 : 139 : case EXESS_DATE_TIME:
112 : 139 : return fixed(exess_read_date_time(str, (ExessDateTime*)out),
113 : : sizeof(ExessDateTime));
114 : :
115 : 3 : case EXESS_DATE_TIME_STAMP:
116 : 3 : r = fixed(exess_read_date_time(str, (ExessDateTime*)out),
117 : : sizeof(ExessDateTime));
118 : 5 : return (!r.status &&
119 [ + + ]: 2 : (((const ExessDateTime*)out)->zone == EXESS_TIMEZONE_LOCAL))
120 : 1 : ? VRESULT(EXESS_BAD_VALUE, r.read_count, 0U)
121 [ + + ]: 5 : : r;
122 : :
123 : 120 : case EXESS_TIME:
124 : 120 : return fixed(exess_read_time(str, (ExessTime*)out), sizeof(ExessTime));
125 : 80 : case EXESS_DATE:
126 : 80 : return fixed(exess_read_date(str, (ExessDate*)out), sizeof(ExessDate));
127 : 39 : case EXESS_HEX:
128 : 39 : return exess_read_hex(str, out_size, out);
129 : 11 : case EXESS_BASE64:
130 : 11 : return exess_read_base64(str, out_size, out);
131 : : }
132 : :
133 : 6 : return r;
134 : : }
135 : :
136 : : EXESS_NONBLOCKING ExessResult
137 : 700 : exess_write_value(const ExessDatatype datatype,
138 : : const size_t value_size,
139 : : const void* const value,
140 : : const size_t buf_size,
141 : : char* const buf)
142 : : {
143 [ + + + + : 700 : switch (datatype) {
+ + + + +
+ + + + +
+ + + + +
+ - ]
144 : 1 : case EXESS_NOTHING:
145 : 1 : break;
146 : 23 : case EXESS_BOOLEAN:
147 : 23 : return exess_write_boolean(*(const bool*)value, buf_size, buf);
148 : 19 : case EXESS_DOUBLE:
149 : 19 : return exess_write_double(*(const double*)value, buf_size, buf);
150 : 26 : case EXESS_FLOAT:
151 : 26 : return exess_write_float(*(const float*)value, buf_size, buf);
152 : 96 : case EXESS_LONG:
153 : 96 : return exess_write_long(*(const int64_t*)value, buf_size, buf);
154 : 60 : case EXESS_INT:
155 : 60 : return exess_write_int(*(const int32_t*)value, buf_size, buf);
156 : 60 : case EXESS_SHORT:
157 : 60 : return exess_write_short(*(const int16_t*)value, buf_size, buf);
158 : 61 : case EXESS_BYTE:
159 : 61 : return exess_write_byte(*(const int8_t*)value, buf_size, buf);
160 : 59 : case EXESS_ULONG:
161 : 59 : return exess_write_ulong(*(const uint64_t*)value, buf_size, buf);
162 : 31 : case EXESS_UINT:
163 : 31 : return exess_write_uint(*(const uint32_t*)value, buf_size, buf);
164 : 31 : case EXESS_USHORT:
165 : 31 : return exess_write_ushort(*(const uint16_t*)value, buf_size, buf);
166 : 31 : case EXESS_UBYTE:
167 : 31 : return exess_write_ubyte(*(const uint8_t*)value, buf_size, buf);
168 : 14 : case EXESS_DECIMAL:
169 : 14 : return exess_write_decimal(value_size, value, buf_size, buf);
170 : 95 : case EXESS_INTEGER:
171 : : case EXESS_NON_POSITIVE_INTEGER:
172 : : case EXESS_NEGATIVE_INTEGER:
173 : : case EXESS_NON_NEGATIVE_INTEGER:
174 : : case EXESS_POSITIVE_INTEGER:
175 : 95 : return exess_write_integer(value_size, value, buf_size, buf);
176 : 19 : case EXESS_DURATION:
177 : : case EXESS_YEAR_MONTH_DURATION:
178 : : case EXESS_DAY_TIME_DURATION:
179 : 19 : return exess_write_duration(*(const ExessDuration*)value, buf_size, buf);
180 : 20 : case EXESS_DATE_TIME:
181 : : case EXESS_DATE_TIME_STAMP:
182 : 20 : return exess_write_date_time(*(const ExessDateTime*)value, buf_size, buf);
183 : 21 : case EXESS_TIME:
184 : 21 : return exess_write_time(*(const ExessTime*)value, buf_size, buf);
185 : 17 : case EXESS_DATE:
186 : 17 : return exess_write_date(*(const ExessDate*)value, buf_size, buf);
187 : 9 : case EXESS_HEX:
188 : 9 : return exess_write_hex(value_size, value, buf_size, buf);
189 : 7 : case EXESS_BASE64:
190 : 7 : return exess_write_base64(value_size, value, buf_size, buf);
191 : : }
192 : :
193 : 1 : return end_write(EXESS_BAD_VALUE, buf_size, buf, 0);
194 : : }
|