1/*
2 * [The "BSD licence"]
3 * Copyright (c) 2010 Ben Gruver (JesusFreke)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. 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 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29package org.jf.dexlib.Util;
30
31public class NumberUtils {
32
33    /**
34     * Decodes the high signed 4-bit nibble from the given byte
35     * @param b the byte to decode
36     * @return the decoded signed nibble
37     */
38    public static byte decodeHighSignedNibble(byte b) {
39        return (byte)(b >> 4);
40    }
41
42    /**
43     * Decodes the low signed 4-bit nibble from the given byte
44     * @param b the byte to decode
45     * @return the decoded signed nibble
46     */
47    public static byte decodeLowSignedNibble(byte b) {
48        return (byte)(((byte)(b << 4)) >> 4);
49    }
50
51    /**
52     * Decodes the high unsigned 4-bit nibble from the given byte
53     * @param b the byte to decode
54     * @return the decoded unsigned nibble
55     */
56    public static byte decodeHighUnsignedNibble(byte b) {
57        return (byte)((b & 0xFF) >>> 4);
58    }
59
60    /**
61     * Decodes the low unsigned 4-bit nibble from the given byte
62     * @param b the byte to decode
63     * @return the decoded unsigned nibble
64     */
65    public static byte decodeLowUnsignedNibble(byte b) {
66        return (byte)(b & 0x0F);
67    }
68
69    /**
70     * Decodes an unsigned byte from a signed byte
71     * @param b the signed byte to decode
72     * @return the decoded unsigned byte as a short
73     */
74    public static short decodeUnsignedByte(byte b) {
75        return (short)(b & 0xFF);
76    }
77
78    /**
79     * Decodes a signed short value from 2 individual bytes
80     * The parameters are in order from least significant byte to most significant byte
81     * @param lsb the least significant byte
82     * @param msb the most significant byte
83     * @return the decoded signed short value
84     */
85    public static short decodeShort(byte lsb, byte msb) {
86        return (short)
87               (    (lsb & 0xFF) |
88                    (msb << 8)
89               );
90    }
91
92    /**
93     * Decodes a signed short value in little endian format from the given byte array at the given index.
94     * @param bytes the byte array
95     * @param index the index of the first byte of the signed short value to decode
96     * @return the decoded signed short value
97     */
98    public static short decodeShort(byte[] bytes, int index) {
99        return (short)
100               (    (bytes[index++] & 0xFF) |
101                    (bytes[index] << 8)
102               );
103    }
104
105    /**
106     * Decodes an unsigned short value from 2 individual bytes
107     * The parameters are in order from least significant byte to most significant byte
108     * @param lsb the least significant byte
109     * @param msb the most significant byte
110     * @return the decoded unsigned short value as an int
111     */
112    public static int decodeUnsignedShort(byte lsb, byte msb) {
113        return  (   (lsb & 0xFF) |
114                    ((msb & 0xFF) << 8)
115                );
116    }
117
118    /**
119     * Decodes an unsigned short value in little endian format from the given byte array at the given index.
120     * @param bytes the byte array
121     * @param index the index of the first byte of the unsigned short value to decode
122     * @return the decoded unsigned short value as an int
123     */
124    public static int decodeUnsignedShort(byte[] bytes, int index) {
125        return  (   (bytes[index++] & 0xFF) |
126                    ((bytes[index] & 0xFF) << 8)
127                );
128    }
129
130    /**
131     * Decodes a signed integer value from 4 individual bytes
132     * The parameters are in order from least significant byte to most significant byte
133     * @param lsb the least significant byte
134     * @param mlsb the middle least significant byte
135     * @param mmsb the middle most significant byte
136     * @param msb the most significant byte
137     * @return the decoded signed integer value
138     */
139    public static int decodeInt(byte lsb, byte mlsb, byte mmsb, byte msb) {
140        return (lsb & 0xFF) |
141               ((mlsb & 0xFF) << 8) |
142               ((mmsb & 0xFF) << 16) |
143               (msb << 24);
144    }
145
146    /**
147     * Decodes a signed integer value in little endian format from the given byte array at the given index.
148     * @param bytes the byte array
149     * @param index the index of the first byte of the signed integer value to decode
150     * @return the decoded signed integer value
151     */
152    public static int decodeInt(byte[] bytes, int index) {
153        return (bytes[index++]  & 0xFF) |
154               ((bytes[index++] & 0xFF) << 8) |
155               ((bytes[index++] & 0xFF) << 16) |
156               (bytes[index] << 24);
157    }
158
159    /**
160     * Decodes a signed long value from 8 individual bytes
161     * The parameters are in order from least significant byte to most significant byte
162     * @param llsb the lower least significant byte
163     * @param lmlsb the lower middle least significant byte
164     * @param lmmsb the lower middle most significant byte
165     * @param lgsb the lower greater significant byte
166     * @param glsb the greater least significant byte
167     * @param gmlsb the greater middle least significant byte
168     * @param gmmsb the greater middle most significant byte
169     * @param gmsb the greater most significant byte
170     * @return the decoded signed long value
171     */
172    public static long decodeLong(byte llsb, byte lmlsb, byte lmmsb, byte lgsb, byte glsb, byte gmlsb, byte gmmsb,
173                                  byte gmsb) {
174        return  (llsb   & 0xFFL) |
175                ((lmlsb & 0xFFL) << 8) |
176                ((lmmsb & 0xFFL) << 16) |
177                ((lgsb  & 0xFFL) << 24) |
178                ((glsb  & 0xFFL) << 32) |
179                ((gmlsb & 0xFFL) << 40) |
180                ((gmmsb & 0xFFL) << 48) |
181                (((long)gmsb) << 56);
182    }
183
184    /**
185     * Decodes a signed long value in little endian format from the given byte array at the given index.
186     * @param bytes the byte array
187     * @param index the index of the first byte of the signed long value to decode
188     * @return the decoded signed long value
189     */
190    public static long decodeLong(byte[] bytes, int index) {
191        return  (bytes[index++] & 0xFFL) |
192                ((bytes[index++] & 0xFFL) << 8) |
193                ((bytes[index++] & 0xFFL) << 16) |
194                ((bytes[index++] & 0xFFL) << 24) |
195                ((bytes[index++] & 0xFFL) << 32) |
196                ((bytes[index++] & 0xFFL) << 40) |
197                ((bytes[index++] & 0xFFL) << 48) |
198                (((long)bytes[index]) << 56);
199    }
200}
201