1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Copyright 2023 Red Hat
4 */
5
6 #ifndef UDS_NUMERIC_H
7 #define UDS_NUMERIC_H
8
9 #include <linux/unaligned.h>
10 #include <linux/kernel.h>
11 #include <linux/types.h>
12
13 /*
14 * These utilities encode or decode a number from an offset in a larger data buffer and then
15 * advance the offset pointer to the next field in the buffer.
16 */
17
decode_s64_le(const u8 * buffer,size_t * offset,s64 * decoded)18 static inline void decode_s64_le(const u8 *buffer, size_t *offset, s64 *decoded)
19 {
20 *decoded = get_unaligned_le64(buffer + *offset);
21 *offset += sizeof(s64);
22 }
23
encode_s64_le(u8 * data,size_t * offset,s64 to_encode)24 static inline void encode_s64_le(u8 *data, size_t *offset, s64 to_encode)
25 {
26 put_unaligned_le64(to_encode, data + *offset);
27 *offset += sizeof(s64);
28 }
29
decode_u64_le(const u8 * buffer,size_t * offset,u64 * decoded)30 static inline void decode_u64_le(const u8 *buffer, size_t *offset, u64 *decoded)
31 {
32 *decoded = get_unaligned_le64(buffer + *offset);
33 *offset += sizeof(u64);
34 }
35
encode_u64_le(u8 * data,size_t * offset,u64 to_encode)36 static inline void encode_u64_le(u8 *data, size_t *offset, u64 to_encode)
37 {
38 put_unaligned_le64(to_encode, data + *offset);
39 *offset += sizeof(u64);
40 }
41
decode_s32_le(const u8 * buffer,size_t * offset,s32 * decoded)42 static inline void decode_s32_le(const u8 *buffer, size_t *offset, s32 *decoded)
43 {
44 *decoded = get_unaligned_le32(buffer + *offset);
45 *offset += sizeof(s32);
46 }
47
encode_s32_le(u8 * data,size_t * offset,s32 to_encode)48 static inline void encode_s32_le(u8 *data, size_t *offset, s32 to_encode)
49 {
50 put_unaligned_le32(to_encode, data + *offset);
51 *offset += sizeof(s32);
52 }
53
decode_u32_le(const u8 * buffer,size_t * offset,u32 * decoded)54 static inline void decode_u32_le(const u8 *buffer, size_t *offset, u32 *decoded)
55 {
56 *decoded = get_unaligned_le32(buffer + *offset);
57 *offset += sizeof(u32);
58 }
59
encode_u32_le(u8 * data,size_t * offset,u32 to_encode)60 static inline void encode_u32_le(u8 *data, size_t *offset, u32 to_encode)
61 {
62 put_unaligned_le32(to_encode, data + *offset);
63 *offset += sizeof(u32);
64 }
65
decode_u16_le(const u8 * buffer,size_t * offset,u16 * decoded)66 static inline void decode_u16_le(const u8 *buffer, size_t *offset, u16 *decoded)
67 {
68 *decoded = get_unaligned_le16(buffer + *offset);
69 *offset += sizeof(u16);
70 }
71
encode_u16_le(u8 * data,size_t * offset,u16 to_encode)72 static inline void encode_u16_le(u8 *data, size_t *offset, u16 to_encode)
73 {
74 put_unaligned_le16(to_encode, data + *offset);
75 *offset += sizeof(u16);
76 }
77
78 #endif /* UDS_NUMERIC_H */
79