1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-07 01:07:24 +08:00
osu-lazer/osu.Game/IO/Legacy/SerializationWriter.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

250 lines
7.7 KiB
C#
Raw Normal View History

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2018-04-13 17:19:50 +08:00
2022-06-17 15:37:17 +08:00
#nullable disable
2017-02-28 19:14:48 +08:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
2019-02-28 12:31:40 +08:00
// ReSharper disable ConditionIsAlwaysTrueOrFalse (we're allowing nulls to be passed to the writer where the underlying class doesn't).
// ReSharper disable HeuristicUnreachableCode
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
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
{
2021-06-23 14:10:03 +08:00
public SerializationWriter(Stream s, bool leaveOpen = false)
: base(s, Encoding.UTF8, leaveOpen)
2017-02-28 19:14:48 +08:00
{
}
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
/// <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);
}
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
/// <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);
}
}
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
/// <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);
}
}
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
/// <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);
}
}
2018-04-13 17:19:50 +08:00
2017-03-09 13:24:16 +08:00
/// <summary>
/// Writes DateTime to the buffer.
/// </summary>
/// <param name="dt"></param>
2017-02-28 19:14:48 +08:00
public void Write(DateTime dt)
{
Write(dt.ToUniversalTime().Ticks);
}
2018-04-13 17:19:50 +08:00
2017-03-09 13:24:16 +08:00
/// <summary> Writes a generic ICollection (such as an IList(T)) to the buffer.</summary>
2017-02-28 19:14:48 +08:00
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);
}
}
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
/// <summary> Writes a generic IDictionary to the buffer. </summary>
public void Write<TKey, TValue>(IDictionary<TKey, TValue> d)
2017-02-28 19:14:48 +08:00
{
if (d == null)
{
Write(-1);
}
else
{
Write(d.Count);
2019-04-01 11:16:05 +08:00
foreach (KeyValuePair<TKey, TValue> kvp in d)
2017-02-28 19:14:48 +08:00
{
WriteObject(kvp.Key);
WriteObject(kvp.Value);
}
}
}
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
/// <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)
2017-02-28 19:14:48 +08:00
{
case bool boolObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.boolType);
Write(boolObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case byte byteObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.byteType);
Write(byteObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case ushort ushortObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.uint16Type);
Write(ushortObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case uint uintObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.uint32Type);
Write(uintObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case ulong ulongObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.uint64Type);
Write(ulongObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case sbyte sbyteObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.sbyteType);
Write(sbyteObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case short shortObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.int16Type);
Write(shortObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case int intObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.int32Type);
Write(intObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case long longObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.int64Type);
Write(longObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case char charObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.charType);
base.Write(charObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case string stringObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.stringType);
base.Write(stringObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case float floatObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.singleType);
Write(floatObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case double doubleObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.doubleType);
Write(doubleObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case decimal decimalObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.decimalType);
Write(decimalObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case DateTime dateTimeObj:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.dateTimeType);
Write(dateTimeObj);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case byte[] byteArray:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.byteArrayType);
base.Write(byteArray);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
case char[] charArray:
2017-02-28 19:14:48 +08:00
Write((byte)ObjType.charArrayType);
base.Write(charArray);
2017-02-28 19:14:48 +08:00
break;
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
default:
2022-04-12 20:28:14 +08:00
throw new IOException("Serialization of arbitrary type is not supported.");
2017-02-28 19:14:48 +08:00
} // switch
} // if obj==null
} // WriteObject
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
public void WriteRawBytes(byte[] b)
{
base.Write(b);
}
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
public void WriteByteArray(byte[] b)
{
if (b == null)
{
Write(-1);
}
else
{
int len = b.Length;
Write(len);
if (len > 0) base.Write(b);
}
}
2018-04-13 17:19:50 +08:00
2017-02-28 19:14:48 +08:00
public void WriteUtf8(string str)
{
WriteRawBytes(Encoding.UTF8.GetBytes(str));
}
}
}