NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
buffer_utils.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #ifndef APPLICATIONS_STORAGE_STORAGE_COMMON_MESSAGE_UTILS_HPP_
27 #define APPLICATIONS_STORAGE_STORAGE_COMMON_MESSAGE_UTILS_HPP_
28 
29 #include <algorithm>
30 #include <cstdint>
31 #include <string>
32 #include <vector>
33 
35 
36 namespace storage {
37 
38 /*
39  * Emplace an uint8_t value into a byte array
40  *
41  * @buffer [in]: buffer storage
42  * @value [in]: value to set
43  * @return: Pointer to next byte after the written value
44  */
45 inline char *to_buffer(char *buffer, uint8_t value)
46 {
47  *buffer = static_cast<char>(value);
48  return buffer + sizeof(value);
49 }
50 
51 /*
52  * Emplace an uint16_t value as a big endian byte order value into a byte array
53  *
54  * @buffer [in]: buffer storage
55  * @value [in]: value to set
56  * @return: Pointer to next byte after the written value
57  */
58 inline char *to_buffer(char *buffer, uint16_t value)
59 {
60  value = htobe16(value);
61  std::copy(reinterpret_cast<char const *>(&value),
62  reinterpret_cast<char const *>(&value) + sizeof(value),
63  buffer);
64  return buffer + sizeof(value);
65 }
66 
67 /*
68  * Emplace an uint32_t value as a big endian byte order value into a byte array
69  *
70  * @buffer [in]: buffer storage
71  * @value [in]: value to set
72  * @return: Pointer to next byte after the written value
73  */
74 inline char *to_buffer(char *buffer, uint32_t value) noexcept
75 {
76  value = htobe32(value);
77  std::copy(reinterpret_cast<char const *>(&value),
78  reinterpret_cast<char const *>(&value) + sizeof(value),
79  buffer);
80  return buffer + sizeof(value);
81 }
82 
83 /*
84  * Emplace an uint64_t value as a big endian byte order value into a byte array
85  *
86  * @buffer [in]: buffer storage
87  * @value [in]: value to set
88  * @return: Pointer to next byte after the written value
89  */
90 inline char *to_buffer(char *buffer, uint64_t value) noexcept
91 {
92  value = htobe64(value);
93  std::copy(reinterpret_cast<char const *>(&value),
94  reinterpret_cast<char const *>(&value) + sizeof(value),
95  buffer);
96  return buffer + sizeof(value);
97 }
98 
99 /*
100  * Emplace a std::string into a byte array
101  *
102  * @buffer [in]: buffer storage
103  * @value [in]: value to set
104  * @return: Pointer to next byte after the written value
105  */
106 inline char *to_buffer(char *buffer, std::string const &value) noexcept
107 {
108  buffer = to_buffer(buffer, static_cast<uint32_t>(value.size()));
109  std::copy(value.data(), value.data() + value.size(), buffer);
110 
111  return buffer + value.size();
112 }
113 
114 /*
115  * Emplace a std::vector<uint8_t> into a byte array
116  *
117  * @buffer [in]: buffer to read from
118  * @value [out]: Extracted value in the native byte ordering
119  * @return: Pointer to next byte after the read value
120  */
121 inline char *to_buffer(char *buffer, std::vector<uint8_t> const &value) noexcept
122 {
123  buffer = to_buffer(buffer, static_cast<uint32_t>(value.size()));
124  std::copy(value.data(), value.data() + value.size(), buffer);
125 
126  return buffer + value.size();
127 }
128 
129 /*
130  * Function template for decode functions
131  *
132  * @buffer [in]: buffer to read from
133  * @value [out]: Extracted value in the native byte ordering
134  * @return: Pointer to next byte after the read value
135  */
136 template <typename T>
137 inline char const *from_buffer(char const *buffer, T &value);
138 
139 /*
140  * Complete specialization of from_buffer that extracts a uint8_t from the given buffer
141  *
142  * @buffer [in]: buffer to read from
143  * @value [out]: Extracted value in the native byte ordering
144  * @return: Pointer to next byte after the read value
145  */
146 template <>
147 inline char const *from_buffer(char const *buffer, uint8_t &value)
148 {
149  value = *buffer;
150  return buffer + sizeof(value);
151 }
152 
153 /*
154  * Complete specialization of from_buffer that extracts a uint16_t from the given buffer
155  *
156  * @buffer [in]: buffer to read from
157  * @return: Extracted value in the native byte ordering
158  */
159 template <>
160 inline char const *from_buffer(char const *buffer, uint16_t &value)
161 {
162  std::copy(buffer, buffer + sizeof(value), reinterpret_cast<char *>(&value));
163  value = be16toh(value);
164  return buffer + sizeof(value);
165 }
166 
167 /*
168  * Complete specialization of from_buffer that extracts a uint32_t from the given buffer
169  *
170  * @buffer [in]: buffer to read from
171  * @return: Extracted value in the native byte ordering
172  */
173 template <>
174 inline char const *from_buffer(char const *buffer, uint32_t &value)
175 {
176  std::copy(buffer, buffer + sizeof(value), reinterpret_cast<char *>(&value));
177  value = be32toh(value);
178  return buffer + sizeof(value);
179 }
180 
181 /*
182  * Complete specialization of from_buffer that extracts a uint64_t from the given buffer
183  *
184  * @buffer [in]: buffer to read from
185  * @return: Extracted value in the native byte ordering
186  */
187 template <>
188 inline char const *from_buffer(char const *buffer, uint64_t &value)
189 {
190  std::copy(buffer, buffer + sizeof(value), reinterpret_cast<char *>(&value));
191  value = be64toh(value);
192  return buffer + sizeof(value);
193 }
194 
195 /*
196  * Complete specialization of from_buffer that extracts a std::string from the given buffer
197  *
198  * @buffer [in]: buffer to read from
199  * @return: Extracted string
200  */
201 template <>
202 inline char const *from_buffer(char const *buffer, std::string &value)
203 {
204  uint32_t byte_count = 0;
205  buffer = from_buffer(buffer, byte_count);
206  value = std::string{buffer, buffer + byte_count};
207  return buffer + byte_count;
208 }
209 
210 /*
211  * Complete specialization of from_buffer that extracts a std::vector<uint8_t> from the given buffer
212  *
213  * @buffer [in]: buffer to read from
214  * @return: Extracted value in the native byte ordering
215  */
216 template <>
217 inline char const *from_buffer(char const *buffer, std::vector<uint8_t> &value)
218 {
219  uint32_t byte_count = 0;
220  buffer = from_buffer(buffer, byte_count);
221  value = std::vector<uint8_t>{reinterpret_cast<uint8_t const *>(buffer),
222  reinterpret_cast<uint8_t const *>(buffer) + byte_count};
223  return buffer + byte_count;
224 }
225 
226 /*
227  * Convert an array of bytes into a string representing their hexadecimal ASCII values ie: [137, 250] =>
228  * ['8', '9', 'F', 'A']
229  *
230  * @bytes [in]: Pointer to array of bytes to convert
231  * @byte_count [in]: Number of bytes in array
232  * @return: string representation of the byte buffer
233  */
234 std::string bytes_to_hex_str(char const *bytes, size_t byte_count);
235 
236 /*
237  * Convert an array of bytes into a string representing their hexadecimal ASCII values ie: [137, 250] =>
238  * ['8', '9', 'F', 'A']
239  *
240  * @bytes [in]: Pointer to array of bytes to convert
241  * @byte_count [in]: Number of bytes in array
242  * @str [out]: String to append to
243  */
244 void bytes_to_hex_str(char const *bytes, size_t byte_count, std::string &str);
245 
246 /*
247  * Scale the provided size to be a multiple of alignment to satisfy aligned_alloc
248  *
249  * @alignment [in]: Alignment size
250  * @size [in]: Requested size
251  * @return Requested size or the next greater value which is a multiple of alignment
252  */
253 size_t aligned_size(size_t alignment, size_t size);
254 
255 } /* namespace storage */
256 
257 #endif /* APPLICATIONS_STORAGE_STORAGE_COMMON_MESSAGE_UTILS_HPP_ */
type value
std::string bytes_to_hex_str(char const *bytes, size_t byte_count)
size_t aligned_size(size_t alignment, size_t size)
char const * from_buffer(char const *buffer, T &value)
char * to_buffer(char *buffer, uint8_t value)
#define htobe64
Definition: os_utils.hpp:41
#define htobe32
Definition: os_utils.hpp:40
#define htobe16
Definition: os_utils.hpp:39