b5c59ddea1bf4dc9704e096f53c6e5cdc5cc0c74
[babeltrace.git] / formats / ctf / types / integer.c
1 /*
2 * Common Trace Format
3 *
4 * Integers read/write functions.
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19 #include <babeltrace/ctf/types.h>
20 #include <babeltrace/bitfield.h>
21 #include <stdint.h>
22 #include <glib.h>
23 #include <endian.h>
24
25 /*
26 * The aligned read/write functions are expected to be faster than the
27 * bitfield variants. They will be enabled eventually as an
28 * optimisation.
29 */
30
31 static
32 int _aligned_integer_read(struct stream_pos *ppos,
33 struct definition *definition)
34 {
35 struct definition_integer *integer_definition =
36 container_of(definition, struct definition_integer, p);
37 const struct declaration_integer *integer_declaration =
38 integer_definition->declaration;
39 struct ctf_stream_pos *pos = ctf_pos(ppos);
40 int rbo = (integer_declaration->byte_order != BYTE_ORDER); /* reverse byte order */
41
42 ctf_align_pos(pos, integer_declaration->p.alignment);
43
44 if (!ctf_pos_access_ok(pos, integer_declaration->len))
45 return -EFAULT;
46
47 assert(!(pos->offset % CHAR_BIT));
48 if (!integer_declaration->signedness) {
49 switch (integer_declaration->len) {
50 case 8:
51 {
52 uint8_t v;
53
54 v = *(const uint8_t *) ctf_get_pos_addr(pos);
55 integer_definition->value._unsigned = v;
56 break;
57 }
58 case 16:
59 {
60 uint16_t v;
61
62 v = *(const uint16_t *) ctf_get_pos_addr(pos);
63 integer_definition->value._unsigned =
64 rbo ? GUINT16_SWAP_LE_BE(v) : v;
65 break;
66 }
67 case 32:
68 {
69 uint32_t v;
70
71 v = *(const uint32_t *) ctf_get_pos_addr(pos);
72 integer_definition->value._unsigned =
73 rbo ? GUINT32_SWAP_LE_BE(v) : v;
74 break;
75 }
76 case 64:
77 {
78 uint64_t v;
79
80 v = *(const uint64_t *) ctf_get_pos_addr(pos);
81 integer_definition->value._unsigned =
82 rbo ? GUINT64_SWAP_LE_BE(v) : v;
83 break;
84 }
85 default:
86 assert(0);
87 }
88 } else {
89 switch (integer_declaration->len) {
90 case 8:
91 {
92 int8_t v;
93
94 v = *(const int8_t *) ctf_get_pos_addr(pos);
95 integer_definition->value._signed = v;
96 break;
97 }
98 case 16:
99 {
100 int16_t v;
101
102 v = *(const int16_t *) ctf_get_pos_addr(pos);
103 integer_definition->value._signed =
104 rbo ? GUINT16_SWAP_LE_BE(v) : v;
105 break;
106 }
107 case 32:
108 {
109 int32_t v;
110
111 v = *(const int32_t *) ctf_get_pos_addr(pos);
112 integer_definition->value._signed =
113 rbo ? GUINT32_SWAP_LE_BE(v) : v;
114 break;
115 }
116 case 64:
117 {
118 int64_t v;
119
120 v = *(const int64_t *) ctf_get_pos_addr(pos);
121 integer_definition->value._signed =
122 rbo ? GUINT64_SWAP_LE_BE(v) : v;
123 break;
124 }
125 default:
126 assert(0);
127 }
128 }
129 ctf_move_pos(pos, integer_declaration->len);
130 return 0;
131 }
132
133 static
134 int _aligned_integer_write(struct stream_pos *ppos,
135 struct definition *definition)
136 {
137 struct definition_integer *integer_definition =
138 container_of(definition, struct definition_integer, p);
139 const struct declaration_integer *integer_declaration =
140 integer_definition->declaration;
141 struct ctf_stream_pos *pos = ctf_pos(ppos);
142 int rbo = (integer_declaration->byte_order != BYTE_ORDER); /* reverse byte order */
143
144 ctf_align_pos(pos, integer_declaration->p.alignment);
145
146 if (!ctf_pos_access_ok(pos, integer_declaration->len))
147 return -EFAULT;
148
149 assert(!(pos->offset % CHAR_BIT));
150 if (pos->dummy)
151 goto end;
152 if (!integer_declaration->signedness) {
153 uint64_t v = integer_definition->value._unsigned;
154
155 switch (integer_declaration->len) {
156 case 8: *(uint8_t *) ctf_get_pos_addr(pos) = (uint8_t) v;
157 break;
158 case 16:
159 *(uint16_t *) ctf_get_pos_addr(pos) = rbo ?
160 GUINT16_SWAP_LE_BE((uint16_t) v) :
161 (uint16_t) v;
162 break;
163 case 32:
164 *(uint32_t *) ctf_get_pos_addr(pos) = rbo ?
165 GUINT32_SWAP_LE_BE((uint32_t) v) :
166 (uint32_t) v;
167 break;
168 case 64:
169 *(uint64_t *) ctf_get_pos_addr(pos) = rbo ?
170 GUINT64_SWAP_LE_BE(v) : v;
171 break;
172 default:
173 assert(0);
174 }
175 } else {
176 int64_t v = integer_definition->value._signed;
177
178 switch (integer_declaration->len) {
179 case 8: *(int8_t *) ctf_get_pos_addr(pos) = (int8_t) v;
180 break;
181 case 16:
182 *(int16_t *) ctf_get_pos_addr(pos) = rbo ?
183 GUINT16_SWAP_LE_BE((int16_t) v) :
184 (int16_t) v;
185 break;
186 case 32:
187 *(int32_t *) ctf_get_pos_addr(pos) = rbo ?
188 GUINT32_SWAP_LE_BE((int32_t) v) :
189 (int32_t) v;
190 break;
191 case 64:
192 *(int64_t *) ctf_get_pos_addr(pos) = rbo ?
193 GUINT64_SWAP_LE_BE(v) : v;
194 break;
195 default:
196 assert(0);
197 }
198 }
199 end:
200 ctf_move_pos(pos, integer_declaration->len);
201 return 0;
202 }
203
204 int ctf_integer_read(struct stream_pos *ppos, struct definition *definition)
205 {
206 struct definition_integer *integer_definition =
207 container_of(definition, struct definition_integer, p);
208 const struct declaration_integer *integer_declaration =
209 integer_definition->declaration;
210 struct ctf_stream_pos *pos = ctf_pos(ppos);
211
212 if (!(integer_declaration->p.alignment % CHAR_BIT)
213 && !(integer_declaration->len % CHAR_BIT)) {
214 return _aligned_integer_read(ppos, definition);
215 }
216
217 ctf_align_pos(pos, integer_declaration->p.alignment);
218
219 if (!ctf_pos_access_ok(pos, integer_declaration->len))
220 return -EFAULT;
221
222 if (!integer_declaration->signedness) {
223 if (integer_declaration->byte_order == LITTLE_ENDIAN)
224 bt_bitfield_read_le(pos->base, unsigned long,
225 pos->offset, integer_declaration->len,
226 &integer_definition->value._unsigned);
227 else
228 bt_bitfield_read_be(pos->base, unsigned long,
229 pos->offset, integer_declaration->len,
230 &integer_definition->value._unsigned);
231 } else {
232 if (integer_declaration->byte_order == LITTLE_ENDIAN)
233 bt_bitfield_read_le(pos->base, unsigned long,
234 pos->offset, integer_declaration->len,
235 &integer_definition->value._signed);
236 else
237 bt_bitfield_read_be(pos->base, unsigned long,
238 pos->offset, integer_declaration->len,
239 &integer_definition->value._signed);
240 }
241 ctf_move_pos(pos, integer_declaration->len);
242 return 0;
243 }
244
245 int ctf_integer_write(struct stream_pos *ppos, struct definition *definition)
246 {
247 struct definition_integer *integer_definition =
248 container_of(definition, struct definition_integer, p);
249 const struct declaration_integer *integer_declaration =
250 integer_definition->declaration;
251 struct ctf_stream_pos *pos = ctf_pos(ppos);
252
253 if (!(integer_declaration->p.alignment % CHAR_BIT)
254 && !(integer_declaration->len % CHAR_BIT)) {
255 return _aligned_integer_write(ppos, definition);
256 }
257
258 ctf_align_pos(pos, integer_declaration->p.alignment);
259
260 if (!ctf_pos_access_ok(pos, integer_declaration->len))
261 return -EFAULT;
262
263 if (pos->dummy)
264 goto end;
265 if (!integer_declaration->signedness) {
266 if (integer_declaration->byte_order == LITTLE_ENDIAN)
267 bt_bitfield_write_le(pos->base, unsigned long,
268 pos->offset, integer_declaration->len,
269 integer_definition->value._unsigned);
270 else
271 bt_bitfield_write_be(pos->base, unsigned long,
272 pos->offset, integer_declaration->len,
273 integer_definition->value._unsigned);
274 } else {
275 if (integer_declaration->byte_order == LITTLE_ENDIAN)
276 bt_bitfield_write_le(pos->base, unsigned long,
277 pos->offset, integer_declaration->len,
278 integer_definition->value._signed);
279 else
280 bt_bitfield_write_be(pos->base, unsigned long,
281 pos->offset, integer_declaration->len,
282 integer_definition->value._signed);
283 }
284 end:
285 ctf_move_pos(pos, integer_declaration->len);
286 return 0;
287 }
This page took 0.034513 seconds and 4 git commands to generate.