/* 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.marshall; import com.db4o.*; import com.db4o.internal.*; /** * @exclude */ public final class ObjectHeader { private final ClassMetadata _classMetadata; public final MarshallerFamily _marshallerFamily; public final ObjectHeaderAttributes _headerAttributes; private int _handlerVersion; public ObjectHeader(ObjectContainerBase container, ReadWriteBuffer reader){ this(container,null,reader); } public ObjectHeader(ClassMetadata classMetadata, ReadWriteBuffer reader){ this(null,classMetadata,reader); } private ObjectHeader(ObjectContainerBase container, ClassMetadata classMetadata, ReadWriteBuffer reader){ if (Deploy.debug) { reader.readBegin(Const4.YAPOBJECT); } int classID = reader.readInt(); _marshallerFamily = readMarshallerFamily(reader, classID); classID=normalizeID(classID); _classMetadata=(classMetadata!=null ? classMetadata : container.classMetadataForID(classID)); if (Deploy.debug) { // This check has been added to cope with defragment in debug mode: SlotDefragment#setIdentity() // will trigger calling this constructor with a source db class metadata and a target db stream, // thus _classMetadata==null. There may be a better solution, since this call is just meant to // skip the object header. if(_classMetadata!=null) { int ycID = _classMetadata.getID(); if (classID != ycID) { System.out.println("ObjectHeader::init YapClass does not match. Expected ID: " + ycID + " Read ID: " + classID); } } } _headerAttributes = slotFormat().readHeaderAttributes((ByteArrayBuffer)reader); } public static ObjectHeader defrag(DefragmentContextImpl context) { ByteArrayBuffer source = context.sourceBuffer(); ByteArrayBuffer target = context.targetBuffer(); ObjectHeader header=new ObjectHeader(context.services().systemTrans().container(),null,source); int newID =context.mapping().strictMappedID(header.classMetadata().getID()); if (Deploy.debug) { target.readBegin(Const4.YAPOBJECT); } SlotFormat slotFormat = header.slotFormat(); slotFormat.writeObjectClassID(target,newID); slotFormat.skipMarshallerInfo(target); slotFormat.readHeaderAttributes(target); return header; } private SlotFormat slotFormat(){ return SlotFormat.forHandlerVersion(handlerVersion()); } private MarshallerFamily readMarshallerFamily(ReadWriteBuffer reader, int classID) { boolean marshallerAware=marshallerAware(classID); _handlerVersion = 0; if(marshallerAware) { _handlerVersion = reader.readByte(); } MarshallerFamily marshallerFamily=MarshallerFamily.version(_handlerVersion); return marshallerFamily; } private boolean marshallerAware(int id) { return id<0; } private int normalizeID(int id) { return (id<0 ? -id : id); } public ClassMetadata classMetadata() { return _classMetadata; } public int handlerVersion() { return _handlerVersion; } public static ObjectHeader scrollBufferToContent(LocalObjectContainer container, ByteArrayBuffer buffer) { return new ObjectHeader(container, buffer); } }