// Copyright 1997 The Open Group Research Institute.  All rights reserved.
// Copyright 1999 Memesoft.  All rights reserved.

package krb5.lib.util;

import java.io.*;

/**
 * File buffer
 */
public class FileBuf {

	/**
	 * Offset
	 */
    int offset;

	/**
	 * Length
	 */
    int length;

	/**
	 * Buffer
	 */
    byte buf[];

	/**
	 * Class constructor
	 *
	 * @param b is of type byte[]
	 * @param o is of type int
	 * @param l is of type int
	 * @exception IOException an exception
	 * @see java.io.IOException
	 */
	public FileBuf(byte b[], int o, int l) throws IOException {
	    buf = b;
	    offset = o;
	    length = l;
	    if (offset > buf.length || offset < 0)
	        throw new IOException();
	}

	/**
	 * Class constructor
	 *
	 * @param b is of type byte[]
	 */
	public FileBuf(byte b[]) {
	    buf = b;
	    offset = 0;
	    length = buf.length;
	}

	/**
	 * Returns long
	 *
	 * @return long is a result
	 * @exception IOException an exception
	 * @see java.io.IOException
	 */
	public long getLong() throws IOException {
	    long result = 0;
	    if (offset + 8 > length)
	        throw new IOException();
	    result = (long)buf[offset] << 56 |
	             (((long)buf[offset + 1] << 48) & 0x00ff000000000000L) |
	             (((long)buf[offset + 2] << 40) & 0x0000ff0000000000L) |
	             (((long)buf[offset + 3] << 32) & 0x000000ff00000000L) |
	             (((long)buf[offset + 4] << 24) & 0x00000000ff000000L) |
	             (((long)buf[offset + 5] << 16) & 0x0000000000ff0000L) |
	             (((long)buf[offset + 6] << 8 ) & 0x000000000000ff00L) |
	              ((long)buf[offset + 7]        & 0x00000000000000ffL);
	    offset += 8;
	    return result;
	}

	/**
	 * Returns int
	 *
	 * @return int is a result
	 * @exception IOException an exception
	 * @see java.io.IOException
	 */
	public int getInt() throws IOException {
	    int result = 0;
	    if (offset + 4 > length)
	        throw new IOException();
	    result = buf[offset] << 24 |
	             ((buf[offset + 1] << 16) & 0x00ff0000) |
	             ((buf[offset + 2] << 8 ) & 0x0000ff00) |
	              (buf[offset + 3]        & 0x000000ff);
	    offset += 4;
	    return result;
	}

	/**
	 * Returns short
	 *
	 * @return short is a result
	 * @exception IOException an exception
	 * @see java.io.IOException
	 */
	public short getShort() throws IOException {
	    short result = 0;
	    if (offset + 2 > length)
	        throw new IOException();
	    result = (short)(buf[offset] << 8 |
	             (buf[offset + 1] & 0x00ff));
	    offset += 2;
	    return result;
	}

	/**
	 * Returns byte
	 *
	 * @return byte is a result
	 * @exception IOException an exception
	 * @see java.io.IOException
	 */
	public byte getByte() throws IOException {
	    byte result = 0;
	    if (offset + 1 > length)
	        throw new IOException();
	    result = buf[offset];
	    offset += 1;
	    return result;
	}

	/**
	 * Returns bytes
	 *
	 * @return byte[] is a result
	 * @param len is of type int
	 * @exception IOException an exception
	 * @see java.io.IOException
	 */
	public byte[] getBytes(int len) throws IOException {
	    if (offset + len > length)
	        throw new IOException();
	    byte result[] = new byte[len];
	    System.arraycopy(buf, offset, result, 0, len);
	    offset += len;
	    return result;
	}

	/**
	 * Returns string
	 *
	 * @return String is a result
	 * @param len is of type int
	 * @exception IOException an exception
	 * @see java.io.IOException
	 */
	public String getString(int len) throws IOException {
	    return new String(getBytes(len), 0);
	}

	/**
	 * Returns string
	 *
	 * @return String is a result
	 * @exception IOException an exception
	 * @see java.io.IOException
	 */
	public String getString() throws IOException {
	    int len = 0;
	    while (offset + len < length && buf[offset + len] != 0)
	        ++len;
	    if (len > 0 && offset + len == length && buf[offset + len - 1] != 0)
	        throw new IOException();
	    return getString(len);
	}

	/**
	 * Returns offset
	 *
	 * @return int is a result
	 */
	public int getOffset() {
	    return offset;
	}

	/**
	 * Returns length
	 *
	 * @return int is a result
	 */
	public int getLength() {
	    return length;
	}

	/**
	 * Returns buffer
	 *
	 * @return byte[] is a result
	 */
	public byte[] getBuf() {
	    return buf;
	}

	/**
	 * Checks whether it is end of buffer
	 *
	 * @return boolean is a result
	 */
	public boolean endOfBuf() {
	    return offset >= buf.length;
	}

	/**
	 * Initialization
	 */
	static byte a[] = {
	    (byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, 
	    (byte)0x08, (byte)0x09, (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, 
	    (byte)0x10, (byte)0x11, (byte)0x12, (byte)0x13, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, 
	    (byte)0x58, (byte)0x59, (byte)0x5a, (byte)0x5b, (byte)0x5c, (byte)0x5d, (byte)0x5e, (byte)0x00
	};

	/**
	 * Main
	 *
	 * @param args is of type String[]
	 */
	public static void main(String args[]) {
	    try {
	        FileBuf f = new FileBuf(a);
	        long x1 = f.getLong();
	        int t1 = (int)(x1 >>> 32);
	        System.out.println(Integer.toHexString(t1));
	        int t2 = (int)(x1 & 0x00000000ffffffffL);
	        System.out.println(Integer.toHexString(t2));
	        int x2 = f.getInt();
	        short x3 = f.getShort();
	        byte x4 = f.getByte();
	        byte x5[] = f.getBytes(5);
	        String x6 = f.getString(4);
	        String x7 = f.getString();
	    } catch(IOException e) {
	        e.printStackTrace();
	    }
	}
}