1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.util;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Utilities for formatting numbers as hexadecimal.
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class Hex {
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This class is uninstantiable.
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Hex() {
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // This space intentionally left blank.
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
3199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats a {@code long} as an 8-byte unsigned hex value.
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
3499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String u8(long v) {
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[16];
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < 16; i++) {
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[15 - i] = Character.forDigit((int) v & 0x0f, 16);
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v >>= 4;
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats an {@code int} as a 4-byte unsigned hex value.
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String u4(int v) {
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[8];
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < 8; i++) {
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[7 - i] = Character.forDigit(v & 0x0f, 16);
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v >>= 4;
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
6399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats an {@code int} as a 3-byte unsigned hex value.
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String u3(int v) {
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[6];
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < 6; i++) {
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[5 - i] = Character.forDigit(v & 0x0f, 16);
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v >>= 4;
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats an {@code int} as a 2-byte unsigned hex value.
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String u2(int v) {
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[4];
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < 4; i++) {
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[3 - i] = Character.forDigit(v & 0x0f, 16);
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v >>= 4;
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
9599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats an {@code int} as either a 2-byte unsigned hex value
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * (if the value is small enough) or a 4-byte unsigned hex value (if
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * not).
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
10099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String u2or4(int v) {
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (v == (char) v) {
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return u2(v);
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return u4(v);
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
11199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats an {@code int} as a 1-byte unsigned hex value.
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String u1(int v) {
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[2];
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < 2; i++) {
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[1 - i] = Character.forDigit(v & 0x0f, 16);
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v >>= 4;
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
12799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats an {@code int} as a 4-bit unsigned hex nibble.
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
13099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String uNibble(int v) {
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[1];
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result[0] = Character.forDigit(v & 0x0f, 16);
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
14099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats a {@code long} as an 8-byte signed hex value.
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
14399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String s8(long v) {
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[17];
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (v < 0) {
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[0] = '-';
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v = -v;
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[0] = '+';
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < 16; i++) {
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[16 - i] = Character.forDigit((int) v & 0x0f, 16);
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v >>= 4;
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
16499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats an {@code int} as a 4-byte signed hex value.
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
16799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String s4(int v) {
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[9];
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (v < 0) {
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[0] = '-';
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v = -v;
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[0] = '+';
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < 8; i++) {
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[8 - i] = Character.forDigit(v & 0x0f, 16);
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v >>= 4;
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
18899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats an {@code int} as a 2-byte signed hex value.
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
19199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String s2(int v) {
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[5];
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (v < 0) {
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[0] = '-';
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v = -v;
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[0] = '+';
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < 4; i++) {
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[4 - i] = Character.forDigit(v & 0x0f, 16);
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v >>= 4;
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
21299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats an {@code int} as a 1-byte signed hex value.
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param v value to format
21599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} formatted form
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String s1(int v) {
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char[] result = new char[3];
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (v < 0) {
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[0] = '-';
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v = -v;
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[0] = '+';
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < 2; i++) {
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[2 - i] = Character.forDigit(v & 0x0f, 16);
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            v >>= 4;
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(result);
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
23699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Formats a hex dump of a portion of a {@code byte[]}. The result
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is always newline-terminated, unless the passed-in length was zero,
23899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * in which case the result is always the empty string ({@code ""}).
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
24099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param arr {@code non-null;} array to format
24199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param offset {@code >= 0;} offset to the part to dump
24299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param length {@code >= 0;} number of bytes to dump
24399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param outOffset {@code >= 0;} first output offset to print
24499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param bpl {@code >= 0;} number of bytes of output per line
24599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param addressLength {@code {2,4,6,8};} number of characters for each address
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * header
24799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} a string of the dump
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String dump(byte[] arr, int offset, int length,
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                              int outOffset, int bpl, int addressLength) {
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int end = offset + length;
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (((offset | length | end) < 0) || (end > arr.length)) {
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IndexOutOfBoundsException("arr.length " +
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                                arr.length + "; " +
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                                offset + "..!" + end);
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (outOffset < 0) {
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("outOffset < 0");
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (length == 0) {
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "";
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringBuffer sb = new StringBuffer(length * 4 + 6);
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean bol = true;
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int col = 0;
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (length > 0) {
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (col == 0) {
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String astr;
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                switch (addressLength) {
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    case 2:  astr = Hex.u1(outOffset); break;
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    case 4:  astr = Hex.u2(outOffset); break;
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    case 6:  astr = Hex.u3(outOffset); break;
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    default: astr = Hex.u4(outOffset); break;
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sb.append(astr);
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sb.append(": ");
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else if ((col & 1) == 0) {
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sb.append(' ');
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(Hex.u1(arr[offset]));
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            outOffset++;
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            offset++;
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            col++;
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (col == bpl) {
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sb.append('\n');
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                col = 0;
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            length--;
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (col != 0) {
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append('\n');
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sb.toString();
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
304