1/*
2 * Copyright 2004-2005, Axel D��rfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <ByteOrder.h>
8#include <Messenger.h>
9#include <MessengerPrivate.h>
10
11
12status_t
13swap_data(type_code type, void *_data, size_t length, swap_action action)
14{
15	// is there anything to do?
16#if B_HOST_IS_LENDIAN
17	if (action == B_SWAP_HOST_TO_LENDIAN || action == B_SWAP_LENDIAN_TO_HOST)
18		return B_OK;
19#else
20	if (action == B_SWAP_HOST_TO_BENDIAN || action == B_SWAP_BENDIAN_TO_HOST)
21		return B_OK;
22#endif
23
24	if (length == 0)
25		return B_OK;
26
27	if (_data == NULL)
28		return B_BAD_VALUE;
29
30	// ToDo: these are not safe. If the length is smaller than the size of
31	// the type to be converted, too much data may be read. R5 behaves in the
32	// same way though.
33	switch (type) {
34		// 16 bit types
35		case B_INT16_TYPE:
36		case B_UINT16_TYPE:
37		{
38			uint16 *data = (uint16 *)_data;
39			uint16 *end = (uint16 *)((addr_t)_data + length);
40
41			while (data < end) {
42				*data = __swap_int16(*data);
43				data++;
44			}
45			break;
46		}
47
48		// 32 bit types
49		case B_FLOAT_TYPE:
50		case B_INT32_TYPE:
51		case B_UINT32_TYPE:
52		case B_TIME_TYPE:
53		case B_RECT_TYPE:
54		case B_POINT_TYPE:
55#if B_HAIKU_32_BIT
56		case B_SIZE_T_TYPE:
57		case B_SSIZE_T_TYPE:
58		case B_POINTER_TYPE:
59#endif
60		{
61			uint32 *data = (uint32 *)_data;
62			uint32 *end = (uint32 *)((addr_t)_data + length);
63
64			while (data < end) {
65				*data = __swap_int32(*data);
66				data++;
67			}
68			break;
69		}
70
71		// 64 bit types
72		case B_DOUBLE_TYPE:
73		case B_INT64_TYPE:
74		case B_UINT64_TYPE:
75		case B_OFF_T_TYPE:
76#if B_HAIKU_64_BIT
77		case B_SIZE_T_TYPE:
78		case B_SSIZE_T_TYPE:
79		case B_POINTER_TYPE:
80#endif
81		{
82			uint64 *data = (uint64 *)_data;
83			uint64 *end = (uint64 *)((addr_t)_data + length);
84
85			while (data < end) {
86				*data = __swap_int64(*data);
87				data++;
88			}
89			break;
90		}
91
92		// special types
93		case B_MESSENGER_TYPE:
94		{
95			BMessenger *messenger = (BMessenger *)_data;
96			BMessenger *end = (BMessenger *)((addr_t)_data + length);
97
98			while (messenger < end) {
99				BMessenger::Private messengerPrivate(messenger);
100				// ToDo: if the additional fields change, this function has to be updated!
101				messengerPrivate.SetTo(
102					__swap_int32(messengerPrivate.Team()),
103					__swap_int32(messengerPrivate.Port()),
104					__swap_int32(messengerPrivate.Token()));
105				messenger++;
106			}
107			break;
108		}
109
110		default:
111			// not swappable or recognized type!
112			return B_BAD_VALUE;
113	}
114
115	return B_OK;
116}
117
118
119bool
120is_type_swapped(type_code type)
121{
122	// Returns true when the type is in the host's native format
123	// Looks like a pretty strange function to me :)
124
125	switch (type) {
126		case B_BOOL_TYPE:
127		case B_CHAR_TYPE:
128		case B_COLOR_8_BIT_TYPE:
129		case B_DOUBLE_TYPE:
130		case B_FLOAT_TYPE:
131		case B_GRAYSCALE_8_BIT_TYPE:
132		case B_INT64_TYPE:
133		case B_INT32_TYPE:
134		case B_INT16_TYPE:
135		case B_INT8_TYPE:
136		case B_MESSAGE_TYPE:
137		case B_MESSENGER_TYPE:
138		case B_MIME_TYPE:
139		case B_MONOCHROME_1_BIT_TYPE:
140		case B_OFF_T_TYPE:
141		case B_PATTERN_TYPE:
142		case B_POINTER_TYPE:
143		case B_POINT_TYPE:
144		case B_RECT_TYPE:
145		case B_REF_TYPE:
146		case B_NODE_REF_TYPE:
147		case B_RGB_32_BIT_TYPE:
148		case B_RGB_COLOR_TYPE:
149		case B_SIZE_T_TYPE:
150		case B_SSIZE_T_TYPE:
151		case B_STRING_TYPE:
152		case B_TIME_TYPE:
153		case B_UINT64_TYPE:
154		case B_UINT32_TYPE:
155		case B_UINT16_TYPE:
156		case B_UINT8_TYPE:
157			return true;
158	}
159
160	return false;
161}
162