198 lines
5.9 KiB
C#
198 lines
5.9 KiB
C#
// /**
|
|
// * File: ObjectReader.cs
|
|
// * Author: haraldwolff
|
|
// *
|
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
|
// *
|
|
// *
|
|
// **/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Runtime.InteropServices.WindowsRuntime;
|
|
using System.Linq;
|
|
namespace ln.types.serialize
|
|
{
|
|
public class ObjectReader : IDisposable
|
|
{
|
|
public Stream Stream { get; }
|
|
|
|
public object[] ReferencedObjects
|
|
{
|
|
get => referencedObjects.ToArray();
|
|
set => referencedObjects = new List<object>(value);
|
|
}
|
|
|
|
List<object> referencedObjects = new List<object>();
|
|
|
|
public ObjectReader(Stream stream)
|
|
{
|
|
Stream = stream;
|
|
}
|
|
public ObjectReader(String fileName)
|
|
{
|
|
Stream = new FileStream(fileName,FileMode.Open);
|
|
}
|
|
|
|
public virtual object QueryReferencedObject(object re)
|
|
{
|
|
return referencedObjects[(int)re];
|
|
}
|
|
|
|
public object Read()
|
|
{
|
|
byte[] b;
|
|
|
|
char ch = (char)Stream.ReadByte();
|
|
switch (ch)
|
|
{
|
|
case 'N':
|
|
return null;
|
|
case 'O':
|
|
return ReadObject();
|
|
case 'o':
|
|
return QueryReferencedObject(Read());
|
|
case 's':
|
|
return ReadString();
|
|
case '8':
|
|
return (byte)Stream.ReadByte();
|
|
case '2':
|
|
b = new byte[2];
|
|
Stream.Read(b, 0, b.Length);
|
|
return BitConverter.ToInt16(b, 0);
|
|
case '4':
|
|
b = new byte[4];
|
|
Stream.Read(b, 0, b.Length);
|
|
return BitConverter.ToInt32(b, 0);
|
|
case 'L':
|
|
b = new byte[8];
|
|
Stream.Read(b, 0, b.Length);
|
|
return BitConverter.ToInt64(b, 0);
|
|
case '3':
|
|
b = new byte[2];
|
|
Stream.Read(b, 0, b.Length);
|
|
return BitConverter.ToUInt16(b, 0);
|
|
case '5':
|
|
b = new byte[4];
|
|
Stream.Read(b, 0, b.Length);
|
|
return BitConverter.ToUInt32(b, 0);
|
|
case 'l':
|
|
b = new byte[8];
|
|
Stream.Read(b, 0, b.Length);
|
|
return BitConverter.ToUInt64(b, 0);
|
|
case 'f':
|
|
b = new byte[4];
|
|
Stream.Read(b, 0, b.Length);
|
|
return BitConverter.ToSingle(b, 0);
|
|
case 'd':
|
|
b = new byte[8];
|
|
Stream.Read(b, 0, b.Length);
|
|
return BitConverter.ToDouble(b, 0);
|
|
case 'B':
|
|
return true;
|
|
case 'b':
|
|
return false;
|
|
case 'S':
|
|
return ReadStruct();
|
|
case 'A':
|
|
return ReadArray();
|
|
default:
|
|
throw new NotImplementedException(String.Format("Identifier {0} (0x{1:x8})",ch,(int)ch));
|
|
}
|
|
}
|
|
|
|
public Array ReadArray()
|
|
{
|
|
List<object> items = new List<object>();
|
|
string assemblyName = Read() as string;
|
|
String typeName = Read() as string;
|
|
int length = (int)Read();
|
|
|
|
Type eType = Assembly.Load(assemblyName).GetType(typeName);
|
|
|
|
Array array = Array.CreateInstance(eType, length);
|
|
|
|
for (int n = 0; n < length; n++)
|
|
array.SetValue(Read(), n);
|
|
|
|
return array;
|
|
}
|
|
|
|
public object ReadObject()
|
|
{
|
|
String assemblyName = Read() as string;
|
|
String typeName = Read() as string;
|
|
|
|
|
|
object o = Activator.CreateInstance(assemblyName, typeName).Unwrap();
|
|
Type type = o.GetType();
|
|
|
|
referencedObjects.Add(o);
|
|
|
|
ReadFields(o);
|
|
|
|
return o;
|
|
}
|
|
|
|
public void ReadThis(object o)
|
|
{
|
|
Stream.ReadByte();
|
|
String assemblyName = Read() as string;
|
|
String typeName = Read() as string;
|
|
ReadFields(o);
|
|
}
|
|
|
|
private void ReadFields(object o)
|
|
{
|
|
Type type = o.GetType();
|
|
int nFields = (int)Read();
|
|
|
|
for (int n = 0; n < nFields; n++)
|
|
{
|
|
string fieldName = Read() as string;
|
|
object value = Read();
|
|
|
|
FieldInfo fieldInfo = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
fieldInfo.SetValue(o, value);
|
|
}
|
|
}
|
|
|
|
public object ReadStruct()
|
|
{
|
|
String assemblyName = Read() as string;
|
|
String typeName = Read() as string;
|
|
int nFields = (int)Read();
|
|
|
|
object o = Activator.CreateInstance(assemblyName, typeName).Unwrap();
|
|
Type type = o.GetType();
|
|
|
|
for (int n = 0; n < nFields; n++)
|
|
{
|
|
string fieldName = Read() as string;
|
|
object value = Read();
|
|
|
|
FieldInfo fieldInfo = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
fieldInfo.SetValue(o, value);
|
|
}
|
|
|
|
return o;
|
|
}
|
|
private string ReadString()
|
|
{
|
|
int length = (int)Read();
|
|
byte[] buffer = new byte[length];
|
|
Stream.Read(buffer, 0, length);
|
|
return Encoding.UTF8.GetString(buffer);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Stream.Close();
|
|
Stream.Dispose();
|
|
}
|
|
}
|
|
}
|