endian.cpp revision 12785:200804e4ba28
1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26#include "endian.hpp" 27#include "inttypes.hpp" 28 29// Most modern compilers optimize the bswap routines to native instructions. 30inline static u2 bswap_16(u2 x) { 31 return ((x & 0xFF) << 8) | 32 ((x >> 8) & 0xFF); 33} 34 35inline static u4 bswap_32(u4 x) { 36 return ((x & 0xFF) << 24) | 37 ((x & 0xFF00) << 8) | 38 ((x >> 8) & 0xFF00) | 39 ((x >> 24) & 0xFF); 40} 41 42inline static u8 bswap_64(u8 x) { 43 return (u8)bswap_32((u4)x) << 32 | 44 (u8)bswap_32((u4)(x >> 32)); 45} 46 47u2 NativeEndian::get(u2 x) { return x; } 48u4 NativeEndian::get(u4 x) { return x; } 49u8 NativeEndian::get(u8 x) { return x; } 50s2 NativeEndian::get(s2 x) { return x; } 51s4 NativeEndian::get(s4 x) { return x; } 52s8 NativeEndian::get(s8 x) { return x; } 53 54void NativeEndian::set(u2& x, u2 y) { x = y; } 55void NativeEndian::set(u4& x, u4 y) { x = y; } 56void NativeEndian::set(u8& x, u8 y) { x = y; } 57void NativeEndian::set(s2& x, s2 y) { x = y; } 58void NativeEndian::set(s4& x, s4 y) { x = y; } 59void NativeEndian::set(s8& x, s8 y) { x = y; } 60 61NativeEndian NativeEndian::_native; 62 63u2 SwappingEndian::get(u2 x) { return bswap_16(x); } 64u4 SwappingEndian::get(u4 x) { return bswap_32(x); } 65u8 SwappingEndian::get(u8 x) { return bswap_64(x); } 66s2 SwappingEndian::get(s2 x) { return bswap_16(x); } 67s4 SwappingEndian::get(s4 x) { return bswap_32(x); } 68s8 SwappingEndian::get(s8 x) { return bswap_64(x); } 69 70void SwappingEndian::set(u2& x, u2 y) { x = bswap_16(y); } 71void SwappingEndian::set(u4& x, u4 y) { x = bswap_32(y); } 72void SwappingEndian::set(u8& x, u8 y) { x = bswap_64(y); } 73void SwappingEndian::set(s2& x, s2 y) { x = bswap_16(y); } 74void SwappingEndian::set(s4& x, s4 y) { x = bswap_32(y); } 75void SwappingEndian::set(s8& x, s8 y) { x = bswap_64(y); } 76 77SwappingEndian SwappingEndian::_swapping; 78 79Endian* Endian::get_handler(bool big_endian) { 80 // If requesting little endian on a little endian machine or 81 // big endian on a big endian machine use native handler 82 if (big_endian == is_big_endian()) { 83 return NativeEndian::get_native(); 84 } else { 85 // Use swapping handler. 86 return SwappingEndian::get_swapping(); 87 } 88} 89 90// Return a platform u2 from an array in which Big Endian is applied. 91u2 Endian::get_java(u1* x) { 92 return (u2) (x[0]<<8 | x[1]); 93} 94 95// Add a platform u2 to the array as a Big Endian u2 96void Endian::set_java(u1* p, u2 x) { 97 p[0] = (x >> 8) & 0xff; 98 p[1] = x & 0xff; 99} 100 101Endian* Endian::get_native_handler() { 102 return NativeEndian::get_native(); 103} 104