7b8339dfe51eb4a0dadd2bbd1c72216b4035f035
[platform/upstream/connectedhomeip.git] / src / lib / mdns / minimal / QName.h
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 #pragma once
19
20 #include <string.h>
21
22 #include <cstddef>
23 #include <cstdint>
24 #include <utility>
25
26 #include <core/CHIPEncoding.h>
27
28 #include "BytesRange.h"
29 #include "DnsHeader.h"
30
31 namespace mdns {
32 namespace Minimal {
33
34 /// A QName part is a null-terminated string
35 using QNamePart = const char *;
36
37 /// A serialized QNAME is comprised of
38 ///  - length-prefixed parts
39 ///  - Ends in a 0-length item
40 ///  - May contain pointers to previous data (for efficient transmission)
41 ///
42 /// This class allows iterating over such parts while validating
43 /// that the parts are within a valid range
44 class SerializedQNameIterator
45 {
46 public:
47     SerializedQNameIterator() : mLookBehindMax(0), mCurrentPosition(nullptr), mIsValid(false) {}
48     SerializedQNameIterator(const SerializedQNameIterator &) = default;
49     SerializedQNameIterator & operator=(const SerializedQNameIterator &) = default;
50
51     SerializedQNameIterator(const BytesRange validData, const uint8_t * position) :
52         mValidData(validData), mLookBehindMax(static_cast<size_t>(position - validData.Start())), mCurrentPosition(position)
53     {}
54
55     /// Advances to the next element in the sequence
56     /// Returns true if new data was available
57     bool Next();
58
59     /// Find out if the data parsing is ok.
60     /// If invalid data is encountered during a [Next] call, this will
61     /// return false. Check this after Next returns false.
62     bool IsValid() const { return mIsValid; }
63
64     /// Valid IFF Next() returned true.
65     /// Next has to be called after construction
66     QNamePart Value() const { return mValue; }
67
68     /// Get the end of the sequence *without* following any
69     /// backwards pointers. Changes iterator state.
70     ///
71     /// returs nullptr on error (invalid data)
72     const uint8_t * FindDataEnd();
73
74 private:
75     static constexpr size_t kMaxValueSize = 63;
76     static constexpr uint8_t kPtrMask     = 0xC0;
77
78     BytesRange mValidData;
79     size_t mLookBehindMax; // avoid loops by limiting lookbehind
80     const uint8_t * mCurrentPosition;
81     bool mIsValid = true;
82
83     char mValue[kMaxValueSize + 1] = { 0 };
84
85     // Advances to the next element in the sequence
86     bool Next(bool followIndirectPointers);
87 };
88
89 } // namespace Minimal
90
91 } // namespace mdns