/src/wireshark/wsutil/sign_ext.h
Line | Count | Source |
1 | | /** @file |
2 | | * |
3 | | * Wireshark - Network traffic analyzer |
4 | | * By Gerald Combs <gerald@wireshark.org> |
5 | | * Copyright 1998 Gerald Combs |
6 | | * |
7 | | * SPDX-License-Identifier: GPL-2.0-or-later |
8 | | */ |
9 | | |
10 | | #ifndef __WSUTIL_SIGN_EXT_H__ |
11 | | #define __WSUTIL_SIGN_EXT_H__ |
12 | | |
13 | | #include <inttypes.h> |
14 | | |
15 | | #include <glib.h> |
16 | | |
17 | | #include <wsutil/ws_assert.h> |
18 | | |
19 | | /* sign extension routines */ |
20 | | |
21 | | /** |
22 | | * @brief Sign-extends a 32-bit unsigned value from a given bit width. |
23 | | * |
24 | | * Interprets the input value as a signed integer of `no_of_bits` width and |
25 | | * extends the sign bit to the full 32-bit range. This is useful when decoding |
26 | | * signed fields packed into smaller bit widths. |
27 | | * |
28 | | * @param val The unsigned 32-bit value to sign-extend. |
29 | | * @param no_of_bits The number of significant bits (0–32). |
30 | | * @return The sign-extended 32-bit value. |
31 | | */ |
32 | | static inline uint32_t |
33 | | ws_sign_ext32(uint32_t val, int no_of_bits) |
34 | 18.7k | { |
35 | 18.7k | ws_assert (no_of_bits >= 0 && no_of_bits <= 32); |
36 | | |
37 | 18.7k | if ((no_of_bits == 0) || (no_of_bits == 32)) |
38 | 11.7k | return val; |
39 | | |
40 | | /* |
41 | | * Don't shift signed values left; that's not valid in C99, at |
42 | | * least, if the value is negative or if the shift count is |
43 | | * the number of bits in the value - 1, and we might get |
44 | | * compile-time or run-time complaints about that. |
45 | | */ |
46 | 7.03k | if (val & (1U << (no_of_bits-1))) |
47 | 2.16k | val |= (0xFFFFFFFFU << no_of_bits); |
48 | | |
49 | 7.03k | return val; |
50 | 18.7k | } Line | Count | Source | 34 | 14.5k | { | 35 | 14.5k | ws_assert (no_of_bits >= 0 && no_of_bits <= 32); | 36 | | | 37 | 14.5k | if ((no_of_bits == 0) || (no_of_bits == 32)) | 38 | 11.7k | return val; | 39 | | | 40 | | /* | 41 | | * Don't shift signed values left; that's not valid in C99, at | 42 | | * least, if the value is negative or if the shift count is | 43 | | * the number of bits in the value - 1, and we might get | 44 | | * compile-time or run-time complaints about that. | 45 | | */ | 46 | 2.88k | if (val & (1U << (no_of_bits-1))) | 47 | 909 | val |= (0xFFFFFFFFU << no_of_bits); | 48 | | | 49 | 2.88k | return val; | 50 | 14.5k | } |
Line | Count | Source | 34 | 3.93k | { | 35 | 3.93k | ws_assert (no_of_bits >= 0 && no_of_bits <= 32); | 36 | | | 37 | 3.93k | if ((no_of_bits == 0) || (no_of_bits == 32)) | 38 | 0 | return val; | 39 | | | 40 | | /* | 41 | | * Don't shift signed values left; that's not valid in C99, at | 42 | | * least, if the value is negative or if the shift count is | 43 | | * the number of bits in the value - 1, and we might get | 44 | | * compile-time or run-time complaints about that. | 45 | | */ | 46 | 3.93k | if (val & (1U << (no_of_bits-1))) | 47 | 1.18k | val |= (0xFFFFFFFFU << no_of_bits); | 48 | | | 49 | 3.93k | return val; | 50 | 3.93k | } |
Unexecuted instantiation: packet-signal-pdu.c:ws_sign_ext32 Unexecuted instantiation: packet-usb-hid.c:ws_sign_ext32 Line | Count | Source | 34 | 215 | { | 35 | 215 | ws_assert (no_of_bits >= 0 && no_of_bits <= 32); | 36 | | | 37 | 215 | if ((no_of_bits == 0) || (no_of_bits == 32)) | 38 | 0 | return val; | 39 | | | 40 | | /* | 41 | | * Don't shift signed values left; that's not valid in C99, at | 42 | | * least, if the value is negative or if the shift count is | 43 | | * the number of bits in the value - 1, and we might get | 44 | | * compile-time or run-time complaints about that. | 45 | | */ | 46 | 215 | if (val & (1U << (no_of_bits-1))) | 47 | 71 | val |= (0xFFFFFFFFU << no_of_bits); | 48 | | | 49 | 215 | return val; | 50 | 215 | } |
|
51 | | |
52 | | /** |
53 | | * @brief Sign-extends a 64-bit unsigned value from a given bit width. |
54 | | * |
55 | | * Interprets the input value as a signed integer of `no_of_bits` width and |
56 | | * extends the sign bit to the full 64-bit range. This is useful when decoding |
57 | | * signed fields packed into smaller bit widths. |
58 | | * |
59 | | * @param val The unsigned 64-bit value to sign-extend. |
60 | | * @param no_of_bits The number of significant bits (0–64). |
61 | | * @return The sign-extended 64-bit value. |
62 | | */ |
63 | | static inline uint64_t |
64 | | ws_sign_ext64(uint64_t val, int no_of_bits) |
65 | 8.66k | { |
66 | 8.66k | ws_assert (no_of_bits >= 0 && no_of_bits <= 64); |
67 | | |
68 | 8.66k | if ((no_of_bits == 0) || (no_of_bits == 64)) |
69 | 0 | return val; |
70 | | |
71 | | /* |
72 | | * Don't shift signed values left; that's not valid in C99, at |
73 | | * least, if the value is negative or if the shift count is |
74 | | * the number of bits in the value - 1, and we might get |
75 | | * compile-time or run-time complaints about that. |
76 | | */ |
77 | 8.66k | if (val & (UINT64_C(1) << (no_of_bits-1))) |
78 | 2.74k | val |= (UINT64_C(0xFFFFFFFFFFFFFFFF) << no_of_bits); |
79 | | |
80 | 8.66k | return val; |
81 | 8.66k | } Line | Count | Source | 65 | 5.31k | { | 66 | 5.31k | ws_assert (no_of_bits >= 0 && no_of_bits <= 64); | 67 | | | 68 | 5.31k | if ((no_of_bits == 0) || (no_of_bits == 64)) | 69 | 0 | return val; | 70 | | | 71 | | /* | 72 | | * Don't shift signed values left; that's not valid in C99, at | 73 | | * least, if the value is negative or if the shift count is | 74 | | * the number of bits in the value - 1, and we might get | 75 | | * compile-time or run-time complaints about that. | 76 | | */ | 77 | 5.31k | if (val & (UINT64_C(1) << (no_of_bits-1))) | 78 | 1.72k | val |= (UINT64_C(0xFFFFFFFFFFFFFFFF) << no_of_bits); | 79 | | | 80 | 5.31k | return val; | 81 | 5.31k | } |
Line | Count | Source | 65 | 3.35k | { | 66 | 3.35k | ws_assert (no_of_bits >= 0 && no_of_bits <= 64); | 67 | | | 68 | 3.35k | if ((no_of_bits == 0) || (no_of_bits == 64)) | 69 | 0 | return val; | 70 | | | 71 | | /* | 72 | | * Don't shift signed values left; that's not valid in C99, at | 73 | | * least, if the value is negative or if the shift count is | 74 | | * the number of bits in the value - 1, and we might get | 75 | | * compile-time or run-time complaints about that. | 76 | | */ | 77 | 3.35k | if (val & (UINT64_C(1) << (no_of_bits-1))) | 78 | 1.01k | val |= (UINT64_C(0xFFFFFFFFFFFFFFFF) << no_of_bits); | 79 | | | 80 | 3.35k | return val; | 81 | 3.35k | } |
Unexecuted instantiation: packet-signal-pdu.c:ws_sign_ext64 Unexecuted instantiation: packet-usb-hid.c:ws_sign_ext64 Unexecuted instantiation: asn1.c:ws_sign_ext64 |
82 | | |
83 | | /* |
84 | | static inline uint64_t |
85 | | ws_sign_ext64(uint64_t val, int no_of_bits) |
86 | | { |
87 | | int64_t sval = (val << (64 - no_of_bits)); |
88 | | |
89 | | return (uint64_t) (sval >> (64 - no_of_bits)); |
90 | | } |
91 | | */ |
92 | | |
93 | | #endif /* __WSUTIL_SIGN_EXT_H__ */ |