/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o 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 for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package com.db4o.internal; import com.db4o.*; import com.db4o.ext.*; import com.db4o.internal.slots.*; /** * public for .NET conversion reasons * * TODO: Split this class for individual usecases. Only use the member * variables needed for the respective usecase. * * @exclude */ public final class StatefulBuffer extends ByteArrayBuffer { Transaction _trans; private int _address; private int _addressOffset; private int _cascadeDelete; private int _id; private int _length; public StatefulBuffer(Transaction trans, int initialBufferSize) { _trans = trans; _length = initialBufferSize; _buffer = new byte[_length]; } public StatefulBuffer(Transaction trans, int address, int length) { this(trans, length); _address = address; } public StatefulBuffer(Transaction trans, Slot slot){ this(trans, slot.address(), slot.length()); } public StatefulBuffer(Transaction trans, Pointer4 pointer){ this(trans, pointer._slot); _id = pointer._id; } public void debugCheckBytes() { if (Debug4.xbytes) { if (_offset != _length) { // Db4o.log("!!! YapBytes.debugCheckBytes not all bytes used"); // This is normal for writing The FreeSlotArray, becauce one // slot is possibly reserved by it's own pointer. } } } public int getAddress() { return _address; } public int getID() { return _id; } public int length() { return _length; } public ObjectContainerBase container(){ return _trans.container(); } public LocalObjectContainer file(){ return ((LocalTransaction)_trans).localContainer(); } public Transaction transaction() { return _trans; } public byte[] getWrittenBytes(){ byte[] bytes = new byte[_offset]; System.arraycopy(_buffer, 0, bytes, 0, _offset); return bytes; } public void read() throws Db4oIOException { container().readBytes(_buffer, _address,_addressOffset, _length); } public final StatefulBuffer readStatefulBuffer() { int length = readInt(); if (length == 0) { return null; } StatefulBuffer yb = new StatefulBuffer(_trans, length); System.arraycopy(_buffer, _offset, yb._buffer, 0, length); _offset += length; return yb; } public void removeFirstBytes(int aLength) { _length -= aLength; byte[] temp = new byte[_length]; System.arraycopy(_buffer, aLength, temp, 0, _length); _buffer = temp; _offset -= aLength; if (_offset < 0) { _offset = 0; } } public void address(int address) { _address = address; } public void setID(int id) { _id = id; } public void setTransaction(Transaction aTrans) { _trans = aTrans; } public void useSlot(int adress) { _address = adress; _offset = 0; } // FIXME: FB remove public void useSlot(int address, int length) { useSlot(new Slot(address, length)); } public void useSlot(Slot slot) { _address = slot.address(); _offset = 0; if (slot.length() > _buffer.length) { _buffer = new byte[slot.length()]; } _length = slot.length(); } // FIXME: FB remove public void useSlot(int id, int adress, int length) { _id = id; useSlot(adress, length); } public void write() { if (Debug4.xbytes) { debugCheckBytes(); } file().writeBytes(this, _address, _addressOffset); } public void writeEncrypt() { if (Deploy.debug) { debugCheckBytes(); } file().writeEncrypt(this, _address, _addressOffset); } public ByteArrayBuffer readPayloadWriter(int offset, int length){ StatefulBuffer payLoad = new StatefulBuffer(_trans, 0, length); System.arraycopy(_buffer,offset, payLoad._buffer, 0, length); transferPayLoadAddress(payLoad, offset); return payLoad; } private void transferPayLoadAddress(StatefulBuffer toWriter, int offset) { int blockedOffset = offset / container().blockSize(); toWriter._address = _address + blockedOffset; toWriter._id = toWriter._address; toWriter._addressOffset = _addressOffset; } public void moveForward(int length) { _addressOffset += length; } public String toString(){ return "id " + _id + " adr " + _address + " len " + _length; } public Slot slot(){ return new Slot(_address, _length); } public Pointer4 pointer(){ return new Pointer4(_id, slot()); } public int cascadeDeletes() { return _cascadeDelete; } public void setCascadeDeletes(int depth) { _cascadeDelete = depth; } }