001: /*
002: * Copyright 2005 Andrew Howard
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.python.core;
018:
019: import java.lang.reflect.Array;
020:
021: /**
022: * Simple class that provides the capability to swap or reverse the byte order
023: * of all elements of an <code>Array</code>. Used to convert from one endian
024: * type to another. The class swaps the following types:
025: * <ul>
026: * <li>short</li>
027: * <li>integer</li>
028: * <li>long</li>
029: * <li>float</li>
030: * <li>double</li>
031: * </ul>
032: * <p />
033: * Note this functionality is provided in the base types since 1.5.
034: *
035: * @author Andrew Howard
036: */
037: public class ByteSwapper {
038:
039: /**
040: * Reverses the byte order of all elements in the supplied array, converting
041: * between little and big endian byte order.
042: *
043: * @param array the input array for type sensitive byte swapping.
044: */
045: public static void swap(Object array) {
046: Class arrayType = array.getClass().getComponentType();
047:
048: if (arrayType.isPrimitive()) {
049: if (arrayType == Boolean.TYPE) {
050: return;
051: } else if (arrayType == Byte.TYPE) {
052: return;
053: } else if (arrayType == Character.TYPE) {
054: return;
055: } else if (arrayType == Short.TYPE) {
056: swapShortArray(array);
057: } else if (arrayType == Integer.TYPE) {
058: swapIntegerArray(array);
059: } else if (arrayType == Long.TYPE) {
060: swapLongArray(array);
061: } else if (arrayType == Float.TYPE) {
062: swapFloatArray(array);
063: } else if (arrayType == Double.TYPE) {
064: swapDoubleArray(array);
065: }
066: }
067:
068: }
069:
070: /**
071: * Byte order reverses an <code>Array</code> of <code>doubles</code>
072: *
073: * @param array input array
074: */
075: private static void swapDoubleArray(Object array) {
076: int len = Array.getLength(array);
077: double dtmp;
078: long tmp;
079: long b1, b2, b3, b4, b5, b6, b7, b8;
080:
081: for (int i = 0; i < len; i++) {
082: dtmp = Array.getDouble(array, i);
083: tmp = Double.doubleToLongBits(dtmp);
084:
085: b1 = (tmp >> 0) & 0xff;
086: b2 = (tmp >> 8) & 0xff;
087: b3 = (tmp >> 16) & 0xff;
088: b4 = (tmp >> 24) & 0xff;
089: b5 = (tmp >> 32) & 0xff;
090: b6 = (tmp >> 40) & 0xff;
091: b7 = (tmp >> 48) & 0xff;
092: b8 = (tmp >> 56) & 0xff;
093: tmp = b1 << 56 | b2 << 48 | b3 << 40 | b4 << 32 | b5 << 24
094: | b6 << 16 | b7 << 8 | b8 << 0;
095:
096: dtmp = Double.longBitsToDouble(tmp);
097: Array.setDouble(array, i, dtmp);
098: }
099: }
100:
101: /**
102: * Byte order reverses an <code>Array</code> of <code>floats</code>
103: *
104: * @param array input array
105: */
106: private static void swapFloatArray(Object array) {
107: int len = Array.getLength(array);
108: float ftmp;
109: int tmp;
110: int b1, b2, b3, b4;
111:
112: for (int i = 0; i < len; i++) {
113: ftmp = Array.getFloat(array, i);
114: tmp = Float.floatToIntBits(ftmp);
115:
116: b1 = (tmp >> 0) & 0xff;
117: b2 = (tmp >> 8) & 0xff;
118: b3 = (tmp >> 16) & 0xff;
119: b4 = (tmp >> 24) & 0xff;
120: tmp = b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0;
121:
122: ftmp = Float.intBitsToFloat(tmp);
123: Array.setFloat(array, i, ftmp);
124: }
125: }
126:
127: /**
128: * Byte order reverses an <code>Array</code> of <code>ints</code>
129: *
130: * @param array input array
131: */
132: private static void swapIntegerArray(Object array) {
133: int len = Array.getLength(array);
134: int tmp;
135: int b1, b2, b3, b4;
136:
137: for (int i = 0; i < len; i++) {
138: tmp = Array.getInt(array, i);
139:
140: b1 = (tmp >> 0) & 0xff;
141: b2 = (tmp >> 8) & 0xff;
142: b3 = (tmp >> 16) & 0xff;
143: b4 = (tmp >> 24) & 0xff;
144: tmp = b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0;
145:
146: Array.setInt(array, i, tmp);
147: }
148: }
149:
150: /**
151: * Byte order reverses an <code>Array</code> of <code>longs</code>
152: *
153: * @param array input array
154: */
155: private static void swapLongArray(Object array) {
156: int len = Array.getLength(array);
157: long tmp;
158: long b1, b2, b3, b4, b5, b6, b7, b8;
159:
160: for (int i = 0; i < len; i++) {
161: tmp = Array.getLong(array, i);
162:
163: b1 = (tmp >> 0) & 0xff;
164: b2 = (tmp >> 8) & 0xff;
165: b3 = (tmp >> 16) & 0xff;
166: b4 = (tmp >> 24) & 0xff;
167: b5 = (tmp >> 32) & 0xff;
168: b6 = (tmp >> 40) & 0xff;
169: b7 = (tmp >> 48) & 0xff;
170: b8 = (tmp >> 56) & 0xff;
171: tmp = b1 << 56 | b2 << 48 | b3 << 40 | b4 << 32 | b5 << 24
172: | b6 << 16 | b7 << 8 | b8 << 0;
173:
174: Array.setLong(array, i, tmp);
175: }
176: }
177:
178: /**
179: * Byte order reverses an <code>Array</code> of <code>shorts</code>
180: *
181: * @param array input array
182: */
183: private static void swapShortArray(Object array) {
184: int len = Array.getLength(array);
185: short tmp;
186: int b1, b2;
187:
188: for (int i = 0; i < len; i++) {
189: tmp = Array.getShort(array, i);
190:
191: b1 = (tmp >> 0) & 0xff;
192: b2 = (tmp >> 8) & 0xff;
193: tmp = (short) (b1 << 8 | b2 << 0);
194:
195: Array.setShort(array, i, tmp);
196: }
197: }
198: }
|