Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'develop' of github.com:MovingBlocks/Terasology into dev…

…elop
  • Loading branch information...
commit b72b3ab1d23817a35c3f259d27ac1cdca3e1b58a 2 parents 1f4ad28 + 35d7786
@begla begla authored
Showing with 1,210 additions and 0 deletions.
  1. +254 −0 src/org/terasology/persistence/BinaryLevelReader.java
  2. +151 −0 src/org/terasology/persistence/BinaryLevelWriter.java
  3. +74 −0 src/org/terasology/persistence/PersistenceManager.java
  4. +30 −0 src/org/terasology/persistence/interfaces/LevelReader.java
  5. +29 −0 src/org/terasology/persistence/interfaces/LevelWriter.java
  6. +25 −0 src/org/terasology/persistence/interfaces/Persistable.java
  7. +40 −0 src/org/terasology/persistence/interfaces/StorageReader.java
  8. +27 −0 src/org/terasology/persistence/interfaces/StorageWriter.java
  9. +39 −0 src/org/terasology/persistence/interfaces/TypeInfo.java
  10. +52 −0 src/org/terasology/persistence/typeSupport/AbstractTypeInfo.java
  11. +40 −0 src/org/terasology/persistence/typeSupport/BooleanInfo.java
  12. +40 −0 src/org/terasology/persistence/typeSupport/DoubleInfo.java
  13. +39 −0 src/org/terasology/persistence/typeSupport/FloatInfo.java
  14. +40 −0 src/org/terasology/persistence/typeSupport/IntegerInfo.java
  15. +55 −0 src/org/terasology/persistence/typeSupport/ListInfo.java
  16. +41 −0 src/org/terasology/persistence/typeSupport/StringInfo.java
  17. +64 −0 src/org/terasology/persistence/typeSupport/UnknownTypeInfo.java
  18. +46 −0 src/org/terasology/persistence/typeSupport/Vector3dInfo.java
  19. +81 −0 tests/org/terasology/persistence/BinaryPersisterTest.java
  20. +43 −0 tests/org/terasology/persistence/TestPersistable.java
