71ac0f448c0a446b59edf9a5b86688763dde33db
[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
21 #include <babeltrace/ctf/types.h>
22 #include <babeltrace/bitfield.h>
23 #include <stdint.h>
24 #include <glib.h>
25 #include <babeltrace/endian.h>
26
27 /*
28 * The aligned read/write functions are expected to be faster than the
29 * bitfield variants. They will be enabled eventually as an
30 * optimisation.
31 */
32
33 static
34 int _aligned_integer_read(struct stream_pos *ppos,
35 struct definition *definition)
36 {
37 struct definition_integer *integer_definition =
38 container_of(definition, struct definition_integer, p);
39 const struct declaration_integer *integer_declaration =
40 integer_definition->declaration;
41 struct ctf_stream_pos *pos = ctf_pos(ppos);
42 int rbo = (integer_declaration->byte_order != BYTE_ORDER); /* reverse byte order */
43
44 ctf_align_pos(pos, integer_declaration->p.alignment);
45
46 if (!ctf_pos_access_ok(pos, integer_declaration->len))
47 return -EFAULT;
48
49 assert(!(pos->offset % CHAR_BIT));
50 if (!integer_declaration->signedness) {
51 switch (integer_declaration->len) {
52 case 8:
53 {
54 uint8_t v;
55
56 v = *(const uint8_t *) ctf_get_pos_addr(pos);
57 integer_definition->value._unsigned = v;
58 break;
59 }
60 case 16:
61 {
62 uint16_t v;
63
64 v = *(const uint16_t *) ctf_get_pos_addr(pos);
65 integer_definition->value._unsigned =
66 rbo ? GUINT16_SWAP_LE_BE(v) : v;
67 break;
68 }
69 case 32:
70 {
71 uint32_t v;
72
73 v = *(const uint32_t *) ctf_get_pos_addr(pos);
74 integer_definition->value._unsigned =
75 rbo ? GUINT32_SWAP_LE_BE(v) : v;
76 break;
77 }
78 case 64:
79 {
80 uint64_t v;
81
82 v = *(const uint64_t *) ctf_get_pos_addr(pos);
83 integer_definition->value._unsigned =
84 rbo ? GUINT64_SWAP_LE_BE(v) : v;
85 break;
86 }
87 default:
88 assert(0);
89 }
90 } else {
91 switch (integer_declaration->len) {
92 case 8:
93 {
94 int8_t v;
95
96 v = *(const int8_t *) ctf_get_pos_addr(pos);
97 integer_definition->value._signed = v;
98 break;
99 }
100 case 16:
101 {
102 int16_t v;
103
104 v = *(const int16_t *) ctf_get_pos_addr(pos);
105 integer_definition->value._signed =
106 rbo ? (int16_t) GUINT16_SWAP_LE_BE(v) : v;
107 break;
108 }
109 case 32:
110 {
111 int32_t v;
112
113 v = *(const int32_t *) ctf_get_pos_addr(pos);
114 integer_definition->value._signed =
115 rbo ? (int32_t) GUINT32_SWAP_LE_BE(v) : v;
116 break;
117 }
118 case 64:
119 {
120 int64_t v;
121
122 v = *(const int64_t *) ctf_get_pos_addr(pos);
123 integer_definition->value._signed =
124 rbo ? (int64_t) GUINT64_SWAP_LE_BE(v) : v;
125 break;
126 }
127 default:
128 assert(0);
129 }
130 }
131 ctf_move_pos(pos, integer_declaration->len);
132 return 0;
133 }
134
135 static
136 int _aligned_integer_write(struct stream_pos *ppos,
137 struct definition *definition)
138 {
139 struct definition_integer *integer_definition =
140 container_of(definition, struct definition_integer, p);
141 const struct declaration_integer *integer_declaration =
142 integer_definition->declaration;
143 struct ctf_stream_pos *pos = ctf_pos(ppos);
144 int rbo = (integer_declaration->byte_order != BYTE_ORDER); /* reverse byte order */
145
146 ctf_align_pos(pos, integer_declaration->p.alignment);
147
148 if (!ctf_pos_access_ok(pos, integer_declaration->len))
149 return -EFAULT;
150
151 assert(!(pos->offset % CHAR_BIT));
152 if (pos->dummy)
153 goto end;
154 if (!integer_declaration->signedness) {
155 uint64_t v = integer_definition->value._unsigned;
156
157 switch (integer_declaration->len) {
158 case 8: *(uint8_t *) ctf_get_pos_addr(pos) = (uint8_t) v;
159 break;
160 case 16:
161 *(uint16_t *) ctf_get_pos_addr(pos) = rbo ?
162 GUINT16_SWAP_LE_BE((uint16_t) v) :
163 (uint16_t) v;
164 break;
165 case 32:
166 *(uint32_t *) ctf_get_pos_addr(pos) = rbo ?
167 GUINT32_SWAP_LE_BE((uint32_t) v) :
168 (uint32_t) v;
169 break;
170 case 64:
171 *(uint64_t *) ctf_get_pos_addr(pos) = rbo ?
172 GUINT64_SWAP_LE_BE(v) : v;
173 break;
174 default:
175 assert(0);
176 }
177 } else {
178 int64_t v = integer_definition->value._signed;
179
180 switch (integer_declaration->len) {
181 case 8: *(int8_t *) ctf_get_pos_addr(pos) = (int8_t) v;
182 break;
183 case 16:
184 *(int16_t *) ctf_get_pos_addr(pos) = rbo ?
185 (int16_t) GUINT16_SWAP_LE_BE((int16_t) v) :
186 (int16_t) v;
187 break;
188 case 32:
189 *(int32_t *) ctf_get_pos_addr(pos) = rbo ?
190 (int32_t) GUINT32_SWAP_LE_BE((int32_t) v) :
191 (int32_t) v;
192 break;
193 case 64:
194 *(int64_t *) ctf_get_pos_addr(pos) = rbo ?
195 GUINT64_SWAP_LE_BE(v) : v;
196 break;
197 default:
198 assert(0);
199 }
200 }
201 end:
202 ctf_move_pos(pos, integer_declaration->len);
203 return 0;
204 }
205
206 int ctf_integer_read(struct stream_pos *ppos, struct definition *definition)
207 {
208 struct definition_integer *integer_definition =
209 container_of(definition, struct definition_integer, p);
210 const struct declaration_integer *integer_declaration =
211 integer_definition->declaration;
212 struct ctf_stream_pos *pos = ctf_pos(ppos);
213
214 if (!(integer_declaration->p.alignment % CHAR_BIT)
215 && !(integer_declaration->len % CHAR_BIT)) {
216 return _aligned_integer_read(ppos, definition);
217 }
218
219 ctf_align_pos(pos, integer_declaration->p.alignment);
220
221 if (!ctf_pos_access_ok(pos, integer_declaration->len))
222 return -EFAULT;
223
224 if (!integer_declaration->signedness) {
225 if (integer_declaration->byte_order == LITTLE_ENDIAN)
226 bt_bitfield_read_le(mmap_align_addr(pos->base_mma) +
227 pos->mmap_base_offset, unsigned long,
228 pos->offset, integer_declaration->len,
229 &integer_definition->value._unsigned);
230 else
231 bt_bitfield_read_be(mmap_align_addr(pos->base_mma) +
232 pos->mmap_base_offset, unsigned long,
233 pos->offset, integer_declaration->len,
234 &integer_definition->value._unsigned);
235 } else {
236 if (integer_declaration->byte_order == LITTLE_ENDIAN)
237 bt_bitfield_read_le(mmap_align_addr(pos->base_mma) +
238 pos->mmap_base_offset, unsigned long,
239 pos->offset, integer_declaration->len,
240 &integer_definition->value._signed);
241 else
242 bt_bitfield_read_be(mmap_align_addr(pos->base_mma) +
243 pos->mmap_base_offset, unsigned long,
244 pos->offset, integer_declaration->len,
245 &integer_definition->value._signed);
246 }
247 ctf_move_pos(pos, integer_declaration->len);
248 return 0;
249 }
250
251 int ctf_integer_write(struct stream_pos *ppos, struct definition *definition)
252 {
253 struct definition_integer *integer_definition =
254 container_of(definition, struct definition_integer, p);
255 const struct declaration_integer *integer_declaration =
256 integer_definition->declaration;
257 struct ctf_stream_pos *pos = ctf_pos(ppos);
258
259 if (!(integer_declaration->p.alignment % CHAR_BIT)
260 && !(integer_declaration->len % CHAR_BIT)) {
261 return _aligned_integer_write(ppos, definition);
262 }
263
264 ctf_align_pos(pos, integer_declaration->p.alignment);
265
266 if (!ctf_pos_access_ok(pos, integer_declaration->len))
267 return -EFAULT;
268
269 if (pos->dummy)
270 goto end;
271 if (!integer_declaration->signedness) {
272 if (integer_declaration->byte_order == LITTLE_ENDIAN)
273 bt_bitfield_write_le(mmap_align_addr(pos->base_mma) +
274 pos->mmap_base_offset, unsigned long,
275 pos->offset, integer_declaration->len,
276 integer_definition->value._unsigned);
277 else
278 bt_bitfield_write_be(mmap_align_addr(pos->base_mma) +
279 pos->mmap_base_offset, unsigned long,
280 pos->offset, integer_declaration->len,
281 integer_definition->value._unsigned);
282 } else {
283 if (integer_declaration->byte_order == LITTLE_ENDIAN)
284 bt_bitfield_write_le(mmap_align_addr(pos->base_mma) +
285 pos->mmap_base_offset, unsigned long,
286 pos->offset, integer_declaration->len,
287 integer_definition->value._signed);
288 else
289 bt_bitfield_write_be(mmap_align_addr(pos->base_mma) +
290 pos->mmap_base_offset, unsigned long,
291 pos->offset, integer_declaration->len,
292 integer_definition->value._signed);
293 }
294 end:
295 ctf_move_pos(pos, integer_declaration->len);
296 return 0;
297 }
This page took 0.034204 seconds and 3 git commands to generate.