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