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
18static 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
24static 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
30static 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
36static 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
42static 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
48static 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
54static 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
60static 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
66static 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
72static 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