| /* | |
| * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions | |
| * are met: | |
| * | |
| * - Redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer. | |
| * | |
| * - Redistributions in binary form must reproduce the above copyright | |
| * notice, this list of conditions and the following disclaimer in the | |
| * documentation and/or other materials provided with the distribution. | |
| * | |
| * - Neither the name of Oracle nor the names of its | |
| * contributors may be used to endorse or promote products derived | |
| * from this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
| * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| */ | |
| #include "endian.hpp" | |
| #include "inttypes.hpp" | |
| // Most modern compilers optimize the bswap routines to native instructions. | |
| inline static u2 bswap_16(u2 x) { | |
| return ((x & 0xFF) << 8) | | |
| ((x >> 8) & 0xFF); | |
| } | |
| inline static u4 bswap_32(u4 x) { | |
| return ((x & 0xFF) << 24) | | |
| ((x & 0xFF00) << 8) | | |
| ((x >> 8) & 0xFF00) | | |
| ((x >> 24) & 0xFF); | |
| } | |
| inline static u8 bswap_64(u8 x) { | |
| return (u8)bswap_32((u4)x) << 32 | | |
| (u8)bswap_32((u4)(x >> 32)); | |
| } | |
| u2 NativeEndian::get(u2 x) { return x; } | |
| u4 NativeEndian::get(u4 x) { return x; } | |
| u8 NativeEndian::get(u8 x) { return x; } | |
| s2 NativeEndian::get(s2 x) { return x; } | |
| s4 NativeEndian::get(s4 x) { return x; } | |
| s8 NativeEndian::get(s8 x) { return x; } | |
| void NativeEndian::set(u2& x, u2 y) { x = y; } | |
| void NativeEndian::set(u4& x, u4 y) { x = y; } | |
| void NativeEndian::set(u8& x, u8 y) { x = y; } | |
| void NativeEndian::set(s2& x, s2 y) { x = y; } | |
| void NativeEndian::set(s4& x, s4 y) { x = y; } | |
| void NativeEndian::set(s8& x, s8 y) { x = y; } | |
| NativeEndian NativeEndian::_native; | |
| u2 SwappingEndian::get(u2 x) { return bswap_16(x); } | |
| u4 SwappingEndian::get(u4 x) { return bswap_32(x); } | |
| u8 SwappingEndian::get(u8 x) { return bswap_64(x); } | |
| s2 SwappingEndian::get(s2 x) { return bswap_16(x); } | |
| s4 SwappingEndian::get(s4 x) { return bswap_32(x); } | |
| s8 SwappingEndian::get(s8 x) { return bswap_64(x); } | |
| void SwappingEndian::set(u2& x, u2 y) { x = bswap_16(y); } | |
| void SwappingEndian::set(u4& x, u4 y) { x = bswap_32(y); } | |
| void SwappingEndian::set(u8& x, u8 y) { x = bswap_64(y); } | |
| void SwappingEndian::set(s2& x, s2 y) { x = bswap_16(y); } | |
| void SwappingEndian::set(s4& x, s4 y) { x = bswap_32(y); } | |
| void SwappingEndian::set(s8& x, s8 y) { x = bswap_64(y); } | |
| SwappingEndian SwappingEndian::_swapping; | |
| Endian* Endian::get_handler(bool big_endian) { | |
| // If requesting little endian on a little endian machine or | |
| // big endian on a big endian machine use native handler | |
| if (big_endian == is_big_endian()) { | |
| return NativeEndian::get_native(); | |
| } else { | |
| // Use swapping handler. | |
| return SwappingEndian::get_swapping(); | |
| } | |
| } | |
| // Return a platform u2 from an array in which Big Endian is applied. | |
| u2 Endian::get_java(u1* x) { | |
| return (u2) (x[0]<<8 | x[1]); | |
| } | |
| // Add a platform u2 to the array as a Big Endian u2 | |
| void Endian::set_java(u1* p, u2 x) { | |
| p[0] = (x >> 8) & 0xff; | |
| p[1] = x & 0xff; | |
| } | |
| Endian* Endian::get_native_handler() { | |
| return NativeEndian::get_native(); | |
| } |