xref: /linux/drivers/md/dm-vdo/numeric.h (revision 4b660dbd9ee2059850fd30e0df420ca7a38a1856)
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 <asm/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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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