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 EncodedValueUtils {
32    public static byte getRequiredBytesForSignedIntegralValue(long value) {
33        /*
34         * Figure out how many bits are needed to represent the value,
35         * including a sign bit: The bit count is subtracted from 65
36         * and not 64 to account for the sign bit. The xor operation
37         * has the effect of leaving non-negative values alone and
38         * unary complementing negative values (so that a leading zero
39         * count always returns a useful number for our present
40         * purpose).
41         */
42        int requiredBits =
43            65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
44
45        // Round up the requiredBits to a number of bytes.
46        return (byte)((requiredBits + 0x07) >> 3);
47    }
48
49    public static long decodeSignedIntegralValue(byte[] bytes) {
50        long value = 0;
51        for (int i = 0; i < bytes.length; i++) {
52            value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
53        }
54
55        int shift = (8 - bytes.length) * 8;
56        return  value << shift >> shift;
57    }
58
59    public static byte[] encodeSignedIntegralValue(long value) {
60        int requiredBytes = getRequiredBytesForSignedIntegralValue(value);
61
62        byte[] bytes = new byte[requiredBytes];
63
64        for (int i = 0; i < requiredBytes; i++) {
65            bytes[i] = (byte) value;
66            value >>= 8;
67        }
68        return bytes;
69    }
70
71
72
73
74
75    public static byte getRequiredBytesForUnsignedIntegralValue(long value) {
76        // Figure out how many bits are needed to represent the value.
77        int requiredBits = 64 - Long.numberOfLeadingZeros(value);
78        if (requiredBits == 0) {
79            requiredBits = 1;
80        }
81
82        // Round up the requiredBits to a number of bytes.
83        return (byte)((requiredBits + 0x07) >> 3);
84    }
85
86    public static long decodeUnsignedIntegralValue(byte[] bytes) {
87        long value = 0;
88        for (int i = 0; i < bytes.length; i++) {
89            value |= (((long)(bytes[i] & 0xFF)) << i * 8);
90        }
91        return value;
92    }
93
94    public static byte[] encodeUnsignedIntegralValue(long value) {
95        int requiredBytes = getRequiredBytesForUnsignedIntegralValue(value);
96
97        byte[] bytes = new byte[requiredBytes];
98
99        for (int i = 0; i < requiredBytes; i++) {
100            bytes[i] = (byte) value;
101            value >>= 8;
102        }
103        return bytes;
104    }
105
106
107
108
109
110    public static int getRequiredBytesForRightZeroExtendedValue(long value) {
111        // Figure out how many bits are needed to represent the value.
112        int requiredBits = 64 - Long.numberOfTrailingZeros(value);
113        if (requiredBits == 0) {
114            requiredBits = 1;
115        }
116
117        // Round up the requiredBits to a number of bytes.
118        return (requiredBits + 0x07) >> 3;
119    }
120
121    public static long decodeRightZeroExtendedValue(byte[] bytes) {
122        long value = 0;
123        for (int i = 0; i < bytes.length; i++) {
124            value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
125        }
126        return value << (8 - bytes.length) * 8;
127    }
128
129    public static byte[] encodeRightZeroExtendedValue(long value) {
130        int requiredBytes = getRequiredBytesForRightZeroExtendedValue(value);
131
132        // Scootch the first bits to be written down to the low-order bits.
133        value >>= 64 - (requiredBytes * 8);
134
135        byte[] bytes = new byte[requiredBytes];
136
137        for(int i = 0; i < requiredBytes; i++) {
138            bytes[i] = (byte)value;
139            value >>= 8;
140        }
141        return bytes;
142    }
143}
144