Files
sbox-public/engine/Sandbox.System/Utility/BytePack/Packers/ListPacker.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

103 lines
2.1 KiB
C#

using System.Collections;
namespace Sandbox;
internal partial class BytePack
{
class ListPacker : Packer
{
internal override Identifier Header => Identifier.List;
public override void Write( ref ByteStream bs, object obj )
{
if ( obj is not IList list ) throw new NotSupportedException();
var et = obj.GetType().GenericTypeArguments[0];
bs.Write( list.Count );
// List<object> etc - each type needs a header
if ( et == typeof( object ) )
{
bs.Write<byte>( 1 );
for ( int i = 0; i < list.Count; i++ )
{
Serialize( ref bs, list[i] );
}
return;
}
var w = GetHandlerFor( et );
// List<int> etc - value type - easy mode
if ( SandboxedUnsafe.IsAcceptablePod( et ) )
{
bs.Write<byte>( 0 );
w.WriteTypeIdentifier( ref bs, et );
var array = Array.CreateInstance( et, list.Count );
list.CopyTo( array, 0 );
bs.WriteValueArray( array );
return;
}
bs.Write<byte>( 2 );
w.WriteTypeIdentifier( ref bs, et );
for ( int i = 0; i < list.Count; i++ )
{
w.Serialize( ref bs, list[i] );
}
}
public override object Read( ref ByteStream bs )
{
var len = bs.Read<int>();
var type = bs.Read<byte>();
// List<int> etc - value type - easy mode
if ( type == 0 )
{
var handler = GetHandlerFor( ref bs );
var array = Array.CreateInstance( handler.TargetType, len );
bs.ReadValueArray( array );
return Activator.CreateInstance( typeof( List<> ).MakeGenericType( handler.TargetType ), new object[] { array } );
}
// List<object> etc - each type needs a header, slow mode
if ( type == 1 )
{
var list = new List<object>();
for ( int i = 0; i < len; i++ )
{
list.Add( Deserialize( ref bs ) );
}
return list;
}
// some type
if ( type == 2 )
{
var handler = GetHandlerFor( ref bs );
var list = (IList)Activator.CreateInstance( typeof( List<> ).MakeGenericType( handler.TargetType ) );
for ( int i = 0; i < len; i++ )
{
list.Add( handler.Deserialize( ref bs ) );
}
return list;
}
throw new NotSupportedException();
}
}
}