serde-generate/runtime/csharp/Bcs/BcsSerializer.cs (57 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates
// SPDX-License-Identifier: MIT OR Apache-2.0
using Serde;
using System;
using System.IO;
namespace Bcs
{
public class BcsSerializer : BinarySerializer
{
public const long MAX_LENGTH = int.MaxValue;
public const long MAX_CONTAINER_DEPTH = 500;
public BcsSerializer() : base(MAX_CONTAINER_DEPTH) { }
public BcsSerializer(byte[] buffer) : base(buffer, MAX_CONTAINER_DEPTH) { }
public BcsSerializer(ArraySegment<byte> buffer) : base(buffer, MAX_CONTAINER_DEPTH) { }
private void serialize_u32_as_uleb128(uint value)
{
while ((value >> 7) != 0)
{
output.Write((byte)((value & 0x7f) | 0x80));
value >>= 7;
}
output.Write((byte)value);
}
public override void serialize_len(long value)
{
if ((value < 0) || (value > MAX_LENGTH))
{
throw new SerializationException("length value doesn't fit in uint32");
}
serialize_u32_as_uleb128((uint)value);
}
public override void serialize_variant_index(int value) => serialize_u32_as_uleb128((uint)value);
static ReadOnlySpan<byte> Slice(byte[] array, (int start, int end) tup) =>
new ReadOnlySpan<byte>(array, tup.start, tup.end - tup.start);
public override void sort_map_entries(int[] offsets)
{
if (offsets.Length <= 1)
{
return;
}
int offset0 = offsets[0];
var ranges = new (int start, int end)[offsets.Length];
for (int i = 0; i < offsets.Length - 1; i++)
{
ranges[i] = (offsets[i] - offset0, offsets[i + 1] - offset0);
}
ranges[ranges.Length - 1] = (offsets[offsets.Length - 1] - offset0, (int)buffer.Length - offset0);
byte[] data = new byte[buffer.Length - offset0];
buffer.Seek(offset0, SeekOrigin.Begin);
buffer.Read(data, 0, data.Length);
Array.Sort(ranges, (l, r) => Verification.CompareLexicographic(Slice(data, l), Slice(data, r)));
buffer.Seek(offset0, SeekOrigin.Begin);
foreach (var range in ranges)
{
buffer.Write(data, range.start, range.end - range.start);
}
}
}
}