3 * Copyright (c) 2020 Project CHIP Authors
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
25 bool SerializedQNameIterator::Next()
27 return mIsValid && Next(true);
30 bool SerializedQNameIterator::Next(bool followIndirectPointers)
39 assert(mValidData.Contains(mCurrentPosition));
41 const uint8_t length = *mCurrentPosition;
42 if (*mCurrentPosition == 0)
44 // Done with all items
48 if ((length & kPtrMask) == kPtrMask)
50 if (!followIndirectPointers)
52 // Stop at first indirect pointer
56 // PTR contains 2 bytes
57 if (!mValidData.Contains(mCurrentPosition + 1))
63 size_t offset = ((*mCurrentPosition & 0x3F) << 8) | *(mCurrentPosition + 1);
64 if (offset > mLookBehindMax)
66 // Potential infinite recursion.
70 if (offset > mValidData.Size())
77 mLookBehindMax = offset;
78 mCurrentPosition = mValidData.Start() + offset;
82 // This branch handles non-pointer data. This will be string of size [length].
83 if (length > kMaxValueSize)
85 // value is too large (larger than RFC limit)
90 if (!mValidData.Contains(mCurrentPosition + 1 + length))
92 // string outside valid data
97 memcpy(mValue, mCurrentPosition + 1, length);
98 mValue[length] = '\0';
99 mCurrentPosition = mCurrentPosition + length + 1;
105 const uint8_t * SerializedQNameIterator::FindDataEnd()
109 // nothing to do, just advance
118 if (*mCurrentPosition == 0)
120 // mCurrentPosition MUST already be valid
121 return mCurrentPosition + 1;
124 // ends with a dataptr
125 if ((*mCurrentPosition & kPtrMask) == kPtrMask)
127 if (!mValidData.Contains(mCurrentPosition + 1))
131 return mCurrentPosition + 2;
138 bool SerializedQNameIterator::operator==(const FullQName & other) const
140 SerializedQNameIterator self = *this; // allow iteration
143 while ((idx < other.nameCount) && self.Next())
145 if (strcasecmp(self.Value(), other.names[idx]) != 0)
152 return ((idx == other.nameCount) && !self.Next());
155 bool FullQName::operator==(const FullQName & other) const
157 if (nameCount != other.nameCount)
161 for (size_t i = 0; i < nameCount; i++)
163 if (strcasecmp(names[i], other.names[i]) != 0)
171 } // namespace Minimal