示例#1
0
        /// <summary>
        /// Waits for tasks.
        /// </summary>
        /// <param name="tasks">The tasks.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="onTaskComplete">The on task complete.</param>
        /// <param name="logger">The logger.</param>
        /// <param name="memberName">Name of the member.</param>
        /// <returns>Task.</returns>
        /// <autogeneratedoc />
        public static Task WaitForTasks(this List <Task> tasks, CancellationToken cancellationToken, Action <Task> onTaskComplete = null,
                                        IPureLogger logger = null, [CallerMemberName] string memberName = "")
        {
            Task t = Task.WhenAll(tasks);

            try
            {
                cancellationToken.ThrowIfCancellationRequested();
                t.Wait(cancellationToken);
            }
            catch (OperationCanceledException ex)
            {
                t = Task.FromCanceled(cancellationToken);
                logger?.LogError(ex, "Task {Method} timed out with {TaskStatus}", memberName, t.Status);
            }
            catch (Exception ex)
            {
                t = Task.FromException(ex);

                logger?.LogError(ex, "Task {Method} threw an exception with {TaskStatus}", memberName, t.Status);
            }
            finally
            {
                onTaskComplete?.Invoke(t);
            }

            return(t);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="LocalNetworkCollection"/> class.
        /// </summary>
        /// <param name="commonNetworkServices">The common network services.</param>
        /// <exception cref="ArgumentNullException">commonNetworkServices</exception>
        /// <autogeneratedoc />
        public LocalNetworkCollection(ICommonNetworkServices commonNetworkServices)
        {
            _commonNetworkServices =
                commonNetworkServices ?? throw new ArgumentNullException(nameof(commonNetworkServices));

            _logger = commonNetworkServices.LoggerFactory?.CreatePureLogger <LocalNetworkCollection>();
        }
示例#3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DeviceBase"/> class.
 /// </summary>
 /// <param name="commonServices">The common services.</param>
 /// <param name="deviceType">Type of the device.</param>
 /// <param name="logger">The logger.</param>
 /// <autogeneratedoc />
 protected DeviceBase(ICommonServices commonServices, DeviceType deviceType = DeviceType.UnknownDevice,
                      IPureLogger logger = null) :
     base(commonServices?.LoggerFactory, logger)
 {
     DeviceType     = deviceType;
     CommonServices = commonServices;
 }
示例#4
0
 /// <summary>Pushes the log property deconstruct.</summary>
 /// <param name="logger">The logger.</param>
 /// <param name="propertyName">Name of the property.</param>
 /// <param name="value">The value.</param>
 /// <returns>IDisposable.</returns>
 /// <exception cref="ArgumentNullException">logger</exception>
 /// <autogeneratedoc />
 public static IDisposable PushLogPropertyDeconstruct(this IPureLogger logger, string propertyName, object value)
 {
     if (logger == null)
     {
         throw new ArgumentNullException(nameof(logger));
     }
     return(logger.PushProperty(propertyName, value, true));
 }
示例#5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LocalNetwork"/> class.
        /// </summary>
        /// <param name="commonNetworkServices">The common network services.</param>
        /// <param name="networkAdapter">The network adapter.</param>
        /// <param name="logger">The logger.</param>
        /// <autogeneratedoc />
        public LocalNetwork(ICommonNetworkServices commonNetworkServices, INetworkAdapter networkAdapter,
                            IPureLogger logger = null) :
            base(commonNetworkServices, DeviceType.LocalNetwork, logger)
        {
            NetworkAdapterCollection = new NetworkAdapterCollection();
            NetworkGateway           = _DiscoverNetworkGateway();

            NetworkIPAddressSubnet = networkAdapter.NetworkAddressSubnet;

            AddAdapterToNetwork(networkAdapter);
        }
示例#6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SocketService" /> class.
        /// </summary>
        /// <param name="commonServices">The common services</param>
        /// <param name="logger">The logger.</param>
        protected SocketService(ICommonServices commonServices, IPureLogger <SocketService> logger)
        {
            if (commonServices == null)
            {
                throw new ArgumentNullException(nameof(commonServices));
            }

            Logger = logger;

            _interfaceAddress = commonServices.NetworkingSystem.GetDefaultLocalAddress();
        }
示例#7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NetworkMap"/> class.
        /// </summary>
        /// <param name="commonNetworkServices">The common network services.</param>
        /// <exception cref="ArgumentNullException">commonNetworkServices</exception>
        /// <autogeneratedoc />
        public NetworkMap(ICommonNetworkServices commonNetworkServices) : base(commonNetworkServices)
        {
            if (commonNetworkServices == null)
            {
                throw new ArgumentNullException(nameof(commonNetworkServices));
            }

            _logger = commonNetworkServices.LoggerFactory?.CreatePureLogger <NetworkMap>();

            UpdateTimestamp();
        }
示例#8
0
            /// <summary>
            /// Initializes a new instance of the <see cref="PingTaskImpl"/> class.
            /// </summary>
            /// <param name="commonServices">The common services.</param>
            /// <param name="logger">The logger.</param>
            /// <exception cref="ArgumentNullException">commonServices</exception>
            /// <autogeneratedoc />
            public PingTaskImpl(ICommonServices commonServices, IPureLogger <PingTaskImpl> logger = null)
            {
                if (commonServices == null)
                {
                    throw new ArgumentNullException(nameof(commonServices));
                }
                _ping        = new Ping();
                _pingOptions = new PingOptions(64, true);

                _logger = logger ?? commonServices.LoggerFactory.CreatePureLogger <PingTaskImpl>();
            }
示例#9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClientConnectedEventArgs" /> class.
        /// </summary>
        /// <param name="socket">The channel.</param>
        /// <param name="logger">Logger</param>
        /// <exception cref="ArgumentNullException">socket</exception>
        public SocketEventArgs(Socket socket, IPureLogger logger)
        {
            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }

            Channel       = new SocketChannel(logger);
            ChannelBuffer = new SocketBuffer();
            Channel.Assign(socket);
        }
