Soletta™ Framework
Framework for making IoT devices

Full online documentation | C API Index
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sol-util.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Soletta (TM) Project
3  *
4  * Copyright (C) 2015 Intel Corporation. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #pragma once
20 
21 #include <sol-buffer.h>
22 #include <sol-str-slice.h>
23 
24 #include <ctype.h>
25 #include <errno.h>
26 #include <inttypes.h>
27 #include <limits.h>
28 #include <stdarg.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <time.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
54 #define sol_util_array_size(arr) (sizeof(arr) / sizeof((arr)[0]))
55 
59 #define SOL_UTIL_NSEC_PER_SEC 1000000000ULL
60 
64 #define SOL_UTIL_MSEC_PER_SEC 1000ULL
65 
69 #define SOL_UTIL_USEC_PER_SEC 1000000ULL
70 
74 #define SOL_UTIL_NSEC_PER_MSEC 1000000ULL
75 
79 #define SOL_UTIL_NSEC_PER_USEC 1000ULL
80 
89 #define sol_util_min(x, y) \
90  ({ \
91  __typeof__(x)_min1 = (x); \
92  __typeof__(y)_min2 = (y); \
93  (void)(&_min1 == &_min2); \
94  _min1 < _min2 ? _min1 : _min2; \
95  })
96 
105 #define sol_util_max(x, y) \
106  ({ \
107  __typeof__(x)_max1 = (x); \
108  __typeof__(y)_max2 = (y); \
109  (void)(&_max1 == &_max2); \
110  _max1 > _max2 ? _max1 : _max2; \
111  })
112 
118 struct timespec sol_util_timespec_get_current(void);
119 
128 int sol_util_timespec_get_realtime(struct timespec *t);
129 
137 static inline void
138 sol_util_timespec_add(const struct timespec *t1, const struct timespec *t2, struct timespec *result)
139 {
140  result->tv_nsec = t1->tv_nsec + t2->tv_nsec;
141  result->tv_sec = t1->tv_sec + t2->tv_sec;
142  if ((unsigned long long)result->tv_nsec >= SOL_UTIL_NSEC_PER_SEC) {
143  result->tv_nsec -= SOL_UTIL_NSEC_PER_SEC;
144  result->tv_sec++;
145  }
146 }
147 
155 static inline void
156 sol_util_timespec_sub(const struct timespec *t1, const struct timespec *t2, struct timespec *result)
157 {
158  result->tv_nsec = t1->tv_nsec - t2->tv_nsec;
159  result->tv_sec = t1->tv_sec - t2->tv_sec;
160  if (result->tv_nsec < 0) {
161  result->tv_nsec += SOL_UTIL_NSEC_PER_SEC;
162  result->tv_sec--;
163  }
164 }
165 
177 static inline int
178 sol_util_timespec_compare(const struct timespec *t1, const struct timespec *t2)
179 {
180  int retval = (t1->tv_sec > t2->tv_sec) - (t1->tv_sec < t2->tv_sec);
181 
182  if (retval != 0)
183  return retval;
184  return (t1->tv_nsec > t2->tv_nsec) - (t1->tv_nsec < t2->tv_nsec);
185 }
186 
194 static inline struct timespec
196 {
197  struct timespec ts;
198 
199  ts.tv_sec = msec / SOL_UTIL_MSEC_PER_SEC;
200  ts.tv_nsec = (msec % SOL_UTIL_MSEC_PER_SEC) * SOL_UTIL_NSEC_PER_MSEC;
201  return ts;
202 }
203 
211 static inline struct timespec
213 {
214  struct timespec ts;
215 
216  ts.tv_sec = usec / SOL_UTIL_USEC_PER_SEC;
217  ts.tv_nsec = (usec % SOL_UTIL_USEC_PER_SEC) * SOL_UTIL_NSEC_PER_USEC;
218  return ts;
219 }
220 
228 static inline int
229 sol_util_msec_from_timespec(const struct timespec *ts)
230 {
231  return ts->tv_sec * SOL_UTIL_MSEC_PER_SEC + ts->tv_nsec / SOL_UTIL_NSEC_PER_MSEC;
232 }
233 
241 static inline int
242 sol_util_usec_from_timespec(const struct timespec *ts)
243 {
244  return ts->tv_sec * SOL_UTIL_USEC_PER_SEC + ts->tv_nsec / SOL_UTIL_NSEC_PER_USEC;
245 }
246 
260 char *sol_util_strerror(int errnum, struct sol_buffer *buf);
261 
275 #define sol_util_strerrora(errnum) \
276  ({ \
277  SOL_BUFFER_DECLARE_STATIC(buf ## __COUNT__, 512); \
278  sol_util_strerror((errnum), &buf ## __COUNT__); \
279  })
280 
295 int sol_util_ssize_mul(ssize_t op1, ssize_t op2, ssize_t *out);
296 
311 int sol_util_size_mul(size_t op1, size_t op2, size_t *out);
312 
327 int sol_util_size_add(size_t op1, size_t op2, size_t *out);
328 
343 int sol_util_size_sub(size_t op1, size_t op2, size_t *out);
344 
359 int sol_util_uint64_mul(uint64_t op1, uint64_t op2, uint64_t *out);
360 
375 int sol_util_int64_mul(int64_t op1, int64_t op2, int64_t *out);
376 
391 int sol_util_uint64_add(uint64_t op1, uint64_t op2, uint64_t *out);
392 
405 int sol_util_int32_mul(int32_t op1, int32_t op2, int32_t *out);
406 
419 int sol_util_uint32_mul(uint32_t op1, uint32_t op2, uint32_t *out);
420 
437 int sol_util_uuid_gen(bool uppercase, bool with_hyphens, struct sol_buffer *uuid_buf);
438 
449 bool sol_util_uuid_str_is_valid(const struct sol_str_slice uuid);
450 
465 int sol_util_uuid_string_from_bytes(bool uppercase, bool with_hyphens, const uint8_t uuid_bytes[SOL_STATIC_ARRAY_SIZE(16)], struct sol_buffer *uuid_str);
466 
477 int sol_util_uuid_bytes_from_string(struct sol_str_slice uuid_str, struct sol_buffer *uuid_bytes);
478 
490 static inline int32_t
491 sol_util_int32_clamp(int32_t start, int32_t end, int32_t value)
492 {
493  if (value < start)
494  return start;
495  if (value > end)
496  return end;
497  return value;
498 }
499 
515 int sol_util_replace_str_if_changed(char **str, const char *new_str);
516 
532 int sol_util_replace_str_from_slice_if_changed(char **str, const struct sol_str_slice slice);
533 
553 ssize_t sol_util_base64_encode(void *buf, size_t buflen, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)]);
554 
574 ssize_t sol_util_base64_decode(void *buf, size_t buflen, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)]);
575 
586 static inline ssize_t
587 sol_util_base64_calculate_encoded_len(const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
588 {
589  ssize_t req_len = slice.len / 3;
590  int err;
591 
592  if (slice.len % 3 != 0)
593  req_len++;
594  err = sol_util_ssize_mul(req_len, 4, &req_len);
595  if (err < 0)
596  return err;
597  return req_len;
598 }
599 
610 ssize_t
611 sol_util_base64_calculate_decoded_len(const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)]);
612 
630 ssize_t sol_util_base16_encode(void *buf, size_t buflen, const struct sol_str_slice slice, bool uppercase);
631 
651 ssize_t sol_util_base16_decode(void *buf, size_t buflen, const struct sol_str_slice slice, enum sol_decode_case decode_case);
652 
668 int8_t sol_util_utf8_from_unicode_code(uint8_t *buf, size_t buf_len, uint32_t unicode_code);
669 
680 int32_t sol_util_unicode_code_from_utf8(const uint8_t *buf, size_t buf_len, uint8_t *bytes_read);
681 
690 static inline ssize_t
692 {
693  ssize_t req_len;
694  int err = sol_util_ssize_mul(slice.len, 2, &req_len);
695 
696  if (err < 0)
697  return err;
698  return req_len;
699 }
700 
709 static inline ssize_t
711 {
712  return slice.len / 2;
713 }
714 
724 static inline void
725 sol_util_clear_memory_secure(void *buf, size_t len)
726 {
727  memset(buf, 0, len);
728 
729  /* Clobber memory pointed to by `buf` to prevent the optimizer from
730  * eliding the memset() call. */
731  __asm__ __volatile__ ("" : : "g" (buf) : "memory");
732 }
733 
763 double sol_util_strtod_n(const char *nptr, char **endptr, ssize_t len, bool use_locale);
764 
789 long int sol_util_strtol_n(const char *nptr, char **endptr, ssize_t len, int base);
790 
815 unsigned long int sol_util_strtoul_n(const char *nptr, char **endptr, ssize_t len, int base);
816 
820 #define sol_util_uint16_bytes_swap(val) \
821  ((uint16_t)((((val) >> 8) & 0xff) | (((val) & 0xff) << 8)))
822 
835 static inline uint16_t
836 sol_util_cpu_to_be16(uint16_t val)
837 {
838 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
839  return sol_util_uint16_bytes_swap(val);
840 #else
841  return val;
842 #endif
843 }
844 
857 static inline uint16_t
858 sol_util_cpu_to_le16(uint16_t val)
859 {
860 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
861  return sol_util_uint16_bytes_swap(val);
862 #else
863  return val;
864 #endif
865 }
866 
879 static inline uint16_t
880 sol_util_be16_to_cpu(uint16_t val)
881 {
882 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
883  return sol_util_uint16_bytes_swap(val);
884 #else
885  return val;
886 #endif
887 }
888 
901 static inline uint16_t
902 sol_util_le16_to_cpu(uint16_t val)
903 {
904 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
905  return sol_util_uint16_bytes_swap(val);
906 #else
907  return val;
908 #endif
909 }
910 
914 #define sol_util_uint32_bytes_swap(val) \
915  ((uint32_t)((((val) & 0xff000000) >> 24) | (((val) & 0x00ff0000) >> 8) | \
916  (((val) & 0x0000ff00) << 8) | (((val) & 0x000000ff) << 24)))
917 
930 static inline uint32_t
931 sol_util_cpu_to_be32(uint32_t val)
932 {
933 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
934  return sol_util_uint32_bytes_swap(val);
935 #else
936  return val;
937 #endif
938 }
939 
952 static inline uint32_t
953 sol_util_cpu_to_le32(uint32_t val)
954 {
955 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
956  return sol_util_uint32_bytes_swap(val);
957 #else
958  return val;
959 #endif
960 }
961 
974 static inline uint32_t
975 sol_util_be32_to_cpu(uint32_t val)
976 {
977 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
978  return sol_util_uint32_bytes_swap(val);
979 #else
980  return val;
981 #endif
982 }
983 
996 static inline uint32_t
997 sol_util_le32_to_cpu(uint32_t val)
998 {
999 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1000  return sol_util_uint32_bytes_swap(val);
1001 #else
1002  return val;
1003 #endif
1004 }
1005 
1009 #define sol_util_uint64_bytes_swap(val) \
1010  ((uint64_t)((((val) & 0xff00000000000000ull) >> 56) \
1011  | (((val) & 0x00ff000000000000ull) >> 40) | (((val) & 0x0000ff0000000000ull) >> 24) \
1012  | (((val) & 0x000000ff00000000ull) >> 8) | (((val) & 0x00000000ff000000ull) << 8) \
1013  | (((val) & 0x0000000000ff0000ull) << 24) | (((val) & 0x000000000000ff00ull) << 40) \
1014  | (((val) & 0x00000000000000ffull) << 56)))
1015 
1028 static inline uint64_t
1030 {
1031 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1032  return sol_util_uint64_bytes_swap(val);
1033 #else
1034  return val;
1035 #endif
1036 }
1037 
1050 static inline uint64_t
1052 {
1053 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1054  return sol_util_uint64_bytes_swap(val);
1055 #else
1056  return val;
1057 #endif
1058 }
1059 
1072 static inline uint64_t
1074 {
1075 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1076  return sol_util_uint64_bytes_swap(val);
1077 #else
1078  return val;
1079 #endif
1080 }
1081 
1094 static inline uint64_t
1096 {
1097 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1098  return sol_util_uint64_bytes_swap(val);
1099 #else
1100  return val;
1101 #endif
1102 }
1103 
1116 int sol_util_unescape_quotes(const struct sol_str_slice slice, struct sol_buffer *buf);
1117 
1118 
1133 ssize_t sol_util_strftime(struct sol_buffer *buf, const char *format, const struct tm *timeptr, bool use_locale) SOL_ATTR_STRFTIME(2);
1134 
1146 bool sol_util_double_eq(double var0, double var1);
1147 
1160 void *sol_util_memdup(const void *data, size_t len);
1161 
1166 #ifdef __cplusplus
1167 }
1168 #endif
#define SOL_STATIC_ARRAY_SIZE(n)
Convenience macro to declare the size of a static array that will handle differences between C and C+...
Definition: sol-macros.h:208
static void sol_util_timespec_sub(const struct timespec *t1, const struct timespec *t2, struct timespec *result)
Subtracts two time values.
Definition: sol-util.h:156
int sol_util_int32_mul(int32_t op1, int32_t op2, int32_t *out)
Multiply two values checking for overflow.
#define SOL_UTIL_NSEC_PER_SEC
number of nanoseconds in a second: 1,000,000,000.
Definition: sol-util.h:59
unsigned long int sol_util_strtoul_n(const char *nptr, char **endptr, ssize_t len, int base)
Wrapper over strtoul() that consumes up to len bytes.
static uint64_t sol_util_cpu_to_be64(uint64_t val)
Convert a 64 bytes integer to big endian format.
Definition: sol-util.h:1029
static ssize_t sol_util_base16_calculate_decoded_len(const struct sol_str_slice slice)
Calculate the size necessary to decode a given slice in base16.
Definition: sol-util.h:710
#define sol_util_uint32_bytes_swap(val)
Swaps the bytes of a 32 bytes unsigned int.
Definition: sol-util.h:914
static int32_t sol_util_int32_clamp(int32_t start, int32_t end, int32_t value)
Restricts a number between two other numbers.
Definition: sol-util.h:491
static uint64_t sol_util_cpu_to_le64(uint64_t val)
Convert a 64 bytes integer to little endian format.
Definition: sol-util.h:1051
static uint32_t sol_util_be32_to_cpu(uint32_t val)
Convert a 32 bytes big endian integer to cpu endianness.
Definition: sol-util.h:975
static ssize_t sol_util_base64_calculate_encoded_len(const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
Calculate the size necessary to encode a given slice in base64.
Definition: sol-util.h:587
int sol_util_size_mul(size_t op1, size_t op2, size_t *out)
Multiply two values checking for overflow.
static uint16_t sol_util_be16_to_cpu(uint16_t val)
Convert a 16 bytes big endian integer to cpu endianness.
Definition: sol-util.h:880
#define SOL_ATTR_STRFTIME(fmt)
Specifies that a function takes strftime style arguments which should be type-checked against a forma...
Definition: sol-macros.h:191
int sol_util_uuid_bytes_from_string(struct sol_str_slice uuid_str, struct sol_buffer *uuid_bytes)
Convert a UUID in string format to a byte array with UUID bytes.
int32_t sol_util_unicode_code_from_utf8(const uint8_t *buf, size_t buf_len, uint8_t *bytes_read)
Convert a utf-8 character to unicode code.
#define SOL_UTIL_NSEC_PER_USEC
number of nanoseconds in a microsecond: 1,000,000,000 / 1,000,000 = 1,000.
Definition: sol-util.h:79
int sol_util_uuid_gen(bool uppercase, bool with_hyphens, struct sol_buffer *uuid_buf)
Generates a new universally unique identifier (UUID) string.
static struct sol_buffer value
Definition: server.c:42
void * sol_util_memdup(const void *data, size_t len)
Duplicate memory.
ssize_t sol_util_base64_decode(void *buf, size_t buflen, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
Decode the binary slice from base64 using the given map.
int8_t sol_util_utf8_from_unicode_code(uint8_t *buf, size_t buf_len, uint32_t unicode_code)
Convert from unicode code to utf-8 string.
static uint32_t sol_util_cpu_to_be32(uint32_t val)
Convert a 32 bytes integer to big endian format.
Definition: sol-util.h:931
int sol_util_replace_str_from_slice_if_changed(char **str, const struct sol_str_slice slice)
Replace the string's contents.
int sol_util_int64_mul(int64_t op1, int64_t op2, int64_t *out)
Multiply two values checking for overflow.
#define SOL_UTIL_MSEC_PER_SEC
number of milliseconds in a second: 1,000.
Definition: sol-util.h:64
int sol_util_uint64_mul(uint64_t op1, uint64_t op2, uint64_t *out)
Multiply two values checking for overflow.
String slice type.
Definition: sol-str-slice.h:84
These are routines that Soletta provides for its buffer implementation.
ssize_t sol_util_base16_decode(void *buf, size_t buflen, const struct sol_str_slice slice, enum sol_decode_case decode_case)
Decode the binary slice from base16 (hexadecimal).
static uint64_t sol_util_le64_to_cpu(uint64_t val)
Convert a 64 bytes little endian integer to cpu endianness.
Definition: sol-util.h:1095
bool sol_util_uuid_str_is_valid(const struct sol_str_slice uuid)
Checks if a given universally unique identifier (UUID), in string form, is valid. ...
int sol_util_uuid_string_from_bytes(bool uppercase, bool with_hyphens, const uint8_t uuid_bytes[SOL_STATIC_ARRAY_SIZE(16)], struct sol_buffer *uuid_str)
Convert a UUID in byte format to UUID string format.
int sol_util_size_sub(size_t op1, size_t op2, size_t *out)
Subtract two values checking for overflow.
static uint32_t sol_util_le32_to_cpu(uint32_t val)
Convert a 32 bytes little endian integer to cpu endianness.
Definition: sol-util.h:997
static void sol_util_timespec_add(const struct timespec *t1, const struct timespec *t2, struct timespec *result)
Sum two time values.
Definition: sol-util.h:138
static struct timespec sol_util_timespec_from_usec(int usec)
Create a struct timespec from microseconds.
Definition: sol-util.h:212
int sol_util_uint64_add(uint64_t op1, uint64_t op2, uint64_t *out)
Add two values checking for overflow.
bool sol_util_double_eq(double var0, double var1)
Checks var0 and var1 for equality.
static uint16_t sol_util_cpu_to_be16(uint16_t val)
Convert a 16 bytes integer to big endian format.
Definition: sol-util.h:836
int sol_util_unescape_quotes(const struct sol_str_slice slice, struct sol_buffer *buf)
Unescape a string removing quotes from it.
static void sol_util_clear_memory_secure(void *buf, size_t len)
Clear an allocated memory securely.
Definition: sol-util.h:725
ssize_t sol_util_base16_encode(void *buf, size_t buflen, const struct sol_str_slice slice, bool uppercase)
Encode the binary slice to base16 (hexadecimal).
char * sol_util_strerror(int errnum, struct sol_buffer *buf)
Gets a string from a given error.
static int sol_util_timespec_compare(const struct timespec *t1, const struct timespec *t2)
Compare two time values.
Definition: sol-util.h:178
int sol_util_size_add(size_t op1, size_t op2, size_t *out)
Add two values checking for overflow.
#define SOL_UTIL_USEC_PER_SEC
number of microseconds in a second: 1,000,000.
Definition: sol-util.h:69
ssize_t sol_util_base64_calculate_decoded_len(const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
Calculate the size necessary to decode a given slice in base64.
long int sol_util_strtol_n(const char *nptr, char **endptr, ssize_t len, int base)
Wrapper over strtol() that consumes up to len bytes.
static int sol_util_usec_from_timespec(const struct timespec *ts)
Gets the number of microseconds for given time.
Definition: sol-util.h:242
static ssize_t sol_util_base16_calculate_encoded_len(const struct sol_str_slice slice)
Calculate the size necessary to encode a given slice in base16.
Definition: sol-util.h:691
double sol_util_strtod_n(const char *nptr, char **endptr, ssize_t len, bool use_locale)
Wrapper over strtod() that consumes up to len bytes and may not use a locale.
ssize_t sol_util_strftime(struct sol_buffer *buf, const char *format, const struct tm *timeptr, bool use_locale) SOL_ATTR_STRFTIME(2)
Wrapper around strftime()/strftime_l()
These are routines that Soletta provides for its string slice implementation.
struct timespec sol_util_timespec_get_current(void)
Gets the current time (Monotonic).
int sol_util_replace_str_if_changed(char **str, const char *new_str)
Replace the string's contents.
static uint16_t sol_util_le16_to_cpu(uint16_t val)
Convert a 16 bytes little endian integer to cpu endianness.
Definition: sol-util.h:902
sol_decode_case
Case of a string to be decoded.
Definition: sol-buffer.h:142
static struct timespec sol_util_timespec_from_msec(int msec)
Create a struct timespec from milliseconds.
Definition: sol-util.h:195
#define sol_util_uint16_bytes_swap(val)
Swaps the bytes of a 16 bytes unsigned int.
Definition: sol-util.h:820
int sol_util_ssize_mul(ssize_t op1, ssize_t op2, ssize_t *out)
Multiply two values checking for overflow.
static int sol_util_msec_from_timespec(const struct timespec *ts)
Gets the number of milliseconds for given time.
Definition: sol-util.h:229
#define sol_util_uint64_bytes_swap(val)
Swaps the bytes of a 32 bytes unsigned int.
Definition: sol-util.h:1009
int sol_util_timespec_get_realtime(struct timespec *t)
Gets the current time (System-wide clock).
A sol_buffer is a dynamic array, that can be resized if needed.
Definition: sol-buffer.h:130
int sol_util_uint32_mul(uint32_t op1, uint32_t op2, uint32_t *out)
Multiply two values checking for overflow.
static uint16_t sol_util_cpu_to_le16(uint16_t val)
Convert a 16 bytes integer to little endian format.
Definition: sol-util.h:858
#define SOL_UTIL_NSEC_PER_MSEC
number of nanoseconds in a milliseconds: 1,000,000,000 / 1,000 = 1,000,000.
Definition: sol-util.h:74
ssize_t sol_util_base64_encode(void *buf, size_t buflen, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
Encode the binary slice to base64 using the given map.
static uint32_t sol_util_cpu_to_le32(uint32_t val)
Convert a 32 bytes integer to little endian format.
Definition: sol-util.h:953
size_t len
Slice length.
Definition: sol-str-slice.h:85
static uint64_t sol_util_be64_to_cpu(uint64_t val)
Convert a 64 bytes big endian integer to cpu endianness.
Definition: sol-util.h:1073