| File: BinaryWriterExtensions.cs | Web Access |
| Project: src\msbuild\src\Framework\Microsoft.Build.Framework.csproj (Microsoft.Build.Framework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.IO; using System.Runtime.CompilerServices; namespace Microsoft.Build.Framework; internal static class BinaryWriterExtensions { #if !NET [ThreadStatic] private static byte[]? s_guidBuffer; #endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteOptionalString(this BinaryWriter writer, string? value) { if (value == null) { writer.Write((byte)0); } else { writer.Write((byte)1); writer.Write(value); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteOptionalInt32(this BinaryWriter writer, int? value) { if (value == null) { writer.Write((byte)0); } else { writer.Write((byte)1); writer.Write(value.Value); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTimestamp(this BinaryWriter writer, DateTime timestamp) { writer.Write(timestamp.Ticks); writer.Write((Int32)timestamp.Kind); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Write7BitEncodedInt(this BinaryWriter writer, int value) { // Write out an int 7 bits at a time. The high bit of the byte, // when on, tells reader to continue reading more bytes. uint v = (uint)value; // support negative numbers while (v >= 0x80) { writer.Write((byte)(v | 0x80)); v >>= 7; } writer.Write((byte)v); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteOptionalBuildEventContext(this BinaryWriter writer, BuildEventContext? context) { if (context == null) { writer.Write((byte)0); } else { writer.Write((byte)1); writer.WriteBuildEventContext(context); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteBuildEventContext(this BinaryWriter writer, BuildEventContext context) { writer.Write(context.NodeId); writer.Write(context.ProjectContextId); writer.Write(context.TargetId); writer.Write(context.TaskId); writer.Write(context.SubmissionId); writer.Write(context.ProjectInstanceId); writer.Write(context.EvaluationId); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGuid(this BinaryWriter writer, Guid value) { const int GuidSize = 16; #if NET Span<byte> bytes = stackalloc byte[GuidSize]; value.TryWriteBytes(bytes); #else byte[] bytes = s_guidBuffer ??= new byte[GuidSize]; unsafe { fixed (byte* ptr = bytes) { *(Guid*)ptr = value; } } #endif writer.Write(bytes); } public static void WriteExtendedBuildEventData(this BinaryWriter writer, IExtendedBuildEventArgs data) { writer.Write(data.ExtendedType); writer.WriteOptionalString(data.ExtendedData); writer.Write(data.ExtendedMetadata != null); if (data.ExtendedMetadata != null) { writer.Write7BitEncodedInt(data.ExtendedMetadata.Count); foreach (KeyValuePair<string, string?> kvp in data.ExtendedMetadata) { writer.Write(kvp.Key); writer.WriteOptionalString(kvp.Value); } } } public static void WriteDurationsDictionary(this BinaryWriter writer, Dictionary<string, TimeSpan> durations) { writer.Write7BitEncodedInt(durations.Count); foreach (KeyValuePair<string, TimeSpan> kvp in durations) { writer.Write(kvp.Key); writer.Write(kvp.Value.Ticks); } } }