1 | /* |
2 | * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * |
8 | * - Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * |
11 | * - Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
14 | * |
15 | * - Neither the name of Oracle nor the names of its |
16 | * contributors may be used to endorse or promote products derived |
17 | * from this software without specific prior written permission. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
20 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
21 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | #include "endian.hpp" |
33 | #include "inttypes.hpp" |
34 | |
35 | // Most modern compilers optimize the bswap routines to native instructions. |
36 | inline static u2 bswap_16(u2 x) { |
37 | return ((x & 0xFF) << 8) | |
38 | ((x >> 8) & 0xFF); |
39 | } |
40 | |
41 | inline static u4 bswap_32(u4 x) { |
42 | return ((x & 0xFF) << 24) | |
43 | ((x & 0xFF00) << 8) | |
44 | ((x >> 8) & 0xFF00) | |
45 | ((x >> 24) & 0xFF); |
46 | } |
47 | |
48 | inline static u8 bswap_64(u8 x) { |
49 | return (u8)bswap_32((u4)x) << 32 | |
50 | (u8)bswap_32((u4)(x >> 32)); |
51 | } |
52 | |
53 | u2 NativeEndian::get(u2 x) { return x; } |
54 | u4 NativeEndian::get(u4 x) { return x; } |
55 | u8 NativeEndian::get(u8 x) { return x; } |
56 | s2 NativeEndian::get(s2 x) { return x; } |
57 | s4 NativeEndian::get(s4 x) { return x; } |
58 | s8 NativeEndian::get(s8 x) { return x; } |
59 | |
60 | void NativeEndian::set(u2& x, u2 y) { x = y; } |
61 | void NativeEndian::set(u4& x, u4 y) { x = y; } |
62 | void NativeEndian::set(u8& x, u8 y) { x = y; } |
63 | void NativeEndian::(s2& x, s2 y) { x = y; } |
64 | void NativeEndian::set(s4& x, s4 y) { x = y; } |
65 | void NativeEndian::set(s8& x, s8 y) { x = y; } |
66 | |
67 | NativeEndian NativeEndian::_native; |
68 | |
69 | u2 SwappingEndian::get(u2 x) { return bswap_16(x); } |
70 | u4 SwappingEndian::get(u4 x) { return bswap_32(x); } |
71 | u8 SwappingEndian::get(u8 x) { return bswap_64(x); } |
72 | s2 SwappingEndian::get(s2 x) { return bswap_16(x); } |
73 | s4 SwappingEndian::get(s4 x) { return bswap_32(x); } |
74 | s8 SwappingEndian::get(s8 x) { return bswap_64(x); } |
75 | |
76 | void SwappingEndian::set(u2& x, u2 y) { x = bswap_16(y); } |
77 | void SwappingEndian::set(u4& x, u4 y) { x = bswap_32(y); } |
78 | void SwappingEndian::set(u8& x, u8 y) { x = bswap_64(y); } |
79 | void SwappingEndian::(s2& x, s2 y) { x = bswap_16(y); } |
80 | void SwappingEndian::set(s4& x, s4 y) { x = bswap_32(y); } |
81 | void SwappingEndian::set(s8& x, s8 y) { x = bswap_64(y); } |
82 | |
83 | SwappingEndian SwappingEndian::_swapping; |
84 | |
85 | Endian* Endian::get_handler(bool big_endian) { |
86 | // If requesting little endian on a little endian machine or |
87 | // big endian on a big endian machine use native handler |
88 | if (big_endian == is_big_endian()) { |
89 | return NativeEndian::get_native(); |
90 | } else { |
91 | // Use swapping handler. |
92 | return SwappingEndian::get_swapping(); |
93 | } |
94 | } |
95 | |
96 | // Return a platform u2 from an array in which Big Endian is applied. |
97 | u2 Endian::get_java(u1* x) { |
98 | return (u2) (x[0]<<8 | x[1]); |
99 | } |
100 | |
101 | // Add a platform u2 to the array as a Big Endian u2 |
102 | void Endian::set_java(u1* p, u2 x) { |
103 | p[0] = (x >> 8) & 0xff; |
104 | p[1] = x & 0xff; |
105 | } |
106 | |
107 | Endian* Endian::get_native_handler() { |
108 | return NativeEndian::get_native(); |
109 | } |
110 | |