/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.internal.core.index.impl;

import java.io.UTFDataFormatException;

public class Field {
	protected byte[] buffer; // contents
	protected int offset; // offset of the field within the byte array
	protected int length; // length of the field

	/**
	 * ByteSegment constructor comment.
	 */
	public Field(byte[] bytes) {
		this.buffer= bytes;
		this.offset= 0;
		this.length= bytes.length;
	}
	/**
	 * ByteSegment constructor comment.
	 */
	public Field(byte[] bytes, int length) {
		this.buffer= bytes;
		this.offset= 0;
		this.length= length;
	}
	/**
	 * ByteSegment constructor comment.
	 */
	public Field(byte[] bytes, int offset, int length) {
		this.buffer= bytes;
		this.offset= offset;
		this.length= length;
	}
	/**
	 * Creates a new field containing an empty buffer of the given length.
	 */
	public Field(int length) {
		this.buffer= new byte[length];
		this.offset= 0;
		this.length= length;
	}
	public byte[] buffer() {
		return buffer;
	}
	public Field buffer(byte[] buffer) {
		this.buffer= buffer;
		return this;
	}
	public Field clear() {
		clear(buffer, offset, length);
		return this;
	}
	protected static void clear(byte[] buffer, int offset, int length) {
		int n= offset;
		for (int i= 0; i < length; i++) {
			buffer[n]= 0;
			n++;
		}
	}
	public Field clear(int length) {
		clear(buffer, offset, length);
		return this;
	}
	public Field clear(int offset, int length) {
		clear(buffer, this.offset + offset, length);
		return this;
	}
	protected static int compare(byte[] buffer1, int offset1, int length1, byte[] buffer2, int offset2, int length2) {
		int n= Math.min(length1, length2);
		for (int i= 0; i < n; i++) {
			int j1= buffer1[offset1 + i] & 255;
			int j2= buffer2[offset2 + i] & 255;
			if (j1 > j2)
				return 1;
			if (j1 < j2)
				return -1;
		}
		if (length1 > n) {
			for (int i= n; i < length1; i++)
				if (buffer1[offset1 + i] != 0)
					return 1;
			return 0;
		}
		for (int i= n; i < length2; i++)
			if (buffer2[offset2 + i] != 0)
				return -1;
		return 0;
	}
	public static int compare(Field f1, Field f2) {
		return compare(f1.buffer, f1.offset, f1.length, f2.buffer, f2.offset, f2.length);
	}
	// copy bytes from one offset to another within the field
	public Field copy(int fromOffset, int toOffset, int length) {
		System.arraycopy(buffer, offset + fromOffset, buffer, offset + toOffset, length);
		return this;
	}
	public Field dec(int n) {
		offset -= n;
		return this;
	}
	public byte[] get() {
		byte[] result= new byte[length];
		System.arraycopy(buffer, offset, result, 0, length);
		return result;
	}
	public byte[] get(int offset, int length) {
		byte[] result= new byte[length];
		System.arraycopy(buffer, this.offset + offset, result, 0, length);
		return result;
	}
	public Field getField(int offset, int length) {
		return new Field(buffer, this.offset + offset, length);
	}
	public int getInt1() {
		return buffer[this.offset];
	}
	public int getInt1(int offset) {
		return buffer[this.offset + offset];
	}
	public int getInt2() {
		int i= this.offset;
		int v= buffer[i++];
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public int getInt2(int offset) {
		int i= this.offset + offset;
		int v= buffer[i++];
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public int getInt3() {
		int i= this.offset;
		int v= buffer[i++];
		v= (v << 8) | (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public int getInt3(int offset) {
		int i= this.offset + offset;
		int v= buffer[i++];
		v= (v << 8) | (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public int getInt4() {
		int i= this.offset;
		int v= buffer[i++];
		v= (v << 8) | (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public int getInt4(int offset) {
		int i= this.offset + offset;
		int v= buffer[i++];
		v= (v << 8) | (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public int getUInt1() {
		return buffer[this.offset] & 255;
	}
	public int getUInt1(int offset) {
		return buffer[this.offset + offset] & 255;
	}
	public int getUInt2() {
		int i= this.offset;
		int v= (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public int getUInt2(int offset) {
		int i= this.offset + offset;
		int v= (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public int getUInt3() {
		int i= this.offset;
		int v= (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public int getUInt3(int offset) {
		int i= this.offset + offset;
		int v= (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		v= (v << 8) | (buffer[i++] & 255);
		return v;
	}
	public char[] getUTF(int offset) throws UTFDataFormatException {
		int pos= this.offset + offset;
		int utflen= getUInt2(pos);
		pos += 2;
		char str[]= new char[utflen];
		int count= 0;
		int strlen= 0;
		while (count < utflen) {
			int c= buffer[pos++] & 0xFF;
			int char2, char3;
			switch (c >> 4) {
				case 0 :
				case 1 :
				case 2 :
				case 3 :
				case 4 :
				case 5 :
				case 6 :
				case 7 :
					// 0xxxxxxx
					count++;
					str[strlen++]= (char) c;
					break;
				case 12 :
				case 13 :
					// 110x xxxx   10xx xxxx
					count += 2;
					if (count > utflen)
						throw new UTFDataFormatException();
					char2= buffer[pos++] & 0xFF;
					if ((char2 & 0xC0) != 0x80)
						throw new UTFDataFormatException();
					str[strlen++]= (char) (((c & 0x1F) << 6) | (char2 & 0x3F));
					break;
				case 14 :
					// 1110 xxxx  10xx xxxx  10xx xxxx
					count += 3;
					if (count > utflen)
						throw new UTFDataFormatException();
					char2= buffer[pos++] & 0xFF;
					char3= buffer[pos++] & 0xFF;
					if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
						throw new UTFDataFormatException();
					str[strlen++]= (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
					break;
				default :
					// 10xx xxxx,  1111 xxxx
					throw new UTFDataFormatException();
			}
		}
		if (strlen < utflen)
			System.arraycopy(str, 0, str= new char[strlen], 0, strlen);
		return str;
	}
	public Field inc(int n) {
		offset += n;
		return this;
	}
	public int length() {
		return length;
	}
	public Field length(int length) {
		this.length= length;
		return this;
	}
	/**
	Returns the offset into the underlying byte array that this field is defined over.
	*/
	public int offset() {
		return offset;
	}
	public Field offset(int offset) {
		this.offset= offset;
		return this;
	}
	public Field pointTo(int offset) {
		return new Field(buffer, this.offset + offset, 0);
	}
	public Field put(byte[] b) {
		return put(0, b);
	}
	public Field put(int offset, byte[] b) {
		System.arraycopy(b, 0, buffer, this.offset + offset, b.length);
		return this;
	}
	public Field put(int offset, Field f) {
		System.arraycopy(f.buffer, f.offset, buffer, this.offset + offset, f.length);
		return this;
	}
	public Field put(Field f) {
		System.arraycopy(f.buffer, f.offset, buffer, offset, f.length);
		return this;
	}
	public Field putInt1(int n) {
		buffer[offset]= (byte) (n);
		return this;
	}
	public Field putInt1(int offset, int n) {
		buffer[this.offset + offset]= (byte) (n);
		return this;
	}
	public Field putInt2(int n) {
		int i= offset;
		buffer[i++]= (byte) (n >> 8);
		buffer[i++]= (byte) (n >> 0);
		return this;
	}
	public Field putInt2(int offset, int n) {
		int i= this.offset + offset;
		buffer[i++]= (byte) (n >> 8);
		buffer[i++]= (byte) (n >> 0);
		return this;
	}
	public Field putInt3(int n) {
		int i= offset;
		buffer[i++]= (byte) (n >> 16);
		buffer[i++]= (byte) (n >> 8);
		buffer[i++]= (byte) (n >> 0);
		return this;
	}
	public Field putInt3(int offset, int n) {
		int i= this.offset + offset;
		buffer[i++]= (byte) (n >> 16);
		buffer[i++]= (byte) (n >> 8);
		buffer[i++]= (byte) (n >> 0);
		return this;
	}
	public Field putInt4(int n) {
		int i= offset;
		buffer[i++]= (byte) (n >> 24);
		buffer[i++]= (byte) (n >> 16);
		buffer[i++]= (byte) (n >> 8);
		buffer[i++]= (byte) (n >> 0);
		return this;
	}
	public Field putInt4(int offset, int n) {
		int i= this.offset + offset;
		buffer[i++]= (byte) (n >> 24);
		buffer[i++]= (byte) (n >> 16);
		buffer[i++]= (byte) (n >> 8);
		buffer[i++]= (byte) (n >> 0);
		return this;
	}
	public int putUTF(int offset, char[] str) {
		int strlen= str.length;
		int utflen= 0;
		for (int i= 0; i < strlen; i++) {
			int c= str[i];
			if ((c >= 0x0001) && (c <= 0x007F)) {
				utflen++;
			} else if (c > 0x07FF) {
				utflen += 3;
			} else {
				utflen += 2;
			}
		}
		if (utflen > 65535)
			throw new IllegalArgumentException();
		int pos= this.offset + offset;
		buffer[pos++]= (byte) ((utflen >>> 8) & 0xFF);
		buffer[pos++]= (byte) ((utflen >>> 0) & 0xFF);
		for (int i= 0; i < strlen; i++) {
			int c= str[i];
			if ((c >= 0x0001) && (c <= 0x007F)) {
				buffer[pos++]= ((byte) c);
			} else if (c > 0x07FF) {
				buffer[pos++]= ((byte) (0xE0 | ((c >> 12) & 0x0F)));
				buffer[pos++]= ((byte) (0x80 | ((c >> 6) & 0x3F)));
				buffer[pos++]= ((byte) (0x80 | ((c >> 0) & 0x3F)));
			} else {
				buffer[pos++]= ((byte) (0xC0 | ((c >> 6) & 0x1F)));
				buffer[pos++]= ((byte) (0x80 | ((c >> 0) & 0x3F)));
			}
		}
		return 2 + utflen;
	}
}

