blob: 87edb063d8acf3098a1f2179b265f341a79dc887 [file] [log] [blame]
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace DotPulsar.Internal
{
using PulsarApi;
using System;
using System.Buffers;
using System.IO;
public static class Serializer
{
public static T Deserialize<T>(ReadOnlySequence<byte> sequence) => ProtoBuf.Serializer.Deserialize<T>(sequence);
public static ReadOnlySequence<byte> Serialize(BaseCommand command)
{
var commandBytes = Serialize<BaseCommand>(command);
var commandSizeBytes = ToBigEndianBytes((uint) commandBytes.Length);
var totalSizeBytes = ToBigEndianBytes((uint) commandBytes.Length + 4);
return new SequenceBuilder<byte>()
.Append(totalSizeBytes)
.Append(commandSizeBytes)
.Append(commandBytes)
.Build();
}
public static ReadOnlySequence<byte> Serialize(BaseCommand command, MessageMetadata metadata, ReadOnlySequence<byte> payload)
{
var commandBytes = Serialize<BaseCommand>(command);
var commandSizeBytes = ToBigEndianBytes((uint) commandBytes.Length);
var metadataBytes = Serialize(metadata);
var metadataSizeBytes = ToBigEndianBytes((uint) metadataBytes.Length);
var sb = new SequenceBuilder<byte>().Append(metadataSizeBytes).Append(metadataBytes).Append(payload);
var checksum = Crc32C.Calculate(sb.Build());
return sb.Prepend(ToBigEndianBytes(checksum))
.Prepend(Constants.MagicNumber)
.Prepend(commandBytes)
.Prepend(commandSizeBytes)
.Prepend(ToBigEndianBytes((uint) sb.Length))
.Build();
}
public static byte[] ToBigEndianBytes(uint integer)
{
var union = new UIntUnion(integer);
return BitConverter.IsLittleEndian
? new[] { union.B3, union.B2, union.B1, union.B0 }
: new[] { union.B0, union.B1, union.B2, union.B3 };
}
private static byte[] Serialize<T>(T item)
{
using var ms = new MemoryStream();
ProtoBuf.Serializer.Serialize(ms, item);
return ms.ToArray();
}
}
}