示例#10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PureObjectBase"/> class.
        /// </summary>
        /// <param name="loggerFactory">The logger factory.</param>
        /// <param name="logger">The logger.</param>
        /// <exception cref="ArgumentNullException">loggerFactory</exception>
        /// <autogeneratedoc />
        protected PureObjectBase(IPureLoggerFactory loggerFactory, IPureLogger logger = null) :
            base(loggerFactory, logger)
        {
            // Handled by base
            // if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory));

            _createdTimestamp = ModifiedTimestamp = DateTimeOffset.Now;
            _objectId         = Guid.NewGuid();
            ObjectVersion     = ObjectVersionStart;

            Logger = logger ?? LoggerFactory.CreatePureLogger <PureObjectBase>();
        }
示例#11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClientConnectedEventArgs" /> class.
        /// </summary>
        /// <param name="socket">The channel.</param>
        /// <param name="logger">The logger.</param>
        /// <param name="messageBuffer">The message buffer.</param>
        /// <exception cref="ArgumentNullException">socket</exception>
        public ClientConnectedEventArgs(Socket socket, IPureLogger logger, int messageBuffer)
        {
            if (socket == null)
            {
                throw new ArgumentNullException(nameof(socket));
            }

            AllowConnect = true;

            Channel       = new SocketChannel(logger);
            ChannelBuffer = new SocketBuffer(messageBuffer);
            Channel.Assign(socket);
        }
示例#12
0
        /// <summary>
        /// Pushes the log property deconstruct.
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <param name="properties">The properties.</param>
        /// <returns>IDisposable.</returns>
        /// <exception cref="ArgumentNullException">properties</exception>
        /// <autogeneratedoc />
        public static IDisposable PushLogPropertyDeconstruct(this IPureLogger logger,
                                                             IEnumerable <KeyValuePair <string, object> > properties)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            if (properties == null)
            {
                throw new ArgumentNullException(nameof(properties));
            }

            return(logger.PushLogProperties(properties, true));
        }
