Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2022 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 <cstdint>
21 :
22 : #include <lib/dnssd/minimal_mdns/core/QName.h>
23 : #include <lib/support/CHIPMemString.h>
24 : #include <lib/support/CHIPPlatformMemory.h>
25 : #include <lib/support/ScopedBuffer.h>
26 :
27 : namespace mdns {
28 : namespace Minimal {
29 :
30 : /// Contructs a FullQName from a SerializedNameIterator
31 : ///
32 : /// Generally a conversion from an iterator to a `const char *[]`
33 : /// using heap for underlying storage of the data.
34 : class HeapQName
35 : {
36 : public:
37 : HeapQName() {}
38 0 : HeapQName(SerializedQNameIterator name)
39 0 : {
40 : // Storage is:
41 : // - separate pointers into mElementPointers
42 : // - allocated pointers inside that
43 0 : mElementCount = 0;
44 :
45 0 : SerializedQNameIterator it = name;
46 0 : while (it.Next())
47 : {
48 : // Count all elements
49 0 : mElementCount++;
50 : }
51 :
52 0 : if (!it.IsValid())
53 : {
54 0 : return;
55 : }
56 :
57 0 : mElementPointers.Alloc(mElementCount);
58 0 : if (!mElementPointers)
59 : {
60 0 : return;
61 : }
62 : // ensure all set to null since we may need to free
63 0 : for (size_t i = 0; i < mElementCount; i++)
64 : {
65 0 : mElementPointers[i] = nullptr;
66 : }
67 :
68 0 : it = name;
69 0 : size_t idx = 0;
70 0 : while (it.Next())
71 : {
72 0 : mElementPointers[idx] = chip::Platform::MemoryAllocString(it.Value(), strlen(it.Value()));
73 0 : if (!mElementPointers[idx])
74 : {
75 0 : return;
76 : }
77 0 : idx++;
78 : }
79 0 : mIsOk = true;
80 : }
81 :
82 0 : HeapQName(const HeapQName & other) { *this = other; }
83 :
84 0 : HeapQName & operator=(const HeapQName & other)
85 : {
86 0 : Free();
87 :
88 0 : if (!other)
89 : {
90 0 : return *this; // No point in copying the other value
91 : }
92 :
93 0 : mElementCount = other.mElementCount;
94 0 : mElementPointers.Alloc(other.mElementCount);
95 0 : if (!mElementPointers)
96 : {
97 0 : return *this;
98 : }
99 :
100 0 : for (size_t i = 0; i < mElementCount; i++)
101 : {
102 0 : mElementPointers[i] = nullptr;
103 : }
104 :
105 0 : for (size_t i = 0; i < mElementCount; i++)
106 : {
107 0 : const char * other_data = other.mElementPointers[i];
108 0 : mElementPointers[i] = chip::Platform::MemoryAllocString(other_data, strlen(other_data));
109 0 : if (!mElementPointers[i])
110 : {
111 0 : return *this;
112 : }
113 : }
114 0 : mIsOk = true;
115 0 : return *this;
116 : }
117 :
118 0 : ~HeapQName() { Free(); }
119 :
120 0 : bool IsOk() const { return mIsOk; }
121 :
122 0 : operator bool() const { return IsOk(); }
123 0 : bool operator!() const { return !IsOk(); }
124 :
125 : /// Returns the contained FullQName.
126 : ///
127 : /// VALIDITY: since this references data inside `this` it is only valid
128 : /// as long as `this` is valid.
129 0 : FullQName Content() const
130 : {
131 0 : FullQName result;
132 :
133 0 : result.names = mElementPointers.Get();
134 0 : result.nameCount = mElementCount;
135 :
136 0 : return result;
137 : }
138 :
139 : private:
140 0 : void Free()
141 : {
142 0 : if (!mElementPointers)
143 : {
144 0 : return;
145 : }
146 :
147 0 : for (size_t i = 0; i < mElementCount; i++)
148 : {
149 0 : if (mElementPointers[i] != nullptr)
150 : {
151 0 : chip::Platform::MemoryFree(mElementPointers[i]);
152 0 : mElementPointers[i] = nullptr;
153 : }
154 : }
155 0 : mElementPointers.Free();
156 0 : mElementCount = 0;
157 0 : mIsOk = false;
158 : }
159 :
160 : bool mIsOk = false;
161 : size_t mElementCount = 0;
162 : chip::Platform::ScopedMemoryBuffer<char *> mElementPointers;
163 : };
164 :
165 : } // namespace Minimal
166 : } // namespace mdns
|