vfs: check userland buffers before reading them.
[haiku.git] / src / kits / support / ByteOrder.cpp
blobc009a5fe07bd77540aea2cae9598c8225a4c7925
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 */
7 #include <ByteOrder.h>
8 #include <Messenger.h>
9 #include <MessengerPrivate.h>
12 status_t
13 swap_data(type_code type, void *_data, size_t length, swap_action action)
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
24 if (length == 0)
25 return B_OK;
27 if (_data == NULL)
28 return B_BAD_VALUE;
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:
38 uint16 *data = (uint16 *)_data;
39 uint16 *end = (uint16 *)((addr_t)_data + length);
41 while (data < end) {
42 *data = __swap_int16(*data);
43 data++;
45 break;
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
61 uint32 *data = (uint32 *)_data;
62 uint32 *end = (uint32 *)((addr_t)_data + length);
64 while (data < end) {
65 *data = __swap_int32(*data);
66 data++;
68 break;
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
82 uint64 *data = (uint64 *)_data;
83 uint64 *end = (uint64 *)((addr_t)_data + length);
85 while (data < end) {
86 *data = __swap_int64(*data);
87 data++;
89 break;
92 // special types
93 case B_MESSENGER_TYPE:
95 BMessenger *messenger = (BMessenger *)_data;
96 BMessenger *end = (BMessenger *)((addr_t)_data + length);
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++;
107 break;
110 default:
111 // not swappable or recognized type!
112 return B_BAD_VALUE;
115 return B_OK;
119 bool
120 is_type_swapped(type_code type)
122 // Returns true when the type is in the host's native format
123 // Looks like a pretty strange function to me :)
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_RGB_32_BIT_TYPE:
147 case B_RGB_COLOR_TYPE:
148 case B_SIZE_T_TYPE:
149 case B_SSIZE_T_TYPE:
150 case B_STRING_TYPE:
151 case B_TIME_TYPE:
152 case B_UINT64_TYPE:
153 case B_UINT32_TYPE:
154 case B_UINT16_TYPE:
155 case B_UINT8_TYPE:
156 return true;
159 return false;