Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / nlio / repo / include / nlio-base.h
1 /**
2  *    Copyright 2013-2017 Nest Labs Inc. All Rights Reserved.
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 /**
18  *    @file
19  *      This file defines C functions for safely performing simple,
20  *      memory-mapped accesses, potentially to unaligned memory
21  *      locations.
22  */
23
24 #ifndef NLIO_BASE_H
25 #define NLIO_BASE_H
26
27 #include <nlio-private.h>
28
29 #include <stdbool.h>
30 #include <stdint.h>
31 #include <string.h>
32
33 /*
34  * If we are compiling under clang, GCC, or any such compatible
35  * compiler, in which -fno-builtins or -ffreestanding might be
36  * asserted, thereby eliminating built-in function optimization, we
37  * STILL want built-in memcpy. We want this because it allows the
38  * compiler to use architecture-specific machine instructions or
39  * inline code generation to optimize an otherwise-expensive memcpy
40  * for unaligned reads and writes, which is exactly the kind of
41  * efficiency that would be expected of nlIO.
42  */
43 #if __nlIOHasBuiltin(__builtin_memcpy)
44 #define __nlIO_MEMCPY __builtin_memcpy
45 #else
46 #define __nlIO_MEMCPY memcpy
47 #endif
48
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52
53 /**
54  * This determines whether the specified pointer is aligned on the
55  * indicated size boundary.
56  *
57  * @note The size should be a power of 2 (e.g. 1, 2, 4, 8, 16, etc.).
58  *
59  * @param[in]  p     The pointer to check the alignment of.
60  * @param[in]  size  The size, in bytes, boundary to check
61  *                   the alignment against.
62  *
63  * @return True if the pointer is aligned to the specified size;
64  *         otherwise, false.
65  */
66 static inline bool nlIOIsAligned(const void *p, size_t size)
67 {
68     const uintptr_t value = (uintptr_t)(p);
69     const uintptr_t mask  = size - 1;
70
71     return ((value & mask) == 0);
72 }
73
74 /**
75  * Perform an aligned memory read of the 8-bit value at the specified
76  * pointer address.
77  *
78  * @param[in]  p      A pointer address to read the 8-bit value from.
79  *
80  * @return The 8-bit value at the specified pointer address.
81  */
82 static inline uint8_t  nlIOGetAligned8(const void *p)
83 {
84     return *(const uint8_t *)(p);
85 }
86
87 /**
88  * Perform an aligned memory read of the 16-bit value at the specified
89  * pointer address.
90  *
91  * @param[in]  p      A pointer address to read the 16-bit value from.
92  *
93  * @return The 16-bit value at the specified pointer address.
94  */
95 static inline uint16_t nlIOGetAligned16(const void *p)
96 {
97     return *(const uint16_t *)(p);
98 }
99
100 /**
101  * Perform an aligned memory read of the 32-bit value at the specified
102  * pointer address.
103  *
104  * @param[in]  p      A pointer address to read the 32-bit value from.
105  *
106  * @return The 32-bit value at the specified pointer address.
107  */
108 static inline uint32_t nlIOGetAligned32(const void *p)
109 {
110     return *(const uint32_t *)(p);
111 }
112
113 /**
114  * Perform an aligned memory read of the 64-bit value at the specified
115  * pointer address.
116  *
117  * @param[in]  p      A pointer address to read the 64-bit value from.
118  *
119  * @return The 64-bit value at the specified pointer address.
120  */
121 static inline uint64_t nlIOGetAligned64(const void *p)
122 {
123     return *(const uint64_t *)(p);
124 }
125
126 /**
127  * Perform an unaligned memory read of the 8-bit value at the specified
128  * pointer address.
129  *
130  * @param[in]  p      A pointer address to read the 8-bit value from.
131  *
132  * @return The 8-bit value at the specified pointer address.
133  */
134 static inline uint8_t  nlIOGetUnaligned8(const void *p)
135 {
136     return nlIOGetAligned8(p);
137 }
138
139 /**
140  * Perform an unaligned memory read of the 16-bit value at the specified
141  * pointer address.
142  *
143  * @param[in]  p      A pointer address to read the 16-bit value from.
144  *
145  * @return The 16-bit value at the specified pointer address.
146  */
147 static inline uint16_t nlIOGetUnaligned16(const void *p)
148 {
149     uint16_t temp;
150
151     __nlIO_MEMCPY(&temp, p, sizeof(uint16_t));
152
153     return temp;
154 }
155
156 /**
157  * Perform an unaligned memory read of the 32-bit value at the specified
158  * pointer address.
159  *
160  * @param[in]  p      A pointer address to read the 32-bit value from.
161  *
162  * @return The 32-bit value at the specified pointer address.
163  */
164 static inline uint32_t nlIOGetUnaligned32(const void *p)
165 {
166     uint32_t temp;
167
168     __nlIO_MEMCPY(&temp, p, sizeof(uint32_t));
169
170     return temp;
171 }
172
173 /**
174  * Perform an unaligned memory read of the 64-bit value at the specified
175  * pointer address.
176  *
177  * @param[in]  p      A pointer address to read the 64-bit value from.
178  *
179  * @return The 64-bit value at the specified pointer address.
180  */
181 static inline uint64_t nlIOGetUnaligned64(const void *p)
182 {
183     uint64_t temp;
184
185     __nlIO_MEMCPY(&temp, p, sizeof(uint64_t));
186
187     return temp;
188 }
189
190 /**
191  * Perform a, potentially unaligned, memory read of the 8-bit value
192  * from the specified pointer address.
193  *
194  * @param[in]  p      A pointer address, potentially unaligned, to read
195  *                    the 8-bit value from.
196  *
197  * @return The 8-bit value at the specified pointer address.
198  */
199 static inline uint8_t  nlIOGetMaybeAligned8(const void *p)
200 {
201     return nlIOGetAligned8(p);
202 }
203
204 /**
205  * Perform a, potentially unaligned, memory read of the 16-bit value
206  * from the specified pointer address.
207  *
208  * @param[in]  p      A pointer address, potentially unaligned, to read
209  *                    the 16-bit value from.
210  *
211  * @return The 16-bit value at the specified pointer address.
212  */
213 static inline uint16_t nlIOGetMaybeAligned16(const void *p)
214 {
215     if (nlIOIsAligned(p, sizeof (uint16_t)))
216         return nlIOGetAligned16(p);
217     else
218         return nlIOGetUnaligned16(p);
219 }
220
221 /**
222  * Perform a, potentially unaligned, memory read of the 32-bit value
223  * from the specified pointer address.
224  *
225  * @param[in]  p      A pointer address, potentially unaligned, to read
226  *                    the 32-bit value from.
227  *
228  * @return The 32-bit value at the specified pointer address.
229  */
230 static inline uint32_t nlIOGetMaybeAligned32(const void *p)
231 {
232     if (nlIOIsAligned(p, sizeof (uint32_t)))
233         return nlIOGetAligned32(p);
234     else
235         return nlIOGetUnaligned32(p);
236 }
237
238 /**
239  * Perform a, potentially unaligned, memory read of the 64-bit value
240  * from the specified pointer address.
241  *
242  * @param[in]  p      A pointer address, potentially unaligned, to read
243  *                    the 64-bit value from.
244  *
245  * @return The 64-bit value at the specified pointer address.
246  */
247 static inline uint64_t nlIOGetMaybeAligned64(const void *p)
248 {
249     if (nlIOIsAligned(p, sizeof (uint64_t)))
250         return nlIOGetAligned64(p);
251     else
252         return nlIOGetUnaligned64(p);
253 }
254
255 /**
256  * Perform an aligned memory write of the 8-bit value to the specified
257  * pointer address.
258  *
259  * @param[in]  p      A pointer address to write the 8-bit value to.
260  *
261  * @param[in]  v      The 8-bit value to write.
262  *
263  */
264 static inline void     nlIOPutAligned8(void *p, const uint8_t v)
265 {
266     *(uint8_t *)(p) = v;
267 }
268
269 /**
270  * Perform an aligned memory write of the 16-bit value to the specified
271  * pointer address.
272  *
273  * @param[in]  p      A pointer address to write the 16-bit value to.
274  *
275  * @param[in]  v      The 16-bit value to write.
276  *
277  */
278 static inline void     nlIOPutAligned16(void *p, const uint16_t v)
279 {
280     *(uint16_t *)(p) = v;
281 }
282
283 /**
284  * Perform an aligned memory write of the 32-bit value to the specified
285  * pointer address.
286  *
287  * @param[in]  p      A pointer address to write the 32-bit value to.
288  *
289  * @param[in]  v      The 32-bit value to write.
290  *
291  */
292 static inline void     nlIOPutAligned32(void *p, const uint32_t v)
293 {
294     *(uint32_t *)(p) = v;
295 }
296
297 /**
298  * Perform an aligned memory write of the 64-bit value to the specified
299  * pointer address.
300  *
301  * @param[in]  p      A pointer address to write the 64-bit value to.
302  *
303  * @param[in]  v      The 64-bit value to write.
304  *
305  */
306 static inline void     nlIOPutAligned64(void *p, const uint64_t v)
307 {
308     *(uint64_t *)(p) = v;
309 }
310
311 /**
312  * Perform an unaligned memory write of the 8-bit value to the specified
313  * pointer address.
314  *
315  * @param[in]  p      A pointer address to write the 8-bit value to.
316  *
317  * @param[in]  v      The 8-bit value to write.
318  *
319  */
320 static inline void     nlIOPutUnaligned8(void *p, const uint8_t v)
321 {
322     nlIOPutAligned8(p, v);
323 }
324
325 /**
326  * Perform an unaligned memory write of the 16-bit value to the specified
327  * pointer address.
328  *
329  * @param[in]  p      A pointer address to write the 16-bit value to.
330  *
331  * @param[in]  v      The 16-bit value to write.
332  *
333  */
334 static inline void     nlIOPutUnaligned16(void *p, const uint16_t v)
335 {
336     __nlIO_MEMCPY(p, &v, sizeof(uint16_t));
337 }
338
339 /**
340  * Perform an unaligned memory write of the 32-bit value to the specified
341  * pointer address.
342  *
343  * @param[in]  p      A pointer address to write the 32-bit value to.
344  *
345  * @param[in]  v      The 32-bit value to write.
346  *
347  */
348 static inline void     nlIOPutUnaligned32(void *p, const uint32_t v)
349 {
350     __nlIO_MEMCPY(p, &v, sizeof(uint32_t));
351 }
352
353 /**
354  * Perform an unaligned memory write of the 64-bit value to the specified
355  * pointer address.
356  *
357  * @param[in]  p      A pointer address to write the 64-bit value to.
358  *
359  * @param[in]  v      The 64-bit value to write.
360  *
361  */
362 static inline void     nlIOPutUnaligned64(void *p, const uint64_t v)
363 {
364     __nlIO_MEMCPY(p, &v, sizeof(uint64_t));
365 }
366
367 /**
368  * Perform a, potentially unaligned, memory write of the 8-bit value
369  * to the specified pointer address.
370  *
371  * @param[in]  p      A pointer address, potentially unaligned, to write
372  *                    the 8-bit value to.
373  *
374  * @param[in]  v      The 8-bit value to write.
375  *
376  */
377 static inline void     nlIOPutMaybeAligned8(void *p, const uint8_t v)
378 {
379     nlIOPutAligned8(p, v);
380 }
381
382 /**
383  * Perform a, potentially unaligned, memory write of the 16-bit value
384  * to the specified pointer address.
385  *
386  * @param[in]  p      A pointer address, potentially unaligned, to write
387  *                    the 16-bit value to.
388  *
389  * @param[in]  v      The 16-bit value to write.
390  *
391  */
392 static inline void     nlIOPutMaybeAligned16(void *p, const uint16_t v)
393 {
394     if (nlIOIsAligned(p, sizeof (uint16_t)))
395         nlIOPutAligned16(p, v);
396     else
397         nlIOPutUnaligned16(p, v);
398 }
399
400 /**
401  * Perform a, potentially unaligned, memory write of the 32-bit value
402  * to the specified pointer address.
403  *
404  * @param[in]  p      A pointer address, potentially unaligned, to write
405  *                    the 32-bit value to.
406  *
407  * @param[in]  v      The 32-bit value to write.
408  *
409  */
410 static inline void     nlIOPutMaybeAligned32(void *p, const uint32_t v)
411 {
412     if (nlIOIsAligned(p, sizeof (uint32_t)))
413         nlIOPutAligned32(p, v);
414     else
415         nlIOPutUnaligned32(p, v);
416 }
417
418 /**
419  * Perform a, potentially unaligned, memory write of the 64-bit value
420  * to the specified pointer address.
421  *
422  * @param[in]  p      A pointer address, potentially unaligned, to write
423  *                    the 64-bit value to.
424  *
425  * @param[in]  v      The 64-bit value to write.
426  *
427  */
428 static inline void     nlIOPutMaybeAligned64(void *p, const uint64_t v)
429 {
430     if (nlIOIsAligned(p, sizeof (uint64_t)))
431         nlIOPutAligned64(p, v);
432     else
433         nlIOPutUnaligned64(p, v);
434 }
435
436 /**
437  * Perform an aligned memory read of the 8-bit value at the specified
438  * pointer address and increment the pointer by 8-bits (1 byte).
439  *
440  * @param[inout]  p   A pointer to a pointer address to read the
441  *                    8-bit value from and to then increment by
442  *                    8-bits (1 byte).
443  *
444  * @return The 8-bit value at the specified pointer address.
445  */
446 static inline uint8_t  nlIOReadAligned8(const void **p)
447 {
448     const uint8_t temp = nlIOGetAligned8(*p);
449
450     *(const uint8_t **)(p) += sizeof (uint8_t);
451
452     return temp;
453 }
454
455 /**
456  * Perform an aligned memory read of the 16-bit value at the specified
457  * pointer address and increment the pointer by 16-bits (2 bytes).
458  *
459  * @param[inout]  p   A pointer to a pointer address to read the
460  *                    16-bit value from and to then increment by
461  *                    16-bits (2 bytes).
462  *
463  * @return The 16-bit value at the specified pointer address.
464  */
465 static inline uint16_t nlIOReadAligned16(const void **p)
466 {
467     const uint16_t temp = nlIOGetAligned16(*p);
468
469     *(const uint8_t **)(p) += sizeof (uint16_t);
470
471     return temp;
472 }
473
474 /**
475  * Perform an aligned memory read of the 32-bit value at the specified
476  * pointer address and increment the pointer by 32-bits (4 bytes).
477  *
478  * @param[inout]  p   A pointer to a pointer address to read the
479  *                    32-bit value from and to then increment by
480  *                    32-bits (4 bytes).
481  *
482  * @return The 32-bit value at the specified pointer address.
483  */
484 static inline uint32_t nlIOReadAligned32(const void **p)
485 {
486     const uint32_t temp = nlIOGetAligned32(*p);
487
488     *(const uint8_t **)(p) += sizeof (uint32_t);
489
490     return temp;
491 }
492
493 /**
494  * Perform an aligned memory read of the 64-bit value at the specified
495  * pointer address and increment the pointer by 64-bits (8 bytes).
496  *
497  * @param[inout]  p   A pointer to a pointer address to read the
498  *                    64-bit value from and to then increment by
499  *                    64-bits (8 bytes).
500  *
501  * @return The 64-bit value at the specified pointer address.
502  */
503 static inline uint64_t nlIOReadAligned64(const void **p)
504 {
505     const uint64_t temp = nlIOGetAligned64(*p);
506
507     *(const uint8_t **)(p) += sizeof (uint64_t);
508
509     return temp;
510 }
511
512 /**
513  * Perform an unaligned memory read of the 8-bit value at the specified
514  * pointer address and increment the pointer by 8-bits (1 byte).
515  *
516  * @param[inout]  p   A pointer to a pointer address to read the
517  *                    8-bit value from and to then increment by
518  *                    8-bits (1 byte).
519  *
520  * @return The 8-bit value at the specified pointer address.
521  */
522 static inline uint8_t nlIOReadUnaligned8(const void **p)
523 {
524     const uint8_t temp = nlIOGetUnaligned8(*p);
525
526     *(const uint8_t **)(p) += sizeof (uint8_t);
527
528     return temp;
529 }
530
531 /**
532  * Perform an unaligned memory read of the 16-bit value at the specified
533  * pointer address and increment the pointer by 16-bits (2 bytes).
534  *
535  * @param[inout]  p   A pointer to a pointer address to read the
536  *                    16-bit value from and to then increment by
537  *                    16-bits (2 bytes).
538  *
539  * @return The 16-bit value at the specified pointer address.
540  */
541 static inline uint16_t nlIOReadUnaligned16(const void **p)
542 {
543     const uint16_t temp = nlIOGetUnaligned16(*p);
544
545     *(const uint8_t **)(p) += sizeof (uint16_t);
546
547     return temp;
548 }
549
550 /**
551  * Perform an aligned memory read of the 32-bit value at the specified
552  * pointer address and increment the pointer by 32-bits (4 bytes).
553  *
554  * @param[inout]  p   A pointer to a pointer address to read the
555  *                    32-bit value from and to then increment by
556  *                    32-bits (4 bytes).
557  *
558  * @return The 32-bit value at the specified pointer address.
559  */
560 static inline uint32_t nlIOReadUnaligned32(const void **p)
561 {
562     const uint32_t temp = nlIOGetUnaligned32(*p);
563
564     *(const uint8_t **)(p) += sizeof (uint32_t);
565
566     return temp;
567 }
568
569 /**
570  * Perform an unaligned memory read of the 64-bit value at the specified
571  * pointer address and increment the pointer by 64-bits (8 bytes).
572  *
573  * @param[inout]  p   A pointer to a pointer address to read the
574  *                    64-bit value from and to then increment by
575  *                    64-bits (8 bytes).
576  *
577  * @return The 64-bit value at the specified pointer address.
578  */
579 static inline uint64_t nlIOReadUnaligned64(const void **p)
580 {
581     const uint64_t temp = nlIOGetUnaligned64(*p);
582
583     *(const uint8_t **)(p) += sizeof (uint64_t);
584
585     return temp;
586 }
587
588 /**
589  * Perform a, potentially unaligned, memory read of the 8-bit value
590  * from the specified pointer address and increment the pointer by
591  * 8-bits (1 bytes).
592  *
593  * @param[inout]  p   A pointer to a pointer address, potentially
594  *                    unaligned, to read the 8-bit value from and to
595  *                    then increment by 8-bits (1 byte).
596  *
597  * @return The 8-bit value at the specified pointer address.
598  */
599 static inline uint8_t  nlIOReadMaybeAligned8(const void **p)
600 {
601     const uint8_t temp = nlIOGetMaybeAligned8(*p);
602
603     *(const uint8_t **)(p) += sizeof (uint8_t);
604
605     return temp;
606 }
607
608 /**
609  * Perform a, potentially unaligned, memory read of the 16-bit value
610  * from the specified pointer address and increment the pointer by
611  * 16-bits (2 bytes).
612  *
613  * @param[inout]  p   A pointer to a pointer address, potentially
614  *                    unaligned, to read the 16-bit value from and to
615  *                    then increment by 16-bits (2 bytes).
616  *
617  * @return The 16-bit value at the specified pointer address.
618  */
619 static inline uint16_t nlIOReadMaybeAligned16(const void **p)
620 {
621     const uint16_t temp = nlIOGetMaybeAligned16(*p);
622
623     *(const uint8_t **)(p) += sizeof (uint16_t);
624
625     return temp;
626 }
627
628 /**
629  * Perform a, potentially unaligned, memory read of the 32-bit value
630  * from the specified pointer address and increment the pointer by
631  * 32-bits (4 bytes).
632  *
633  * @param[inout]  p   A pointer to a pointer address, potentially
634  *                    unaligned, to read the 32-bit value from and to
635  *                    then increment by 32-bits (4 bytes).
636  *
637  * @return The 32-bit value at the specified pointer address.
638  */
639 static inline uint32_t nlIOReadMaybeAligned32(const void **p)
640 {
641     const uint32_t temp = nlIOGetMaybeAligned32(*p);
642
643     *(const uint8_t **)(p) += sizeof (uint32_t);
644
645     return temp;
646 }
647
648 /**
649  * Perform a, potentially unaligned, memory read of the 64-bit value
650  * from the specified pointer address and increment the pointer by
651  * 64-bits (8 bytes).
652  *
653  * @param[inout]  p   A pointer to a pointer address, potentially
654  *                    unaligned, to read the 64-bit value from and to
655  *                    then increment by 64-bits (8 bytes).
656  *
657  * @return The 64-bit value at the specified pointer address.
658  */
659 static inline uint64_t nlIOReadMaybeAligned64(const void **p)
660 {
661     const uint64_t temp = nlIOGetMaybeAligned64(*p);
662
663     *(const uint8_t **)(p) += sizeof (uint64_t);
664
665     return temp;
666 }
667
668 /**
669  * Perform an aligned memory write of the 8-bit value to the specified
670  * pointer address and increment the pointer by 8-bits (1 byte).
671  *
672  * @param[inout]  p   A pointer to a pointer address to read the 8-bit
673  *                    value from and to then increment by 8-bits (1 byte).
674  *
675  * @param[in]     v   The 8-bit value to write.
676  *
677  */
678 static inline void     nlIOWriteAligned8(void **p, const uint8_t v)
679 {
680     nlIOPutAligned8(*p, v);       *(const uint8_t **)(p) += sizeof (uint8_t);
681 }
682
683 /**
684  * Perform an aligned memory write of the 16-bit value to the specified
685  * pointer address and increment the pointer by 16-bits (2 bytes).
686  *
687  * @param[inout]  p   A pointer to a pointer address to read the 16-bit
688  *                    value from and to then increment by 16-bits (2 bytes).
689  *
690  * @param[in]     v   The 16-bit value to write.
691  *
692  */
693 static inline void     nlIOWriteAligned16(void **p, const uint16_t v)
694 {
695     nlIOPutAligned16(*p, v);      *(const uint8_t **)(p) += sizeof (uint16_t);
696 }
697
698 /**
699  * Perform an aligned memory write of the 32-bit value to the specified
700  * pointer address and increment the pointer by 32-bits (4 bytes).
701  *
702  * @param[inout]  p   A pointer to a pointer address to read the 32-bit
703  *                    value from and to then increment by 32-bits (4 bytes).
704  *
705  * @param[in]     v   The 32-bit value to write.
706  *
707  */
708 static inline void     nlIOWriteAligned32(void **p, const uint32_t v)
709 {
710     nlIOPutAligned32(*p, v);      *(const uint8_t **)(p) += sizeof (uint32_t);
711 }
712
713 /**
714  * Perform an aligned memory write of the 64-bit value to the specified
715  * pointer address and increment the pointer by 64-bits (8 bytes).
716  *
717  * @param[inout]  p   A pointer to a pointer address to read the 64-bit
718  *                    value from and to then increment by 64-bits (8 bytes).
719  *
720  * @param[in]     v   The 64-bit value to write.
721  *
722  */
723 static inline void     nlIOWriteAligned64(void **p, const uint64_t v)
724 {
725     nlIOPutAligned64(*p, v);      *(const uint8_t **)(p) += sizeof (uint64_t);
726 }
727
728 /**
729  * Perform an unaligned memory write of the 8-bit value to the specified
730  * pointer address and increment the pointer by 8-bits (1 byte).
731  *
732  * @param[inout]  p   A pointer to a pointer address to read the 8-bit
733  *                    value from and to then increment by 8-bits (1 byte).
734  *
735  * @param[in]     v   The 8-bit value to write.
736  *
737  */
738 static inline void     nlIOWriteUnaligned8(void **p, const uint8_t v)
739 {
740     nlIOPutUnaligned8(*p, v);     *(const uint8_t **)(p) += sizeof (uint8_t);
741 }
742
743 /**
744  * Perform an unaligned memory write of the 16-bit value to the specified
745  * pointer address and increment the pointer by 16-bits (2 bytes).
746  *
747  * @param[inout]  p   A pointer to a pointer address to read the 16-bit
748  *                    value from and to then increment by 16-bits (2 bytes).
749  *
750  * @param[in]     v   The 16-bit value to write.
751  *
752  */
753 static inline void     nlIOWriteUnaligned16(void **p, const uint16_t v)
754 {
755     nlIOPutUnaligned16(*p, v);    *(const uint8_t **)(p) += sizeof (uint16_t);
756 }
757
758 /**
759  * Perform an unaligned memory write of the 32-bit value to the specified
760  * pointer address and increment the pointer by 32-bits (4 bytes).
761  *
762  * @param[inout]  p   A pointer to a pointer address to read the 32-bit
763  *                    value from and to then increment by 32-bits (4 bytes).
764  *
765  * @param[in]     v   The 32-bit value to write.
766  *
767  */
768 static inline void     nlIOWriteUnaligned32(void **p, const uint32_t v)
769 {
770     nlIOPutUnaligned32(*p, v);    *(const uint8_t **)(p) += sizeof (uint32_t);
771 }
772
773 /**
774  * Perform an unaligned memory write of the 64-bit value to the specified
775  * pointer address and increment the pointer by 64-bits (8 bytes).
776  *
777  * @param[inout]  p   A pointer to a pointer address to read the 64-bit
778  *                    value from and to then increment by 64-bits (8 bytes).
779  *
780  * @param[in]     v   The 64-bit value to write.
781  *
782  */
783 static inline void     nlIOWriteUnaligned64(void **p, const uint64_t v)
784 {
785     nlIOPutUnaligned64(*p, v);    *(const uint8_t **)(p) += sizeof (uint64_t);
786 }
787
788 /**
789  * Perform a, potentially unaligned, memory write of the 8-bit value
790  * to the specified pointer address and increment the pointer by
791  * 8-bits (2 byte).
792  *
793  * @param[inout]  p   A pointer to a pointer address, potentially
794  *                    unaligned, to read the 8-bit value from and to
795  *                    then increment by 8-bits (1 byte).
796  *
797  * @param[in]     v   The 8-bit value to write.
798  *
799  */
800 static inline void     nlIOWriteMaybeAligned8(void **p, const uint8_t v)
801 {
802     nlIOPutMaybeAligned8(*p, v);  *(const uint8_t **)(p) += sizeof (uint8_t);
803 }
804
805 /**
806  * Perform a, potentially unaligned, memory write of the 16-bit value
807  * to the specified pointer address and increment the pointer by
808  * 16-bits (2 bytes).
809  *
810  * @param[inout]  p   A pointer to a pointer address, potentially
811  *                    unaligned, to read the 16-bit value from and to
812  *                    then increment by 16-bits (2 bytes).
813  *
814  * @param[in]     v   The 16-bit value to write.
815  *
816  */
817 static inline void     nlIOWriteMaybeAligned16(void **p, const uint16_t v)
818 {
819     nlIOPutMaybeAligned16(*p, v); *(const uint8_t **)(p) += sizeof (uint16_t);
820 }
821
822 /**
823  * Perform a, potentially unaligned, memory write of the 32-bit value
824  * to the specified pointer address and increment the pointer by
825  * 32-bits (4 bytes).
826  *
827  * @param[inout]  p   A pointer to a pointer address, potentially
828  *                    unaligned, to read the 32-bit value from and to
829  *                    then increment by 32-bits (4 bytes).
830  *
831  * @param[in]     v   The 32-bit value to write.
832  *
833  */
834 static inline void     nlIOWriteMaybeAligned32(void **p, const uint32_t v)
835 {
836     nlIOPutMaybeAligned32(*p, v); *(const uint8_t **)(p) += sizeof (uint32_t);
837 }
838
839 /**
840  * Perform a, potentially unaligned, memory write of the 64-bit value
841  * to the specified pointer address and increment the pointer by
842  * 64-bits (8 bytes).
843  *
844  * @param[inout]  p   A pointer to a pointer address, potentially
845  *                    unaligned, to read the 64-bit value from and to
846  *                    then increment by 64-bits (8 bytes).
847  *
848  * @param[in]     v   The 64-bit value to write.
849  *
850  */
851 static inline void     nlIOWriteMaybeAligned64(void **p, const uint64_t v)
852 {
853     nlIOPutMaybeAligned64(*p, v); *(const uint8_t **)(p) += sizeof (uint64_t);
854 }
855
856 /**
857  * Perform a memory read of the 8-bit value at the specified pointer
858  * address.
859  *
860  * @param[in]  p      A pointer address to read the 8-bit value from.
861  *
862  * @return The 8-bit value at the specified pointer address.
863  */
864 static inline uint8_t nlIOGet8(const void *p)
865 {
866     return nlIOGetAligned8(p);
867 }
868
869 /**
870  * Perform a, potentially unaligned, memory read of the 16-bit value
871  * from the specified pointer address.
872  *
873  * @param[in]  p      A pointer address, potentially unaligned, to read
874  *                    the 16-bit value from.
875  *
876  * @return The 16-bit value at the specified pointer address.
877  */
878 static inline uint16_t nlIOGet16(const void *p)
879 {
880     return nlIOGetMaybeAligned16(p);
881 }
882
883 /**
884  * Perform a, potentially unaligned, memory read of the 32-bit value
885  * from the specified pointer address.
886  *
887  * @param[in]  p      A pointer address, potentially unaligned, to read
888  *                    the 32-bit value from.
889  *
890  * @return The 32-bit value at the specified pointer address.
891  */
892 static inline uint32_t nlIOGet32(const void *p)
893 {
894     return nlIOGetMaybeAligned32(p);
895 }
896
897 /**
898  * Perform a, potentially unaligned, memory read of the 64-bit value
899  * from the specified pointer address.
900  *
901  * @param[in]  p      A pointer address, potentially unaligned, to read
902  *                    the 64-bit value from.
903  *
904  * @return The 64-bit value at the specified pointer address.
905  */
906 static inline uint64_t nlIOGet64(const void *p)
907 {
908     return nlIOGetMaybeAligned64(p);
909 }
910
911 /**
912  * Perform a memory write of the 8-bit value to the specified pointer
913  * address.
914  *
915  * @param[in]  p      A pointer address to write the 8-bit value to.
916  *
917  * @param[in]  v      The 8-bit value to write.
918  *
919  */
920 static inline void nlIOPut8(void *p, uint8_t v)
921 {
922     nlIOPutAligned8(p, v);
923 }
924
925 /**
926  * Perform a, potentially unaligned, memory write of the 16-bit value
927  * to the specified pointer address.
928  *
929  * @param[in]  p      A pointer address, potentially unaligned, to write
930  *                    the 16-bit value to.
931  *
932  * @param[in]  v      The 16-bit value to write.
933  *
934  */
935 static inline void nlIOPut16(void *p, uint16_t v)
936 {
937     nlIOPutMaybeAligned16(p, v);
938 }
939
940 /**
941  * Perform a, potentially unaligned, memory write of the 32-bit value
942  * to the specified pointer address.
943  *
944  * @param[in]  p      A pointer address, potentially unaligned, to write
945  *                    the 32-bit value to.
946  *
947  * @param[in]  v      The 32-bit value to write.
948  *
949  */
950 static inline void nlIOPut32(void *p, uint32_t v)
951 {
952     nlIOPutMaybeAligned32(p, v);
953 }
954
955 /**
956  * Perform a, potentially unaligned, memory write of the 64-bit value
957  * to the specified pointer address.
958  *
959  * @param[in]  p      A pointer address, potentially unaligned, to write
960  *                    the 64-bit value to.
961  *
962  * @param[in]  v      The 64-bit value to write.
963  *
964  */
965 static inline void nlIOPut64(void *p, uint64_t v)
966 {
967     nlIOPutMaybeAligned64(p, v);
968 }
969
970 /**
971  * Perform a, potentially unaligned, memory read of the 16-bit value
972  * from the specified pointer address and increment the pointer by
973  * 8-bits (1 byte).
974  *
975  * @param[inout]  p   A pointer to a pointer address, potentially
976  *                    unaligned, to read the 8-bit value from and to
977  *                    then increment by 8-bits (1 byte).
978  *
979  * @return The 8-bit value at the specified pointer address.
980  */
981 static inline uint8_t  nlIORead8(const void **p)
982 {
983     return nlIOReadAligned8(p);
984 }
985
986 /**
987  * Perform a, potentially unaligned, memory read of the 16-bit value
988  * from the specified pointer address and increment the pointer by
989  * 16-bits (2 bytes).
990  *
991  * @param[inout]  p   A pointer to a pointer address, potentially
992  *                    unaligned, to read the 16-bit value from and to
993  *                    then increment by 16-bits (2 bytes).
994  *
995  * @return The 16-bit value at the specified pointer address.
996  */
997 static inline uint16_t nlIORead16(const void **p)
998 {
999     return nlIOReadMaybeAligned16(p);
1000 }
1001
1002 /**
1003  * Perform a, potentially unaligned, memory read of the 32-bit value
1004  * from the specified pointer address and increment the pointer by
1005  * 32-bits (4 bytes).
1006  *
1007  * @param[inout]  p   A pointer to a pointer address, potentially
1008  *                    unaligned, to read the 32-bit value from and to
1009  *                    then increment by 32-bits (4 bytes).
1010  *
1011  * @return The 32-bit value at the specified pointer address.
1012  */
1013 static inline uint32_t nlIORead32(const void **p)
1014 {
1015     return nlIOReadMaybeAligned32(p);
1016 }
1017
1018 /**
1019  * Perform a, potentially unaligned, memory read of the 64-bit value
1020  * from the specified pointer address and increment the pointer by
1021  * 64-bits (8 bytes).
1022  *
1023  * @param[inout]  p   A pointer to a pointer address, potentially
1024  *                    unaligned, to read the 64-bit value from and to
1025  *                    then increment by 64-bits (8 bytes).
1026  *
1027  * @return The 64-bit value at the specified pointer address.
1028  */
1029 static inline uint64_t nlIORead64(const void **p)
1030 {
1031     return nlIOReadMaybeAligned64(p);
1032 }
1033
1034 /**
1035  * Perform a, potentially unaligned, memory write of the 8-bit value
1036  * to the specified pointer address and increment the pointer by
1037  * 8-bits (1 byte).
1038  *
1039  * @param[inout]  p   A pointer to a pointer address, potentially
1040  *                    unaligned, to read the 8-bit value from and to
1041  *                    then increment by 8-bits (1 byte).
1042  *
1043  * @param[in]     v   The 8-bit value to write.
1044  *
1045  */
1046 static inline void nlIOWrite8(void **p, uint8_t v)
1047 {
1048     nlIOWriteAligned8(p, v);
1049 }
1050
1051 /**
1052  * Perform a, potentially unaligned, memory write of the 16-bit value
1053  * to the specified pointer address and increment the pointer by
1054  * 16-bits (2 bytes).
1055  *
1056  * @param[inout]  p   A pointer to a pointer address, potentially
1057  *                    unaligned, to read the 16-bit value from and to
1058  *                    then increment by 16-bits (2 bytes).
1059  *
1060  * @param[in]     v   The 16-bit value to write.
1061  *
1062  */
1063 static inline void nlIOWrite16(void **p, uint16_t v)
1064 {
1065     nlIOWriteMaybeAligned16(p, v);
1066 }
1067
1068 /**
1069  * Perform a, potentially unaligned, memory write of the 32-bit value
1070  * to the specified pointer address and increment the pointer by
1071  * 32-bits (4 bytes).
1072  *
1073  * @param[inout]  p   A pointer to a pointer address, potentially
1074  *                    unaligned, to read the 32-bit value from and to
1075  *                    then increment by 32-bits (4 bytes).
1076  *
1077  * @param[in]     v   The 32-bit value to write.
1078  *
1079  */
1080 static inline void nlIOWrite32(void **p, uint32_t v)
1081 {
1082     nlIOWriteMaybeAligned32(p, v);
1083 }
1084
1085 /**
1086  * Perform a, potentially unaligned, memory write of the 64-bit value
1087  * to the specified pointer address and increment the pointer by
1088  * 64-bits (8 bytes).
1089  *
1090  * @param[inout]  p   A pointer to a pointer address, potentially
1091  *                    unaligned, to read the 64-bit value from and to
1092  *                    then increment by 64-bits (8 bytes).
1093  *
1094  * @param[in]     v   The 64-bit value to write.
1095  *
1096  */
1097 static inline void nlIOWrite64(void **p, uint64_t v)
1098 {
1099     nlIOWriteMaybeAligned64(p, v);
1100 }
1101
1102 #ifdef __cplusplus
1103 }
1104 #endif
1105
1106 #undef __nlIO_MEMCPY
1107
1108 #endif /* NLIO_BASE_H */