2 * Copyright (C) 2007 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.dx.util;
20 * Utilities for parsing hexadecimal text.
22 public final class HexParser {
24 * This class is uninstantiable.
27 // This space intentionally left blank.
31 * Parses the given text as hex, returning a {@code byte[]}
32 * corresponding to the text. The format is simple: Each line may
33 * start with a hex offset followed by a colon (which is verified
34 * and presumably used just as a comment), and then consists of
35 * hex digits freely interspersed with whitespace. If a pound sign
36 * is encountered, it and the rest of the line are ignored as a
37 * comment. If a double quote is encountered, then the ASCII value
38 * of the subsequent characters is used, until the next double
39 * quote. Quoted strings may not span multiple lines.
41 * @param src {@code non-null;} the source string
42 * @return {@code non-null;} the parsed form
44 public static byte[] parse(String src) {
45 int len = src.length();
46 byte[] result = new byte[len / 2];
51 int nlAt = src.indexOf('\n', at);
55 int poundAt = src.indexOf('#', at);
58 if ((poundAt >= 0) && (poundAt < nlAt)) {
59 line = src.substring(at, poundAt);
61 line = src.substring(at, nlAt);
65 int colonAt = line.indexOf(':');
69 int quoteAt = line.indexOf('\"');
70 if ((quoteAt != -1) && (quoteAt < colonAt)) {
74 String atStr = line.substring(0, colonAt).trim();
75 line = line.substring(colonAt + 1);
76 int alleged = Integer.parseInt(atStr, 16);
77 if (alleged != outAt) {
78 throw new RuntimeException("bogus offset marker: " +
83 int lineLen = line.length();
85 boolean quoteMode = false;
87 for (int i = 0; i < lineLen; i++) {
88 char c = line.charAt(i);
94 result[outAt] = (byte) c;
105 throw new RuntimeException("spare digit around " +
106 "offset " + Hex.u4(outAt));
112 int digVal = Character.digit(c, 16);
114 throw new RuntimeException("bogus digit character: \"" +
120 result[outAt] = (byte) ((value << 4) | digVal);
127 throw new RuntimeException("spare digit around offset " +
132 throw new RuntimeException("unterminated quote around " +
133 "offset " + Hex.u4(outAt));
137 if (outAt < result.length) {
138 byte[] newr = new byte[outAt];
139 System.arraycopy(result, 0, newr, 0, outAt);