/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dx.util;

/**
 * Utilities for parsing hexadecimal text.
 */
public final class HexParser {
    /**
     * This class is uninstantiable.
     */
    private HexParser() {
        // This space intentionally left blank.
    }

    /**
     * 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
     */
    public static byte[] parse(String src) {
        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;
    }
}