示例#13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TestBaseLoggable{T}"/> class.
        /// </summary>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="testOutputHelper">The test output helper.</param>
        /// <param name="initialMinimumLevel">The initial minimum level.</param>
        /// <param name="xUnitSerilogFormatter">The x unit serilog formatter.</param>
        /// <autogeneratedoc />
        protected TestBaseLoggable(IFileSystem fileSystem, ITestOutputHelper testOutputHelper,
                                   LogLevel initialMinimumLevel = LogLevel.Debug,
                                   XUnitSerilogFormatter xUnitSerilogFormatter = XUnitSerilogFormatter.RenderedCompactJsonFormatter)
        {
            FileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));

            TestOutputHelper = testOutputHelper;
            LoggerSettings   = new SerilogLoggerSettings(fileSystem, initialMinimumLevel, LoggingOutputFlags.Testing);

            var loggerConfiguration =
                XunitLoggingSink.CreateXUnitLoggerConfiguration(testOutputHelper, LoggerSettings,
                                                                xUnitSerilogFormatter);

            TestLoggerFactory = XunitLoggingSink.CreateXUnitSerilogFactory(LoggerSettings, loggerConfiguration);

            Logger = TestLoggerFactory?.CreatePureLogger <T>();
        }
示例#14
0
        /// <summary>
        /// Pushes the log properties.
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <param name="logPropertyList">The log property list.</param>
        /// <param name="pureLogLevel">The pure log level.</param>
        /// <returns>IDisposable.</returns>
        /// <exception cref="ArgumentNullException">
        /// logger
        /// or
        /// logPropertyList
        /// or
        /// pureLogLevel
        /// </exception>
        /// <autogeneratedoc />
        public static IDisposable PushLogProperties(this IPureLogger logger,
                                                    IEnumerable <IPureLogPropertyLevel> logPropertyList, IPureLogLevel pureLogLevel)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            if (logPropertyList == null)
            {
                throw new ArgumentNullException(nameof(logPropertyList));
            }
            if (pureLogLevel == null)
            {
                throw new ArgumentNullException(nameof(pureLogLevel));
            }

            return(logger.PushLogProperties(logPropertyList, pureLogLevel.MinimumLogLevel));
        }
示例#15
0
        /// <summary>Pushes the log property.</summary>
        /// <param name="logger">The logger.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="value">The value.</param>
        /// <param name="destructureObjects">if set to <c>true</c> [destructure objects].</param>
        /// <returns>IDisposable.</returns>
        /// <exception cref="ArgumentNullException">logger
        /// or
        /// propertyName
        /// or
        /// value</exception>
        /// <autogeneratedoc />
        public static IDisposable PushLogProperty(this IPureLogger logger, string propertyName, object value,
                                                  bool destructureObjects = false)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException(nameof(propertyName));
            }
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            return(logger.PushProperty(propertyName, value, destructureObjects));
        }
示例#16
0
        /// <summary>Begins the property scope.</summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="logger">The logger.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="value">The value.</param>
        /// <returns>IDisposable.</returns>
        /// <exception cref="ArgumentNullException">logger
        /// or
        /// propertyName
        /// or
        /// value</exception>
        /// <autogeneratedoc />
        public static IDisposable BeginPropertyScope <T>(this IPureLogger logger, string propertyName, T value)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException(nameof(propertyName));
            }
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            return(logger.BeginScope(new Dictionary <string, T> {
                { propertyName, value }
            }));
        }
