
org.zoodb.jdo.internal.GenericObjectWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of parent Show documentation
Show all versions of parent Show documentation
ZooDB Java JDO Object Database.
The newest version!
/*
* Copyright 2009-2013 Tilmann Zaeschke. All rights reserved.
*
* This file is part of ZooDB.
*
* ZooDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZooDB 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 ZooDB. If not, see .
*
* See the README and COPYING files for further information.
*/
package org.zoodb.jdo.internal;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import org.zoodb.jdo.internal.server.DiskIO;
import org.zoodb.jdo.internal.server.ObjectWriter;
/**
*
* @author Tilmann Zaschke
*
*/
class GenericObjectWriter implements ObjectWriter, DiskIO {
private ByteBuffer buf;
private final long headerClassOid;
private int MAX_POS;
public GenericObjectWriter(int nBytes, long clsOid) {
this.buf = ByteBuffer.allocate(nBytes);
this.headerClassOid = clsOid;
this.MAX_POS = nBytes;
}
@Override
public void startObject(long oid, int prevSchemaVersion) {
//nothing to do...
}
@Override
public void finishObject() {
//nothing to do...
}
/**
* This can be necessary when subsequent objects are of a different class.
*/
@Override
public void newPage() {
writeHeader();
}
private void writeHeader() {
writeLong(headerClassOid);
}
@Override
public void writeString(String string) {
checkPosWrite(4);
buf.putInt(string.length());
//Align for 2-byte writing
int p = buf.position();
if ((p & 0x00000001) == 1) {
buf.position(p+1);
}
CharBuffer cb;
int l = string.length();
int posA = 0; //position in array
while (l > 0) {
checkPosWrite(2);
int putLen = MAX_POS - buf.position();
putLen = putLen >> 1; //TODO loses odd values!
if (putLen > l) {
putLen = l;
}
//This is crazy!!! Unlike ByteBuffer, CharBuffer requires END as third param!!
cb = buf.asCharBuffer();
cb.put(string, posA, posA + putLen);
buf.position(buf.position() + putLen * 2);
posA += putLen;
l -= putLen;
}
}
@Override
public void write(byte[] array) {
int l = array.length;
int posA = 0; //position in array
while (l > 0) {
checkPosWrite(1);
int putLen = MAX_POS - buf.position();
if (putLen > l) {
putLen = l;
}
buf.put(array, posA, putLen);
posA += putLen;
l -= putLen;
}
}
@Override
public void writeBoolean(boolean boolean1) {
writeByte((byte) (boolean1 ? 1 : 0));
}
@Override
public void writeByte(byte byte1) {
checkPosWrite(S_BYTE);
buf.put(byte1);
}
@Override
public void writeChar(char char1) {
if (!checkPos(S_CHAR)) {
write(ByteBuffer.allocate(S_CHAR).putChar(char1).array());
return;
}
buf.putChar(char1);
}
@Override
public void writeDouble(double double1) {
if (!checkPos(S_DOUBLE)) {
writeLong(Double.doubleToLongBits(double1));
return;
}
buf.putDouble(double1);
}
@Override
public void writeFloat(float float1) {
if (!checkPos(S_FLOAT)) {
writeInt(Float.floatToIntBits(float1));
return;
}
buf.putFloat(float1);
}
@Override
public void writeInt(int int1) {
if (!checkPos(S_INT)) {
write(ByteBuffer.allocate(S_INT).putInt(int1).array());
return;
}
buf.putInt(int1);
}
@Override
public void writeLong(long long1) {
if (!checkPos(S_LONG)) {
write(ByteBuffer.allocate(S_LONG).putLong(long1).array());
return;
}
buf.putLong(long1);
}
@Override
public void writeShort(short short1) {
if (!checkPos(S_SHORT)) {
write(ByteBuffer.allocate(S_SHORT).putShort(short1).array());
return;
}
buf.putShort(short1);
}
private boolean checkPos(int delta) {
//TODO remove autopaging, the indices use anyway the noCheckMethods!!
//TODO -> otherwise, make it final, as it should be known when a view is constructed.
// if (isAutoPaging) {
// return (buf.position() + delta - MAX_POS) <= 0;
// }
return true;
}
private void checkPosWrite(int delta) {
if (buf.position() + delta > MAX_POS) {
MAX_POS = buf.capacity()*2 + delta;
System.err.println("FIXME: Resizing buffer (internally)! " + MAX_POS);
ByteBuffer b2 = ByteBuffer.allocate(MAX_POS);
buf.flip();
b2.put(buf);
buf = b2;
//throw new ArrayIndexOutOfBoundsException((buf.position() + delta) + " > " + MAX_POS);
}
}
@Override
public void skipWrite(int nBytes) {
int l = nBytes;
while (l > 0) {
checkPosWrite(1);
int bPos = buf.position();
int putLen = MAX_POS - bPos;
if (putLen > l) {
putLen = l;
}
buf.position(bPos + putLen);
l -= putLen;
}
}
@Override
public void flush() {
//nothing to do...
}
public ByteBuffer toByteArray() {
return buf;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy