1/*
2 * Copyright 2007, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _FSSH_BYTEORDER_H
6#define _FSSH_BYTEORDER_H
7
8#include <endian.h>
9	// platform endian.h
10
11
12#include "fssh_defs.h"
13
14
15// swap directions
16typedef enum {
17	FSSH_B_SWAP_HOST_TO_LENDIAN,
18	FSSH_B_SWAP_HOST_TO_BENDIAN,
19	FSSH_B_SWAP_LENDIAN_TO_HOST,
20	FSSH_B_SWAP_BENDIAN_TO_HOST,
21	FSSH_B_SWAP_ALWAYS
22} fssh_swap_action;
23
24
25// BSD/networking macros
26#ifndef fssh_htonl
27#	define fssh_htonl(x) FSSH_B_HOST_TO_BENDIAN_INT32(x)
28#	define fssh_ntohl(x) FSSH_B_BENDIAN_TO_HOST_INT32(x)
29#	define fssh_htons(x) FSSH_B_HOST_TO_BENDIAN_INT16(x)
30#	define fssh_ntohs(x) FSSH_B_BENDIAN_TO_HOST_INT16(x)
31#endif
32
33// always swap macros
34#define FSSH_B_SWAP_DOUBLE(arg)   __fssh_swap_double(arg)
35#define FSSH_B_SWAP_FLOAT(arg)    __fssh_swap_float(arg)
36#define FSSH_B_SWAP_INT64(arg)    __fssh_swap_int64(arg)
37#define FSSH_B_SWAP_INT32(arg)    __fssh_swap_int32(arg)
38#define FSSH_B_SWAP_INT16(arg)    __fssh_swap_int16(arg)
39
40#if BYTE_ORDER == __LITTLE_ENDIAN
41// Host is little endian
42
43#define FSSH_B_HOST_IS_LENDIAN 1
44#define FSSH_B_HOST_IS_BENDIAN 0
45
46// Host native to little endian
47#define FSSH_B_HOST_TO_LENDIAN_DOUBLE(arg)	(double)(arg)
48#define FSSH_B_HOST_TO_LENDIAN_FLOAT(arg)	(float)(arg)
49#define FSSH_B_HOST_TO_LENDIAN_INT64(arg)	(uint64_t)(arg)
50#define FSSH_B_HOST_TO_LENDIAN_INT32(arg)	(uint32_t)(arg)
51#define FSSH_B_HOST_TO_LENDIAN_INT16(arg)	(uint16_t)(arg)
52
53// Little endian to host native
54#define FSSH_B_LENDIAN_TO_HOST_DOUBLE(arg)	(double)(arg)
55#define FSSH_B_LENDIAN_TO_HOST_FLOAT(arg)	(float)(arg)
56#define FSSH_B_LENDIAN_TO_HOST_INT64(arg)	(uint64_t)(arg)
57#define FSSH_B_LENDIAN_TO_HOST_INT32(arg)	(uint32_t)(arg)
58#define FSSH_B_LENDIAN_TO_HOST_INT16(arg)	(uint16_t)(arg)
59
60// Host native to big endian
61#define FSSH_B_HOST_TO_BENDIAN_DOUBLE(arg)	__fssh_swap_double(arg)
62#define FSSH_B_HOST_TO_BENDIAN_FLOAT(arg)	__fssh_swap_float(arg)
63#define FSSH_B_HOST_TO_BENDIAN_INT64(arg)	__fssh_swap_int64(arg)
64#define FSSH_B_HOST_TO_BENDIAN_INT32(arg)	__fssh_swap_int32(arg)
65#define FSSH_B_HOST_TO_BENDIAN_INT16(arg)	__fssh_swap_int16(arg)
66
67// Big endian to host native
68#define FSSH_B_BENDIAN_TO_HOST_DOUBLE(arg)	__fssh_swap_double(arg)
69#define FSSH_B_BENDIAN_TO_HOST_FLOAT(arg)	__fssh_swap_float(arg)
70#define FSSH_B_BENDIAN_TO_HOST_INT64(arg)	__fssh_swap_int64(arg)
71#define FSSH_B_BENDIAN_TO_HOST_INT32(arg)	__fssh_swap_int32(arg)
72#define FSSH_B_BENDIAN_TO_HOST_INT16(arg)	__fssh_swap_int16(arg)
73
74#else	// BYTE_ORDER
75// Host is big endian
76
77#define FSSH_B_HOST_IS_LENDIAN 0
78#define FSSH_B_HOST_IS_BENDIAN 1
79
80// Host native to little endian
81#define FSSH_B_HOST_TO_LENDIAN_DOUBLE(arg)	__fssh_swap_double(arg)
82#define FSSH_B_HOST_TO_LENDIAN_FLOAT(arg)	__fssh_swap_float(arg)
83#define FSSH_B_HOST_TO_LENDIAN_INT64(arg)	__fssh_swap_int64(arg)
84#define FSSH_B_HOST_TO_LENDIAN_INT32(arg)	__fssh_swap_int32(arg)
85#define FSSH_B_HOST_TO_LENDIAN_INT16(arg)	__fssh_swap_int16(arg)
86
87// Little endian to host native
88#define FSSH_B_LENDIAN_TO_HOST_DOUBLE(arg)	__fssh_swap_double(arg)
89#define FSSH_B_LENDIAN_TO_HOST_FLOAT(arg)	__fssh_swap_float(arg)
90#define FSSH_B_LENDIAN_TO_HOST_INT64(arg)	__fssh_swap_int64(arg)
91#define FSSH_B_LENDIAN_TO_HOST_INT32(arg)	__fssh_swap_int32(arg)
92#define FSSH_B_LENDIAN_TO_HOST_INT16(arg)	__fssh_swap_int16(arg)
93
94// Host native to big endian
95#define FSSH_B_HOST_TO_BENDIAN_DOUBLE(arg)	(double)(arg)
96#define FSSH_B_HOST_TO_BENDIAN_FLOAT(arg)	(float)(arg)
97#define FSSH_B_HOST_TO_BENDIAN_INT64(arg)	(uint64_t)(arg)
98#define FSSH_B_HOST_TO_BENDIAN_INT32(arg)	(uint32_t)(arg)
99#define FSSH_B_HOST_TO_BENDIAN_INT16(arg)	(uint16_t)(arg)
100
101// Big endian to host native
102#define FSSH_B_BENDIAN_TO_HOST_DOUBLE(arg)	(double)(arg)
103#define FSSH_B_BENDIAN_TO_HOST_FLOAT(arg)	(float)(arg)
104#define FSSH_B_BENDIAN_TO_HOST_INT64(arg)	(uint64_t)(arg)
105#define FSSH_B_BENDIAN_TO_HOST_INT32(arg)	(uint32_t)(arg)
106#define FSSH_B_BENDIAN_TO_HOST_INT16(arg)	(uint16_t)(arg)
107
108#endif	// BYTE_ORDER
109
110
111#ifdef __cplusplus
112extern "C" {
113#endif
114
115extern fssh_status_t fssh_swap_data(fssh_type_code type, void *data,
116	fssh_size_t length, fssh_swap_action action);
117extern bool fssh_is_type_swapped(fssh_type_code type);
118
119
120// Private implementations
121extern double __fssh_swap_double(double arg);
122extern float  __fssh_swap_float(float arg);
123extern uint64_t __fssh_swap_int64(uint64_t arg);
124extern uint32_t __fssh_swap_int32(uint32_t arg);
125extern uint16_t __fssh_swap_int16(uint16_t arg);
126
127#ifdef __cplusplus
128}
129#endif
130
131#endif	// _FSSH_BYTEORDER_H
132