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