Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / core / CHIPEncoding.h
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2013-2017 Nest Labs, Inc.
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 /**
20  *    @file
21  *      This file provides functions for:
22  *
23  *      <ul>
24  *         <li>Performing byte reordering by value for 16-, 32-, and 64-bit
25  *         types.</li>
26  *         <li>Safely performing simple, efficient memory-mapped
27  *         accesses, potentially to unaligned memory locations, with or
28  *         without byte reordering, to 8-, 16-, 32-, and 64-bit
29  *         quantities, both with and without pointer management.</li>
30  *      </ul>
31  *
32  */
33
34 #pragma once
35
36 #include <nlbyteorder.hpp>
37 #include <nlio-byteorder.hpp>
38 #include <nlio.hpp>
39
40 #include <stdint.h>
41
42 namespace chip {
43
44 /**
45  *  @namespace chip::Encoding
46  *
47  *  This namespace provides functions for:
48  *
49  *  <ul>
50  *     <li>Performing byte reordering by value for 16-, 32-, and 64-bit
51  *     types.</li>
52  *     <li>Safely performing simple, efficient memory-mapped
53  *     accesses, potentially to unaligned memory locations, with or
54  *     without byte reordering, to 8-, 16-, 32-, and 64-bit
55  *     quantities, both with and without pointer management.</li>
56  *  </ul>
57  *
58  */
59 namespace Encoding {
60
61 /**
62  * This unconditionally performs a byte order swap by value of the
63  * specified 16-bit value.
64  *
65  * @param[in]  v  The 16-bit value to be byte order swapped.
66  *
67  * @return The input value, byte order swapped.
68  */
69 inline uint16_t Swap16(uint16_t v)
70 {
71     return nl::ByteOrder::Swap16(v);
72 }
73
74 /**
75  * This unconditionally performs a byte order swap by value of the
76  * specified 32-bit value.
77  *
78  * @param[in]  v  The 32-bit value to be byte order swapped.
79  *
80  * @return The input value, byte order swapped.
81  */
82 inline uint32_t Swap32(uint32_t v)
83 {
84     return nl::ByteOrder::Swap32(v);
85 }
86
87 /**
88  * This unconditionally performs a byte order swap by value of the
89  * specified 64-bit value.
90  *
91  * @param[in]  v  The 64-bit value to be byte order swapped.
92  *
93  * @return The input value, byte order swapped.
94  */
95 inline uint64_t Swap64(uint64_t v)
96 {
97     return nl::ByteOrder::Swap64(v);
98 }
99
100 /**
101  * Perform a, potentially unaligned, memory read of the 8-bit value
102  * from the specified pointer address.
103  *
104  * @param[in]  p      A pointer address, potentially unaligned, to read
105  *                    the 8-bit value from.
106  *
107  * @return The 8-bit value at the specified pointer address.
108  */
109 inline uint8_t Get8(const uint8_t * p)
110 {
111     return nl::IO::Get8(p);
112 }
113
114 /**
115  * Perform a, potentially unaligned, memory write of the target system
116  * byte ordered 8-bit value to the specified pointer address.
117  *
118  * @param[in]  p      A pointer address, potentially unaligned, to write
119  *                    the 8-bit value to.
120  *
121  * @param[in]  v      The 8-bit value to write.
122  *
123  */
124 inline void Put8(uint8_t * p, uint8_t v)
125 {
126     nl::IO::Put8(p, v);
127 }
128
129 /**
130  * Perform a, potentially unaligned, memory read of the 8-bit value
131  * from the specified pointer address and increment the pointer by
132  * 8-bits (1 byte).
133  *
134  * @param[in,out] p   A reference to a constant pointer address,
135  *                    potentially unaligned, to read the 8-bit value
136  *                    from and to then increment by 8-bits (1 byte).
137  *
138  * @return The 8-bit value at the specified pointer address.
139  */
140 inline uint8_t Read8(const uint8_t *& p)
141 {
142     return nl::IO::Read8(reinterpret_cast<const void *&>(p));
143 }
144
145 /**
146  * Perform a, potentially unaligned, memory read of the 8-bit value
147  * from the specified pointer address and increment the pointer by
148  * 8-bits (1 byte).
149  *
150  * @param[in,out] p   A reference to a pointer address, potentially
151  *                    unaligned, to read the 8-bit value from and to
152  *                    then increment by 8-bits (1 byte).
153  *
154  * @return The 8-bit value at the specified pointer address.
155  */
156 inline uint8_t Read8(uint8_t *& p)
157 {
158     return Read8(const_cast<const uint8_t *&>(p));
159 }
160
161 /**
162  * Perform a, potentially unaligned, memory write of the 8-bit value
163  * to the specified pointer address and increment the pointer by
164  * 8-bits (1 byte).
165  *
166  * @param[in,out] p   A reference to a pointer address, potentially
167  *                    unaligned, to read the 8-bit value from and to
168  *                    then increment by 8-bits (1 byte).
169  *
170  * @param[in]     v   The 8-bit value to write.
171  *
172  */
173 inline void Write8(uint8_t *& p, uint8_t v)
174 {
175     *p++ = v;
176 }
177
178 /**
179  *  @namespace chip::Encoding::LittleEndian
180  *
181  *  This namespace provides functions for:
182  *
183  *  <ul>
184  *     <li>Performing byte reordering, relative to the host system, by
185  *     value of little endian byte ordered values for 16-, 32-, and
186  *     64-bit types.</li>
187  *     <li>Safely performing simple, efficient memory-mapped accesses,
188  *     potentially to unaligned memory locations, with or without byte
189  *     reordering, to 8-, 16-, 32-, and 64-bit little endian byte
190  *     ordered quantities, both with and without pointer
191  *     management.</li>
192  *  </ul>
193  *
194  *  On little endian host systems no actual byte reordering will
195  *  occur. On other systems, byte reordering is peformed as
196  *  appropriate.
197  *
198  */
199 namespace LittleEndian {
200
201 /**
202  * This conditionally performs, as necessary for the target system, a
203  * byte order swap by value of the specified 16-bit value, presumed to
204  * be in little endian byte ordering to the target system (i.e. host)
205  * byte ordering.
206  *
207  * Consequently, on little endian target systems, this is a no-op and
208  * on big endian target systems, this performs a reordering.
209  *
210  * @param[in]  v  The 16-bit value to be byte order swapped.
211  *
212  * @return The input value, if necessary, byte order swapped.
213  */
214 inline uint16_t HostSwap16(uint16_t v)
215 {
216     return nl::ByteOrder::Swap16LittleToHost(v);
217 }
218
219 /**
220  * This conditionally performs, as necessary for the target system, a
221  * byte order swap by value of the specified 32-bit value, presumed to
222  * be in little endian byte ordering to the target system (i.e. host)
223  * byte ordering.
224  *
225  * Consequently, on little endian target systems, this is a no-op and
226  * on big endian target systems, this performs a reordering.
227  *
228  * @param[in]  v  The 32-bit value to be byte order swapped.
229  *
230  * @return The input value, if necessary, byte order swapped.
231  */
232 inline uint32_t HostSwap32(uint32_t v)
233 {
234     return nl::ByteOrder::Swap32LittleToHost(v);
235 }
236
237 /**
238  * This conditionally performs, as necessary for the target system, a
239  * byte order swap by value of the specified 64-bit value, presumed to
240  * be in little endian byte ordering to the target system (i.e. host)
241  * byte ordering.
242  *
243  * Consequently, on little endian target systems, this is a no-op and
244  * on big endian target systems, this performs a reordering.
245  *
246  * @param[in]  v  The 64-bit value to be byte order swapped.
247  *
248  * @return The input value, if necessary, byte order swapped.
249  */
250 inline uint64_t HostSwap64(uint64_t v)
251 {
252     return nl::ByteOrder::Swap64LittleToHost(v);
253 }
254
255 /**
256  * Perform a, potentially unaligned, memory read of the little endian
257  * byte ordered 16-bit value from the specified pointer address,
258  * perform byte reordering, as necessary, for the target system to
259  * put the value in target system byte ordering.
260  *
261  * @param[in]  p      A pointer address, potentially unaligned, to read
262  *                    the 16-bit little endian byte ordered value from.
263  *
264  * @return The 16-bit value at the specified pointer address, if
265  *         necessary, byte reordered.
266  */
267 inline uint16_t Get16(const uint8_t * p)
268 {
269     return nl::IO::LittleEndian::GetUnaligned16(p);
270 }
271
272 /**
273  * Perform a, potentially unaligned, memory read of the little endian
274  * byte ordered 32-bit value from the specified pointer address,
275  * perform byte reordering, as necessary, for the target system to
276  * put the value in target system byte ordering.
277  *
278  * @param[in]  p      A pointer address, potentially unaligned, to read
279  *                    the 32-bit little endian byte ordered value from.
280  *
281  * @return The 32-bit value at the specified pointer address, if
282  *         necessary, byte reordered.
283  */
284 inline uint32_t Get32(const uint8_t * p)
285 {
286     return nl::IO::LittleEndian::GetUnaligned32(p);
287 }
288
289 /**
290  * Perform a, potentially unaligned, memory read of the little endian
291  * byte ordered 64-bit value from the specified pointer address,
292  * perform byte reordering, as necessary, for the target system to
293  * put the value in target system byte ordering.
294  *
295  * @param[in]  p      A pointer address, potentially unaligned, to read
296  *                    the 64-bit little endian byte ordered value from.
297  *
298  * @return The 64-bit value at the specified pointer address, if
299  *         necessary, byte reordered.
300  */
301 inline uint64_t Get64(const uint8_t * p)
302 {
303     return nl::IO::LittleEndian::GetUnaligned64(p);
304 }
305
306 /**
307  * Perform a, potentially unaligned, memory write of the target system
308  * byte ordered 16-bit value to the specified pointer address,
309  * perform byte reordering, as necessary, for the target system to
310  * put the value in little endian byte ordering.
311  *
312  * @param[in]  p      A pointer address, potentially unaligned, to write
313  *                    the target system byte ordered 16-bit value to in little
314  *                    endian byte ordering.
315  *
316  * @param[in]  v      The 16-bit value to write, if necessary, byte reordered.
317  *
318  */
319 inline void Put16(uint8_t * p, uint16_t v)
320 {
321     nl::IO::LittleEndian::PutUnaligned16(p, v);
322 }
323
324 /**
325  * Perform a, potentially unaligned, memory write of the target system
326  * byte ordered 32-bit value to the specified pointer address,
327  * perform byte reordering, as necessary, for the target system to
328  * put the value in little endian byte ordering.
329  *
330  * @param[in]  p      A pointer address, potentially unaligned, to write
331  *                    the target system byte ordered 32-bit value to in little
332  *                    endian byte ordering.
333  *
334  * @param[in]  v      The 32-bit value to write, if necessary, byte reordered.
335  *
336  */
337 inline void Put32(uint8_t * p, uint32_t v)
338 {
339     nl::IO::LittleEndian::PutUnaligned32(p, v);
340 }
341
342 /**
343  * Perform a, potentially unaligned, memory write of the target system
344  * byte ordered 64-bit value to the specified pointer address,
345  * perform byte reordering, as necessary, for the target system to
346  * put the value in little endian byte ordering.
347  *
348  * @param[in]  p      A pointer address, potentially unaligned, to write
349  *                    the target system byte ordered 64-bit value to in little
350  *                    endian byte ordering.
351  *
352  * @param[in]  v      The 64-bit value to write, if necessary, byte reordered.
353  *
354  */
355 inline void Put64(uint8_t * p, uint64_t v)
356 {
357     nl::IO::LittleEndian::PutUnaligned64(p, v);
358 }
359
360 /**
361  * Perform a, potentially unaligned, memory read of the little endian
362  * byte ordered 16-bit value from the specified pointer address,
363  * perform byte reordering, as necessary, for the target system to put
364  * the value in target system byte ordering, and increment the pointer
365  * by 16-bits (2 bytes).
366  *
367  * @param[in,out] p   A reference to a constant pointer address, potentially
368  *                    unaligned, to read the 16-bit little endian byte
369  *                    ordered value from and to then increment by 16-
370  *                    bits (2 bytes).
371  *
372  * @return The 16-bit value at the specified pointer address, if necessary,
373  *         byte order swapped.
374  */
375 inline uint16_t Read16(const uint8_t *& p)
376 {
377     return nl::IO::LittleEndian::ReadUnaligned16(reinterpret_cast<const void *&>(p));
378 }
379
380 /**
381  * Perform a, potentially unaligned, memory read of the little endian
382  * byte ordered 16-bit value from the specified pointer address,
383  * perform byte reordering, as necessary, for the target system to put
384  * the value in target system byte ordering, and increment the pointer
385  * by 16-bits (2 bytes).
386  *
387  * @param[in,out] p   A reference to a pointer address, potentially
388  *                    unaligned, to read the 16-bit little endian byte
389  *                    ordered value from and to then increment by 16-
390  *                    bits (2 bytes).
391  *
392  * @return The 16-bit value at the specified pointer address, if necessary,
393  *         byte order swapped.
394  */
395 inline uint16_t Read16(uint8_t *& p)
396 {
397     return Read16(const_cast<const uint8_t *&>(p));
398 }
399
400 /**
401  * Perform a, potentially unaligned, memory read of the little endian
402  * byte ordered 32-bit value from the specified pointer address,
403  * perform byte reordering, as necessary, for the target system to put
404  * the value in target system byte ordering, and increment the pointer
405  * by 32-bits (4 bytes).
406  *
407  * @param[in,out] p   A reference to a constant pointer address, potentially
408  *                    unaligned, to read the 32-bit little endian byte
409  *                    ordered value from and to then increment by 32-
410  *                    bits (4 bytes).
411  *
412  * @return The 32-bit value at the specified pointer address, if necessary,
413  *         byte order swapped.
414  */
415 inline uint32_t Read32(const uint8_t *& p)
416 {
417     return nl::IO::LittleEndian::ReadUnaligned32(reinterpret_cast<const void *&>(p));
418 }
419
420 /**
421  * Perform a, potentially unaligned, memory read of the little endian
422  * byte ordered 32-bit value from the specified pointer address,
423  * perform byte reordering, as necessary, for the target system to put
424  * the value in target system byte ordering, and increment the pointer
425  * by 32-bits (4 bytes).
426  *
427  * @param[in,out] p   A reference to a pointer address, potentially
428  *                    unaligned, to read the 32-bit little endian byte
429  *                    ordered value from and to then increment by 32-
430  *                    bits (4 bytes).
431  *
432  * @return The 32-bit value at the specified pointer address, if necessary,
433  *         byte order swapped.
434  */
435 inline uint32_t Read32(uint8_t *& p)
436 {
437     return Read32(const_cast<const uint8_t *&>(p));
438 }
439
440 /**
441  * Perform a, potentially unaligned, memory read of the little endian
442  * byte ordered 64-bit value from the specified pointer address,
443  * perform byte reordering, as necessary, for the target system to put
444  * the value in target system byte ordering, and increment the pointer
445  * by 64-bits (8 bytes).
446  *
447  * @param[in,out] p   A reference to a constant pointer address, potentially
448  *                    unaligned, to read the 64-bit little endian byte
449  *                    ordered value from and to then increment by 64-
450  *                    bits (8 bytes).
451  *
452  * @return The 64-bit value at the specified pointer address, if necessary,
453  *         byte order swapped.
454  */
455 inline uint64_t Read64(const uint8_t *& p)
456 {
457     return nl::IO::LittleEndian::ReadUnaligned64(reinterpret_cast<const void *&>(p));
458 }
459
460 /**
461  * Perform a, potentially unaligned, memory read of the little endian
462  * byte ordered 64-bit value from the specified pointer address,
463  * perform byte reordering, as necessary, for the target system to put
464  * the value in target system byte ordering, and increment the pointer
465  * by 64-bits (8 bytes).
466  *
467  * @param[in,out] p   A reference to a pointer address, potentially
468  *                    unaligned, to read the 64-bit little endian byte
469  *                    ordered value from and to then increment by 64-
470  *                    bits (8 bytes).
471  *
472  * @return The 64-bit value at the specified pointer address, if necessary,
473  *         byte order swapped.
474  */
475 inline uint64_t Read64(uint8_t *& p)
476 {
477     return Read64(const_cast<const uint8_t *&>(p));
478 }
479
480 /**
481  * Perform a, potentially unaligned, memory write of the target system
482  * byte ordered 16-bit value to the specified pointer address,
483  * perform byte reordering, as necessary, for the target system to
484  * put the value in little endian byte ordering.
485  *
486  * @param[in]  p      A reference to a pointer address, potentially
487  *                    unaligned, to write the target system byte
488  *                    ordered 16-bit value to in little endian byte
489  *                    ordering and to then increment by 16-bits (2
490  *                    bytes).
491  *
492  * @param[in]  v      The 16-bit value to write, if necessary, byte order
493  *                    swapped.
494  *
495  */
496 inline void Write16(uint8_t *& p, uint16_t v)
497 {
498     Put16(p, v);
499     p += sizeof(uint16_t);
500 }
501
502 /**
503  * Perform a, potentially unaligned, memory write of the target system
504  * byte ordered 32-bit value to the specified pointer address,
505  * perform byte reordering, as necessary, for the target system to
506  * put the value in little endian byte ordering.
507  *
508  * @param[in]  p      A reference to a pointer address, potentially
509  *                    unaligned, to write the target system byte
510  *                    ordered 32-bit value to in little endian byte
511  *                    ordering and to then increment by 32-bits (4
512  *                    bytes).
513  *
514  * @param[in]  v      The 32-bit value to write, if necessary, byte order
515  *                    swapped.
516  *
517  */
518 inline void Write32(uint8_t *& p, uint32_t v)
519 {
520     Put32(p, v);
521     p += sizeof(uint32_t);
522 }
523
524 /**
525  * Perform a, potentially unaligned, memory write of the target system
526  * byte ordered 64-bit value to the specified pointer address,
527  * perform byte reordering, as necessary, for the target system to
528  * put the value in little endian byte ordering.
529  *
530  * @param[in]  p      A reference to a pointer address, potentially
531  *                    unaligned, to write the target system byte
532  *                    ordered 64-bit value to in little endian byte
533  *                    ordering and to then increment by 64-bits (8
534  *                    bytes).
535  *
536  * @param[in]  v      The 64-bit value to write, if necessary, byte order
537  *                    swapped.
538  *
539  */
540 inline void Write64(uint8_t *& p, uint64_t v)
541 {
542     Put64(p, v);
543     p += sizeof(uint64_t);
544 }
545
546 } // namespace LittleEndian
547
548 /**
549  *  @namespace chip::Encoding::BigEndian
550  *
551  *  This namespace provides functions for:
552  *
553  *  <ul>
554  *     <li>Performing byte reordering, relative to the host system, by
555  *     value of big endian byte ordered values for 16-, 32-, and
556  *     64-bit types.</li>
557  *     <li>Safely performing simple, efficient memory-mapped accesses,
558  *     potentially to unaligned memory locations, with or without byte
559  *     reordering, to 8-, 16-, 32-, and 64-bit big endian byte
560  *     ordered quantities, both with and without pointer
561  *     management.</li>
562  *  </ul>
563  *
564  *  On big endian host systems no actual byte reordering will
565  *  occur. On other systems, byte reordering is peformed as
566  *  appropriate.
567  *
568  */
569 namespace BigEndian {
570
571 /**
572  * This conditionally performs, as necessary for the target system, a
573  * byte order swap by value of the specified 16-bit value, presumed to
574  * be in big endian byte ordering to the target system (i.e. host)
575  * byte ordering.
576  *
577  * Consequently, on bit endian target systems, this is a no-op and
578  * on big endian target systems, this performs a reordering.
579  *
580  * @param[in]  v  The 16-bit value to be byte order swapped.
581  *
582  * @return The input value, if necessary, byte order swapped.
583  */
584 inline uint16_t HostSwap16(uint16_t v)
585 {
586     return nl::ByteOrder::Swap16BigToHost(v);
587 }
588
589 /**
590  * This conditionally performs, as necessary for the target system, a
591  * byte order swap by value of the specified 32-bit value, presumed to
592  * be in big endian byte ordering to the target system (i.e. host)
593  * byte ordering.
594  *
595  * Consequently, on bit endian target systems, this is a no-op and
596  * on big endian target systems, this performs a reordering.
597  *
598  * @param[in]  v  The 32-bit value to be byte order swapped.
599  *
600  * @return The input value, if necessary, byte order swapped.
601  */
602 inline uint32_t HostSwap32(uint32_t v)
603 {
604     return nl::ByteOrder::Swap32BigToHost(v);
605 }
606
607 /**
608  * This conditionally performs, as necessary for the target system, a
609  * byte order swap by value of the specified 64-bit value, presumed to
610  * be in big endian byte ordering to the target system (i.e. host)
611  * byte ordering.
612  *
613  * Consequently, on bit endian target systems, this is a no-op and
614  * on big endian target systems, this performs a reordering.
615  *
616  * @param[in]  v  The 64-bit value to be byte order swapped.
617  *
618  * @return The input value, if necessary, byte order swapped.
619  */
620 inline uint64_t HostSwap64(uint64_t v)
621 {
622     return nl::ByteOrder::Swap64BigToHost(v);
623 }
624
625 /**
626  * Perform a, potentially unaligned, memory read of the big endian
627  * byte ordered 16-bit value from the specified pointer address,
628  * perform byte reordering, as necessary, for the target system to
629  * put the value in target system byte ordering.
630  *
631  * @param[in]  p      A pointer address, potentially unaligned, to read
632  *                    the 16-bit big endian byte ordered value from.
633  *
634  * @return The 16-bit value at the specified pointer address, if
635  *         necessary, byte reordered.
636  */
637 inline uint16_t Get16(const uint8_t * p)
638 {
639     return nl::IO::BigEndian::GetUnaligned16(p);
640 }
641
642 /**
643  * Perform a, potentially unaligned, memory read of the big endian
644  * byte ordered 32-bit value from the specified pointer address,
645  * perform byte reordering, as necessary, for the target system to
646  * put the value in target system byte ordering.
647  *
648  * @param[in]  p      A pointer address, potentially unaligned, to read
649  *                    the 32-bit big endian byte ordered value from.
650  *
651  * @return The 32-bit value at the specified pointer address, if
652  *         necessary, byte reordered.
653  */
654 inline uint32_t Get32(const uint8_t * p)
655 {
656     return nl::IO::BigEndian::GetUnaligned32(p);
657 }
658
659 /**
660  * Perform a, potentially unaligned, memory read of the big endian
661  * byte ordered 64-bit value from the specified pointer address,
662  * perform byte reordering, as necessary, for the target system to
663  * put the value in target system byte ordering.
664  *
665  * @param[in]  p      A pointer address, potentially unaligned, to read
666  *                    the 64-bit big endian byte ordered value from.
667  *
668  * @return The 64-bit value at the specified pointer address, if
669  *         necessary, byte reordered.
670  */
671 inline uint64_t Get64(const uint8_t * p)
672 {
673     return nl::IO::BigEndian::GetUnaligned64(p);
674 }
675
676 /**
677  * Perform a, potentially unaligned, memory write of the target system
678  * byte ordered 16-bit value to the specified pointer address,
679  * perform byte reordering, as necessary, for the target system to
680  * put the value in big endian byte ordering.
681  *
682  * @param[in]  p      A pointer address, potentially unaligned, to write
683  *                    the target system byte ordered 16-bit value to in big
684  *                    endian byte ordering.
685  *
686  * @param[in]  v      The 16-bit value to write, if necessary, byte order
687  *                    swapped.
688  *
689  */
690 inline void Put16(uint8_t * p, uint16_t v)
691 {
692     nl::IO::BigEndian::PutUnaligned16(p, v);
693 }
694
695 /**
696  * Perform a, potentially unaligned, memory write of the target system
697  * byte ordered 32-bit value to the specified pointer address,
698  * perform byte reordering, as necessary, for the target system to
699  * put the value in big endian byte ordering.
700  *
701  * @param[in]  p      A pointer address, potentially unaligned, to write
702  *                    the target system byte ordered 32-bit value to in big
703  *                    endian byte ordering.
704  *
705  * @param[in]  v      The 32-bit value to write, if necessary, byte order
706  *                    swapped.
707  *
708  */
709 inline void Put32(uint8_t * p, uint32_t v)
710 {
711     nl::IO::BigEndian::PutUnaligned32(p, v);
712 }
713
714 /**
715  * Perform a, potentially unaligned, memory write of the target system
716  * byte ordered 64-bit value to the specified pointer address,
717  * perform byte reordering, as necessary, for the target system to
718  * put the value in big endian byte ordering.
719  *
720  * @param[in]  p      A pointer address, potentially unaligned, to write
721  *                    the target system byte ordered 64-bit value to in big
722  *                    endian byte ordering.
723  *
724  * @param[in]  v      The 64-bit value to write, if necessary, byte order
725  *                    swapped.
726  *
727  */
728 inline void Put64(uint8_t * p, uint64_t v)
729 {
730     nl::IO::BigEndian::PutUnaligned64(p, v);
731 }
732
733 /**
734  * Perform a, potentially unaligned, memory read of the big endian
735  * byte ordered 16-bit value from the specified pointer address,
736  * perform byte reordering, as necessary, for the target system to put
737  * the value in target system byte ordering, and increment the pointer
738  * by 16-bits (2 bytes).
739  *
740  * @param[in,out] p   A reference to a constant pointer address, potentially
741  *                    unaligned, to read the 16-bit big endian byte
742  *                    ordered value from and to then increment by 16-
743  *                    bits (2 bytes).
744  *
745  * @return The 16-bit value at the specified pointer address, if necessary,
746  *         byte order swapped.
747  */
748 inline uint16_t Read16(const uint8_t *& p)
749 {
750     return nl::IO::BigEndian::ReadUnaligned16(reinterpret_cast<const void *&>(p));
751 }
752
753 /**
754  * Perform a, potentially unaligned, memory read of the big endian
755  * byte ordered 16-bit value from the specified pointer address,
756  * perform byte reordering, as necessary, for the target system to put
757  * the value in target system byte ordering, and increment the pointer
758  * by 16-bits (2 bytes).
759  *
760  * @param[in,out] p   A reference to a pointer address, potentially
761  *                    unaligned, to read the 16-bit big endian byte
762  *                    ordered value from and to then increment by 16-
763  *                    bits (2 bytes).
764  *
765  * @return The 16-bit value at the specified pointer address, if necessary,
766  *         byte order swapped.
767  */
768 inline uint16_t Read16(uint8_t *& p)
769 {
770     return Read16(const_cast<const uint8_t *&>(p));
771 }
772
773 /**
774  * Perform a, potentially unaligned, memory read of the big endian
775  * byte ordered 32-bit value from the specified pointer address,
776  * perform byte reordering, as necessary, for the target system to put
777  * the value in target system byte ordering, and increment the pointer
778  * by 32-bits (4 bytes).
779  *
780  * @param[in,out] p   A reference to a constant pointer address, potentially
781  *                    unaligned, to read the 32-bit big endian byte
782  *                    ordered value from and to then increment by 32-
783  *                    bits (4 bytes).
784  *
785  * @return The 32-bit value at the specified pointer address, if necessary,
786  *         byte order swapped.
787  */
788 inline uint32_t Read32(const uint8_t *& p)
789 {
790     return nl::IO::BigEndian::ReadUnaligned32(reinterpret_cast<const void *&>(p));
791 }
792
793 /**
794  * Perform a, potentially unaligned, memory read of the big endian
795  * byte ordered 32-bit value from the specified pointer address,
796  * perform byte reordering, as necessary, for the target system to put
797  * the value in target system byte ordering, and increment the pointer
798  * by 32-bits (4 bytes).
799  *
800  * @param[in,out] p   A reference to a pointer address, potentially
801  *                    unaligned, to read the 32-bit big endian byte
802  *                    ordered value from and to then increment by 32-
803  *                    bits (4 bytes).
804  *
805  * @return The 32-bit value at the specified pointer address, if necessary,
806  *         byte order swapped.
807  */
808 inline uint32_t Read32(uint8_t *& p)
809 {
810     return Read32(const_cast<const uint8_t *&>(p));
811 }
812
813 /**
814  * Perform a, potentially unaligned, memory read of the big endian
815  * byte ordered 64-bit value from the specified pointer address,
816  * perform byte reordering, as necessary, for the target system to put
817  * the value in target system byte ordering, and increment the pointer
818  * by 64-bits (8 bytes).
819  *
820  * @param[in,out] p   A reference to a constant pointer address, potentially
821  *                    unaligned, to read the 64-bit big endian byte
822  *                    ordered value from and to then increment by 64-
823  *                    bits (8 bytes).
824  *
825  * @return The 64-bit value at the specified pointer address, if necessary,
826  *         byte order swapped.
827  */
828 inline uint64_t Read64(const uint8_t *& p)
829 {
830     return nl::IO::BigEndian::ReadUnaligned64(reinterpret_cast<const void *&>(p));
831 }
832
833 /**
834  * Perform a, potentially unaligned, memory read of the big endian
835  * byte ordered 64-bit value from the specified pointer address,
836  * perform byte reordering, as necessary, for the target system to put
837  * the value in target system byte ordering, and increment the pointer
838  * by 64-bits (8 bytes).
839  *
840  * @param[in,out] p   A reference to a pointer address, potentially
841  *                    unaligned, to read the 64-bit big endian byte
842  *                    ordered value from and to then increment by 64-
843  *                    bits (8 bytes).
844  *
845  * @return The 64-bit value at the specified pointer address, if necessary,
846  *         byte order swapped.
847  */
848 inline uint64_t Read64(uint8_t *& p)
849 {
850     return Read64(const_cast<const uint8_t *&>(p));
851 }
852
853 /**
854  * Perform a, potentially unaligned, memory write of the target system
855  * byte ordered 16-bit value to the specified pointer address,
856  * perform byte reordering, as necessary, for the target system to
857  * put the value in big endian byte ordering.
858  *
859  * @param[in]  p      A reference to a pointer address, potentially
860  *                    unaligned, to write the target system byte
861  *                    ordered 16-bit value to in big endian byte
862  *                    ordering and to then increment by 16-bits (2
863  *                    bytes).
864  *
865  * @param[in]  v      The 16-bit value to write, if necessary, byte order
866  *                    swapped.
867  *
868  */
869 inline void Write16(uint8_t *& p, uint16_t v)
870 {
871     Put16(p, v);
872     p += sizeof(uint16_t);
873 }
874
875 /**
876  * Perform a, potentially unaligned, memory write of the target system
877  * byte ordered 32-bit value to the specified pointer address,
878  * perform byte reordering, as necessary, for the target system to
879  * put the value in big endian byte ordering.
880  *
881  * @param[in]  p      A reference to a pointer address, potentially
882  *                    unaligned, to write the target system byte
883  *                    ordered 32-bit value to in big endian byte
884  *                    ordering and to then increment by 32-bits (4
885  *                    bytes).
886  *
887  * @param[in]  v      The 32-bit value to write, if necessary, byte order
888  *                    swapped.
889  *
890  */
891 inline void Write32(uint8_t *& p, uint32_t v)
892 {
893     Put32(p, v);
894     p += sizeof(uint32_t);
895 }
896
897 /**
898  * Perform a, potentially unaligned, memory write of the target system
899  * byte ordered 64-bit value to the specified pointer address,
900  * perform byte reordering, as necessary, for the target system to
901  * put the value in big endian byte ordering.
902  *
903  * @param[in]  p      A reference to a pointer address, potentially
904  *                    unaligned, to write the target system byte
905  *                    ordered 64-bit value to in big endian byte
906  *                    ordering and to then increment by 64-bits (8
907  *                    bytes).
908  *
909  * @param[in]  v      The 64-bit value to write, if necessary, byte order
910  *                    swapped.
911  *
912  */
913 inline void Write64(uint8_t *& p, uint64_t v)
914 {
915     Put64(p, v);
916     p += sizeof(uint64_t);
917 }
918
919 } // namespace BigEndian
920
921 } // namespace Encoding
922 } // namespace chip