1 /**
2  * @file endian.c  Endianness converting routines
3  *
4  * Copyright (C) 2010 Creytiv.com
5  */
6 #include <re_types.h>
7 #include <re_mbuf.h>
8 #include <re_sys.h>
9 
10 
11 /*
12  * These routes are working on both little-endian and big-endian platforms.
13  */
14 
15 
16 /**
17  * Convert a 16-bit value from host order to little endian
18  *
19  * @param v 16-bit in host order
20  *
21  * @return 16-bit little endian value
22  */
sys_htols(uint16_t v)23 uint16_t sys_htols(uint16_t v)
24 {
25 	uint8_t *p = (uint8_t *)&v;
26 	uint16_t l = 0;
27 
28 	l |= (uint16_t)*p++ << 0;
29 	l |= (uint16_t)*p   << 8;
30 
31 	return l;
32 }
33 
34 
35 /**
36  * Convert a 32-bit value from host order to little endian
37  *
38  * @param v 32-bit in host order
39  *
40  * @return 32-bit little endian value
41  */
sys_htoll(uint32_t v)42 uint32_t sys_htoll(uint32_t v)
43 {
44 	uint8_t *p = (uint8_t *)&v;
45 	uint32_t l = 0;
46 
47 	l |= (uint32_t)*p++ << 0;
48 	l |= (uint32_t)*p++ << 8;
49 	l |= (uint32_t)*p++ << 16;
50 	l |= (uint32_t)*p   << 24;
51 
52 	return l;
53 }
54 
55 
56 /**
57  * Convert a 16-bit value from little endian to host order
58  *
59  * @param v 16-bit little endian value
60  *
61  * @return 16-bit value in host order
62  */
sys_ltohs(uint16_t v)63 uint16_t sys_ltohs(uint16_t v)
64 {
65 	uint16_t s;
66 	uint8_t *p = (uint8_t *)&s;
67 
68 	*p++ = v>>0 & 0xff;
69 	*p   = v>>8 & 0xff;
70 
71 	return s;
72 }
73 
74 
75 /**
76  * Convert a 32-bit value from little endian to host order
77  *
78  * @param v 32-bit little endian value
79  *
80  * @return 32-bit value in host order
81  */
sys_ltohl(uint32_t v)82 uint32_t sys_ltohl(uint32_t v)
83 {
84 	uint32_t h;
85 	uint8_t *p = (uint8_t *)&h;
86 
87 	*p++ = v>>0  & 0xff;
88 	*p++ = v>>8  & 0xff;
89 	*p++ = v>>16 & 0xff;
90 	*p   = v>>24 & 0xff;
91 
92 	return h;
93 }
94 
95 
96 /**
97  * Convert a 64-bit value from host to network byte-order
98  *
99  * @param v 64-bit host byte-order value
100  *
101  * @return 64-bit value in network byte-order
102  */
sys_htonll(uint64_t v)103 uint64_t sys_htonll(uint64_t v)
104 {
105 	uint64_t h = 0;
106 	uint8_t *p = (uint8_t *)&v;
107 
108 	h |= (uint64_t)*p++ << 56;
109 	h |= (uint64_t)*p++ << 48;
110 	h |= (uint64_t)*p++ << 40;
111 	h |= (uint64_t)*p++ << 32;
112 	h |= (uint64_t)*p++ << 24;
113 	h |= (uint64_t)*p++ << 16;
114 	h |= (uint64_t)*p++ << 8;
115 	h |= (uint64_t)*p   << 0;
116 
117 	return h;
118 }
119 
120 
121 /**
122  * Convert a 64-bit value from network to host byte-order
123  *
124  * @param v 64-bit network byte-order value
125  *
126  * @return 64-bit value in host byte-order
127  */
sys_ntohll(uint64_t v)128 uint64_t sys_ntohll(uint64_t v)
129 {
130 	uint64_t h;
131 	uint8_t *p = (uint8_t *)&h;
132 
133 	*p++ = (uint8_t) (v>>56 & 0xff);
134 	*p++ = (uint8_t) (v>>48 & 0xff);
135 	*p++ = (uint8_t) (v>>40 & 0xff);
136 	*p++ = (uint8_t) (v>>32 & 0xff);
137 	*p++ = (uint8_t) (v>>24 & 0xff);
138 	*p++ = (uint8_t) (v>>16 & 0xff);
139 	*p++ = (uint8_t) (v>>8  & 0xff);
140 	*p   = (uint8_t) (v>>0  & 0xff);
141 
142 	return h;
143 }
144