示例#17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DhcpMessage" /> class.
        /// </summary>
        /// <param name="loggerFactory">The logger factory.</param>
        /// <param name="logger">The logger.</param>
        public DhcpMessage(IPureLoggerFactory loggerFactory, IPureLogger logger = null) :
            base(loggerFactory, logger)
        {
            CreatedTimestamp = DateTimeOffset.Now;

            _op    = (byte)OperationCode.BootReply;
            _htype = (byte)HardwareType.Ethernet;
            _hlen  = 0;
            _hops  = 0;
            _xid   = (ushort)Random.Next(ushort.MaxValue);
            _secs  = 0;
            Array.Clear(_flags, 0, _flags.Length);
            Array.Clear(_ciaddr, 0, _ciaddr.Length);
            Array.Clear(_yiaddr, 0, _yiaddr.Length);
            Array.Clear(_siaddr, 0, _siaddr.Length);
            Array.Clear(_giaddr, 0, _giaddr.Length);
            Array.Clear(_chaddr, 0, _chaddr.Length);
            Array.Clear(_sname, 0, _sname.Length);
            Array.Clear(_file, 0, _file.Length);
        }
示例#18
0
 /// <summary>
 /// Constructor for NetworkingSystem
 /// </summary>
 /// <param name="logger"></param>
 public NetworkingSystem(IPureLogger <NetworkingSystem> logger)
 {
     _logger = logger ?? throw new ArgumentNullException(nameof(logger));
 }
示例#19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="NetworkAdapter"/> class.
 /// </summary>
 /// <param name="commonNetworkServices">The common network services.</param>
 /// <param name="networkInterface">The network interface.</param>
 /// <param name="logger">The logger.</param>
 /// <autogeneratedoc />
 public NetworkAdapter(ICommonNetworkServices commonNetworkServices, NetworkInterface networkInterface,
                       IPureLogger logger = null) :
     base(commonNetworkServices, DeviceType.NetworkAdapter, logger)
 {
     NetworkInterface = networkInterface;
 }
示例#20
0
 /// <inheritdoc />
 public TestLoggable(string stringValue, IPureLoggerFactory loggerFactory, IPureLogger logger = null) :
     base(ParentTestValue, loggerFactory, logger)
 {
     StringValue = stringValue;
 }
示例#21
0
 public TestLoggableParent(string parentStringValue, IPureLoggerFactory loggerFactory, IPureLogger logger = null) :
     base(loggerFactory, logger)
 {
     ParentStringValue = parentStringValue;
 }
示例#22
0
 /// <summary>
 /// Quotes the added.
 /// </summary>
 /// <param name="logger">The logger.</param>
 /// <param name="quote">The quote.</param>
 /// <autogeneratedoc />
 public static void QuoteAdded(this IPureLogger logger, string quote)
 {
     QuoteAddedMessage(logger, quote, null);
 }
示例#23
0
        /// <summary>
        /// Gets the DHCP option string.
        /// </summary>
        /// <param name="dhcpOption">The DHCP option.</param>
        /// <param name="dhcpOptionValue">The DHCP option value.</param>
        /// <param name="dhcpRequestListFormat">The DHCP request list format.</param>
        /// <param name="logger">The logger.</param>
        /// <returns>System.String.</returns>
        /// <autogeneratedoc />
        public static string GetDhcpOptionString(
            DhcpOption dhcpOption, byte[] dhcpOptionValue,
            DhcpRequestListFormat dhcpRequestListFormat = DhcpRequestListFormat.StringNewlineIndentedSeparated,
            IPureLogger logger = null
            )
        {
            try
            {
                if (dhcpOptionValue == null)
                {
                    return("Null");
                }

                if (dhcpOption == DhcpOption.ParamReqList)
                {
                    return(GetDhcpRequestListString(dhcpOptionValue, dhcpRequestListFormat, logger));
                }

                switch (DhcpOptionTypes[dhcpOption])
                {
                case DhcpOptionType.IPAddress:
                    return(new IPAddress(dhcpOptionValue).ToString());

                case DhcpOptionType.PhysicalAddressSkip1DashString:
                    return(new PhysicalAddress(dhcpOptionValue.Skip(1).ToArray()).ToDashString());

                case DhcpOptionType.PhysicalAddressSkip1ColonString:
                    return(new PhysicalAddress(dhcpOptionValue.Skip(1).ToArray()).ToColonString());

                case DhcpOptionType.PhysicalAddressDashString:
                    return(new PhysicalAddress(dhcpOptionValue).ToDashString());

                case DhcpOptionType.PhysicalAddressColonString:
                    return(new PhysicalAddress(dhcpOptionValue).ToColonString());

                case DhcpOptionType.MessageTypeString:
                    return(MessageTypeString.GetName((MessageType)dhcpOptionValue[0]));

                case DhcpOptionType.SafeString:
                    return(ByteUtility.GetSafeString(dhcpOptionValue));

                case DhcpOptionType.SafeBytes:
                    return(ByteUtility.PrintSafeBytes(dhcpOptionValue));

                case DhcpOptionType.UInt16:
                    return(BitConverter.ToUInt16(dhcpOptionValue, 0).ToString());

                case DhcpOptionType.UInt32:
                    return(BitConverter.ToUInt32(dhcpOptionValue, 0).ToString());

                case DhcpOptionType.UInt16Network:
                    return(IPAddress.NetworkToHostOrder(BitConverter.ToUInt16(dhcpOptionValue, 0)).ToString());

                case DhcpOptionType.UInt32Network:
                    return(IPAddress.NetworkToHostOrder(BitConverter.ToUInt32(dhcpOptionValue, 0)).ToString());
                }
            }
            catch (Exception ex)
            {
                logger?.LogError(ex, "Invalid DhcpOption: {dhcpOption}", dhcpOption);
            }

            return(string.Empty);
        }
