Medical Imaging Interaction Toolkit  2018.4.99-18ddd2ed
Medical Imaging Interaction Toolkit
berryExtensionType.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "berryExtensionType.h"
14 
15 #include <QVector>
16 #include <QReadWriteLock>
17 
18 #include <cstring>
19 
20 namespace berry {
21 
22 class CustomTypeInfo
23 {
24 public:
25  CustomTypeInfo() : typeName(), constr(nullptr), destr(nullptr)
26  {}
27 
28  QByteArray typeName;
31 
32  int alias;
33 };
34 
35 //Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
36 Q_GLOBAL_STATIC(QVector<CustomTypeInfo>, customTypes)
37 Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
38 
39 const char* ExtensionType::typeName(int type)
40 {
41 
42  const QVector<CustomTypeInfo>* const ct = customTypes();
43  QReadLocker locker(customTypesLock());
44  return ct && ct->count() > type && !ct->at(type).typeName.isEmpty()
45  ? ct->at(type).typeName.constData()
46  : static_cast<const char *>(nullptr);
47 }
48 
49 
53 static int extensionTypeCustomType_unlocked(const char *typeName, int length)
54 {
55  const QVector<CustomTypeInfo>* const ct = customTypes();
56  if (!ct) return 0;
57 
58  for (int v = 0; v < ct->count(); ++v)
59  {
60  const CustomTypeInfo& customInfo = ct->at(v);
61  if ((length == customInfo.typeName.size())
62  && !std::strcmp(typeName, customInfo.typeName.constData()))
63  {
64  if (customInfo.alias >= 0)
65  return customInfo.alias;
66  return v+1;
67  }
68  }
69  return 0;
70 }
71 
72 int ExtensionType::registerType(const char *typeName, Destructor destructor,
73  Constructor constructor)
74 {
75  QVector<CustomTypeInfo>* ct = customTypes();
76  if (!ct || !typeName || !destructor || !constructor)
77  return -1;
78 
79  QByteArray normalizedTypeName = QMetaObject::normalizedType(typeName);
80 
81  QWriteLocker locker(customTypesLock());
82  int idx = extensionTypeCustomType_unlocked(normalizedTypeName.constData(),
83  normalizedTypeName.size());
84  if (!idx)
85  {
86  CustomTypeInfo inf;
87  inf.typeName = normalizedTypeName;
88  inf.constr = constructor;
89  inf.destr = destructor;
90  inf.alias = -1;
91  idx = ct->size();
92  ct->append(inf);
93  }
94 
95  return idx;
96 }
97 
98 int ExtensionType::registerTypedef(const char* typeName, int aliasId)
99 {
100  QVector<CustomTypeInfo>* ct = customTypes();
101  if (!ct || !typeName) return -1;
102 
103  QByteArray normalizedTypeName = QMetaObject::normalizedType(typeName);
104 
105  QWriteLocker locker(customTypesLock());
106  int idx = extensionTypeCustomType_unlocked(normalizedTypeName.constData(),
107  normalizedTypeName.size());
108 
109  if (idx) return idx;
110 
111  CustomTypeInfo inf;
112  inf.typeName = normalizedTypeName;
113  inf.alias = aliasId;
114  inf.constr = nullptr;
115  inf.destr = nullptr;
116  ct->append(inf);
117  return aliasId;
118 }
119 
120 void ExtensionType::unregisterType(const char* typeName)
121 {
122  QVector<CustomTypeInfo> *ct = customTypes();
123  if (!ct || !typeName) return;
124 
125  QByteArray normalizedTypeName = QMetaObject::normalizedType(typeName);
126 
127  QWriteLocker locker(customTypesLock());
128  for (int v = 0; v < ct->count(); ++v)
129  {
130  if (ct->at(v).typeName == typeName)
131  {
132  CustomTypeInfo &inf = (*ct)[v];
133  inf.typeName.clear();
134  inf.constr = nullptr;
135  inf.destr = nullptr;
136  inf.alias = -1;
137  }
138  }
139 }
140 
142 {
143  QReadLocker locker(customTypesLock());
144  const QVector<CustomTypeInfo>* const ct = customTypes();
145  return ((type > 0) && (ct && ct->count() > type - 1) &&
146  !ct->at(type - 1).typeName.isEmpty());
147 }
148 
149 int ExtensionType::type(const char *typeName)
150 {
151  int length = static_cast<int>(std::strlen(typeName));
152  if (!length) return 0;
153 
154  QReadLocker locker(customTypesLock());
155  int type = extensionTypeCustomType_unlocked(typeName, length);
156  if (!type)
157  {
158  const QByteArray normalizedTypeName = QMetaObject::normalizedType(typeName);
159  type = extensionTypeCustomType_unlocked(normalizedTypeName.constData(),
160  normalizedTypeName.size());
161  }
162 
163  return type;
164 }
165 
166 QObject* ExtensionType::construct(int type)
167 {
168  const QVector<CustomTypeInfo> * const ct = customTypes();
169 
170  Constructor constr = nullptr;
171 
172  QReadLocker locker(customTypesLock());
173  if (!ct || ct->count() <= type - 1)
174  return nullptr;
175  if (ct->at(type - 1).typeName.isEmpty())
176  return nullptr;
177  constr = ct->at(type - 1).constr;
178  return constr();
179 }
180 
181 void ExtensionType::destroy(int type, QObject* data)
182 {
183  if (!data) return;
184 
185  const QVector<CustomTypeInfo> * const ct = customTypes();
186  if (!ct || ct->count() <= type - 1) return;
187 
188  Destructor destr = nullptr;
189 
190  QReadLocker locker(customTypesLock());
191  if (ct->at(type - 1).typeName.isEmpty())
192  return;
193  destr = ct->at(type - 1).destr;
194  destr(data);
195 }
196 
197 } // end namespace berry
void(* Destructor)(QObject *)
static int type(const char *typeName)
The ExtensionType class manages named types.
static QObject * construct(int type)
static int registerType(const char *typeName, Destructor destructor, Constructor constructor)
static bool isRegistered(int type)
static void unregisterType(const char *typeName)
static int extensionTypeCustomType_unlocked(const char *typeName, int length)
static int registerTypedef(const char *typeName, int aliasId)
static void destroy(int type, QObject *data)
QObject *(* Constructor)()