/*
** 2015 November 23
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
*/
package info.ata4.junity.serialize;
import info.ata4.io.DataReader;
import info.ata4.io.DataWriter;
import info.ata4.io.Struct;
import info.ata4.junity.serialize.fileidentifier.FileIdentifier;
import info.ata4.junity.serialize.fileidentifier.FileIdentifierTable;
import info.ata4.junity.serialize.fileidentifier.FileIdentifierV1;
import info.ata4.junity.serialize.fileidentifier.FileIdentifierV2;
import info.ata4.junity.serialize.objectidentifier.ObjectIdentifierTable;
import info.ata4.junity.serialize.objectinfo.ObjectInfo;
import info.ata4.junity.serialize.objectinfo.ObjectInfoTable;
import info.ata4.junity.serialize.objectinfo.ObjectInfoTableV1;
import info.ata4.junity.serialize.objectinfo.ObjectInfoTableV2;
import info.ata4.junity.serialize.objectinfo.ObjectInfoV1;
import info.ata4.junity.serialize.objectinfo.ObjectInfoV2;
import info.ata4.junity.serialize.objectinfo.ObjectInfoV3;
import info.ata4.junity.serialize.typetree.Type;
import info.ata4.junity.serialize.typetree.TypeTree;
import info.ata4.junity.serialize.typetree.TypeTreeV1;
import info.ata4.junity.serialize.typetree.TypeTreeV2;
import info.ata4.junity.serialize.typetree.TypeTreeV3;
import info.ata4.junity.serialize.typetree.TypeV1;
import info.ata4.junity.serialize.typetree.TypeV2;
import info.ata4.log.LogUtils;
import info.ata4.util.io.DataBlock;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Nico Bergemann <barracuda415 at yahoo.de>
*/
public class SerializedFileMetadata implements Struct {
private static final Logger L = LogUtils.getLogger();
private final DataBlock typeTreeBlock = new DataBlock();
private final DataBlock objectInfoBlock = new DataBlock();
private final DataBlock objectIDBlock = new DataBlock();
private final DataBlock externalsBlock = new DataBlock();
private TypeTree typeTree;
private ObjectInfoTable objectInfoTable;
private ObjectIdentifierTable objectIDTable;
private FileIdentifierTable externals;
private int version;
public DataBlock typeTreeBlock() {
return typeTreeBlock;
}
public DataBlock objectInfoBlock() {
return objectInfoBlock;
}
public DataBlock objectIDBlock() {
return objectIDBlock;
}
public DataBlock externalsBlock() {
return externalsBlock;
}
public List<DataBlock> dataBlocks() {
List<DataBlock> blocks = new ArrayList<>();
blocks.add(typeTreeBlock());
blocks.add(objectInfoBlock());
blocks.add(objectIDBlock());
blocks.add(externalsBlock());
return blocks;
}
public int version() {
return version;
}
public void version(int version) {
this.version = version;
}
public <T extends Type> TypeTree<T> typeTree() {
return typeTree;
}
public <T extends Type> void typeTree(TypeTree<T> typeTree) {
this.typeTree = Objects.requireNonNull(typeTree);
}
public <T extends ObjectInfo> ObjectInfoTable<T> objectInfoTable() {
return objectInfoTable;
}
public <T extends ObjectInfo> void objectInfoTable(ObjectInfoTable<T> objInfoTable) {
this.objectInfoTable = Objects.requireNonNull(objInfoTable);
}
public ObjectIdentifierTable objectIDTable() {
return objectIDTable;
}
public void objectIDTable(ObjectIdentifierTable objectIDTable) {
this.objectIDTable = Objects.requireNonNull(objectIDTable);
}
public <T extends FileIdentifier> FileIdentifierTable<T> externals() {
return externals;
}
public <T extends FileIdentifier> void externals(FileIdentifierTable<T> externals) {
this.externals = Objects.requireNonNull(externals);
}
@Override
public void read(DataReader in) throws IOException {
// load type tree
if (version > 13) {
typeTree = new TypeTreeV3(TypeV2.class);
} else if (version > 6) {
typeTree = new TypeTreeV2(TypeV1.class);
} else {
typeTree = new TypeTreeV1(TypeV1.class);
}
typeTreeBlock.markBegin(in);
in.readStruct(typeTree);
typeTreeBlock.markEnd(in);
L.log(Level.FINER, "typeTreeBlock: {0}", typeTreeBlock);
// load object info table
if (version > 14) {
objectInfoTable = new ObjectInfoTableV2(ObjectInfoV3.class);
} else if (version > 13) {
objectInfoTable = new ObjectInfoTableV2(ObjectInfoV2.class);
} else {
objectInfoTable = new ObjectInfoTableV1(ObjectInfoV1.class);
}
objectInfoBlock.markBegin(in);
in.readStruct(objectInfoTable);
objectInfoBlock.markEnd(in);
L.log(Level.FINER, "objectInfoBlock: {0}", objectInfoBlock);
// load object identifiers (Unity 5+ only)
objectIDTable = new ObjectIdentifierTable();
if (version > 10) {
objectIDBlock.markBegin(in);
in.readStruct(objectIDTable);
objectIDBlock.markEnd(in);
L.log(Level.FINER, "objectIDBlock: {0}", objectIDBlock);
}
// load external references
if (version > 5) {
externals = new FileIdentifierTable(FileIdentifierV2.class);
} else {
externals = new FileIdentifierTable(FileIdentifierV1.class);
}
externalsBlock.markBegin(in);
in.readStruct(externals);
externalsBlock.markEnd(in);
L.log(Level.FINER, "externalsBlock: {0}", externalsBlock);
}
@Override
public void write(DataWriter out) throws IOException {
typeTreeBlock.markBegin(out);
out.writeStruct(typeTree);
typeTreeBlock.markEnd(out);
L.log(Level.FINER, "typeTreeBlock: {0}", typeTreeBlock);
objectInfoBlock.markBegin(out);
out.writeStruct(objectInfoTable);
objectInfoBlock.markEnd(out);
L.log(Level.FINER, "objectInfoBlock: {0}", objectInfoBlock);
if (version > 10) {
objectIDBlock.markBegin(out);
out.writeStruct(objectIDTable);
objectIDBlock.markEnd(out);
L.log(Level.FINER, "objectIDBlock: {0}", objectIDBlock);
}
externalsBlock.markBegin(out);
out.writeStruct(externals);
externalsBlock.markEnd(out);
L.log(Level.FINER, "externalsBlock: {0}", externalsBlock);
}
}