| File: System\Private\Windows\BinaryFormat\Serializer\Record.cs | Web Access |
| Project: src\winforms\src\System.Private.Windows.Core\src\Microsoft.Private.Windows.Core.csproj (Microsoft.Private.Windows.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; namespace System.Private.Windows.BinaryFormat.Serializer; /// <summary> /// Base record class. /// </summary> internal abstract class Record : IWritableRecord { // Prevent creating outside of the assembly. private protected Record() { } Id IRecord.Id => Id; private protected virtual Id Id => Id.Null; /// <summary> /// Writes <paramref name="value"/> as <paramref name="primitiveType"/> to the given <paramref name="writer"/>. /// </summary> private protected static unsafe void WritePrimitiveType(BinaryWriter writer, PrimitiveType primitiveType, object value) { switch (primitiveType) { case PrimitiveType.Boolean: writer.Write((bool)value); break; case PrimitiveType.Byte: writer.Write((byte)value); break; case PrimitiveType.Char: writer.Write((char)value); break; case PrimitiveType.Decimal: writer.Write(((decimal)value).ToString(CultureInfo.InvariantCulture)); break; case PrimitiveType.Double: writer.Write((double)value); break; case PrimitiveType.Int16: writer.Write((short)value); break; case PrimitiveType.Int32: writer.Write((int)value); break; case PrimitiveType.Int64: writer.Write((long)value); break; case PrimitiveType.SByte: writer.Write((sbyte)value); break; case PrimitiveType.Single: writer.Write((float)value); break; case PrimitiveType.TimeSpan: writer.Write(((TimeSpan)value).Ticks); break; case PrimitiveType.DateTime: writer.Write((DateTime)value); break; case PrimitiveType.UInt16: writer.Write((ushort)value); break; case PrimitiveType.UInt32: writer.Write((uint)value); break; case PrimitiveType.UInt64: writer.Write((ulong)value); break; // String is handled with a record, never on it's own case PrimitiveType.Null: case PrimitiveType.String: default: throw new ArgumentException("Invalid primitive type.", nameof(primitiveType)); } } /// <summary> /// Writes records, coalescing null records into single entries. /// </summary> /// <exception cref="InvalidOperationException"> /// <paramref name="objects"/> contained an object that isn't a record. /// </exception> private protected static void WriteRecords(BinaryWriter writer, IReadOnlyList<object?> objects, bool coalesceNulls) { int nullCount = 0; // Indexing for performance and avoiding writing an enumerator of ListConverter. for (int i = 0; i < objects.Count; i++) { object? @object = objects[i]; // Aggregate consecutive null records. if (@object is null) { nullCount++; if (coalesceNulls) { continue; } } if (nullCount > 0) { NullRecord.Write(writer, nullCount); nullCount = 0; } if (@object is not IWritableRecord record || record is NullRecord) { throw new ArgumentException("Invalid record.", nameof(objects)); } record.Write(writer); } if (nullCount > 0) { NullRecord.Write(writer, nullCount); } } private protected abstract void Write(BinaryWriter writer); void IWritableRecord.Write(BinaryWriter writer) => Write(writer); }