byteorder.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 RenĂ© Kijewski
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
19 #ifndef BYTEORDER_H
20 #define BYTEORDER_H
21 
22 #include <stdint.h>
23 #include "unaligned.h"
24 
25 #if defined(__MACH__)
26 # include "clang_compat.h"
27 #endif
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /* ******************************* INTERFACE ******************************* */
34 
35 
41 typedef union __attribute__((packed)) {
42  uint16_t u16;
43  uint8_t u8[2];
44 } le_uint16_t;
45 
51 typedef union __attribute__((packed)) {
52  uint32_t u32;
53  uint8_t u8[4];
54  uint16_t u16[2];
55  le_uint16_t l16[2];
56 } le_uint32_t;
57 
63 typedef union __attribute__((packed)) {
64  uint64_t u64;
65  uint8_t u8[8];
66  uint16_t u16[4];
67  uint32_t u32[2];
68  le_uint16_t l16[4];
69  le_uint32_t l32[2];
70 } le_uint64_t;
71 
77 typedef union __attribute__((packed)) {
78  uint16_t u16;
79  uint8_t u8[2];
80 } be_uint16_t;
81 
87 typedef union __attribute__((packed)) {
88  uint32_t u32;
89  uint8_t u8[4];
90  uint16_t u16[2];
91  be_uint16_t b16[2];
92 } be_uint32_t;
93 
99 typedef union __attribute__((packed)) {
100  uint64_t u64;
101  uint8_t u8[8];
102  uint16_t u16[4];
103  uint32_t u32[2];
104  be_uint16_t b16[4];
105  be_uint32_t b32[2];
106 } be_uint64_t;
107 
112 
117 
122 
128 static inline be_uint16_t byteorder_ltobs(le_uint16_t v);
129 
135 static inline be_uint32_t byteorder_ltobl(le_uint32_t v);
136 
142 static inline be_uint64_t byteorder_ltobll(le_uint64_t v);
143 
149 static inline le_uint16_t byteorder_btols(be_uint16_t v);
150 
156 static inline le_uint32_t byteorder_btoll(be_uint32_t v);
157 
163 static inline le_uint64_t byteorder_btolll(be_uint64_t v);
164 
170 static inline network_uint16_t byteorder_htons(uint16_t v);
171 
177 static inline network_uint32_t byteorder_htonl(uint32_t v);
178 
184 static inline network_uint64_t byteorder_htonll(uint64_t v);
185 
191 static inline uint16_t byteorder_ntohs(network_uint16_t v);
192 
198 static inline uint32_t byteorder_ntohl(network_uint32_t v);
199 
205 static inline uint64_t byteorder_ntohll(network_uint64_t v);
206 
212 static inline uint16_t byteorder_swaps(uint16_t v);
213 
219 static inline uint32_t byteorder_swapl(uint32_t v);
220 
226 static inline uint64_t byteorder_swapll(uint64_t v);
227 
239 static inline uint16_t byteorder_bebuftohs(const uint8_t *buf);
240 
252 static inline uint32_t byteorder_bebuftohl(const uint8_t *buf);
253 
265 static inline uint64_t byteorder_bebuftohll(const uint8_t *buf);
266 
277 static inline void byteorder_htobebufs(uint8_t *buf, uint16_t val);
278 
289 static inline void byteorder_htobebufl(uint8_t *buf, uint32_t val);
290 
301 static inline void byteorder_htobebufll(uint8_t *buf, uint64_t val);
302 
309 static inline uint16_t htons(uint16_t v);
310 
317 static inline uint32_t htonl(uint32_t v);
318 
325 static inline uint64_t htonll(uint64_t v);
326 
333 static inline uint16_t ntohs(uint16_t v);
334 
341 static inline uint32_t ntohl(uint32_t v);
342 
349 static inline uint64_t ntohll(uint64_t v);
350 
351 
352 /* **************************** IMPLEMENTATION ***************************** */
353 
354 #ifdef HAVE_NO_BUILTIN_BSWAP16
355 static inline unsigned short __builtin_bswap16(unsigned short a)
356 {
357  return (a << 8) | (a >> 8);
358 }
359 #endif
360 
361 static inline uint16_t byteorder_swaps(uint16_t v)
362 {
363 #ifndef MODULE_MSP430_COMMON
364  return __builtin_bswap16(v);
365 #else
366  network_uint16_t result = { v };
367  uint8_t tmp = result.u8[0];
368  result.u8[0] = result.u8[1];
369  result.u8[1] = tmp;
370  return result.u16;
371 #endif
372 }
373 
374 static inline uint32_t byteorder_swapl(uint32_t v)
375 {
376  return __builtin_bswap32(v);
377 }
378 
379 static inline uint64_t byteorder_swapll(uint64_t v)
380 {
381  return __builtin_bswap64(v);
382 }
383 
385 {
386  be_uint16_t result = { byteorder_swaps(v.u16) };
387 
388  return result;
389 }
390 
392 {
393  be_uint32_t result = { byteorder_swapl(v.u32) };
394 
395  return result;
396 }
397 
399 {
400  be_uint64_t result = { byteorder_swapll(v.u64) };
401 
402  return result;
403 }
404 
406 {
407  le_uint16_t result = { byteorder_swaps(v.u16) };
408 
409  return result;
410 }
411 
413 {
414  le_uint32_t result = { byteorder_swapl(v.u32) };
415 
416  return result;
417 }
418 
420 {
421  le_uint64_t result = { byteorder_swapll(v.u64) };
422 
423  return result;
424 }
425 
429 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
430 # define _byteorder_swap(V, T) (byteorder_swap ## T((V)))
431 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
432 # define _byteorder_swap(V, T) (V)
433 #else
434 # error "Byte order is neither little nor big!"
435 #endif
436 
437 static inline network_uint16_t byteorder_htons(uint16_t v)
438 {
439  network_uint16_t result = { _byteorder_swap(v, s) };
440 
441  return result;
442 }
443 
444 static inline network_uint32_t byteorder_htonl(uint32_t v)
445 {
446  network_uint32_t result = { _byteorder_swap(v, l) };
447 
448  return result;
449 }
450 
451 static inline network_uint64_t byteorder_htonll(uint64_t v)
452 {
453  network_uint64_t result = { _byteorder_swap(v, ll) };
454 
455  return result;
456 }
457 
458 static inline uint16_t byteorder_ntohs(network_uint16_t v)
459 {
460  return _byteorder_swap(v.u16, s);
461 }
462 
463 static inline uint32_t byteorder_ntohl(network_uint32_t v)
464 {
465  return _byteorder_swap(v.u32, l);
466 }
467 
468 static inline uint64_t byteorder_ntohll(network_uint64_t v)
469 {
470  return _byteorder_swap(v.u64, ll);
471 }
472 
473 static inline uint16_t htons(uint16_t v)
474 {
475  return byteorder_htons(v).u16;
476 }
477 
478 static inline uint32_t htonl(uint32_t v)
479 {
480  return byteorder_htonl(v).u32;
481 }
482 
483 static inline uint64_t htonll(uint64_t v)
484 {
485  return byteorder_htonll(v).u64;
486 }
487 
488 static inline uint16_t ntohs(uint16_t v)
489 {
490  network_uint16_t input = { v };
491 
492  return byteorder_ntohs(input);
493 }
494 
495 static inline uint32_t ntohl(uint32_t v)
496 {
497  network_uint32_t input = { v };
498 
499  return byteorder_ntohl(input);
500 }
501 
502 static inline uint64_t ntohll(uint64_t v)
503 {
504  network_uint64_t input = { v };
505 
506  return byteorder_ntohll(input);
507 }
508 
509 static inline uint16_t byteorder_bebuftohs(const uint8_t *buf)
510 {
511 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
512  return (uint16_t)((buf[0] << 8) | (buf[1] << 0));
513 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
514  /* big endian to big endian conversion is easy, but buffer might be
515  * unaligned */
516  return unaligned_get_u16(buf);
517 #endif
518 }
519 
520 static inline uint32_t byteorder_bebuftohl(const uint8_t *buf)
521 {
522 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
523  return (((uint32_t) buf[0] << 24)
524  | ((uint32_t) buf[1] << 16)
525  | ((uint32_t) buf[2] << 8)
526  | ((uint32_t) buf[3] << 0));
527 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
528  /* big endian to big endian conversion is easy, but buffer might be
529  * unaligned */
530  return unaligned_get_u32(buf);
531 #endif
532 }
533 
534 static inline uint64_t byteorder_bebuftohll(const uint8_t *buf)
535 {
536 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
537  return (((uint64_t) buf[0] << 56)
538  | ((uint64_t) buf[1] << 48)
539  | ((uint64_t) buf[2] << 40)
540  | ((uint64_t) buf[3] << 32)
541  | ((uint64_t) buf[4] << 24)
542  | ((uint64_t) buf[5] << 16)
543  | ((uint64_t) buf[6] << 8)
544  | ((uint64_t) buf[7] << 0));
545 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
546  /* big endian to big endian conversion is easy, but buffer might be
547  * unaligned */
548  return unaligned_get_u64(buf);
549 #endif
550 }
551 
552 static inline void byteorder_htobebufs(uint8_t *buf, uint16_t val)
553 {
554 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
555  buf[0] = (uint8_t)(val >> 8);
556  buf[1] = (uint8_t)(val >> 0);
557 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
558  /* big endian to big endian conversion is easy, but buffer might be
559  * unaligned */
560  memcpy(buf, &val, sizeof(val));
561 #endif
562 }
563 
564 static inline void byteorder_htobebufl(uint8_t *buf, uint32_t val)
565 {
566 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
567  buf[0] = (uint8_t)(val >> 24);
568  buf[1] = (uint8_t)(val >> 16);
569  buf[2] = (uint8_t)(val >> 8);
570  buf[3] = (uint8_t)(val >> 0);
571 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
572  /* big endian to big endian conversion is easy, but buffer might be
573  * unaligned */
574  memcpy(buf, &val, sizeof(val));
575 #endif
576 }
577 
578 static inline void byteorder_htobebufll(uint8_t *buf, uint64_t val)
579 {
580 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
581  buf[0] = (uint8_t)(val >> 56);
582  buf[1] = (uint8_t)(val >> 48);
583  buf[2] = (uint8_t)(val >> 40);
584  buf[3] = (uint8_t)(val >> 32);
585  buf[4] = (uint8_t)(val >> 24);
586  buf[5] = (uint8_t)(val >> 16);
587  buf[6] = (uint8_t)(val >> 8);
588  buf[7] = (uint8_t)(val >> 0);
589 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
590  /* big endian to big endian conversion is easy, but buffer might be
591  * unaligned */
592  memcpy(buf, &val, sizeof(val));
593 #endif
594 }
595 
596 #ifdef __cplusplus
597 }
598 #endif
599 
600 #endif /* BYTEORDER_H */
601 
le_uint32_t
A 32 bit integer in little endian.
Definition: byteorder.h:51
byteorder_swaps
static uint16_t byteorder_swaps(uint16_t v)
Swap byte order, 16 bit.
Definition: byteorder.h:361
byteorder_bebuftohl
static uint32_t byteorder_bebuftohl(const uint8_t *buf)
Read a big endian encoded unsigned integer from a buffer into host byte order encoded variable,...
Definition: byteorder.h:520
be_uint32_t
A 32 bit integer in big endian aka network byte order.
Definition: byteorder.h:87
byteorder_bebuftohs
static uint16_t byteorder_bebuftohs(const uint8_t *buf)
Read a big endian encoded unsigned integer from a buffer into host byte order encoded variable,...
Definition: byteorder.h:509
le_uint16_t
A 16 bit integer in little endian.
Definition: byteorder.h:41
ntohll
static uint64_t ntohll(uint64_t v)
Convert from network byte order to host byte order, 64 bit.
Definition: byteorder.h:502
be_uint16_t
A 16 bit integer in big endian aka network byte order.
Definition: byteorder.h:77
ntohs
static uint16_t ntohs(uint16_t v)
Convert from network byte order to host byte order, 16 bit.
Definition: byteorder.h:488
unaligned_get_u64
static uint64_t unaligned_get_u64(const void *ptr)
Get uint64_t from possibly unaligned pointer.
Definition: unaligned.h:94
be_uint16_t::u8
uint8_t u8[2]
8 bit representation
Definition: byteorder.h:79
byteorder_ltobl
static be_uint32_t byteorder_ltobl(le_uint32_t v)
Convert from little endian to big endian, 32 bit.
Definition: byteorder.h:391
network_uint32_t
be_uint32_t network_uint32_t
A 32 bit integer in network byte order.
Definition: byteorder.h:116
htonll
static uint64_t htonll(uint64_t v)
Convert from host byte order to network byte order, 64 bit.
Definition: byteorder.h:483
le_uint64_t::u64
uint64_t u64
64 bit representation
Definition: byteorder.h:64
unaligned_get_u16
static uint16_t unaligned_get_u16(const void *ptr)
Get uint16_t from possibly unaligned pointer.
Definition: unaligned.h:68
byteorder_btols
static le_uint16_t byteorder_btols(be_uint16_t v)
Convert from big endian to little endian, 16 bit.
Definition: byteorder.h:405
be_uint32_t::u32
uint32_t u32
32 bit representation
Definition: byteorder.h:88
byteorder_ntohl
static uint32_t byteorder_ntohl(network_uint32_t v)
Convert from network byte order to host byte order, 32 bit.
Definition: byteorder.h:463
_byteorder_swap
#define _byteorder_swap(V, T)
Swaps the byteorder according to the endianness.
Definition: byteorder.h:430
byteorder_bebuftohll
static uint64_t byteorder_bebuftohll(const uint8_t *buf)
Read a big endian encoded unsigned integer from a buffer into host byte order encoded variable,...
Definition: byteorder.h:534
byteorder_htons
static network_uint16_t byteorder_htons(uint16_t v)
Convert from host byte order to network byte order, 16 bit.
Definition: byteorder.h:437
byteorder_swapll
static uint64_t byteorder_swapll(uint64_t v)
Swap byte order, 64 bit.
Definition: byteorder.h:379
byteorder_ntohll
static uint64_t byteorder_ntohll(network_uint64_t v)
Convert from network byte order to host byte order, 64 bit.
Definition: byteorder.h:468
byteorder_htonl
static network_uint32_t byteorder_htonl(uint32_t v)
Convert from host byte order to network byte order, 32 bit.
Definition: byteorder.h:444
byteorder_swapl
static uint32_t byteorder_swapl(uint32_t v)
Swap byte order, 32 bit.
Definition: byteorder.h:374
byteorder_htobebufl
static void byteorder_htobebufl(uint8_t *buf, uint32_t val)
Write a host byte order encoded unsigned integer as big endian encoded value into a buffer,...
Definition: byteorder.h:564
byteorder_ltobll
static be_uint64_t byteorder_ltobll(le_uint64_t v)
Convert from little endian to big endian, 64 bit.
Definition: byteorder.h:398
unaligned.h
Unaligned but safe memory access functions.
htonl
static uint32_t htonl(uint32_t v)
Convert from host byte order to network byte order, 32 bit.
Definition: byteorder.h:478
byteorder_btoll
static le_uint32_t byteorder_btoll(be_uint32_t v)
Convert from big endian to little endian, 32 bit.
Definition: byteorder.h:412
ntohl
static uint32_t ntohl(uint32_t v)
Convert from network byte order to host byte order, 32 bit.
Definition: byteorder.h:495
unaligned_get_u32
static uint32_t unaligned_get_u32(const void *ptr)
Get uint32_t from possibly unaligned pointer.
Definition: unaligned.h:81
byteorder_htobebufll
static void byteorder_htobebufll(uint8_t *buf, uint64_t val)
Write a host byte order encoded unsigned integer as big endian encoded value into a buffer,...
Definition: byteorder.h:578
byteorder_htobebufs
static void byteorder_htobebufs(uint8_t *buf, uint16_t val)
Write a host byte order encoded unsigned integer as big endian encoded value into a buffer,...
Definition: byteorder.h:552
htons
static uint16_t htons(uint16_t v)
Convert from host byte order to network byte order, 16 bit.
Definition: byteorder.h:473
byteorder_ntohs
static uint16_t byteorder_ntohs(network_uint16_t v)
Convert from network byte order to host byte order, 16 bit.
Definition: byteorder.h:458
network_uint16_t
be_uint16_t network_uint16_t
A 16 bit integer in network byte order.
Definition: byteorder.h:111
le_uint64_t
A 64 bit integer in little endian.
Definition: byteorder.h:63
be_uint16_t::u16
uint16_t u16
16 bit representation
Definition: byteorder.h:78
be_uint64_t::u64
uint64_t u64
64 bit representation
Definition: byteorder.h:100
byteorder_btolll
static le_uint64_t byteorder_btolll(be_uint64_t v)
Convert from big endian to little endian, 64 bit.
Definition: byteorder.h:419
le_uint32_t::u32
uint32_t u32
32 bit representation
Definition: byteorder.h:52
be_uint64_t
A 64 bit integer in big endian aka network byte order.
Definition: byteorder.h:99
byteorder_ltobs
static be_uint16_t byteorder_ltobs(le_uint16_t v)
Convert from little endian to big endian, 16 bit.
Definition: byteorder.h:384
network_uint64_t
be_uint64_t network_uint64_t
A 64 bit integer in network byte order.
Definition: byteorder.h:121
le_uint16_t::u16
uint16_t u16
16 bit representation
Definition: byteorder.h:42
byteorder_htonll
static network_uint64_t byteorder_htonll(uint64_t v)
Convert from host byte order to network byte order, 64 bit.
Definition: byteorder.h:451