mirror of
https://github.com/simtactics/mysimulation.git
synced 2025-03-20 00:41:20 +00:00
- NioTSO client isn't needed because we're using RayLib - Added FreeSO's API server to handle most backend operations
304 lines
8.6 KiB
C#
Executable file
304 lines
8.6 KiB
C#
Executable file
using Mina.Core.Buffer;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace FSO.Common.Serialization
|
|
{
|
|
public static class IoBufferUtils
|
|
{
|
|
public static void PutSerializable(this IoBuffer buffer, object obj, ISerializationContext context)
|
|
{
|
|
buffer.PutSerializable(context, obj, false);
|
|
}
|
|
|
|
public static byte[] GetBytes(this IoBuffer buffer)
|
|
{
|
|
var result = new byte[buffer.Limit];
|
|
buffer.Get(result, 0, buffer.Limit);
|
|
return result;
|
|
}
|
|
|
|
public static T Deserialize<T>(byte[] bytes, ISerializationContext context) where T : IoBufferDeserializable
|
|
{
|
|
var buffer = IoBuffer.Wrap(bytes);
|
|
return Deserialize<T>(buffer, context);
|
|
}
|
|
|
|
public static T Deserialize<T>(IoBuffer buffer, ISerializationContext context) where T : IoBufferDeserializable
|
|
{
|
|
var model = Activator.CreateInstance<T>();
|
|
model.Deserialize(buffer, context);
|
|
return (T)model;
|
|
}
|
|
|
|
public static IoBuffer SerializableToIoBuffer(object obj, ISerializationContext context)
|
|
{
|
|
if (obj is IoBuffer)
|
|
{
|
|
var ioBuffer = (IoBuffer)obj;
|
|
return (IoBuffer)ioBuffer;
|
|
}
|
|
else if (obj is byte[])
|
|
{
|
|
var byteArray = (byte[])obj;
|
|
return IoBuffer.Wrap(byteArray);
|
|
}
|
|
else if (obj is IoBufferSerializable)
|
|
{
|
|
var ioBuffer = IoBuffer.Allocate(0);
|
|
ioBuffer.AutoExpand = true;
|
|
ioBuffer.Order = ByteOrder.BigEndian;
|
|
|
|
var serializable = (IoBufferSerializable)obj;
|
|
serializable.Serialize(ioBuffer, context);
|
|
ioBuffer.Flip();
|
|
return ioBuffer;
|
|
}
|
|
|
|
throw new Exception("Unknown serializable type: " + obj);
|
|
}
|
|
|
|
public static void PutSerializable(this IoBuffer buffer, ISerializationContext context, object obj, bool writeLength)
|
|
{
|
|
if(obj is IoBuffer)
|
|
{
|
|
var ioBuffer = (IoBuffer)obj;
|
|
if (writeLength){
|
|
buffer.PutUInt32((uint)ioBuffer.Remaining);
|
|
}
|
|
buffer.Put(ioBuffer);
|
|
}else if(obj is byte[])
|
|
{
|
|
var byteArray = (byte[])obj;
|
|
if (writeLength)
|
|
{
|
|
buffer.PutUInt32((uint)byteArray.Length);
|
|
}
|
|
buffer.Put(byteArray);
|
|
}else if(obj is IoBufferSerializable)
|
|
{
|
|
var ioBuffer = IoBuffer.Allocate(0);
|
|
ioBuffer.AutoExpand = true;
|
|
ioBuffer.Order = ByteOrder.BigEndian;
|
|
|
|
var serializable = (IoBufferSerializable)obj;
|
|
serializable.Serialize(ioBuffer, context);
|
|
ioBuffer.Flip();
|
|
|
|
if (writeLength)
|
|
{
|
|
buffer.PutUInt32((uint)ioBuffer.Remaining);
|
|
}
|
|
buffer.Put(ioBuffer);
|
|
}
|
|
}
|
|
|
|
public static void PutBool(this IoBuffer buffer, bool value)
|
|
{
|
|
buffer.Put(value ? (byte)0x01 : (byte)0x00);
|
|
}
|
|
|
|
public static bool GetBool(this IoBuffer buffer)
|
|
{
|
|
return buffer.Get() == 1 ? true : false;
|
|
}
|
|
|
|
public static void PutUInt32(this IoBuffer buffer, uint value)
|
|
{
|
|
int converted = unchecked((int)value);
|
|
buffer.PutInt32(converted);
|
|
}
|
|
|
|
public static uint GetUInt32(this IoBuffer buffer)
|
|
{
|
|
return (uint)buffer.GetInt32();
|
|
}
|
|
|
|
public static void PutUInt16(this IoBuffer buffer, ushort value)
|
|
{
|
|
buffer.PutInt16((short)value);
|
|
}
|
|
|
|
public static void PutUInt64(this IoBuffer buffer, ulong value)
|
|
{
|
|
buffer.PutInt64((long)value);
|
|
}
|
|
|
|
|
|
public static void PutEnum<T>(this IoBuffer buffer, T enumValue)
|
|
{
|
|
ushort value = Convert.ToUInt16((object)enumValue);
|
|
buffer.PutUInt16(value);
|
|
}
|
|
|
|
|
|
public static void PutUTF8(this IoBuffer buffer, string value)
|
|
{
|
|
if (value == null)
|
|
{
|
|
buffer.PutInt16(-1);
|
|
}
|
|
else
|
|
{
|
|
buffer.PutInt16((short)value.Length);
|
|
buffer.PutString(value, Encoding.UTF8);
|
|
}
|
|
}
|
|
|
|
public static string GetUTF8(this IoBuffer buffer)
|
|
{
|
|
short len = buffer.GetInt16();
|
|
if (len == -1)
|
|
{
|
|
return null;
|
|
}
|
|
return buffer.GetString(len, Encoding.UTF8);
|
|
}
|
|
|
|
public static ushort GetUInt16(this IoBuffer buffer)
|
|
{
|
|
return (ushort)buffer.GetInt16();
|
|
}
|
|
|
|
public static ulong GetUInt64(this IoBuffer buffer)
|
|
{
|
|
return (ulong)buffer.GetInt64();
|
|
}
|
|
|
|
public static T GetEnum<T>(this IoBuffer buffer)
|
|
{
|
|
return (T)System.Enum.Parse(typeof(T), buffer.GetUInt16().ToString());
|
|
}
|
|
|
|
public static String GetPascalVLCString(this IoBuffer buffer)
|
|
{
|
|
byte lengthByte = 0;
|
|
uint length = 0;
|
|
int shift = 0;
|
|
|
|
do
|
|
{
|
|
lengthByte = buffer.Get();
|
|
length |= (uint)((lengthByte & (uint)0x7F) << shift);
|
|
shift += 7;
|
|
} while (
|
|
(lengthByte >> 7) == 1
|
|
);
|
|
|
|
|
|
|
|
if (length > 0)
|
|
{
|
|
var data = new List<byte>();
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
data.Add(buffer.Get());
|
|
}
|
|
return Encoding.UTF8.GetString(data.ToArray());
|
|
}
|
|
else
|
|
{
|
|
return "";
|
|
}
|
|
}
|
|
|
|
public static byte[] GetPascalVLCString(String value)
|
|
{
|
|
if(value == null)
|
|
{
|
|
return new byte[] { 0x00 };
|
|
}
|
|
|
|
//TODO: Support strings bigger than 128 chars
|
|
var buffer = new byte[1 + value.Length];
|
|
buffer[0] = (byte)value.Length;
|
|
|
|
var chars = value.ToCharArray();
|
|
|
|
for(int i=0; i < chars.Length; i++){
|
|
buffer[i + 1] = (byte)chars[i];
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
|
|
public static void PutPascalVLCString(this IoBuffer buffer, String value)
|
|
{
|
|
byte[] encode = null;
|
|
long strlen = 0;
|
|
if (value != null)
|
|
{
|
|
encode = Encoding.UTF8.GetBytes(value);
|
|
strlen = encode.Length;
|
|
}
|
|
|
|
bool write = strlen > 0;
|
|
bool first = true;
|
|
while (strlen > 0 || first)
|
|
{
|
|
buffer.Put((byte)(((strlen > 127) ? (uint)128 : 0) | (strlen & 127)));
|
|
strlen >>= 7;
|
|
first = false;
|
|
}
|
|
|
|
if (write)
|
|
{
|
|
buffer.Put(encode);
|
|
}
|
|
}
|
|
|
|
public static String GetPascalString(this IoBuffer buffer)
|
|
{
|
|
byte len1 = buffer.Get();
|
|
byte len2 = buffer.Get();
|
|
byte len3 = buffer.Get();
|
|
byte len4 = buffer.Get();
|
|
len1 &= 0x7F;
|
|
|
|
long len = len1 << 24 | len2 << 16 | len3 << 8 | len4;
|
|
if (len > 0)
|
|
{
|
|
StringBuilder str = new StringBuilder();
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
str.Append((char)buffer.Get());
|
|
}
|
|
return str.ToString();
|
|
|
|
}
|
|
else
|
|
{
|
|
return "";
|
|
}
|
|
}
|
|
|
|
public static void PutPascalString(this IoBuffer buffer, String value)
|
|
{
|
|
|
|
long strlen = 0;
|
|
if (value != null)
|
|
{
|
|
strlen = value.Length;
|
|
}
|
|
|
|
byte len1 = (byte)((strlen >> 24) | 0x80);
|
|
byte len2 = (byte)((strlen >> 16) & 0xFF);
|
|
byte len3 = (byte)((strlen >> 8) & 0xFF);
|
|
byte len4 = (byte)(strlen & 0xFF);
|
|
|
|
buffer.Put(len1);
|
|
buffer.Put(len2);
|
|
buffer.Put(len3);
|
|
buffer.Put(len4);
|
|
|
|
if (strlen > 0)
|
|
{
|
|
foreach (char ch in value.ToCharArray())
|
|
{
|
|
buffer.Put((byte)ch);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|