Commit | Line | Data |
---|---|---|
6dc2ca62 MD |
1 | /* |
2 | * Common Trace Format | |
3 | * | |
4 | * Integers read/write functions. | |
5 | * | |
de0ba614 | 6 | * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
6dc2ca62 | 7 | * |
de0ba614 MD |
8 | * This library is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License as published by the Free Software Foundation; either | |
11 | * version 2.1 of the License, or (at your option) any later version. | |
12 | * | |
13 | * This library is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * Lesser General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU Lesser General Public | |
19 | * License along with this library; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
6dc2ca62 MD |
21 | */ |
22 | ||
23 | #include <ctf/ctf-types.h> | |
7fe00194 | 24 | #include <ctf/bitfield.h> |
6dc2ca62 MD |
25 | #include <stdint.h> |
26 | #include <glib.h> | |
27 | #include <endian.h> | |
28 | ||
7fe00194 MD |
29 | static |
30 | uint64_t _aligned_uint_read(struct stream_pos *pos, | |
bed864a7 | 31 | const struct type_class_integer *int_class) |
6dc2ca62 | 32 | { |
bed864a7 | 33 | int rbo = (int_class->byte_order != BYTE_ORDER); /* reverse byte order */ |
6dc2ca62 | 34 | |
bed864a7 MD |
35 | align_pos(pos, int_class->p.alignment); |
36 | assert(!(pos->offset % CHAR_BIT)); | |
37 | switch (int_class->len) { | |
6dc2ca62 MD |
38 | case 8: |
39 | { | |
40 | uint8_t v; | |
41 | ||
bed864a7 MD |
42 | v = *(const uint8_t *)pos->base; |
43 | move_pos(pos, int_class->len); | |
6dc2ca62 MD |
44 | return v; |
45 | } | |
46 | case 16: | |
47 | { | |
48 | uint16_t v; | |
49 | ||
bed864a7 MD |
50 | v = *(const uint16_t *)pos->base; |
51 | move_pos(pos, int_class->len); | |
6dc2ca62 MD |
52 | return rbo ? GUINT16_SWAP_LE_BE(v) : v; |
53 | } | |
54 | case 32: | |
55 | { | |
56 | uint32_t v; | |
57 | ||
bed864a7 MD |
58 | v = *(const uint32_t *)pos->base; |
59 | move_pos(pos, int_class->len); | |
6dc2ca62 MD |
60 | return rbo ? GUINT32_SWAP_LE_BE(v) : v; |
61 | } | |
62 | case 64: | |
63 | { | |
64 | uint64_t v; | |
65 | ||
bed864a7 MD |
66 | v = *(const uint64_t *)pos->base; |
67 | move_pos(pos, int_class->len); | |
6dc2ca62 MD |
68 | return rbo ? GUINT64_SWAP_LE_BE(v) : v; |
69 | } | |
70 | default: | |
71 | assert(0); | |
72 | } | |
73 | } | |
74 | ||
7fe00194 MD |
75 | static |
76 | int64_t _aligned_int_read(struct stream_pos *pos, | |
bed864a7 | 77 | const struct type_class_integer *int_class) |
6dc2ca62 | 78 | { |
bed864a7 | 79 | int rbo = (int_class->byte_order != BYTE_ORDER); /* reverse byte order */ |
6dc2ca62 | 80 | |
bed864a7 MD |
81 | align_pos(pos, int_class->p.alignment); |
82 | assert(!(pos->offset % CHAR_BIT)); | |
83 | switch (int_class->len) { | |
6dc2ca62 MD |
84 | case 8: |
85 | { | |
86 | int8_t v; | |
87 | ||
bed864a7 MD |
88 | v = *(const int8_t *)pos->base; |
89 | move_pos(pos, int_class->len); | |
6dc2ca62 MD |
90 | return v; |
91 | } | |
92 | case 16: | |
93 | { | |
94 | int16_t v; | |
95 | ||
bed864a7 MD |
96 | v = *(const int16_t *)pos->base; |
97 | move_pos(pos, int_class->len); | |
6dc2ca62 MD |
98 | return rbo ? GUINT16_SWAP_LE_BE(v) : v; |
99 | } | |
100 | case 32: | |
101 | { | |
102 | int32_t v; | |
103 | ||
bed864a7 MD |
104 | v = *(const int32_t *)pos->base; |
105 | move_pos(pos, int_class->len); | |
6dc2ca62 MD |
106 | return rbo ? GUINT32_SWAP_LE_BE(v) : v; |
107 | } | |
108 | case 64: | |
109 | { | |
110 | int64_t v; | |
111 | ||
bed864a7 MD |
112 | v = *(const int64_t *)pos->base; |
113 | move_pos(pos, int_class->len); | |
6dc2ca62 MD |
114 | return rbo ? GUINT64_SWAP_LE_BE(v) : v; |
115 | } | |
116 | default: | |
117 | assert(0); | |
118 | } | |
119 | } | |
120 | ||
7fe00194 MD |
121 | static |
122 | void _aligned_uint_write(struct stream_pos *pos, | |
bed864a7 MD |
123 | const struct type_class_integer *int_class, |
124 | uint64_t v) | |
6dc2ca62 | 125 | { |
bed864a7 | 126 | int rbo = (int_class->byte_order != BYTE_ORDER); /* reverse byte order */ |
6dc2ca62 | 127 | |
bed864a7 MD |
128 | align_pos(pos, int_class->p.alignment); |
129 | assert(!(pos->offset % CHAR_BIT)); | |
130 | if (pos->dummy) | |
6dc2ca62 MD |
131 | goto end; |
132 | ||
bed864a7 MD |
133 | switch (int_class->len) { |
134 | case 8: *(uint8_t *) get_pos_addr(pos) = (uint8_t) v; | |
6dc2ca62 MD |
135 | break; |
136 | case 16: | |
bed864a7 MD |
137 | *(uint16_t *) get_pos_addr(pos) = rbo ? |
138 | GUINT16_SWAP_LE_BE((uint16_t) v) : | |
6dc2ca62 MD |
139 | (uint16_t) v; |
140 | break; | |
141 | case 32: | |
bed864a7 MD |
142 | *(uint32_t *) get_pos_addr(pos) = rbo ? |
143 | GUINT32_SWAP_LE_BE((uint32_t) v) : | |
6dc2ca62 MD |
144 | (uint32_t) v; |
145 | break; | |
146 | case 64: | |
bed864a7 MD |
147 | *(uint64_t *) get_pos_addr(pos) = rbo ? |
148 | GUINT64_SWAP_LE_BE(v) : v; | |
6dc2ca62 MD |
149 | break; |
150 | default: | |
151 | assert(0); | |
152 | } | |
153 | end: | |
bed864a7 | 154 | move_pos(pos, int_class->len); |
6dc2ca62 MD |
155 | } |
156 | ||
7fe00194 MD |
157 | static |
158 | void _aligned_int_write(struct stream_pos *pos, | |
bed864a7 MD |
159 | const struct type_class_integer *int_class, |
160 | int64_t v) | |
6dc2ca62 | 161 | { |
bed864a7 | 162 | int rbo = (int_class->byte_order != BYTE_ORDER); /* reverse byte order */ |
6dc2ca62 | 163 | |
bed864a7 MD |
164 | align_pos(pos, int_class->p.alignment); |
165 | assert(!(pos->offset % CHAR_BIT)); | |
166 | if (pos->dummy) | |
6dc2ca62 MD |
167 | goto end; |
168 | ||
bed864a7 MD |
169 | switch (int_class->len) { |
170 | case 8: *(int8_t *) get_pos_addr(pos) = (int8_t) v; | |
6dc2ca62 MD |
171 | break; |
172 | case 16: | |
bed864a7 MD |
173 | *(int16_t *) get_pos_addr(pos) = rbo ? |
174 | GUINT16_SWAP_LE_BE((int16_t) v) : | |
6dc2ca62 MD |
175 | (int16_t) v; |
176 | break; | |
177 | case 32: | |
bed864a7 MD |
178 | *(int32_t *) get_pos_addr(pos) = rbo ? |
179 | GUINT32_SWAP_LE_BE((int32_t) v) : | |
6dc2ca62 MD |
180 | (int32_t) v; |
181 | break; | |
182 | case 64: | |
bed864a7 MD |
183 | *(int64_t *) get_pos_addr(pos) = rbo ? |
184 | GUINT64_SWAP_LE_BE(v) : v; | |
6dc2ca62 MD |
185 | break; |
186 | default: | |
187 | assert(0); | |
188 | } | |
189 | end: | |
bed864a7 MD |
190 | move_pos(pos, int_class->len); |
191 | return; | |
6dc2ca62 | 192 | } |
7fe00194 MD |
193 | |
194 | uint64_t ctf_uint_read(struct stream_pos *pos, | |
195 | const struct type_class_bitfield *int_class) | |
196 | { | |
197 | uint64_t v; | |
198 | ||
199 | align_pos(pos, int_class->p.alignment); | |
200 | if (int_class->byte_order == LITTLE_ENDIAN) | |
201 | ctf_bitfield_read_le(pos->base, pos->offset, | |
202 | int_class->len, &v); | |
203 | else | |
204 | ctf_bitfield_read_be(pos->base, pos->offset, | |
205 | int_class->len, &v); | |
206 | move_pos(pos, int_class->len); | |
207 | return v; | |
208 | } | |
209 | ||
210 | int64_t ctf_int_read(struct stream_pos *pos, | |
211 | const struct type_class_bitfield *int_class) | |
212 | { | |
213 | int64_t v; | |
214 | ||
215 | align_pos(pos, int_class->p.alignment); | |
216 | if (int_class->byte_order == LITTLE_ENDIAN) | |
217 | ctf_bitfield_read_le(pos->base, pos->offset, | |
218 | int_class->len, &v); | |
219 | else | |
220 | ctf_bitfield_read_be(pos->base, pos->offset, | |
221 | int_class->len, &v); | |
222 | move_pos(pos, int_class->len); | |
223 | return v; | |
224 | } | |
225 | ||
226 | void ctf_uint_write(struct stream_pos *pos, | |
227 | const struct type_class_bitfield *int_class, | |
228 | uint64_t v) | |
229 | { | |
230 | align_pos(pos, int_class->p.alignment); | |
231 | if (pos->dummy) | |
232 | goto end; | |
233 | if (int_class->byte_order == LITTLE_ENDIAN) | |
234 | ctf_bitfield_write_le(pos->base, pos->offset, | |
235 | int_class->len, v); | |
236 | else | |
237 | ctf_bitfield_write_be(pos->base, pos->offset, | |
238 | int_class->len,, v); | |
239 | end: | |
240 | move_pos(pos, int_class->len); | |
241 | } | |
242 | ||
243 | void ctf_int_write(struct stream_pos *pos, | |
244 | const struct type_class_bitfield *int_class, | |
245 | int64_t v) | |
246 | { | |
247 | align_pos(pos, int_class->p.alignment); | |
248 | if (pos->dummy) | |
249 | goto end; | |
250 | if (int_class->byte_order == LITTLE_ENDIAN) | |
251 | ctf_bitfield_write_le(pos->base, pos->offset, | |
252 | int_class->len, v); | |
253 | else | |
254 | ctf_bitfield_write_be(pos->base, pos->offset, | |
255 | int_class->len, v); | |
256 | end: | |
257 | move_pos(pos, int_class->len); | |
258 | } |