示例#24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HostedSocketService"/> class.
 /// </summary>
 /// <param name="commonServices">The commonServices</param>
 /// <param name="logger">The logger.</param>
 /// <autogeneratedoc />
 public HostedSocketService(ICommonServices commonServices, IPureLogger <SocketService> logger) : base(commonServices, logger)
 {
 }
示例#25
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="logger">The logger.</param>
 public ProcessRunner(IPureLogger <ProcessRunner> logger)
 {
     _logger = logger;
 }
示例#26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SocketListener" /> class.
 /// </summary>
 /// <param name="logger">The logger.</param>
 public SocketListener(IPureLogger <SocketListener> logger)
 {
     Logger = logger;
 }
示例#27
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DhcpMessage" /> class.
        /// </summary>
        /// <param name="data">Array containing the data to decode.</param>
        /// <param name="loggerFactory">The logger factory.</param>
        /// <param name="logger">The logger.</param>
        public DhcpMessage(byte[] data, IPureLoggerFactory loggerFactory, IPureLogger logger = null)
            : base(loggerFactory, logger)
        {
            ByteReader byteReader = new ByteReader(data, ByteOrder.Network);

            CreatedTimestamp = DateTimeOffset.Now;

            _op     = byteReader.ReadByte();
            _htype  = byteReader.ReadByte();
            _hlen   = byteReader.ReadByte();
            _hops   = byteReader.ReadByte();
            _xid    = byteReader.ReadUInt32();
            _secs   = byteReader.ReadUInt16();
            _flags  = byteReader.ReadBytes(2);
            _ciaddr = byteReader.ReadBytes(4);
            _yiaddr = byteReader.ReadBytes(4);
            _siaddr = byteReader.ReadBytes(4);
            _giaddr = byteReader.ReadBytes(4);
            _chaddr = byteReader.ReadBytes(16);
            _sname  = byteReader.ReadBytes(64);
            _file   = byteReader.ReadBytes(128);

            byte[] rawOptions = byteReader.ReadBytes(byteReader.AvailableBytes);
            int    offset     = 0;

            // if magic number is valid then process options
            if (offset + 4 < rawOptions.Length &&
                (BitConverter.ToUInt32(rawOptions, offset) == DhcpConstants.DhcpOptionsMagicNumber ||
                 BitConverter.ToUInt32(rawOptions, offset) == DhcpConstants.DhcpWinOptionsMagicNumber))
            {
                offset += 4;
                bool end = false;

                while (!end && offset < rawOptions.Length)
                {
                    DhcpOption option = (DhcpOption)rawOptions[offset];
                    offset++;

                    int optionLen;

                    switch (option)
                    {
                    case DhcpOption.Pad:
                        continue;

                    case DhcpOption.End:
                        end = true;
                        continue;

                    default:
                        optionLen = rawOptions[offset];
                        offset++;
                        break;
                    }

                    byte[] optionData = new byte[optionLen];

                    Array.Copy(rawOptions, offset, optionData, 0, optionLen);
                    offset += optionLen;

                    _options.Add(option, optionData);
                    _optionDataSize += optionLen;
                }
            }
        }
