| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #ifndef BYTEORDER_H_INCLUDED |
| #define BYTEORDER_H_INCLUDED |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <algorithm> |
| #include <boost/endian/arithmetic.hpp> |
| #include "RocketMQClient.h" |
| #include "UtilAll.h" |
| //============================================================================== |
| /** Contains static methods for converting the byte order between different |
| endiannesses. |
| */ |
| namespace rocketmq { |
| |
| class ROCKETMQCLIENT_API ByteOrder { |
| public: |
| //============================================================================== |
| /** Swaps the upper and lower bytes of a 16-bit integer. */ |
| static uint16 swap(uint16 value); |
| |
| /** Reverses the order of the 4 bytes in a 32-bit integer. */ |
| static uint32 swap(uint32 value); |
| |
| /** Reverses the order of the 8 bytes in a 64-bit integer. */ |
| static uint64 swap(uint64 value); |
| |
| //============================================================================== |
| /** Swaps the byte order of a 16-bit int if the CPU is big-endian */ |
| static uint16 swapIfBigEndian(uint16 value); |
| |
| /** Swaps the byte order of a 32-bit int if the CPU is big-endian */ |
| static uint32 swapIfBigEndian(uint32 value); |
| |
| /** Swaps the byte order of a 64-bit int if the CPU is big-endian */ |
| static uint64 swapIfBigEndian(uint64 value); |
| |
| /** Swaps the byte order of a 16-bit int if the CPU is little-endian */ |
| static uint16 swapIfLittleEndian(uint16 value); |
| |
| /** Swaps the byte order of a 32-bit int if the CPU is little-endian */ |
| static uint32 swapIfLittleEndian(uint32 value); |
| |
| /** Swaps the byte order of a 64-bit int if the CPU is little-endian */ |
| static uint64 swapIfLittleEndian(uint64 value); |
| |
| //============================================================================== |
| /** Turns 4 bytes into a little-endian integer. */ |
| static uint32 littleEndianInt(const void* bytes); |
| |
| /** Turns 8 bytes into a little-endian integer. */ |
| static uint64 littleEndianInt64(const void* bytes); |
| |
| /** Turns 2 bytes into a little-endian integer. */ |
| static uint16 littleEndianShort(const void* bytes); |
| |
| /** Turns 4 bytes into a big-endian integer. */ |
| static uint32 bigEndianInt(const void* bytes); |
| |
| /** Turns 8 bytes into a big-endian integer. */ |
| static uint64 bigEndianInt64(const void* bytes); |
| |
| /** Turns 2 bytes into a big-endian integer. */ |
| static uint16 bigEndianShort(const void* bytes); |
| |
| //============================================================================== |
| /** Converts 3 little-endian bytes into a signed 24-bit value (which is |
| * sign-extended to 32 bits). */ |
| static int littleEndian24Bit(const void* bytes); |
| |
| /** Converts 3 big-endian bytes into a signed 24-bit value (which is |
| * sign-extended to 32 bits). */ |
| static int bigEndian24Bit(const void* bytes); |
| |
| /** Copies a 24-bit number to 3 little-endian bytes. */ |
| static void littleEndian24BitToChars(int value, void* destBytes); |
| |
| /** Copies a 24-bit number to 3 big-endian bytes. */ |
| static void bigEndian24BitToChars(int value, void* destBytes); |
| |
| //============================================================================== |
| /** Returns true if the current CPU is big-endian. */ |
| static bool isBigEndian(); |
| }; |
| |
| //============================================================================== |
| |
| inline uint16 ByteOrder::swap(uint16 n) { |
| return static_cast<uint16>((n << 8) | (n >> 8)); |
| } |
| |
| inline uint32 ByteOrder::swap(uint32 n) { |
| return (n << 24) | (n >> 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8); |
| } |
| |
| inline uint64 ByteOrder::swap(uint64 value) { |
| return (((uint64)swap((uint32)value)) << 32) | swap((uint32)(value >> 32)); |
| } |
| |
| #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ //__BYTE_ORDER__ is defined by GCC |
| inline uint16 ByteOrder::swapIfBigEndian(const uint16 v) { |
| return v; |
| } |
| inline uint32 ByteOrder::swapIfBigEndian(const uint32 v) { |
| return v; |
| } |
| inline uint64 ByteOrder::swapIfBigEndian(const uint64 v) { |
| return v; |
| } |
| inline uint16 ByteOrder::swapIfLittleEndian(const uint16 v) { |
| return swap(v); |
| } |
| inline uint32 ByteOrder::swapIfLittleEndian(const uint32 v) { |
| return swap(v); |
| } |
| inline uint64 ByteOrder::swapIfLittleEndian(const uint64 v) { |
| return swap(v); |
| } |
| inline uint32 ByteOrder::littleEndianInt(const void* const bytes) { |
| return *static_cast<const uint32*>(bytes); |
| } |
| inline uint64 ByteOrder::littleEndianInt64(const void* const bytes) { |
| return *static_cast<const uint64*>(bytes); |
| } |
| inline uint16 ByteOrder::littleEndianShort(const void* const bytes) { |
| return *static_cast<const uint16*>(bytes); |
| } |
| inline uint32 ByteOrder::bigEndianInt(const void* const bytes) { |
| return swap(*static_cast<const uint32*>(bytes)); |
| } |
| inline uint64 ByteOrder::bigEndianInt64(const void* const bytes) { |
| return swap(*static_cast<const uint64*>(bytes)); |
| } |
| inline uint16 ByteOrder::bigEndianShort(const void* const bytes) { |
| return swap(*static_cast<const uint16*>(bytes)); |
| } |
| inline bool ByteOrder::isBigEndian() { |
| return false; |
| } |
| #else |
| inline uint16 ByteOrder::swapIfBigEndian(const uint16 v) { |
| return swap(v); |
| } |
| inline uint32 ByteOrder::swapIfBigEndian(const uint32 v) { |
| return swap(v); |
| } |
| inline uint64 ByteOrder::swapIfBigEndian(const uint64 v) { |
| return swap(v); |
| } |
| inline uint16 ByteOrder::swapIfLittleEndian(const uint16 v) { |
| return v; |
| } |
| inline uint32 ByteOrder::swapIfLittleEndian(const uint32 v) { |
| return v; |
| } |
| inline uint64 ByteOrder::swapIfLittleEndian(const uint64 v) { |
| return v; |
| } |
| inline uint32 ByteOrder::littleEndianInt(const void* const bytes) { |
| return swap(*static_cast<const uint32*>(bytes)); |
| } |
| inline uint64 ByteOrder::littleEndianInt64(const void* const bytes) { |
| return swap(*static_cast<const uint64*>(bytes)); |
| } |
| inline uint16 ByteOrder::littleEndianShort(const void* const bytes) { |
| return swap(*static_cast<const uint16*>(bytes)); |
| } |
| inline uint32 ByteOrder::bigEndianInt(const void* const bytes) { |
| return *static_cast<const uint32*>(bytes); |
| } |
| inline uint64 ByteOrder::bigEndianInt64(const void* const bytes) { |
| return *static_cast<const uint64*>(bytes); |
| } |
| inline uint16 ByteOrder::bigEndianShort(const void* const bytes) { |
| return *static_cast<const uint16*>(bytes); |
| } |
| inline bool ByteOrder::isBigEndian() { |
| return true; |
| } |
| #endif |
| |
| inline int ByteOrder::littleEndian24Bit(const void* const bytes) { |
| return (((int)static_cast<const int8*>(bytes)[2]) << 16) | (((int)static_cast<const uint8*>(bytes)[1]) << 8) | |
| ((int)static_cast<const uint8*>(bytes)[0]); |
| } |
| inline int ByteOrder::bigEndian24Bit(const void* const bytes) { |
| return (((int)static_cast<const int8*>(bytes)[0]) << 16) | (((int)static_cast<const uint8*>(bytes)[1]) << 8) | |
| ((int)static_cast<const uint8*>(bytes)[2]); |
| } |
| inline void ByteOrder::littleEndian24BitToChars(const int value, void* const destBytes) { |
| static_cast<uint8*>(destBytes)[0] = (uint8)value; |
| static_cast<uint8*>(destBytes)[1] = (uint8)(value >> 8); |
| static_cast<uint8*>(destBytes)[2] = (uint8)(value >> 16); |
| } |
| inline void ByteOrder::bigEndian24BitToChars(const int value, void* const destBytes) { |
| static_cast<uint8*>(destBytes)[0] = (uint8)(value >> 16); |
| static_cast<uint8*>(destBytes)[1] = (uint8)(value >> 8); |
| static_cast<uint8*>(destBytes)[2] = (uint8)value; |
| } |
| } // namespace rocketmq |
| #endif // BYTEORDER_H_INCLUDED |