An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
5.7 KiB

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using UnityEngine;
namespace UnityTest
{
public class DTOFormatter {
private interface ITransferInterface
{
void Transfer(ref ResultDTO.MessageType val);
void Transfer(ref TestResultState val);
void Transfer(ref byte val);
void Transfer(ref bool val);
void Transfer(ref int val);
void Transfer(ref float val);
void Transfer(ref double val);
void Transfer(ref string val);
}
private class Writer : ITransferInterface
{
private readonly Stream _stream;
public Writer(Stream stream) { _stream = stream; }
private void WriteConvertedNumber(byte[] bytes)
{
if(BitConverter.IsLittleEndian)
Array.Reverse(bytes);
_stream.Write(bytes, 0, bytes.Length);
}
public void Transfer(ref ResultDTO.MessageType val) { _stream.WriteByte((byte)val); }
public void Transfer(ref TestResultState val) { _stream.WriteByte((byte)val); }
public void Transfer(ref byte val) { _stream.WriteByte(val); }
public void Transfer(ref bool val) { _stream.WriteByte((byte)(val ? 0x01 : 0x00)); }
public void Transfer(ref int val) { WriteConvertedNumber(BitConverter.GetBytes(val)); }
public void Transfer(ref float val) { WriteConvertedNumber(BitConverter.GetBytes(val)); }
public void Transfer(ref double val) { WriteConvertedNumber(BitConverter.GetBytes(val)); }
public void Transfer(ref string val)
{
var bytes = Encoding.BigEndianUnicode.GetBytes(val);
int length = bytes.Length;
Transfer(ref length);
_stream.Write(bytes, 0, bytes.Length);
}
}
private class Reader : ITransferInterface
{
private readonly Stream _stream;
public Reader(Stream stream) { _stream = stream; }
private byte[] ReadConvertedNumber(int size)
{
byte[] buffer = new byte[size];
_stream.Read (buffer, 0, buffer.Length);
if(BitConverter.IsLittleEndian)
Array.Reverse(buffer);
return buffer;
}
public void Transfer(ref ResultDTO.MessageType val) { val = (ResultDTO.MessageType)_stream.ReadByte(); }
public void Transfer(ref TestResultState val) { val = (TestResultState)_stream.ReadByte(); }
public void Transfer(ref byte val) { val = (byte)_stream.ReadByte(); }
public void Transfer(ref bool val) { val = (_stream.ReadByte() != 0); }
public void Transfer(ref int val) { val = BitConverter.ToInt32(ReadConvertedNumber(4), 0); }
public void Transfer(ref float val) { val = BitConverter.ToSingle(ReadConvertedNumber(4), 0); }
public void Transfer(ref double val) { val = BitConverter.ToDouble(ReadConvertedNumber(8), 0); }
public void Transfer(ref string val)
{
int length = 0;
Transfer (ref length);
var bytes = new byte[length];
int remain = length;
int index = 0;
do {
int bytesRead = _stream.Read(bytes, index, remain);
remain -= bytesRead;
index += bytesRead;
} while (remain > 0);
#if !UNITY_WSA
val = Encoding.BigEndianUnicode.GetString(bytes);
#endif
}
}
private void Transfer(ResultDTO dto, ITransferInterface transfer)
{
transfer.Transfer(ref dto.messageType);
transfer.Transfer(ref dto.levelCount);
transfer.Transfer(ref dto.loadedLevel);
transfer.Transfer(ref dto.loadedLevelName);
if(dto.messageType == ResultDTO.MessageType.Ping
|| dto.messageType == ResultDTO.MessageType.RunStarted
|| dto.messageType == ResultDTO.MessageType.RunFinished
|| dto.messageType == ResultDTO.MessageType.RunInterrupted
|| dto.messageType == ResultDTO.MessageType.AllScenesFinished)
return;
transfer.Transfer(ref dto.testName);
transfer.Transfer(ref dto.testTimeout);
if(dto.messageType == ResultDTO.MessageType.TestStarted)
return;
if(transfer is Reader)
dto.testResult = new SerializableTestResult();
SerializableTestResult str = (SerializableTestResult)dto.testResult;
transfer.Transfer(ref str.resultState);
transfer.Transfer(ref str.message);
transfer.Transfer(ref str.executed);
transfer.Transfer(ref str.name);
transfer.Transfer(ref str.fullName);
transfer.Transfer(ref str.id);
transfer.Transfer(ref str.isSuccess);
transfer.Transfer(ref str.duration);
transfer.Transfer(ref str.stackTrace);
}
public void Serialize (Stream stream, ResultDTO dto)
{
Transfer(dto, new Writer(stream));
}
public object Deserialize (Stream stream)
{
#if !UNITY_WSA
var result = (ResultDTO)FormatterServices.GetSafeUninitializedObject(typeof(ResultDTO));
Transfer (result, new Reader(stream));
return result;
#else
return null;
#endif
}
}
}