FileDocCategorySizeDatePackage
HexParser.javaAPI DocAndroid 5.1 API4835Thu Mar 12 22:18:30 GMT 2015com.android.dx.util

HexParser

public final class HexParser extends Object
Utilities for parsing hexadecimal text.

Fields Summary
Constructors Summary
private HexParser()
This class is uninstantiable.

        // This space intentionally left blank.
    
Methods Summary
public static byte[]parse(java.lang.String src)
Parses the given text as hex, returning a {@code byte[]} corresponding to the text. The format is simple: Each line may start with a hex offset followed by a colon (which is verified and presumably used just as a comment), and then consists of hex digits freely interspersed with whitespace. If a pound sign is encountered, it and the rest of the line are ignored as a comment. If a double quote is encountered, then the ASCII value of the subsequent characters is used, until the next double quote. Quoted strings may not span multiple lines.

param
src {@code non-null;} the source string
return
{@code non-null;} the parsed form

        int len = src.length();
        byte[] result = new byte[len / 2];
        int at = 0;
        int outAt = 0;

        while (at < len) {
            int nlAt = src.indexOf('\n", at);
            if (nlAt < 0) {
                nlAt = len;
            }
            int poundAt = src.indexOf('#", at);

            String line;
            if ((poundAt >= 0) && (poundAt < nlAt)) {
                line = src.substring(at, poundAt);
            } else {
                line = src.substring(at, nlAt);
            }
            at = nlAt + 1;

            int colonAt = line.indexOf(':");

            atCheck:
            if (colonAt != -1) {
                int quoteAt = line.indexOf('\"");
                if ((quoteAt != -1) && (quoteAt < colonAt)) {
                    break atCheck;
                }

                String atStr = line.substring(0, colonAt).trim();
                line = line.substring(colonAt + 1);
                int alleged = Integer.parseInt(atStr, 16);
                if (alleged != outAt) {
                    throw new RuntimeException("bogus offset marker: " +
                                               atStr);
                }
            }

            int lineLen = line.length();
            int value = -1;
            boolean quoteMode = false;

            for (int i = 0; i < lineLen; i++) {
                char c = line.charAt(i);

                if (quoteMode) {
                    if (c == '\"") {
                        quoteMode = false;
                    } else {
                        result[outAt] = (byte) c;
                        outAt++;
                    }
                    continue;
                }

                if (c <= ' ") {
                    continue;
                }
                if (c == '\"") {
                    if (value != -1) {
                        throw new RuntimeException("spare digit around " +
                                                   "offset " + Hex.u4(outAt));
                    }
                    quoteMode = true;
                    continue;
                }

                int digVal = Character.digit(c, 16);
                if (digVal == -1) {
                    throw new RuntimeException("bogus digit character: \"" +
                                               c + "\"");
                }
                if (value == -1) {
                    value = digVal;
                } else {
                    result[outAt] = (byte) ((value << 4) | digVal);
                    outAt++;
                    value = -1;
                }
            }

            if (value != -1) {
                throw new RuntimeException("spare digit around offset " +
                                           Hex.u4(outAt));
            }

            if (quoteMode) {
                throw new RuntimeException("unterminated quote around " +
                                           "offset " + Hex.u4(outAt));
            }
        }

        if (outAt < result.length) {
            byte[] newr = new byte[outAt];
            System.arraycopy(result, 0, newr, 0, outAt);
            result = newr;
        }

        return result;