| File: Commands\Test\MTP\IPC\Serializers\CommandLineOptionMessagesSerializer.cs | Web Access |
| Project: src\sdk\src\Cli\dotnet\dotnet.csproj (dotnet) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using Microsoft.DotNet.Cli.Commands.Test.IPC.Models; namespace Microsoft.DotNet.Cli.Commands.Test.IPC.Serializers; /* |---FieldCount---| 2 bytes |---ModuleName Id---| (2 bytes) |---ModuleName Size---| (4 bytes) |---ModuleName Value---| (n bytes) |---CommandLineOptionMessageList Id---| (2 bytes) |---CommandLineOptionMessageList Size---| (4 bytes) |---CommandLineOptionMessageList Value---| (n bytes) |---CommandLineOptionMessageList Length---| (4 bytes) |---CommandLineOptionMessageList[0] FieldCount---| 2 bytes |---CommandLineOptionMessageList[0].Name Id---| (2 bytes) |---CommandLineOptionMessageList[0].Name Size---| (4 bytes) |---CommandLineOptionMessageList[0].Name Value---| (n bytes) |---CommandLineOptionMessageList[0].Description Id---| (2 bytes) |---CommandLineOptionMessageList[0].Description Size---| (4 bytes) |---CommandLineOptionMessageList[0].Description Value---| (n bytes) |---CommandLineOptionMessageList[0].IsHidden Id---| (2 bytes) |---CommandLineOptionMessageList[0].IsHidden Size---| (4 bytes) |---CommandLineOptionMessageList[0].IsHidden Value---| (1 byte) |---CommandLineOptionMessageList[0].IsBuiltIn Id---| (2 bytes) |---CommandLineOptionMessageList[0].IsBuiltIn Size---| (4 bytes) |---CommandLineOptionMessageList[0].IsBuiltIn Value---| (1 byte) */ internal sealed class CommandLineOptionMessagesSerializer : BaseSerializer, INamedPipeSerializer { public int Id => CommandLineOptionMessagesFieldsId.MessagesSerializerId; public object Deserialize(Stream stream) { string? moduleName = null; List<CommandLineOptionMessage>? commandLineOptionMessages = null; ushort fieldCount = ReadUShort(stream); for (int i = 0; i < fieldCount; i++) { int fieldId = ReadUShort(stream); int fieldSize = ReadInt(stream); switch (fieldId) { case CommandLineOptionMessagesFieldsId.ModulePath: moduleName = ReadStringValue(stream, fieldSize); break; case CommandLineOptionMessagesFieldsId.CommandLineOptionMessageList: commandLineOptionMessages = ReadCommandLineOptionMessagesPayload(stream); break; default: // If we don't recognize the field id, skip the payload corresponding to that field SetPosition(stream, stream.Position + fieldSize); break; } } return new CommandLineOptionMessages(moduleName, commandLineOptionMessages is null ? [] : [.. commandLineOptionMessages]); } private static List<CommandLineOptionMessage> ReadCommandLineOptionMessagesPayload(Stream stream) { List<CommandLineOptionMessage> commandLineOptionMessages = []; int length = ReadInt(stream); for (int i = 0; i < length; i++) { string? name = null, description = null; bool? isHidden = null, isBuiltIn = null; int fieldCount = ReadUShort(stream); for (int j = 0; j < fieldCount; j++) { int fieldId = ReadUShort(stream); int fieldSize = ReadInt(stream); switch (fieldId) { case CommandLineOptionMessageFieldsId.Name: name = ReadStringValue(stream, fieldSize); break; case CommandLineOptionMessageFieldsId.Description: description = ReadStringValue(stream, fieldSize); break; case CommandLineOptionMessageFieldsId.IsHidden: isHidden = ReadBool(stream); break; case CommandLineOptionMessageFieldsId.IsBuiltIn: isBuiltIn = ReadBool(stream); break; default: SetPosition(stream, stream.Position + fieldSize); break; } } commandLineOptionMessages.Add(new CommandLineOptionMessage(name, description, isHidden, isBuiltIn)); } return commandLineOptionMessages; } public void Serialize(object objectToSerialize, Stream stream) { Debug.Assert(stream.CanSeek, "We expect a seekable stream."); var commandLineOptionMessages = (CommandLineOptionMessages)objectToSerialize; WriteUShort(stream, GetFieldCount(commandLineOptionMessages)); WriteField(stream, CommandLineOptionMessagesFieldsId.ModulePath, commandLineOptionMessages.ModulePath); WriteCommandLineOptionMessagesPayload(stream, commandLineOptionMessages.CommandLineOptionMessageList); } private static void WriteCommandLineOptionMessagesPayload(Stream stream, CommandLineOptionMessage[]? commandLineOptionMessageList) { if (commandLineOptionMessageList is null || commandLineOptionMessageList.Length == 0) { return; } WriteUShort(stream, CommandLineOptionMessagesFieldsId.CommandLineOptionMessageList); // We will reserve an int (4 bytes) // so that we fill the size later, once we write the payload WriteInt(stream, 0); long before = stream.Position; WriteInt(stream, commandLineOptionMessageList.Length); foreach (CommandLineOptionMessage commandLineOptionMessage in commandLineOptionMessageList) { WriteUShort(stream, GetFieldCount(commandLineOptionMessage)); WriteField(stream, CommandLineOptionMessageFieldsId.Name, commandLineOptionMessage.Name); WriteField(stream, CommandLineOptionMessageFieldsId.Description, commandLineOptionMessage.Description); WriteField(stream, CommandLineOptionMessageFieldsId.IsHidden, commandLineOptionMessage.IsHidden); WriteField(stream, CommandLineOptionMessageFieldsId.IsBuiltIn, commandLineOptionMessage.IsBuiltIn); } // NOTE: We are able to seek only if we are using a MemoryStream // thus, the seek operation is fast as we are only changing the value of a property WriteAtPosition(stream, (int)(stream.Position - before), before - sizeof(int)); } private static ushort GetFieldCount(CommandLineOptionMessages commandLineOptionMessages) => (ushort)((commandLineOptionMessages.ModulePath is null ? 0 : 1) + (IsNullOrEmpty(commandLineOptionMessages.CommandLineOptionMessageList) ? 0 : 1)); private static ushort GetFieldCount(CommandLineOptionMessage commandLineOptionMessage) => (ushort)((commandLineOptionMessage.Name is null ? 0 : 1) + (commandLineOptionMessage.Description is null ? 0 : 1) + (commandLineOptionMessage.IsHidden is null ? 0 : 1) + (commandLineOptionMessage.IsBuiltIn is null ? 0 : 1)); }