/*******************************************************************************
 * Copyright (c) 2005, 2007 QNX Software Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * QNX - Initial API and implementation
 * Markus Schorn (Wind River Systems)
 * IBM Corporation
 *******************************************************************************/
package org.eclipse.rephraserengine.internal.db.org.eclipse.cdt.internal.core.pdom.db;

import java.io.IOException;
import java.nio.ByteBuffer;

import org.eclipse.core.runtime.CoreException;

/**
 * Caches the content of a piece of the database.
 */
final class Chunk {
	final private byte[] fBuffer= new byte[Database.CHUNK_SIZE];

	final Database fDatabase;
	final int fSequenceNumber;
	
	boolean fCacheHitFlag= false;
	boolean fDirty= false;
	boolean fLocked= false;	// locked chunks must not be released from cache.
	int fCacheIndex= -1;
		
	Chunk(Database db, int sequenceNumber) {
		fDatabase= db;
		fSequenceNumber= sequenceNumber;
	}

	void read() throws CoreException {
		try {
			final ByteBuffer buf= ByteBuffer.wrap(fBuffer);
			fDatabase.read(buf, fSequenceNumber*Database.CHUNK_SIZE);
		} catch (IOException e) {
			throw new CoreException(new DBStatus(e));
		}
	}

	void flush() throws CoreException {
		try {
			final ByteBuffer buf= ByteBuffer.wrap(fBuffer);
			fDatabase.write(buf, fSequenceNumber*Database.CHUNK_SIZE);
		} catch (IOException e) {
			throw new CoreException(new DBStatus(e));
		}
		fDirty= false;
	}

	public void putByte(final int offset, final byte value) {
		assert fLocked;
		fDirty= true;
		fBuffer[offset % Database.CHUNK_SIZE]= value;
	}
	
	public byte getByte(final int offset) {
		return fBuffer[offset % Database.CHUNK_SIZE];
	}
	
	public byte[] getBytes(final int offset, final int length) {
		final byte[] bytes = new byte[length];
		System.arraycopy(fBuffer, offset % Database.CHUNK_SIZE, bytes, 0, length);
		return bytes;
	}
	
	public void putBytes(final int offset, final byte[] bytes) {
		assert fLocked;
		fDirty= true;
		System.arraycopy(bytes, 0, fBuffer, offset % Database.CHUNK_SIZE, bytes.length);
	}
	
	public void putInt(final int offset, final int value) {
		assert fLocked;
		fDirty= true;
		int idx= offset % Database.CHUNK_SIZE;
		fBuffer[idx]=   (byte)(value >> 24);
		fBuffer[++idx]= (byte)(value >> 16);
		fBuffer[++idx]= (byte)(value >> 8);
		fBuffer[++idx]= (byte)(value);
	}
	
	public int getInt(final int offset) {
		int idx= offset % Database.CHUNK_SIZE;
		return ((fBuffer[idx] & 0xff) << 24) |
			((fBuffer[++idx] & 0xff) << 16) |
			((fBuffer[++idx] & 0xff) <<  8) |
			((fBuffer[++idx] & 0xff) <<  0);
	}

	public void putShort(final int offset, final short value) {
		assert fLocked;
		fDirty= true;
		int idx= offset % Database.CHUNK_SIZE;
		fBuffer[idx]= (byte)(value >> 8);
		fBuffer[++idx]= (byte)(value);
	}
	
	public short getShort(final int offset) {
		int idx= offset % Database.CHUNK_SIZE;
		return (short) (((fBuffer[idx] << 8) | (fBuffer[++idx] & 0xff)));
	}

	public long getLong(final int offset) {
		int idx= offset % Database.CHUNK_SIZE;
		return ((((long)fBuffer[idx] & 0xff) << 56) |
				(((long)fBuffer[++idx] & 0xff) << 48) |
				(((long)fBuffer[++idx] & 0xff) << 40) |
				(((long)fBuffer[++idx] & 0xff) << 32) |
				(((long)fBuffer[++idx] & 0xff) << 24) |
				(((long)fBuffer[++idx] & 0xff) << 16) |
				(((long)fBuffer[++idx] & 0xff) <<  8) |
				(((long)fBuffer[++idx] & 0xff) <<  0));
	}

	public void putLong(final int offset, final long value) {
		assert fLocked;
		fDirty= true;
		int idx= offset % Database.CHUNK_SIZE;

		fBuffer[idx]=   (byte)(value >> 56);
		fBuffer[++idx]= (byte)(value >> 48);
		fBuffer[++idx]= (byte)(value >> 40);
		fBuffer[++idx]= (byte)(value >> 32);
		fBuffer[++idx]= (byte)(value >> 24);
		fBuffer[++idx]= (byte)(value >> 16);
		fBuffer[++idx]= (byte)(value >> 8);
		fBuffer[++idx]= (byte)(value);
	}
	
	public void putChar(final int offset, final char value) {
		assert fLocked;
		fDirty= true;
		int idx= offset % Database.CHUNK_SIZE;
		fBuffer[idx]= (byte)(value >> 8);
		fBuffer[++idx]= (byte)(value);
	}
	
	public char getChar(final int offset) {
		int idx= offset % Database.CHUNK_SIZE;
		return (char) (((fBuffer[idx] << 8) | (fBuffer[++idx] & 0xff)));
	}

	public void getCharArray(final int offset, final char[] result) {
		final ByteBuffer buf= ByteBuffer.wrap(fBuffer);
		buf.position(offset % Database.CHUNK_SIZE);
		buf.asCharBuffer().get(result);
	}
	
	void clear(final int offset, final int length) {
		assert fLocked;
		fDirty= true;
		int idx= (offset % Database.CHUNK_SIZE);
		final int end= idx + length;
		for (; idx < end; idx++) {
			fBuffer[idx]= 0;
		}
	}
}
