/*
* Copyright 2009-2016 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 <http://www.gnu.org/licenses/>.
*
* See the README and COPYING files for further information.
*/
package org.zoodb.internal;
import org.zoodb.internal.server.StorageChannelInput;
import org.zoodb.internal.server.DiskIO.PAGE_TYPE;
import org.zoodb.internal.server.index.BitTools;
import org.zoodb.internal.util.Util;
/**
* This class allows reading individual attributes of a serialized class.
*
* @author Tilmann Zaeschke
*/
public class DataDeSerializerNoClass {
private final StorageChannelInput in;
private long oid;
private long clsOid;
/**
* Create a new DataDeserializer.
* @param in Stream to read the data from.
* persistent.
*/
public DataDeSerializerNoClass(StorageChannelInput in) {
this.in = in;
// //Read OID
// oid = in.readLong();
// //read class info:
// clsOid = in.readLongAtOffset(0);
}
public void seekPos(long pos) {
in.seekPosAP(PAGE_TYPE.DATA, pos);
}
private int readHeader(ZooClassDef clsDef) {
return readHeader(clsDef, false);
}
private int readHeader(ZooClassDef clsDef, boolean allowSchemaMismatch) {
//Read object header.
//Read OID
oid = in.readLong();
//read class info:
clsOid = in.getHeaderClassOID();
if (!allowSchemaMismatch && clsOid != clsDef.getOid()) {
System.err.println();
throw new UnsupportedOperationException("Schema evolution not yet supported: " +
clsDef.getClassName() + ": " + Util.oidToString(clsDef.getOid()) + " to " +
Util.oidToString(clsOid));
}
//we already read 8 bytes, so we don't need to skip them anymore
return -ZooFieldDef.OFS_INIITIAL;
//TODO check cache? We could use reflection to extract data from there.
//On the client that should definitely be done. On the server, we don't have a cache with
//instantiated object, only pages or possibly byte arrays.
}
public long getClassOid() {
//readHeader(clsDef)
//Read OID
oid = in.readLong();
//read class info:
clsOid = in.getHeaderClassOID();
return clsOid;
}
public long getOid() {
//The oid position is independent of the schema version
readHeader(null, true);
return getLastOid();
}
public long getAttrLong(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
return in.readLong();
}
public int getAttrInt(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
return in.readInt();
}
public byte getAttrByte(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
return in.readByte();
}
public short getAttrShort(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
return in.readShort();
}
public double getAttrDouble(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
return in.readDouble();
}
public float getAttrFloat(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
return in.readFloat();
}
public char getAttrChar(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
return in.readChar();
}
public boolean getAttrBool(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
return in.readBoolean();
}
/**
* @param clsDef
* @param field
* @return The magic number of the String or 'null' if the String is null.
*/
public Long getStringMagic(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
if (in.readByte() == -1) {
return null;
}
return getAttrLong(clsDef, field);
}
public long getAttrRefOid(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
if (in.readByte() == -1) {
return OidBuffer.NULL_REF;
}
in.readLong(); //schema
return in.readLong();
}
public long getAttrAsLong(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
switch (field.getPrimitiveType()) {
case BOOLEAN: return in.readBoolean() ? 1 : 0;
case BYTE: return in.readByte();
case CHAR: return in.readChar();
case DOUBLE: {
//long has different sorting order than double!
return BitTools.toSortableLong(in.readDouble());
}
case FLOAT: {
//long has different sorting order than float!
return BitTools.toSortableLong(in.readFloat());
}
case INT: return in.readInt();
case LONG: return in.readLong();
case SHORT: return in.readShort();
default:
throw new IllegalArgumentException(field.getJdoType() + " " + field.getName());
}
}
// public Long getAttrAsLongObject(ZooClassDef clsDef, ZooFieldDef field) {
// int skip = readHeader(clsDef);
// skip += field.getOffset();
// in.skipRead(skip);
// if (in.readByte() == -1) {
// return null;
// }
// switch (field.getJdoType()) {
// case DATE: return in.readLong();
// case STRING: return in.readLong();
// case REFERENCE: return in.readLong();
// default:
// throw new IllegalArgumentException(field.getJdoType() + " " + field.getName());
// }
// }
public long getAttrAsLongObjectNotNull(ZooClassDef clsDef, ZooFieldDef field) {
int skip = readHeader(clsDef);
skip += field.getOffset();
in.skipRead(skip);
if (in.readByte() == -1) {
return BitTools.NULL;
}
switch (field.getJdoType()) {
case DATE: return in.readLong();
case STRING: return in.readLong();
case REFERENCE:
in.readLong();//schema id
return in.readLong();
default:
throw new IllegalArgumentException(field.getJdoType() + " " + field.getName());
}
}
public long getLastOid() {
return oid;
}
}