public static IMessage Deserialize(ref byte[] Raw) { var Stream = new DnStream(ref Raw); var Message = new Message { ID = Stream.GetUShort(), MessageType = Stream.GetBit().AsEnum <MessageType>(), OperationCode = Stream.GetBits(4).AsEnum <OperationCode>(), AuthoritativeAnswer = Stream.GetBit().AsEnum <AuthoritativeAnswer>(), Truncated = Stream.GetBit().AsBool(), RecursionDesired = Stream.GetBit().AsBool(), RecursionAvailable = Stream.GetBit().AsBool(), Zero = Stream.GetBit(), AuthenticatedData = Stream.GetBit().AsBool(), CheckingDisabled = Stream.GetBit().AsBool(), ResponseCode = Stream.GetBits(4).AsEnum <ResponseCode>(), QuestionsCount = Stream.GetUShort(), AnswersCount = Stream.GetUShort(), AuthorityCount = Stream.GetUShort(), AdditionalCount = Stream.GetUShort() }; Message.Questions = GetQuestions(ref Stream, Message.QuestionsCount); Message.Answers = GetAnswers(ref Stream, Message.AnswersCount); return(Message); }
private static IEnumerable <string> GetLabels(ref DnStream Stream) { var Labels = new List <string>(); while (true) { var LabelType = Stream.GetBits(2).AsEnum <LabelType>(); switch (LabelType) { case LabelType.Normal: { var Length = Stream.GetBits(6); if (Length == 0) { return(Labels); } var Label = Stream.GetString(Length); Labels.Add(Label); break; } case LabelType.Compressed: { var Pointer = (ushort)(Stream.GetBits(6) + Stream.GetByte()); if (Pointer >= Stream.BytePosition - 2) { throw new ArgumentOutOfRangeException(nameof(Pointer), Pointer, "Compressed Label Infinite Loop Detected."); } var Position = Stream.BytePosition; Stream.Seek(Pointer); Labels.AddRange(GetLabels(ref Stream)); Stream.Seek(Position); return(Labels); } default: throw new ArgumentOutOfRangeException(nameof(LabelType), LabelType, null); } } }