001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/metaobj/tags/sakai_2-4-1/metaobj-impl/api-impl/src/java/org/sakaiproject/metaobj/utils/id/guid/ByteOrder.java $
003: * $Id: ByteOrder.java 14225 2006-09-05 17:39:44Z chmaurer@iupui.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.metaobj.utils.id.guid;
021:
022: /**
023: * Various static routines for solving endian problems.
024: */
025: public class ByteOrder {
026: private static final int UNSIGNED_BYTE_MASK = 0x000000FF;
027:
028: /**
029: * Returns the reverse of x.
030: */
031: public static byte[] reverse(byte[] x) {
032: int n = x.length;
033: byte[] ret = new byte[n];
034: for (int i = 0; i < n; i++) {
035: ret[i] = x[n - i - 1];
036: }
037: return ret;
038: }
039:
040: /**
041: * Little-endian bytes to short
042: *
043: * @requires x.length-offset>=2
044: * @effects returns the value of x[offset..offset+2] as a short,
045: * assuming x is interpreted as a signed little endian number (i.e.,
046: * x[offset] is LSB). If you want to interpret it as an unsigned number,
047: * call ubytes2int on the result.
048: */
049: public static short leb2short(byte[] x, int offset) {
050: int x0 = (x[offset]) & UNSIGNED_BYTE_MASK;
051: int x1 = (x[offset + 1] << 8);
052: return (short) (x1 | x0);
053: }
054:
055: /**
056: * Little-endian bytes to int
057: *
058: * @requires x.length-offset>=4
059: * @effects returns the value of x[offset..offset+4] as an int,
060: * assuming x is interpreted as a signed little endian number (i.e.,
061: * x[offset] is LSB) If you want to interpret it as an unsigned number,
062: * call ubytes2int on the result.
063: */
064: public static int leb2int(byte[] x, int offset) {
065: //Must mask value after left-shifting, since case from byte
066: //to int copies most significant bit to the left!
067: int x0 = x[offset] & UNSIGNED_BYTE_MASK;
068: int x1 = (x[offset + 1] << 8) & 0x0000FF00;
069: int x2 = (x[offset + 2] << 16) & 0x00FF0000;
070: int x3 = (x[offset + 3] << 24);
071: return x3 | x2 | x1 | x0;
072: }
073:
074: /**
075: * Short to little-endian bytes: writes x to buf[offset...]
076: */
077: public static void short2leb(short x, byte[] buf, int offset) {
078: buf[offset] = (byte) (x & (short) 0x00FF);
079: buf[offset + 1] = (byte) ((short) (x >> 8) & (short) 0x00FF);
080: }
081:
082: /**
083: * Int to little-endian bytes: writes x to buf[offset..]
084: */
085: public static void int2leb(int x, byte[] buf, int offset) {
086: buf[offset] = (byte) (x & UNSIGNED_BYTE_MASK);
087: buf[offset + 1] = (byte) ((x >> 8) & UNSIGNED_BYTE_MASK);
088: buf[offset + 2] = (byte) ((x >> 16) & UNSIGNED_BYTE_MASK);
089: buf[offset + 3] = (byte) ((x >> 24) & UNSIGNED_BYTE_MASK);
090: }
091:
092: /**
093: * Interprets the value of x as an unsigned byte, and returns
094: * it as integer. For example, ubyte2int(0xFF)==255, not -1.
095: */
096: public static int ubyte2int(byte x) {
097: return ((int) x) & UNSIGNED_BYTE_MASK;
098: }
099:
100: /**
101: * Interprets the value of x as am unsigned two-byte number
102: */
103: public static int ubytes2int(short x) {
104: return ((int) x) & 0x0000FFFF;
105: }
106:
107: /**
108: * Interprets the value of x as an unsigned two-byte number
109: */
110: public static long ubytes2long(int x) {
111: return ((long) x) & 0x00000000FFFFFFFFl;
112: }
113:
114: /**
115: * Returns the int value that is closest to l. That is, if l can fit into a
116: * 32-bit unsigned number, returns (int)l. Otherwise, returns either
117: * Integer.MAX_VALUE or Integer.MIN_VALUE as appropriate.
118: */
119: public static int long2int(long l) {
120: if (l >= Integer.MAX_VALUE) {
121: return Integer.MAX_VALUE;
122: } else if (l <= Integer.MIN_VALUE) {
123: return Integer.MIN_VALUE;
124: } else {
125: return (int) l;
126: }
127: }
128:
129: /** Unit test */
130: /*
131: public static void main(String args[]) {
132: byte[] x1={(byte)0x2, (byte)0x1}; //{x1[0], x1[1]}
133: short result1=leb2short(x1,0);
134: Assert.that(result1==(short)258, "result1="+result1 ); //256+2;
135: byte[] x1b=new byte[2];
136: short2leb(result1, x1b, 0);
137: for (int i=0; i<2; i++)
138: Assert.that(x1b[i]==x1[i]);
139:
140: byte[] x2={(byte)0x2, (byte)0, (byte)0, (byte)0x1};
141: //2^24+2 = 16777216+2 = 16777218
142: int result2=leb2int(x2,0);
143: Assert.that(result2==16777218, "result2="+result2);
144:
145: byte[] x2b=new byte[4];
146: int2leb(result2, x2b, 0);
147: for (int i=0; i<4; i++)
148: Assert.that(x2b[i]==x2[i]);
149:
150: byte[] x3={(byte)0x00, (byte)0xF3, (byte)0, (byte)0xFF};
151: int result3=leb2int(x3,0);
152: Assert.that(result3==0xFF00F300, Integer.toHexString(result3));
153:
154: byte[] x4={(byte)0xFF, (byte)0xF3};
155: short result4=leb2short(x4,0);
156: Assert.that(result4==(short)0xF3FF, Integer.toHexString(result4));
157:
158: byte in=(byte)0xFF; //255 if unsigned, -1 if signed.
159: int out=(int)in;
160: Assert.that(out==-1, out+"");
161: out=ubyte2int(in);
162: Assert.that(out==255, out+"");
163: out=ubyte2int((byte)1);
164: Assert.that(out==1, out+"");
165:
166: short in2=(short)0xFFFF;
167: Assert.that(in2<0,"L122");
168: Assert.that(ubytes2int(in2)==0x0000FFFF, "L123");
169: Assert.that(ubytes2int(in2)>0, "L124");
170:
171: int in3=(int)0xFFFFFFFF;
172: Assert.that(in3<0, "L127");
173: Assert.that(ubytes2long(in3)==0x00000000FFFFFFFFl, "L128");
174: Assert.that(ubytes2long(in3)>0, "L129");
175:
176: byte[] buf={(byte)0xFF, (byte)0xFF};
177: in2=leb2short(buf,0);
178: Assert.that(in2==-1, "L133: "+Integer.toHexString(in2));
179: int out2=ubytes2int(in2);
180: Assert.that(out2==0x0000FFFF, "L134: "+out);
181:
182: byte[] buf2={(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF};
183: in3=leb2int(buf2,0);
184: Assert.that(in3==-1, "L139");
185: long out4=ubytes2long(in3);
186: Assert.that(out4==0x00000000FFFFFFFFl, "L141");
187:
188: Assert.that(long2int(5l)==5);
189: Assert.that(long2int(-10l)==-10);
190: Assert.that(long2int(0l)==0);
191: Assert.that(long2int(0xABFFFFFFFFl)==0x7FFFFFFF); //Integer.MAX_VALUE
192: Assert.that(long2int(-0xABFFFFFFFFl)==0x80000000); //Integer.MIN_VALUE
193: }
194: */
195: }
|