xref: /haiku/src/kits/support/ByteOrder.cpp (revision 13581b3d2a71545960b98fefebc5225b5bf29072)
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 	// 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 
119 bool
120 is_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