Created
March 1, 2019 12:25
-
-
Save alksily/8f735ae7a76b4a6c556d2ed5ee796980 to your computer and use it in GitHub Desktop.
Named Data Tags
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.aengine.ndt; | |
import java.io.*; | |
import java.util.*; | |
import java.util.zip.*; | |
/** | |
* Named Data Tags (NDT) - file format for save array map. | |
* StreamReader class for read data from *.ndt file; | |
*/ | |
public class StreamReader { | |
/** | |
* Read NDT structure from file | |
* | |
* @param file object class File with selected file. | |
* @return Map<String, Object> object structure. | |
*/ | |
public static HashMap<String, Object> read(File file) { | |
try { | |
DataInputStream data = new DataInputStream(new GZIPInputStream(new FileInputStream(file))); | |
try { | |
return read((DataInput) data); | |
} finally { | |
data.close(); | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
private static HashMap<String, Object> read(DataInput in) throws IOException { | |
if (in.readByte() != 9) { | |
throw new IOException("The root tag is incorrect."); | |
} | |
String name = readString(in); | |
HashMap<String, Object> map = readList(in); | |
if (!name.isEmpty()) { | |
map.put("$this.name", name); | |
} | |
return map; | |
} | |
private static Object readTag(DataInput in, byte type) throws IOException { | |
switch (type) { | |
case 1: | |
return in.readByte(); | |
case 2: | |
return in.readShort(); | |
case 3: | |
return in.readInt(); | |
case 4: | |
return in.readLong(); | |
case 5: | |
return in.readFloat(); | |
case 6: | |
return in.readDouble(); | |
case 7: | |
return readString(in); | |
case 8: | |
return readList(in); | |
case 9: | |
return readArray(in); | |
case 10: | |
return readByteArray(in); | |
default: | |
throw new IOException("Wrong data NDT type tags (1-10): " + type); | |
} | |
} | |
private static byte[] readByteArray(DataInput in) throws IOException { | |
byte[] data = new byte[in.readInt()]; | |
in.readFully(data); | |
return data; | |
} | |
private static String readString(DataInput in) throws IOException { | |
return in.readUTF(); | |
} | |
private static List<Object> readArray(DataInput in) throws IOException { | |
byte type = in.readByte(); | |
int length = in.readInt(); | |
List<Object> list = new ArrayList<Object>(length); | |
for (int i = 0; i < length; ++i) { | |
Object tag = readTag(in, type); | |
list.add(tag); | |
} | |
return list; | |
} | |
private static HashMap<String, Object> readList(DataInput in) throws IOException { | |
HashMap<String, Object> map = new HashMap<String, Object>(); | |
for (byte type; (type = in.readByte()) != 0; ) { | |
String name = readString(in); | |
Object tag = readTag(in, type); | |
map.put(name, tag); | |
} | |
return map; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.aengine.ndt; | |
import java.io.*; | |
import java.util.*; | |
import java.util.zip.*; | |
/** | |
* Named Data Tags (NDT) - file format for save array map. | |
* StreamWriter class for write data in *.ndt file; | |
*/ | |
public class StreamWriter { | |
/** | |
* Write NDT structure to file | |
* | |
* @param file object class File with selected file. | |
* @param map<String, Object> object with data | |
*/ | |
public static void write(File file, Map<String, Object> map) { | |
try { | |
DataOutputStream data = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(file))); | |
try { | |
write((DataOutput) data, map); | |
} finally { | |
data.close(); | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
private static void write(DataOutput out, Map<String, Object> map) throws IOException { | |
out.writeByte(9); | |
Object name = map.get("$this.name"); | |
writeString(out, name != null ? (String) name : ""); | |
writeList(out, map); | |
} | |
private static byte whichType(Object tag) { | |
if (tag instanceof Byte) return 1; | |
if (tag instanceof Short) return 2; | |
if (tag instanceof Integer) return 3; | |
if (tag instanceof Long) return 4; | |
if (tag instanceof Float) return 5; | |
if (tag instanceof Double) return 6; | |
if (tag instanceof String) return 7; | |
if (tag instanceof Map<?, ?>) return 8; | |
if (tag instanceof List<?>) return 9; | |
if (tag instanceof byte[]) return 10; | |
throw new RuntimeException("Wrong data type " + tag.getClass()); | |
} | |
@SuppressWarnings("unchecked") | |
private static void writeTag(DataOutput out, byte type, Object tag) throws IOException { | |
switch (type) { | |
case 1: | |
out.writeByte((Byte) tag); | |
break; | |
case 2: | |
out.writeShort((Short) tag); | |
break; | |
case 3: | |
out.writeInt((Integer) tag); | |
break; | |
case 4: | |
out.writeLong((Long) tag); | |
break; | |
case 5: | |
out.writeFloat((Float) tag); | |
break; | |
case 6: | |
out.writeDouble((Double) tag); | |
break; | |
case 7: | |
writeString(out, (String) tag); | |
break; | |
case 8: | |
writeList(out, (Map<String, Object>) tag); | |
break; | |
case 9: | |
writeArray(out, (List<Object>) tag); | |
break; | |
case 10: | |
writeByteArray(out, (byte[]) tag); | |
break; | |
default: | |
throw new IOException("Wrong data NDT type tags (1-10): " + type); | |
} | |
} | |
private static void writeByteArray(DataOutput out, byte[] array) throws IOException { | |
out.writeInt(array.length); | |
out.write(array); | |
} | |
private static void writeString(DataOutput out, String str) throws IOException { | |
out.writeUTF(str); | |
} | |
private static void writeArray(DataOutput out, List<Object> list) throws IOException { | |
byte type = list.isEmpty() ? 1 : whichType(list.get(0)); | |
out.writeByte(type); | |
out.writeInt(list.size()); | |
for (Object tag : list) { | |
writeTag(out, type, tag); | |
} | |
} | |
private static void writeList(DataOutput out, Map<String, Object> map) throws IOException { | |
for (Map.Entry<String, Object> entry : map.entrySet()) { | |
if (entry.getKey().equals("$this.name")) { | |
continue; // skip internal name | |
} | |
byte type = whichType(entry.getValue()); | |
out.writeByte(type); | |
writeString(out, entry.getKey()); | |
writeTag(out, type, entry.getValue()); | |
} | |
out.writeByte(0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment