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