mirror of
https://github.com/osukey/osukey.git
synced 2025-07-03 01:09:57 +09:00
Basic partial replay support.
This commit is contained in:
255
osu.Game/IO/Legacy/SerializationWriter.cs
Normal file
255
osu.Game/IO/Legacy/SerializationWriter.cs
Normal file
@ -0,0 +1,255 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
|
||||
namespace osu.Game.IO.Legacy
|
||||
{
|
||||
/// <summary> SerializationWriter. Extends BinaryWriter to add additional data types,
|
||||
/// handle null strings and simplify use with ISerializable. </summary>
|
||||
public class SerializationWriter : BinaryWriter
|
||||
{
|
||||
public SerializationWriter(Stream s)
|
||||
: base(s, Encoding.UTF8)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary> Static method to initialise the writer with a suitable MemoryStream. </summary>
|
||||
public static SerializationWriter GetWriter()
|
||||
{
|
||||
MemoryStream ms = new MemoryStream(1024);
|
||||
return new SerializationWriter(ms);
|
||||
}
|
||||
|
||||
/// <summary> Writes a string to the buffer. Overrides the base implementation so it can cope with nulls </summary>
|
||||
public override void Write(string str)
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
Write((byte)ObjType.nullType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write((byte)ObjType.stringType);
|
||||
base.Write(str);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Writes a byte array to the buffer. Overrides the base implementation to
|
||||
/// send the length of the array which is needed when it is retrieved </summary>
|
||||
public override void Write(byte[] b)
|
||||
{
|
||||
if (b == null)
|
||||
{
|
||||
Write(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = b.Length;
|
||||
Write(len);
|
||||
if (len > 0) base.Write(b);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Writes a char array to the buffer. Overrides the base implementation to
|
||||
/// sends the length of the array which is needed when it is read. </summary>
|
||||
public override void Write(char[] c)
|
||||
{
|
||||
if (c == null)
|
||||
{
|
||||
Write(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = c.Length;
|
||||
Write(len);
|
||||
if (len > 0) base.Write(c);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Writes a DateTime to the buffer. <summary>
|
||||
public void Write(DateTime dt)
|
||||
{
|
||||
Write(dt.ToUniversalTime().Ticks);
|
||||
}
|
||||
|
||||
/// <summary> Writes a generic ICollection (such as an IList<T>) to the buffer. </summary>
|
||||
public void Write<T>(List<T> c) where T : ILegacySerializable
|
||||
{
|
||||
if (c == null)
|
||||
{
|
||||
Write(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = c.Count;
|
||||
Write(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
c[i].WriteToStream(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Writes a generic IDictionary to the buffer. </summary>
|
||||
public void Write<T, U>(IDictionary<T, U> d)
|
||||
{
|
||||
if (d == null)
|
||||
{
|
||||
Write(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(d.Count);
|
||||
foreach (KeyValuePair<T, U> kvp in d)
|
||||
{
|
||||
WriteObject(kvp.Key);
|
||||
WriteObject(kvp.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Writes an arbitrary object to the buffer. Useful where we have something of type "object"
|
||||
/// and don't know how to treat it. This works out the best method to use to write to the buffer. </summary>
|
||||
public void WriteObject(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
Write((byte)ObjType.nullType);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (obj.GetType().Name)
|
||||
{
|
||||
case "Boolean":
|
||||
Write((byte)ObjType.boolType);
|
||||
Write((bool)obj);
|
||||
break;
|
||||
|
||||
case "Byte":
|
||||
Write((byte)ObjType.byteType);
|
||||
Write((byte)obj);
|
||||
break;
|
||||
|
||||
case "UInt16":
|
||||
Write((byte)ObjType.uint16Type);
|
||||
Write((ushort)obj);
|
||||
break;
|
||||
|
||||
case "UInt32":
|
||||
Write((byte)ObjType.uint32Type);
|
||||
Write((uint)obj);
|
||||
break;
|
||||
|
||||
case "UInt64":
|
||||
Write((byte)ObjType.uint64Type);
|
||||
Write((ulong)obj);
|
||||
break;
|
||||
|
||||
case "SByte":
|
||||
Write((byte)ObjType.sbyteType);
|
||||
Write((sbyte)obj);
|
||||
break;
|
||||
|
||||
case "Int16":
|
||||
Write((byte)ObjType.int16Type);
|
||||
Write((short)obj);
|
||||
break;
|
||||
|
||||
case "Int32":
|
||||
Write((byte)ObjType.int32Type);
|
||||
Write((int)obj);
|
||||
break;
|
||||
|
||||
case "Int64":
|
||||
Write((byte)ObjType.int64Type);
|
||||
Write((long)obj);
|
||||
break;
|
||||
|
||||
case "Char":
|
||||
Write((byte)ObjType.charType);
|
||||
base.Write((char)obj);
|
||||
break;
|
||||
|
||||
case "String":
|
||||
Write((byte)ObjType.stringType);
|
||||
base.Write((string)obj);
|
||||
break;
|
||||
|
||||
case "Single":
|
||||
Write((byte)ObjType.singleType);
|
||||
Write((float)obj);
|
||||
break;
|
||||
|
||||
case "Double":
|
||||
Write((byte)ObjType.doubleType);
|
||||
Write((double)obj);
|
||||
break;
|
||||
|
||||
case "Decimal":
|
||||
Write((byte)ObjType.decimalType);
|
||||
Write((decimal)obj);
|
||||
break;
|
||||
|
||||
case "DateTime":
|
||||
Write((byte)ObjType.dateTimeType);
|
||||
Write((DateTime)obj);
|
||||
break;
|
||||
|
||||
case "Byte[]":
|
||||
Write((byte)ObjType.byteArrayType);
|
||||
base.Write((byte[])obj);
|
||||
break;
|
||||
|
||||
case "Char[]":
|
||||
Write((byte)ObjType.charArrayType);
|
||||
base.Write((char[])obj);
|
||||
break;
|
||||
|
||||
default:
|
||||
Write((byte)ObjType.otherType);
|
||||
BinaryFormatter b = new BinaryFormatter();
|
||||
b.AssemblyFormat = FormatterAssemblyStyle.Simple;
|
||||
b.TypeFormat = FormatterTypeStyle.TypesWhenNeeded;
|
||||
b.Serialize(BaseStream, obj);
|
||||
break;
|
||||
} // switch
|
||||
} // if obj==null
|
||||
} // WriteObject
|
||||
|
||||
/// <summary> Adds the SerializationWriter buffer to the SerializationInfo at the end of GetObjectData(). </summary>
|
||||
public void AddToInfo(SerializationInfo info)
|
||||
{
|
||||
byte[] b = ((MemoryStream)BaseStream).ToArray();
|
||||
info.AddValue("X", b, typeof(byte[]));
|
||||
}
|
||||
|
||||
public void WriteRawBytes(byte[] b)
|
||||
{
|
||||
base.Write(b);
|
||||
}
|
||||
|
||||
public void WriteByteArray(byte[] b)
|
||||
{
|
||||
if (b == null)
|
||||
{
|
||||
Write(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = b.Length;
|
||||
Write(len);
|
||||
if (len > 0) base.Write(b);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteUtf8(string str)
|
||||
{
|
||||
WriteRawBytes(Encoding.UTF8.GetBytes(str));
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user