示例#28
0
 /// <summary>
 ///     Constructor.
 /// </summary>
 public HangfireLogger(IPureLogger logger)
 {
     _logger = logger;
 }
示例#29
0
 /// <summary>
 /// Subscribe an observer that logs each notification to the test console output
 /// </summary>
 /// <typeparam name="T">Type being observed</typeparam>
 /// <param name="observable">The observable.</param>
 /// <param name="logger">IPureLogger based on ITestOutputHelper</param>
 /// <param name="name">optional name parameter for observable.</param>
 /// <returns>a disposable subscription object</returns>
 public static IDisposable SubscribeTestLogger <T>(this IObservable <T> observable, IPureLogger logger, string name = "")
 {
     return(observable.Subscribe(new TestLoggerObserver <T>(logger, name)));
 }
示例#30
0
        /// <summary>
        /// Gets the DHCP request list string.
        /// </summary>
        /// <param name="dhcpOptionValue">The DHCP option value.</param>
        /// <param name="dhcpRequestListFormat">The DHCP request list format.</param>
        /// <param name="logger">The logger.</param>
        /// <returns>System.String.</returns>
        /// <autogeneratedoc />
        public static string GetDhcpRequestListString(byte[] dhcpOptionValue,
                                                      DhcpRequestListFormat dhcpRequestListFormat, IPureLogger logger = null)
        {
            StringBuilder sb = new StringBuilder();

            foreach (var requestOption in dhcpOptionValue)
            {
                DhcpOption dhcpRequestOption = (DhcpOption)requestOption;

                switch (dhcpRequestListFormat)
                {
                case DhcpRequestListFormat.StringCommaSeparated:
                    sb.Append($"{dhcpRequestOption.ToString()}, ");
                    break;

                case DhcpRequestListFormat.StringNewlineSeparated:
                    sb.Append($"{Environment.NewLine}{dhcpRequestOption.ToString()}");
                    break;

                case DhcpRequestListFormat.StringNewlineIndentedSeparated:
                    sb.Append($"{Environment.NewLine}    {dhcpRequestOption.ToString()}");
                    break;

                case DhcpRequestListFormat.HexValueCommaSeparated:
                    sb.Append($"{ByteUtility.ByteToHex((byte) dhcpRequestOption)}, ");
                    break;

                case DhcpRequestListFormat.HexValueSpaceSeparated:
                    sb.Append($"{ByteUtility.ByteToHex((byte) dhcpRequestOption)} ");
                    break;

                case DhcpRequestListFormat.HexValueDashSeparated:
                    sb.Append($"{ByteUtility.ByteToHex((byte) dhcpRequestOption)}-");
                    break;

                case DhcpRequestListFormat.DecimalValueCommaSeparated:
                    sb.Append($"{(byte) dhcpRequestOption}, ");
                    break;

                case DhcpRequestListFormat.DecimalValueSpaceSeparated:
                    sb.Append($"{(byte) dhcpRequestOption} ");
                    break;
                }
            }

            // Remove trailing space
            if (sb.Length > 1)
            {
                if (sb[sb.Length - 1] == ' ' || sb[sb.Length - 1] == '-')
                {
                    sb.Length--;
                }
            }

            // Remove trailing comma
            if (sb.Length > 1)
            {
                if (sb[sb.Length - 1] == ',')
                {
                    sb.Length--;
                }
            }

            return(sb.ToString());
        }