xref: /haiku/src/kits/support/ByteOrder.cpp (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
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 
12 status_t
13 swap_data(type_code type, void *_data, size_t length, swap_action action)
14 {
15 	if (_data == NULL || length == 0)
16 		return B_BAD_VALUE;
17 
18 	switch (type) {
19 		// allowed types
20 		case B_INT16_TYPE:
21 		case B_UINT16_TYPE:
22 		case B_FLOAT_TYPE:
23 		case B_INT32_TYPE:
24 		case B_UINT32_TYPE:
25 		case B_SIZE_T_TYPE:
26 		case B_SSIZE_T_TYPE:
27 		case B_TIME_TYPE:
28 		case B_POINTER_TYPE:
29 		case B_RECT_TYPE:
30 		case B_POINT_TYPE:
31 		case B_DOUBLE_TYPE:
32 		case B_INT64_TYPE:
33 		case B_UINT64_TYPE:
34 		case B_OFF_T_TYPE:
35 		case B_MESSENGER_TYPE:
36 			break;
37 
38 		default:
39 			// not swappable or recognized type!
40 			return B_BAD_VALUE;
41 	}
42 
43 	// is there anything to do?
44 #if B_HOST_IS_LENDIAN
45 	if (action == B_SWAP_HOST_TO_LENDIAN || action == B_SWAP_LENDIAN_TO_HOST)
46 		return B_OK;
47 #else
48 	if (action == B_SWAP_HOST_TO_BENDIAN || action == B_SWAP_BENDIAN_TO_HOST)
49 		return B_OK;
50 #endif
51 
52 	switch (type) {
53 		// 16 bit types
54 		case B_INT16_TYPE:
55 		case B_UINT16_TYPE:
56 		{
57 			uint16 *data = (uint16 *)_data;
58 			uint16 *end = (uint16 *)((addr_t)_data + length);
59 
60 			while (data < end) {
61 				*data = __swap_int16(*data);
62 				data++;
63 			}
64 			break;
65 		}
66 
67 		// 32 bit types
68 		case B_FLOAT_TYPE:
69 		case B_INT32_TYPE:
70 		case B_UINT32_TYPE:
71 		case B_SIZE_T_TYPE:
72 		case B_SSIZE_T_TYPE:
73 		case B_TIME_TYPE:
74 		case B_POINTER_TYPE:
75 		case B_RECT_TYPE:
76 		case B_POINT_TYPE:
77 		{
78 			// ToDo: some of these types may not be 32-bit on 64-bit platforms!
79 			uint32 *data = (uint32 *)_data;
80 			uint32 *end = (uint32 *)((addr_t)_data + length);
81 
82 			while (data < end) {
83 				*data = __swap_int32(*data);
84 				data++;
85 			}
86 			break;
87 		}
88 
89 		// 64 bit types
90 		case B_DOUBLE_TYPE:
91 		case B_INT64_TYPE:
92 		case B_UINT64_TYPE:
93 		case B_OFF_T_TYPE:
94 		{
95 			uint64 *data = (uint64 *)_data;
96 			uint64 *end = (uint64 *)((addr_t)_data + length);
97 
98 			while (data < end) {
99 				*data = __swap_int64(*data);
100 				data++;
101 			}
102 			break;
103 		}
104 
105 		// special types
106 		case B_MESSENGER_TYPE:
107 		{
108 			BMessenger *messenger = (BMessenger *)_data;
109 			BMessenger *end = (BMessenger *)((addr_t)_data + length);
110 
111 			while (messenger < end) {
112 				BMessenger::Private messengerPrivate(messenger);
113 				// ToDo: if the additional fields change, this function has to be updated!
114 				messengerPrivate.SetTo(
115 					__swap_int32(messengerPrivate.Team()),
116 					__swap_int32(messengerPrivate.Port()),
117 					__swap_int32(messengerPrivate.Token()));
118 				messenger++;
119 			}
120 			break;
121 		}
122 	}
123 
124 	return B_OK;
125 }
126 
127 
128 bool
129 is_type_swapped(type_code type)
130 {
131 	// Returns true when the type is in the host's native format
132 	// Looks like a pretty strange function to me :)
133 
134 	switch (type) {
135 		case B_ANY_TYPE:
136 		case B_BOOL_TYPE:
137 		case B_CHAR_TYPE:
138 		case B_COLOR_8_BIT_TYPE:
139 		case B_DOUBLE_TYPE:
140 		case B_FLOAT_TYPE:
141 		case B_GRAYSCALE_8_BIT_TYPE:
142 		case B_INT64_TYPE:
143 		case B_INT32_TYPE:
144 		case B_INT16_TYPE:
145 		case B_INT8_TYPE:
146 		case B_MESSAGE_TYPE:
147 		case B_MESSENGER_TYPE:
148 		case B_MIME_TYPE:
149 		case B_MONOCHROME_1_BIT_TYPE:
150 		case B_OBJECT_TYPE:
151 		case B_OFF_T_TYPE:
152 		case B_PATTERN_TYPE:
153 		case B_POINTER_TYPE:
154 		case B_POINT_TYPE:
155 		case B_RAW_TYPE:
156 		case B_RECT_TYPE:
157 		case B_REF_TYPE:
158 		case B_RGB_32_BIT_TYPE:
159 		case B_RGB_COLOR_TYPE:
160 		case B_SIZE_T_TYPE:
161 		case B_SSIZE_T_TYPE:
162 		case B_STRING_TYPE:
163 		case B_TIME_TYPE:
164 		case B_UINT64_TYPE:
165 		case B_UINT32_TYPE:
166 		case B_UINT16_TYPE:
167 		case B_UINT8_TYPE:
168 		case B_MEDIA_PARAMETER_TYPE:
169 		case B_MEDIA_PARAMETER_WEB_TYPE:
170 		case B_MEDIA_PARAMETER_GROUP_TYPE:
171 			return true;
172 	}
173 
174 	return false;
175 }
176 
177