001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.internal.marshall;
022:
023: import java.io.IOException;
024:
025: import com.db4o.*;
026: import com.db4o.internal.*;
027:
028: /**
029: * @exclude
030: */
031: public abstract class ClassMarshaller {
032:
033: public MarshallerFamily _family;
034:
035: public RawClassSpec readSpec(Transaction trans, Buffer reader) {
036: byte[] nameBytes = readName(trans, reader);
037: String className = trans.container().stringIO().read(nameBytes);
038: readMetaClassID(reader); // skip
039: int ancestorID = reader.readInt();
040: reader.incrementOffset(Const4.INT_LENGTH); // index ID
041: int numFields = reader.readInt();
042: return new RawClassSpec(className, ancestorID, numFields);
043: }
044:
045: public void write(Transaction trans, ClassMetadata clazz,
046: Buffer writer) {
047:
048: writer.writeShortString(trans, clazz.nameToWrite());
049:
050: int intFormerlyKnownAsMetaClassID = 0;
051: writer.writeInt(intFormerlyKnownAsMetaClassID);
052:
053: writer.writeIDOf(trans, clazz.i_ancestor);
054:
055: writeIndex(trans, clazz, writer);
056:
057: FieldMetadata[] fields = clazz.i_fields;
058:
059: if (fields == null) {
060: writer.writeInt(0);
061: return;
062: }
063: writer.writeInt(fields.length);
064: for (int i = 0; i < fields.length; i++) {
065: _family._field.write(trans, clazz, fields[i], writer);
066: }
067: }
068:
069: protected void writeIndex(Transaction trans, ClassMetadata clazz,
070: Buffer writer) {
071: int indexID = clazz.index().write(trans);
072: writer.writeInt(indexIDForWriting(indexID));
073: }
074:
075: protected abstract int indexIDForWriting(int indexID);
076:
077: public byte[] readName(Transaction trans, Buffer reader) {
078: byte[] name = readName(trans.container().stringIO(), reader);
079: return name;
080: }
081:
082: public int readMetaClassID(Buffer reader) {
083: return reader.readInt();
084: }
085:
086: private byte[] readName(LatinStringIO sio, Buffer reader) {
087: if (Deploy.debug) {
088: reader.readBegin(Const4.YAPCLASS);
089: }
090: int len = reader.readInt();
091: len = len * sio.bytesPerChar();
092: byte[] nameBytes = new byte[len];
093: System.arraycopy(reader._buffer, reader._offset, nameBytes, 0,
094: len);
095: if (Deploy.csharp) {
096: nameBytes = Platform4.updateClassName(nameBytes);
097: }
098: reader.incrementOffset(len);
099: return nameBytes;
100: }
101:
102: public final void read(ObjectContainerBase stream,
103: ClassMetadata clazz, Buffer reader) {
104: clazz.setAncestor(stream.classMetadataForId(reader.readInt()));
105:
106: if (clazz.callConstructor()) {
107: // The logic further down checks the ancestor YapClass, whether
108: // or not it is allowed, not to call constructors. The ancestor
109: // YapClass may possibly have not been loaded yet.
110: clazz.createConstructor(stream, clazz.classReflector(),
111: clazz.getName(), true);
112: }
113:
114: clazz.checkType();
115:
116: readIndex(stream, clazz, reader);
117:
118: clazz.i_fields = createFields(clazz, reader.readInt());
119: readFields(stream, reader, clazz.i_fields);
120: }
121:
122: protected abstract void readIndex(ObjectContainerBase stream,
123: ClassMetadata clazz, Buffer reader);
124:
125: private FieldMetadata[] createFields(ClassMetadata clazz,
126: final int fieldCount) {
127: final FieldMetadata[] fields = new FieldMetadata[fieldCount];
128: for (int i = 0; i < fields.length; i++) {
129: fields[i] = new FieldMetadata(clazz);
130: fields[i].setArrayPosition(i);
131: }
132: return fields;
133: }
134:
135: private void readFields(ObjectContainerBase stream, Buffer reader,
136: final FieldMetadata[] fields) {
137: for (int i = 0; i < fields.length; i++) {
138: fields[i] = _family._field.read(stream, fields[i], reader);
139: }
140: }
141:
142: public int marshalledLength(ObjectContainerBase stream,
143: ClassMetadata clazz) {
144: int len = stream.stringIO().shortLength(clazz.nameToWrite())
145: + Const4.OBJECT_LENGTH + (Const4.INT_LENGTH * 2)
146: + (Const4.ID_LENGTH);
147:
148: len += clazz.index().ownLength();
149:
150: if (clazz.i_fields != null) {
151: for (int i = 0; i < clazz.i_fields.length; i++) {
152: len += _family._field.marshalledLength(stream,
153: clazz.i_fields[i]);
154: }
155: }
156: return len;
157: }
158:
159: public void defrag(ClassMetadata yapClass, LatinStringIO sio,
160: BufferPair readers, int classIndexID)
161: throws CorruptionException, IOException {
162: readName(sio, readers.source());
163: readName(sio, readers.target());
164:
165: int metaClassID = 0;
166: readers.writeInt(metaClassID);
167:
168: // ancestor ID
169: readers.copyID();
170:
171: readers.writeInt(indexIDForWriting(classIndexID));
172:
173: // field length
174: readers.incrementIntSize();
175:
176: FieldMetadata[] fields = yapClass.i_fields;
177: for (int fieldIdx = 0; fieldIdx < fields.length; fieldIdx++) {
178: _family._field.defrag(yapClass, fields[fieldIdx], sio,
179: readers);
180: }
181: }
182: }
|