/*
 * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package ilib;

class ClassReaderWriter implements RuntimeConstants {

    int codeAttributeIndex;
    int lineNumberAttributeIndex;
    int localVarAttributeIndex;

    private final byte[] orig;
    private final byte[] gen;
    private final int sectionLength;

    private static final int GROWTH_FACTOR = 2;
    private static final int SECTIONS = 2;
    private static final String codeAttributeName = "Code";
    private static final String lineNumberAttributeName = "LineNumberTable";
    private static final String localVarAttributeName = "LocalVariableTable";

    private int[] genSectionPos = new int[SECTIONS];

    private int inputPos = 0;
    private int genPos = 0;
    private int markPos = 0;
    private int currentSection = 0;

    private String[] constantPool;

    ClassReaderWriter(byte[] orig) {
        this.orig = orig;
        sectionLength = orig.length * GROWTH_FACTOR;
        gen = new byte[sectionLength * SECTIONS];
        for (int section = 0; section < SECTIONS; ++section) {
            genSectionPos[section] = section * sectionLength;
        }
    }

    int setSection(int section) {
        int prevSection = currentSection;
        genSectionPos[prevSection] = genPos;
        genPos = genSectionPos[section];
        currentSection = section;
        return prevSection;
    }

    byte[] result() {
        int section;
        int totalLength = 0;

        setSection(0); // save current section

        for (section = 0; section < SECTIONS; ++section) {
            int sectionStart = section * sectionLength;
            int sectionGenLength = genSectionPos[section] - sectionStart;
            totalLength += sectionGenLength;
        }

        byte[] newcf = new byte[totalLength];
        int written = 0;
        for (section = 0; section < SECTIONS; ++section) {
            int sectionStart = section * sectionLength;
            int sectionGenLength = genSectionPos[section] - sectionStart;
            System.arraycopy(gen, sectionStart, newcf, written, sectionGenLength);
            written += sectionGenLength;
        }

        return newcf;
    }

    int readU1() {
        return ((int)orig[inputPos++]) & 0xFF;
    }

    int readU2() {
        int res = readU1();
        return (res << 8) + readU1();
    }

    short readS2() {
        int res = readU1();
        return (short)((res << 8) + readU1());
    }

    int readU4() {
        int res = readU2();
        return (res << 16) + readU2();
    }

    void writeU1(int val) {
        gen[genPos++] = (byte)val;
    }

    void writeU2(int val) {
        writeU1(val >> 8);
        writeU1(val & 0xFF);
    }

    void writeU4(int val) {
        writeU2(val >> 16);
        writeU2(val & 0xFFFF);
    }

    int copyU1() {
        int value = readU1();
        writeU1(value);
        return value;
    }

    int copyU2() {
        int value = readU2();
        writeU2(value);
        return value;
    }

    int copyU4() {
        int value = readU4();
        writeU4(value);
        return value;
    }

    void copy(int count) {
        for (int i = 0; i < count; ++i) {
            gen[genPos++] = orig[inputPos++];
        }
    }

    void skip(int count) {
        inputPos += count;
    }

    byte[] readBytes(int count) {
        byte[] bytes = new byte[count];
        for (int i = 0; i < count; ++i) {
            bytes[i] = orig[inputPos++];
        }
        return bytes;
    }

    void writeBytes(byte[] bytes) {
        for (int i = 0; i < bytes.length; ++i) {
            gen[genPos++] = bytes[i];
        }
    }

    byte[] inputBytes() {
        return orig;
    }

    int inputPosition() {
        return inputPos;
    }

    void setInputPosition(int pos) {
        inputPos = pos;
    }

    void markLocalPositionStart() {
        markPos = inputPos;
    }

    int localPosition() {
        return inputPos - markPos;
    }

    void rewind() {
        setInputPosition(markPos);
    }

    int generatedPosition() {
        return genPos;
    }

    void randomAccessWriteU2(int pos, int val) {
        int savePos = genPos;
        genPos = pos;
        writeU2(val);
        genPos = savePos;
    }

    void randomAccessWriteU4(int pos, int val) {
        int savePos = genPos;
        genPos = pos;
        writeU4(val);
        genPos = savePos;
    }

    String constantPoolString(int index) {
        return constantPool[index];
    }

    void copyConstantPool(int constantPoolCount){
        // copy const pool
        constantPool = new String[constantPoolCount];
        // index zero not in class file
        for (int i = 1; i < constantPoolCount; ++i) {
            int tag = readU1();
            writeU1(tag);
            switch (tag) {
                case CONSTANT_CLASS:
                case CONSTANT_STRING:
                    copy(2);
                    break;
                case CONSTANT_FIELD:
                case CONSTANT_METHOD:
                case CONSTANT_INTERFACEMETHOD:
                case CONSTANT_INTEGER:
                case CONSTANT_FLOAT:
                case CONSTANT_NAMEANDTYPE:
                    copy(4);
                    break;
                case CONSTANT_LONG:
                case CONSTANT_DOUBLE:
                    copy(8);
                    ++i;  // these take two CP entries - duh!
                    break;
                case CONSTANT_UTF8:
                    int len = copyU2();
                    byte[] utf8 = readBytes(len);
                    String str = null; // null to shut the compiler up
                    try {
                        str = new String(utf8, "UTF-8");
                    } catch (Exception exc) {
                        throw new Error("CP exception: " + exc);
                    }
                    constantPool[i] = str;
                    if (str.equals(codeAttributeName)) {
                        codeAttributeIndex = i;
                    } else if (str.equals(lineNumberAttributeName)) {
                        lineNumberAttributeIndex = i;
                    } else if (str.equals(localVarAttributeName)) {
                        localVarAttributeIndex = i;
                    }
                    writeBytes(utf8);
                    break;
                default:
                    throw new Error(i + " unexpected CP tag: " + tag);
            }
        }
    }

}