View
254 src/org/terasology/persistence/BinaryLevelReader.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence;
+
+import gnu.trove.map.TShortObjectMap;
+import gnu.trove.map.hash.TShortObjectHashMap;
+import org.terasology.persistence.interfaces.*;
+import org.terasology.persistence.typeSupport.UnknownTypeInfo;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Immortius <immortius@gmail.com>
+ */
+public class BinaryLevelReader implements LevelReader, StorageReader {
+ private Logger logger = Logger.getLogger(getClass().getName());
+ private DataInputStream input;
+ private TShortObjectMap<TypeInfo> typeLookup = new TShortObjectHashMap<TypeInfo>();
+ private TShortObjectMap<Class<? extends Persistable>> persistableTypeLookup = new TShortObjectHashMap<Class<? extends Persistable>>();
+ private Persistable nextPersistable;
+
+ private List<Map<String,Object>> propStack = new ArrayList<Map<String, Object>>();
+
+ public BinaryLevelReader(DataInputStream in, Map<String,TypeInfo> typeNameMap, Map<String, Class<? extends Persistable>> persistableTypeMap) throws IOException {
+ this.input = in;
+ readHeader(typeNameMap, persistableTypeMap);
+ }
+
+ private void readHeader(Map<String,TypeInfo> typeNameMap, Map<String, Class<? extends Persistable>> persistableTypeMap) throws IOException {
+ if (input.readChar() != 'T' ||
+ input.readChar() != 'E' ||
+ input.readChar() != 'R' ||
+ input.readChar() != 'A')
+ throw new IOException("Not a valid binary file");
+
+ int fileVersion = input.readInt();
+ short numTypes = input.readShort();
+ for (int i = 0; i < numTypes; ++i) {
+ short typeId = input.readShort();
+ byte size = input.readByte();
+ String name = input.readUTF();
+
+ TypeInfo info = typeNameMap.get(name);
+ if (info != null && info.size() == size) {
+ typeLookup.put(typeId, info);
+ } else {
+ if (info != null) {
+ logger.log(Level.SEVERE, String.format("Size mismatch for type %s, expected %d but found %d", name, info.size(), size));
+ } else {
+ logger.log(Level.SEVERE, String.format("Unknown type %s", name));
+ }
+ if (size == TypeInfo.VARIABLE_LENGTH) {
+ // TODO: If possible support variable length types better
+ throw new IOException("Unknown variable length type, cannot continue data read");
+ }
+ typeLookup.put(typeId, new UnknownTypeInfo(size));
+ }
+ }
+ short numPersistableTypes = input.readShort();
+ for (int i = 0; i < numPersistableTypes; ++i) {
+ short id = input.readShort();
+ String name = input.readUTF();
+ Class<? extends Persistable> clazz = persistableTypeMap.get(name);
+ if (clazz != null) {
+ persistableTypeLookup.put(id, clazz);
+ } else {
+ logger.warning(String.format("Unknown persistable class \"%s\" will be skipped", name));
+ }
+ }
+
+ loadNextPersistable();
+ }
+
+ public Persistable next() throws IOException {
+ if (nextPersistable == null) return null;
+ Persistable result = nextPersistable;
+ loadNextPersistable();
+ return result;
+ }
+
+ public boolean hasNext() {
+ return nextPersistable != null;
+ }
+
+ public TypeInfo<?> getType(short id) {
+ return typeLookup.get(id);
+ }
+
+ private Map<String, Object> properties() {
+ return propStack.get(propStack.size() - 1);
+ }
+
+ public Object read(String name) {
+ return properties().get(name);
+ }
+
+ public <T> T read(String name, Class<T> clazz) {
+ Object item = properties().get(name);
+ if (clazz.isInstance(item))
+ {
+ return clazz.cast(item);
+ }
+ return null;
+ }
+
+ public String readString(String name) {
+ return read(name, String.class);
+ }
+
+ public Integer readInt(String name) {
+ return read(name, Integer.class);
+ }
+
+ public int readInt(String name, int defaultVal) {
+ Object item = properties().get(name);
+ if (item instanceof Integer)
+ {
+ return (Integer) item;
+ }
+ return defaultVal;
+ }
+
+ public Float readFloat(String name) {
+ return read(name, Float.class);
+ }
+
+ public float readFloat(String name, float defaultVal) {
+ Object item = properties().get(name);
+ if (item instanceof Float)
+ {
+ return (Float) item;
+ }
+ return defaultVal;
+ }
+
+ public Double readDouble(String name) {
+ return read(name, Double.class);
+ }
+
+ public double readDouble(String name, double defaultVal) {
+ Object item = properties().get(name);
+ if (item instanceof Double)
+ {
+ return (Double) item;
+ }
+ return defaultVal;
+ }
+
+ public Boolean readBoolean(String name) {
+ return read(name, Boolean.class);
+ }
+
+ public boolean readBoolean(String name, boolean defaultVal) {
+ Object item = properties().get(name);
+ if (item instanceof Boolean)
+ {
+ return (Boolean) item;
+ }
+ return defaultVal;
+ }
+
+ public <T> List<T> readList(String name, Class<T> type) {
+ Object item = properties().get(name);
+ if (item instanceof List)
+ {
+ Object sample = ((List)item).get(0);
+ if (type.isInstance(sample))
+ {
+ return (List) item;
+ }
+ }
+ return Arrays.asList();
+ }
+
+ private void loadNextPersistable() throws IOException {
+ nextPersistable = null;
+ while (nextPersistable == null) {
+ short persistableId = input.readShort();
+ if (persistableId == PersistenceManager.END_OF_SECTION) {
+ return;
+ }
+
+ Class<? extends Persistable> persistableClass = persistableTypeLookup.get(persistableId);
+ if (persistableClass == null) {
+ // Consume unusable data
+ while (true) {
+ short typeId = input.readShort();
+ if (typeId == PersistenceManager.END_OF_SECTION)
+ break;
+ TypeInfo info = typeLookup.get(typeId);
+ if (info == null) {
+ throw new IOException("Unexpected type: " + typeId);
+ }
+
+ input.readUTF();
+ try {
+ info.read(input, this);
+ } catch (Exception e) {
+ throw new IOException("Error reading data", e);
+ }
+ }
+ } else {
+ propStack.add(new HashMap<String, Object>());
+ // Load
+ while (true) {
+ short typeId = input.readShort();
+ if (typeId == PersistenceManager.END_OF_SECTION)
+ break;
+ TypeInfo info = typeLookup.get(typeId);
+ if (info == null) {
+ throw new IOException("Unexpected type: " + typeId);
+ }
+
+ String propName = input.readUTF();
+ try {
+ properties().put(propName, info.read(input, this));
+ } catch (Exception e) {
+ throw new IOException("Error reading data", e);
+ }
+ }
+ try {
+ nextPersistable = persistableClass.newInstance();
+ nextPersistable.retrieve(this);
+ } catch (InstantiationException e) {
+ throw new IOException("Could not read persistable " + persistableClass.getName(), e);
+ } catch (IllegalAccessException e) {
+ throw new IOException("Could not read persistable " + persistableClass.getName(), e);
+ }
+
+ propStack.remove(propStack.size() - 1);
+ }
+
+ }
+ }
+
+}
View
151 src/org/terasology/persistence/BinaryLevelWriter.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence;
+
+
+import org.terasology.persistence.interfaces.*;
+
+import java.util.HashMap;
+import java.util.List;
+
+import java.util.Map;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Immortius <immortius@gmail.com>
+ */
+public class BinaryLevelWriter implements LevelWriter, StorageWriter
+{
+ Logger logger = Logger.getLogger(getClass().getName());
+ boolean errored = false;
+ DataOutputStream output;
+ Map<Class, TypeInfo> typeMap;
+ TypeInfo<List> listInfo;
+ Map<Class<? extends Persistable>, Short> persistableIdMap = new HashMap<Class<? extends Persistable>, Short>();
+
+ public BinaryLevelWriter(DataOutputStream out, Map<Class, TypeInfo> typeMap, Map<String, Class<? extends Persistable>> persistableClasses) throws IOException {
+ this.output = out;
+ this.typeMap = typeMap;
+ listInfo = typeMap.get(List.class);
+ if (listInfo == null) throw new IOException("Required type for List is missing");
+ short id = 1;
+ for (Class<? extends Persistable> clazz : persistableClasses.values()) {
+ persistableIdMap.put(clazz, id++);
+ }
+
+ writeHeader();
+ }
+
+ private void writeHeader() throws IOException {
+ output.writeChar('T');
+ output.writeChar('E');
+ output.writeChar('R');
+ output.writeChar('A');
+ output.writeInt(0x1);
+ // Write type info
+ output.writeShort(typeMap.size());
+ for (TypeInfo info : typeMap.values()) {
+ output.writeShort(info.getId());
+ output.writeByte(info.size());
+ output.writeUTF(info.getTypeName());
+ }
+ // Write persistable info
+ output.writeShort(persistableIdMap.size());
+ for (Map.Entry<Class<? extends Persistable>, Short> item : persistableIdMap.entrySet()) {
+ output.writeShort(item.getValue());
+ output.writeUTF(item.getKey().getName());
+ }
+ }
+
+ public boolean isInErrorState() {
+ return errored;
+ }
+
+ public <T> void write(String name, T value) {
+ if (value != null)
+ {
+ try {
+ TypeInfo info = typeMap.get(value.getClass());
+ if (info == null) {
+ throw new IOException("Unsupported type : " + value.getClass());
+ } else {
+ output.writeShort(info.getId());
+ output.writeUTF(name);
+ info.write(output, value, this);
+ }
+ } catch (Exception ex) {
+ logger.log(Level.SEVERE, "Error writing data", ex);
+ errored = true;
+ }
+ }
+ }
+
+ public <T> void write(String name, List<T> value) {
+ if (value != null && value.size() > 0)
+ {
+ try
+ {
+ // It is assumed that all values in the list are of the same type
+ T sample = value.get(0);
+ TypeInfo info = typeMap.get(sample.getClass());
+ if (info == null)
+ {
+ throw new IOException("Unsupported type : " + sample.getClass());
+ }
+ output.writeShort(listInfo.getId());
+ output.writeUTF(name);
+ output.writeShort(info.getId());
+ output.writeInt(value.size());
+ for (T val : value)
+ {
+ info.write(output, val, this);
+ }
+ } catch (Exception ex) {
+ logger.log(Level.SEVERE, "Error writing data", ex);
+ errored = true;
+ }
+ }
+ }
+
+ public void write(Persistable value) throws IOException {
+ Short id = persistableIdMap.get(value.getClass());
+ if (id != null) {
+ output.writeShort(id);
+ value.store(this);
+ output.writeShort(PersistenceManager.END_OF_SECTION);
+ } else {
+ logger.log(Level.SEVERE, "Error writing data, unknown persistable type: " + value.getClass().getName());
+ throw new IOException("Error writing data, unknown persistable type: " + value.getClass().getName());
+ }
+ }
+
+ public void close() throws IOException {
+ output.writeShort(PersistenceManager.END_OF_SECTION);
+ try {
+ output.flush();
+ output.close();
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, "Error writing data", ex);
+ errored = true;
+ }
+
+ }
+
+}
View
74 src/org/terasology/persistence/PersistenceManager.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence;
+
+import org.terasology.persistence.interfaces.*;
+import org.terasology.persistence.typeSupport.*;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public class PersistenceManager {
+
+ public static final short END_OF_SECTION = 0;
+ short nextId = 1;
+
+ Map<String, TypeInfo> typeNameLookup = new HashMap<String, TypeInfo>();
+ Map<Class, TypeInfo> typeLookup = new HashMap<Class, TypeInfo>();
+ Map<String,Class<? extends Persistable>> persistableClasses = new HashMap<String,Class<? extends Persistable>>();
+
+ public PersistenceManager() {
+ registerType(new BooleanInfo());
+ registerType(new DoubleInfo());
+ registerType(new FloatInfo());
+ registerType(new IntegerInfo());
+ registerType(new ListInfo());
+ registerType(new StringInfo());
+ registerType(new Vector3dInfo());
+ }
+
+ public void registerType(TypeInfo<?> info) {
+ info.setId(nextId++);
+ typeNameLookup.put(info.getTypeName(), info);
+ typeLookup.put(info.getType(), info);
+ }
+
+ public void registerPersistableClasses(Class<? extends Persistable> persistableClass) {
+ persistableClasses.put(persistableClass.getName(), persistableClass);
+ }
+
+ public LevelReader newReader(InputStream in) throws IOException {
+ return newReader(new DataInputStream(in));
+ }
+
+ public LevelReader newReader(DataInputStream in) throws IOException {
+ return new BinaryLevelReader(in, typeNameLookup, persistableClasses);
+ }
+
+ public LevelWriter newWriter(OutputStream out) throws IOException {
+ return newWriter(new DataOutputStream(out));
+ }
+
+ public LevelWriter newWriter(DataOutputStream out) throws IOException {
+ return new BinaryLevelWriter(out, typeLookup, persistableClasses);
+ }
+
+
+}
View
30 src/org/terasology/persistence/interfaces/LevelReader.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.interfaces;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author Immortius <immortius@gmail.com>
+ */
+public interface LevelReader extends StorageReader {
+
+ TypeInfo<?> getType(short id);
+ Persistable next() throws IOException;
+ boolean hasNext();
+
+}
View
29 src/org/terasology/persistence/interfaces/LevelWriter.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.interfaces;
+
+import java.io.IOException;
+
+/**
+ * Interface for persister
+ * @author Immortius <immortius@gmail.com>
+ */
+public interface LevelWriter {
+
+ void write(Persistable value) throws IOException;
+ boolean isInErrorState();
+ void close() throws IOException;
+}
View
25 src/org/terasology/persistence/interfaces/Persistable.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.interfaces;
+
+/**
+ *
+ * @author Immortius <immortius@gmail.com>
+ */
+public interface Persistable {
+ void store(StorageWriter writer);
+ void retrieve(StorageReader reader);
+}
View
40 src/org/terasology/persistence/interfaces/StorageReader.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.interfaces;
+
+import java.util.List;
+
+/**
+ *
+ * @author Immortius <immortius@gmail.com>
+ */
+public interface StorageReader {
+ Object read(String name);
+ <T> T read(String name, Class<T> clazz);
+ <T> List<T> readList(String name, Class<T> type);
+
+ String readString(String name);
+ Integer readInt(String name);
+ int readInt(String name, int defaultVal);
+ Float readFloat(String name);
+ float readFloat(String name, float defaultVal);
+ Double readDouble(String name);
+ double readDouble(String name, double defaultVal);
+ Boolean readBoolean(String name);
+ boolean readBoolean(String name, boolean defaultVal);
+
+
+}
View
27 src/org/terasology/persistence/interfaces/StorageWriter.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.interfaces;
+
+import java.util.List;
+
+/**
+ *
+ * @author Immortius <immortius@gmail.com>
+ */
+public interface StorageWriter {
+ <T> void write(String name, T value);
+ <T> void write(String name, List<T> value);
+}
View
39 src/org/terasology/persistence/interfaces/TypeInfo.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.interfaces;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public interface TypeInfo<T> {
+ public static final byte VARIABLE_LENGTH = 0;
+
+ void write(DataOutputStream out, T value, LevelWriter writer) throws Exception;
+ T read(DataInputStream in, LevelReader reader) throws Exception;
+
+ short getId();
+ void setId(short id);
+ Class<T> getType();
+ String getTypeName();
+
+ /**
+ * @return The size of this type in bytes
+ */
+ byte size();
+}
View
52 src/org/terasology/persistence/typeSupport/AbstractTypeInfo.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.typeSupport;
+
+import org.terasology.persistence.interfaces.TypeInfo;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public abstract class AbstractTypeInfo<T> implements TypeInfo<T> {
+ private byte size;
+ private short id;
+ private Class<T> type;
+
+ public AbstractTypeInfo(Class<T> type, byte size) {
+ this.size = size;
+ this.type = type;
+ }
+
+ public short getId() {
+ return id;
+ }
+
+ public void setId(short id) {
+ this.id = id;
+ }
+
+ public byte size() {
+ return size;
+ }
+
+ public Class<T> getType() {
+ return type;
+ }
+
+ public String getTypeName() {
+ return type.getSimpleName();
+ }
+}
View
40 src/org/terasology/persistence/typeSupport/BooleanInfo.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.typeSupport;
+
+import org.terasology.persistence.interfaces.LevelReader;
+import org.terasology.persistence.interfaces.LevelWriter;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public class BooleanInfo extends AbstractTypeInfo<Boolean> {
+
+ public BooleanInfo() {
+ super(Boolean.class, (byte)1);
+ }
+
+ public void write(DataOutputStream out, Boolean value, LevelWriter writer) throws Exception {
+ out.writeBoolean(value);
+ }
+
+ public Boolean read(DataInputStream in, LevelReader reader) throws Exception {
+ return in.readBoolean();
+ }
+}
View
40 src/org/terasology/persistence/typeSupport/DoubleInfo.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.typeSupport;
+
+import org.terasology.persistence.interfaces.LevelReader;
+import org.terasology.persistence.interfaces.LevelWriter;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public class DoubleInfo extends AbstractTypeInfo<Double> {
+
+ public DoubleInfo() {
+ super(Double.class, (byte)8);
+ }
+
+ public void write(DataOutputStream out, Double value, LevelWriter writer) throws Exception {
+ out.writeDouble(value);
+ }
+
+ public Double read(DataInputStream in, LevelReader reader) throws Exception {
+ return in.readDouble();
+ }
+}
View
39 src/org/terasology/persistence/typeSupport/FloatInfo.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.typeSupport;
+
+import org.terasology.persistence.interfaces.LevelReader;
+import org.terasology.persistence.interfaces.LevelWriter;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public class FloatInfo extends AbstractTypeInfo<Float> {
+ public FloatInfo() {
+ super(Float.class, (byte)4);
+ }
+
+ public void write(DataOutputStream out, Float value, LevelWriter writer) throws Exception {
+ out.writeFloat(value);
+ }
+
+ public Float read(DataInputStream in, LevelReader reader) throws Exception {
+ return in.readFloat();
+ }
+}
View
40 src/org/terasology/persistence/typeSupport/IntegerInfo.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.typeSupport;
+
+import org.terasology.persistence.interfaces.LevelReader;
+import org.terasology.persistence.interfaces.LevelWriter;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public class IntegerInfo extends AbstractTypeInfo<Integer> {
+
+ public IntegerInfo() {
+ super(Integer.class, (byte)4);
+ }
+
+ public void write(DataOutputStream out, Integer value, LevelWriter writer) throws Exception {
+ out.writeInt(value);
+ }
+
+ public Integer read(DataInputStream in, LevelReader reader) throws Exception {
+ return in.readInt();
+ }
+}
View
55 src/org/terasology/persistence/typeSupport/ListInfo.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.typeSupport;
+
+import org.terasology.persistence.interfaces.LevelReader;
+import org.terasology.persistence.interfaces.LevelWriter;
+import org.terasology.persistence.interfaces.TypeInfo;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public class ListInfo extends AbstractTypeInfo<List> {
+
+ public ListInfo() {
+ super(List.class, TypeInfo.VARIABLE_LENGTH);
+ }
+
+ public void write(DataOutputStream out, List value, LevelWriter writer) throws Exception {
+ throw new UnsupportedOperationException("This should be implemented by LevelWriter");
+ }
+
+ public List read(DataInputStream in, LevelReader reader) throws Exception {
+ List list = new ArrayList();
+ TypeInfo contentsType = reader.getType(in.readShort());
+ if (contentsType == null)
+ {
+ throw new IOException("Unknown object type: " + contentsType);
+ }
+ int size = in.readInt();
+ for (int i = 0; i < size; i++)
+ {
+ list.add(contentsType.read(in, reader));
+ }
+ return list;
+ }
+}
View
41 src/org/terasology/persistence/typeSupport/StringInfo.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.typeSupport;
+
+import org.terasology.persistence.interfaces.LevelReader;
+import org.terasology.persistence.interfaces.LevelWriter;
+import org.terasology.persistence.interfaces.TypeInfo;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public class StringInfo extends AbstractTypeInfo<String> {
+
+ public StringInfo() {
+ super(String.class, TypeInfo.VARIABLE_LENGTH);
+ }
+
+ public void write(DataOutputStream out, String value, LevelWriter writer) throws Exception {
+ out.writeUTF(value);
+ }
+
+ public String read(DataInputStream in, LevelReader reader) throws Exception {
+ return in.readUTF();
+ }
+}
View
64 src/org/terasology/persistence/typeSupport/UnknownTypeInfo.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.typeSupport;
+
+import org.terasology.persistence.interfaces.LevelReader;
+import org.terasology.persistence.interfaces.LevelWriter;
+import org.terasology.persistence.interfaces.TypeInfo;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * Dummy Unknown type used by the reader to eat unknown info.
+ * @author Immortius <immortius@gmail.com>
+ */
+public class UnknownTypeInfo implements TypeInfo {
+ private byte size;
+
+ public UnknownTypeInfo(byte size) {
+ this.size = size;
+ }
+
+ public void write(DataOutputStream out, Object value, LevelWriter writer) throws Exception {
+
+ }
+
+ public Object read(DataInputStream in, LevelReader reader) throws Exception {
+ byte[] result = new byte[size];
+ in.readFully(result);
+ return result;
+ }
+
+ public short getId() {
+ return 0;
+ }
+
+ public void setId(short id) {
+ }
+
+ public Class getType() {
+ return byte[].class;
+ }
+
+ public String getTypeName() {
+ return "Unknown";
+ }
+
+ public byte size() {
+ return size;
+ }
+}
View
46 src/org/terasology/persistence/typeSupport/Vector3dInfo.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence.typeSupport;
+
+import org.terasology.persistence.interfaces.LevelReader;
+import org.terasology.persistence.interfaces.LevelWriter;
+
+import javax.vecmath.Vector3d;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public class Vector3dInfo extends AbstractTypeInfo<Vector3d> {
+
+ public Vector3dInfo() {
+ super(Vector3d.class, (byte)(8 * 3));
+ }
+
+ public void write(DataOutputStream out, Vector3d value, LevelWriter writer) throws Exception {
+ out.writeDouble(value.x);
+ out.writeDouble(value.y);
+ out.writeDouble(value.z);
+ }
+
+ public Vector3d read(DataInputStream in, LevelReader reader) throws Exception {
+ double x = in.readDouble();
+ double y = in.readDouble();
+ double z = in.readDouble();
+ return new Vector3d(x,y,z);
+ }
+}
View
81 tests/org/terasology/persistence/BinaryPersisterTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.terasology.persistence.interfaces.LevelReader;
+import org.terasology.persistence.interfaces.LevelWriter;
+
+import javax.vecmath.Vector3d;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Immortius <immortius@gmail.com>
+ */
+public class BinaryPersisterTest
+{
+ String name = "name";
+ String stringData = "DATA";
+ ByteArrayOutputStream memStream;
+ PersistenceManager persistenceManager;
+
+ @Before
+ public void setup() throws IOException {
+ persistenceManager = new PersistenceManager();
+ }
+
+ private LevelWriter createLevelWriter() throws IOException {
+ memStream = new ByteArrayOutputStream();
+ return persistenceManager.newWriter(memStream);
+ }
+
+ private LevelReader createLevelReader() throws IOException {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(memStream.toByteArray());
+ return persistenceManager.newReader(inStream);
+ }
+
+ @Test
+ public void testReadAndWrite() throws IOException{
+ persistenceManager.registerPersistableClasses(TestPersistable.class);
+
+ TestPersistable testPersist = new TestPersistable();
+ testPersist.doubleVal = 3.5;
+ testPersist.stringVal = "Test";
+ testPersist.vector3dVal = new Vector3d(1,2,3);
+
+ LevelWriter writer = createLevelWriter();
+ writer.write(testPersist);
+ writer.close();
+ assertFalse(writer.isInErrorState());
+
+ LevelReader reader = createLevelReader();
+ assertTrue(reader.hasNext());
+ TestPersistable result = (TestPersistable)reader.next();
+ assertFalse(reader.hasNext());
+
+ assertEquals(testPersist.doubleVal, result.doubleVal, 0.0001);
+ assertEquals(testPersist.stringVal, result.stringVal);
+ assertEquals(testPersist.vector3dVal, result.vector3dVal);
+ }
+
+}
View
43 tests/org/terasology/persistence/TestPersistable.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011 Benjamin Glatzel <benjamin.glatzel@me.com>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.terasology.persistence;
+
+import org.terasology.persistence.interfaces.Persistable;
+import org.terasology.persistence.interfaces.StorageReader;
+import org.terasology.persistence.interfaces.StorageWriter;
+
+import javax.vecmath.Vector3d;
+
+/**
+ * @author Immortius <immortius@gmail.com>
+ */
+public class TestPersistable implements Persistable {
+ String stringVal;
+ Vector3d vector3dVal;
+ double doubleVal;
+
+ public void store(StorageWriter writer) {
+ writer.write("string", stringVal);
+ writer.write("vector3d", vector3dVal);
+ writer.write("double", doubleVal);
+ }
+
+ public void retrieve(StorageReader reader) {
+ stringVal = reader.readString("string");
+ doubleVal = reader.readDouble("double",0);
+ vector3dVal = reader.read("vector3d", Vector3d.class);
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.