status_t swap_data(type_code type, void *_data, size_t length, swap_action action) { // is there anything to do? #if B_HOST_IS_LENDIAN if (action == B_SWAP_HOST_TO_LENDIAN || action == B_SWAP_LENDIAN_TO_HOST) return B_OK; #else if (action == B_SWAP_HOST_TO_BENDIAN || action == B_SWAP_BENDIAN_TO_HOST) return B_OK; #endif if (length == 0) return B_OK; if (_data == NULL) return B_BAD_VALUE; // ToDo: these are not safe. If the length is smaller than the size of // the type to be converted, too much data may be read. R5 behaves in the // same way though. switch (type) { // 16 bit types case B_INT16_TYPE: case B_UINT16_TYPE: { uint16 *data = (uint16 *)_data; uint16 *end = (uint16 *)((addr_t)_data + length); while (data < end) { *data = __swap_int16(*data); data++; } break; } // 32 bit types case B_FLOAT_TYPE: case B_INT32_TYPE: case B_UINT32_TYPE: case B_TIME_TYPE: case B_RECT_TYPE: case B_POINT_TYPE: #if B_HAIKU_32_BIT case B_SIZE_T_TYPE: case B_SSIZE_T_TYPE: case B_POINTER_TYPE: #endif { uint32 *data = (uint32 *)_data; uint32 *end = (uint32 *)((addr_t)_data + length); while (data < end) { *data = __swap_int32(*data); data++; } break; } // 64 bit types case B_DOUBLE_TYPE: case B_INT64_TYPE: case B_UINT64_TYPE: case B_OFF_T_TYPE: #if B_HAIKU_64_BIT case B_SIZE_T_TYPE: case B_SSIZE_T_TYPE: case B_POINTER_TYPE: #endif { uint64 *data = (uint64 *)_data; uint64 *end = (uint64 *)((addr_t)_data + length); while (data < end) { *data = __swap_int64(*data); data++; } break; } // special types case B_MESSENGER_TYPE: { BMessenger *messenger = (BMessenger *)_data; BMessenger *end = (BMessenger *)((addr_t)_data + length); while (messenger < end) { BMessenger::Private messengerPrivate(messenger); // ToDo: if the additional fields change, this function has to be updated! messengerPrivate.SetTo( __swap_int32(messengerPrivate.Team()), __swap_int32(messengerPrivate.Port()), __swap_int32(messengerPrivate.Token())); messenger++; } break; } default: // not swappable or recognized type! return B_BAD_VALUE; } return B_OK; }
status_t swap_data(type_code type, void *_data, size_t length, swap_action action) { if (_data == NULL || length == 0) return B_BAD_VALUE; switch (type) { // allowed types case B_INT16_TYPE: case B_UINT16_TYPE: case B_FLOAT_TYPE: case B_INT32_TYPE: case B_UINT32_TYPE: case B_SIZE_T_TYPE: case B_SSIZE_T_TYPE: case B_TIME_TYPE: case B_POINTER_TYPE: case B_RECT_TYPE: case B_POINT_TYPE: case B_DOUBLE_TYPE: case B_INT64_TYPE: case B_UINT64_TYPE: case B_OFF_T_TYPE: case B_MESSENGER_TYPE: break; default: // not swappable or recognized type! return B_BAD_VALUE; } // is there anything to do? #if B_HOST_IS_LENDIAN if (action == B_SWAP_HOST_TO_LENDIAN || action == B_SWAP_LENDIAN_TO_HOST) return B_OK; #else if (action == B_SWAP_HOST_TO_BENDIAN || action == B_SWAP_BENDIAN_TO_HOST) return B_OK; #endif switch (type) { // 16 bit types case B_INT16_TYPE: case B_UINT16_TYPE: { uint16 *data = (uint16 *)_data; uint16 *end = (uint16 *)((addr_t)_data + length); while (data < end) { *data = __swap_int16(*data); data++; } break; } // 32 bit types case B_FLOAT_TYPE: case B_INT32_TYPE: case B_UINT32_TYPE: case B_SIZE_T_TYPE: case B_SSIZE_T_TYPE: case B_TIME_TYPE: case B_POINTER_TYPE: case B_RECT_TYPE: case B_POINT_TYPE: { // ToDo: some of these types may not be 32-bit on 64-bit platforms! uint32 *data = (uint32 *)_data; uint32 *end = (uint32 *)((addr_t)_data + length); while (data < end) { *data = __swap_int32(*data); data++; } break; } // 64 bit types case B_DOUBLE_TYPE: case B_INT64_TYPE: case B_UINT64_TYPE: case B_OFF_T_TYPE: { uint64 *data = (uint64 *)_data; uint64 *end = (uint64 *)((addr_t)_data + length); while (data < end) { *data = __swap_int64(*data); data++; } break; } // special types case B_MESSENGER_TYPE: { BMessenger *messenger = (BMessenger *)_data; BMessenger *end = (BMessenger *)((addr_t)_data + length); while (messenger < end) { BMessenger::Private messengerPrivate(messenger); // ToDo: if the additional fields change, this function has to be updated! messengerPrivate.SetTo( __swap_int32(messengerPrivate.Team()), __swap_int32(messengerPrivate.Port()), __swap_int32(messengerPrivate.Token())); messenger++; } break; } } return B_OK; }