matio-cpp v0.3.0
A C++ wrapper of the matio library, with memory ownership handling, to read and write .mat files.
Loading...
Searching...
No Matches
MatvarHandler.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020 Fondazione Istituto Italiano di Tecnologia
3 *
4 * This software may be modified and distributed under the terms of the
5 * BSD-2-Clause license (https://opensource.org/licenses/BSD-2-Clause).
6 */
7
11
19
21{
22 changePointer(ptr, deleteMode);
23}
24
26{
27 //It does nothing by default. The ownership determines when to delete the pointer
28}
29
31{
32 //The previous pointer is not deleted since it is the ownership triggering it
33 m_ptr = ptr;
34 m_mode = deleteMode;
37 get_types_from_matvart(m_ptr, m_varType, m_valueType);
38}
39
41{
42 DeletePointer(m_ptr, m_mode);
43 m_ptr = nullptr;
44}
45
50
55
60
65
70
72{
73 if (deleteMode == DeleteMode::Delete || deleteMode == DeleteMode::ShallowDelete)
74 {
75 if (deleteMode == DeleteMode::ShallowDelete)
76 {
77 ptr->data = nullptr; //When doing a shallow copy, the data pointer is copied.
78 //Hence, by freeing the shallowCopy, also the data would be deallocated.
79 //This avoids matio to attempt freeing the data
80 // See https://github.com/tbeu/matio/issues/158
81 }
82 Mat_VarFree(ptr);
83 }
84}
85
86void matioCpp::MatvarHandler::Ownership::dropDependencies(matvar_t *previouslyOwned)
87{
88 if (!previouslyOwned)
89 {
90 return;
91 }
92
94
95 if (it == m_dependencyTree.end())
96 {
97 return;
98 }
99
100 for (matvar_t* child : it->second.dependencies)
101 {
102 dropDependencies(child);
103 }
104
105 PointerInfo::DeletePointer(previouslyOwned, it->second.mode);
106
107 m_dependencyTree.erase(previouslyOwned);
108}
109
115
120
122{
123 return (test && ((test == (m_main.lock()->pointer())) || (m_dependencyTree.find(test) != m_dependencyTree.end())));
124}
125
127{
128 assert(owner);
129 if (owned)
130 {
132 dep.mode = mode;
133 if (*(owner->m_ptr) != *(m_main.lock()))
134 {
135 dep.parent = owner->m_ptr->pointer();
136
137 assert(m_dependencyTree.find(dep.parent) != m_dependencyTree.end());
138
139 m_dependencyTree[dep.parent].dependencies.insert(owned);
140 }
141
142 m_dependencyTree[owned] = dep;
143 }
144}
145
147{
148 if (!previouslyOwned)
149 {
150 return;
151 }
152
154
155 if (it == m_dependencyTree.end())
156 {
157 return;
158 }
159
160 std::unordered_map<matvar_t*, Dependency>::iterator parent = m_dependencyTree.find(it->second.parent);
161
162 if ((it->second.parent != m_main.lock()->pointer()) && (parent != m_dependencyTree.end()))
163 {
164 parent->second.dependencies.erase(previouslyOwned);
165 }
166
167 dropDependencies(previouslyOwned);
168
169 m_dependencyTree.erase(previouslyOwned);
170}
171
173{
174 std::shared_ptr<PointerInfo> locked = m_main.lock();
175 if (locked)
176 {
177 locked->deletePointer();
178 }
179
180 for(std::pair<matvar_t*, Dependency> dep : m_dependencyTree)
181 {
182 PointerInfo::DeletePointer(dep.first, dep.second.mode);
183 }
184
185 m_dependencyTree.clear();
186}
187
192
194 : m_ptr(std::make_shared<PointerInfo>(inputPtr, deleteMode))
195{
196
197}
198
204
210
212{
213 return m_ptr->valueType();
214}
215
217{
218 return m_ptr->variableType();
219}
220
222{
223 std::string errorPrefix = "[ERROR][matioCpp::MatvarHandler::GetMatvarDuplicate] ";
224 if (!inputPtr)
225 {
226 return nullptr;
227 }
228
232
234 {
235 std::cerr << errorPrefix << "The inputPtr is not supported." << std::endl;
236 return nullptr;
237 }
238
239 if (outputVariableType == matioCpp::VariableType::CellArray) // It is a different case because Mat_VarDuplicate segfaults with a CellArray
240 {
242
243 size_t totalElements = 1;
244
245 for (int i = 0; i < inputPtr->rank; ++i)
246 {
247 totalElements *= inputPtr->dims[i];
248 }
249
251 for (size_t i = 0; i < totalElements; ++i)
252 {
253 matvar_t* internalPointer = Mat_VarGetCell(shallowCopy.get(), static_cast<int>(i));
254 if (internalPointer)
255 {
256 vectorOfPointers[i] = GetMatvarDuplicate(internalPointer); //Deep copy
257 }
258 }
259
260 outputPtr = Mat_VarCreate(inputPtr->name, inputPtr->class_type, inputPtr->data_type, inputPtr->rank, inputPtr->dims, vectorOfPointers.data(), 0);
261 }
263 {
265
266 size_t totalElements = 1;
267
268 for (int i = 0; i < inputPtr->rank; ++i)
269 {
270 totalElements *= inputPtr->dims[i];
271 }
272
273 size_t numberOfFields = Mat_VarGetNumberOfFields(shallowCopy.get());
274
275 std::vector<matvar_t*> vectorOfPointers(totalElements * numberOfFields + 1, nullptr); //The vector of pointers has to be nullptr terminated.
276
277 size_t innerIndex = 0;
278 for (size_t i = 0; i < totalElements; ++i)
279 {
280 for (size_t field = 0; field < numberOfFields; ++field)
281 {
283 if (internalPointer)
284 {
285 vectorOfPointers[innerIndex] = GetMatvarDuplicate(internalPointer); //Deep copy
286 }
287 innerIndex++;
288 }
289 }
290 assert(innerIndex == totalElements * numberOfFields);
291
292 outputPtr = Mat_VarCreate(inputPtr->name, inputPtr->class_type, inputPtr->data_type, inputPtr->rank, inputPtr->dims, vectorOfPointers.data(), 0);
293 }
294 else
295 {
296 outputPtr = Mat_VarDuplicate(inputPtr, 1); //0 Shallow copy, 1 Deep copy
297 }
298
299 return outputPtr;
300
301}
302
304{
305 PointerInfo::DeletePointer(pointerToDelete, mode);
306}
void drop(matvar_t *previouslyOwned)
Drop a previously owned pointer and deleted if necessary.
bool isOwning(matvar_t *test)
Check if an input pointer is owned by this ownership object.
void own(matvar_t *owned, const MatvarHandler *owner, matioCpp::DeleteMode mode)
Add a pointer to the list of owned pointers.
Ownership(std::weak_ptr< PointerInfo > pointerToDeallocate)
Constructor.
void dropAll()
Drops all the previously owned pointers and free those that need to be deallocated,...
matvar_t * pointer()
Get the matvar pointer.
void deletePointer()
Delete the matvar pointer.
ValueType valueType() const
Get the value type.
VariableType variableType() const
Get the variable type.
bool operator!=(const PointerInfo &other) const
Comparison operator.
void changePointer(matvar_t *ptr, DeleteMode deleteMode)
Change the input pointer.
DeleteMode deleteMode() const
Get the deletion mode.
static void DeletePointer(matvar_t *ptr, DeleteMode deleteMode)
Delete the given pointer given the mode.
static matvar_t * GetMatvarDuplicate(const matvar_t *inputPtr)
Get a duplicate of the input matvar pointer/.
static void DeleteMatvar(matvar_t *pointerToDelete, DeleteMode mode=DeleteMode::Delete)
Delete the specified Matvar.
ValueType valueType() const
Get the value type of the pointer.
MatvarHandler()
Default constructor.
std::shared_ptr< PointerInfo > m_ptr
Shared pointer to a PointerInfo.
VariableType variableType() const
Get the variable type of the pointer.
MultiDimensionalArray is a particular type of Variable specialized for multidimensional arrays of a g...
pointer data()
Direct access to the underlying array.
typename std::allocator_traits< std::allocator< element_type > >::pointer pointer
The reference type.
static SharedMatvar GetMatvarShallowDuplicate(const matvar_t *inputPtr)
Get the shallow duplicate of an input Matvar.
std::string name() const
Get the name of the Variable.
Definition Variable.cpp:498
T end(T... args)
T endl(T... args)
T erase(T... args)
T find(T... args)
DeleteMode
The delete mode of matvar_t pointers.
@ ShallowDelete
The handler does not delete the pointer.
@ Delete
The handler deletes the pointer but not the data.
VariableType
Define the type of variable.
bool get_types_from_matvart(const matvar_t *input, VariableType &outputVariableType, ValueType &outputValueType)
Get the VariableType and the ValueType from a matvar_t pointer.
ValueType
The list of types for an element of a certain variable type.
STL namespace.