| File: Resolver\DnsDataWriter.cs | Web Access |
| Project: src\src\Libraries\Microsoft.Extensions.ServiceDiscovery.Dns\Microsoft.Extensions.ServiceDiscovery.Dns.csproj (Microsoft.Extensions.ServiceDiscovery.Dns) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers.Binary; using System.Diagnostics; namespace Microsoft.Extensions.ServiceDiscovery.Dns.Resolver; internal sealed class DnsDataWriter { private readonly Memory<byte> _buffer; private int _position; internal DnsDataWriter(Memory<byte> buffer) { _buffer = buffer; _position = 0; } public int Position => _position; internal bool TryWriteHeader(in DnsMessageHeader header) { if (!DnsPrimitives.TryWriteMessageHeader(_buffer.Span.Slice(_position), header, out int written)) { return false; } _position += written; return true; } internal bool TryWriteQuestion(EncodedDomainName name, QueryType type, QueryClass @class) { if (!TryWriteDomainName(name) || !TryWriteUInt16((ushort)type) || !TryWriteUInt16((ushort)@class)) { return false; } return true; } private bool TryWriteDomainName(EncodedDomainName name) { foreach (var label in name.Labels) { // this should be already validated by the caller Debug.Assert(label.Length <= 63, "Label length must not exceed 63 bytes."); if (!TryWriteByte((byte)label.Length) || !TryWriteRawData(label.Span)) { return false; } } // root label return TryWriteByte(0); } internal bool TryWriteDomainName(string name) { if (DnsPrimitives.TryWriteQName(_buffer.Span.Slice(_position), name, out int written)) { _position += written; return true; } return false; } internal bool TryWriteByte(byte value) { if (_buffer.Length - _position < 1) { return false; } _buffer.Span[_position] = value; _position += 1; return true; } internal bool TryWriteUInt16(ushort value) { if (_buffer.Length - _position < 2) { return false; } BinaryPrimitives.WriteUInt16BigEndian(_buffer.Span.Slice(_position), value); _position += 2; return true; } internal bool TryWriteUInt32(uint value) { if (_buffer.Length - _position < 4) { return false; } BinaryPrimitives.WriteUInt32BigEndian(_buffer.Span.Slice(_position), value); _position += 4; return true; } internal bool TryWriteRawData(ReadOnlySpan<byte> value) { if (_buffer.Length - _position < value.Length) { return false; } value.CopyTo(_buffer.Span.Slice(_position)); _position += value.Length; return true; } }