2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
7 #include "TypeHandlerRoster.h"
11 #include <AutoDeleter.h>
12 #include <AutoLocker.h>
14 #include "AddressValueNode.h"
15 #include "ArrayValueNode.h"
16 #include "CompoundValueNode.h"
17 #include "BListTypeHandler.h"
18 #include "BMessageTypeHandler.h"
19 #include "CStringTypeHandler.h"
20 #include "EnumerationValueNode.h"
21 #include "PointerToMemberValueNode.h"
22 #include "PrimitiveValueNode.h"
24 #include "TypeHandler.h"
27 // #pragma mark - BasicTypeHandler
33 template<typename TypeClass
, typename NodeClass
>
34 class BasicTypeHandler
: public TypeHandler
{
36 virtual float SupportsType(Type
* type
)
38 return dynamic_cast<TypeClass
*>(type
) != NULL
? 0.5f
: 0;
41 virtual status_t
CreateValueNode(ValueNodeChild
* nodeChild
,
42 Type
* type
, ValueNode
*& _node
)
44 TypeClass
* supportedType
= dynamic_cast<TypeClass
*>(type
);
45 if (supportedType
== NULL
)
48 ValueNode
* node
= new(std::nothrow
) NodeClass(nodeChild
, supportedType
);
58 } // unnamed namespace
61 // #pragma mark - TypeHandlerRoster
64 /*static*/ TypeHandlerRoster
* TypeHandlerRoster::sDefaultInstance
= NULL
;
67 TypeHandlerRoster::TypeHandlerRoster()
69 fLock("type handler roster")
74 TypeHandlerRoster::~TypeHandlerRoster()
78 /*static*/ TypeHandlerRoster
*
79 TypeHandlerRoster::Default()
81 return sDefaultInstance
;
86 TypeHandlerRoster::CreateDefault()
88 if (sDefaultInstance
!= NULL
)
91 TypeHandlerRoster
* roster
= new(std::nothrow
) TypeHandlerRoster
;
94 ObjectDeleter
<TypeHandlerRoster
> rosterDeleter(roster
);
96 status_t error
= roster
->Init();
100 error
= roster
->RegisterDefaultHandlers();
104 sDefaultInstance
= rosterDeleter
.Detach();
110 TypeHandlerRoster::DeleteDefault()
112 TypeHandlerRoster
* roster
= sDefaultInstance
;
113 sDefaultInstance
= NULL
;
119 TypeHandlerRoster::Init()
121 return fLock
.InitCheck();
126 TypeHandlerRoster::RegisterDefaultHandlers()
128 TypeHandler
* handler
;
129 BReference
<TypeHandler
> handlerReference
;
131 #undef REGISTER_BASIC_HANDLER
132 #define REGISTER_BASIC_HANDLER(name) \
133 handler = new(std::nothrow) \
134 BasicTypeHandler<name##Type, name##ValueNode>(); \
135 handlerReference.SetTo(handler, true); \
136 if (handler == NULL || !RegisterHandler(handler)) \
139 REGISTER_BASIC_HANDLER(Address
);
140 REGISTER_BASIC_HANDLER(Array
);
141 REGISTER_BASIC_HANDLER(Compound
);
142 REGISTER_BASIC_HANDLER(Enumeration
);
143 REGISTER_BASIC_HANDLER(PointerToMember
);
144 REGISTER_BASIC_HANDLER(Primitive
);
146 #undef REGISTER_SPECIALIZED_HANDLER
147 #define REGISTER_SPECIALIZED_HANDLER(name) \
148 handler = new(std::nothrow) \
149 name##TypeHandler(); \
150 handlerReference.SetTo(handler, true); \
151 if (handler == NULL || !RegisterHandler(handler)) \
154 REGISTER_SPECIALIZED_HANDLER(CString
);
155 REGISTER_SPECIALIZED_HANDLER(BMessage
);
156 REGISTER_SPECIALIZED_HANDLER(BList
);
163 TypeHandlerRoster::FindTypeHandler(ValueNodeChild
* nodeChild
, Type
* type
,
164 TypeHandler
*& _handler
)
166 // find the best-supporting handler
167 AutoLocker
<BLocker
> locker(fLock
);
169 TypeHandler
* bestHandler
= NULL
;
170 float bestSupport
= 0;
172 for (int32 i
= 0; TypeHandler
* handler
= fTypeHandlers
.ItemAt(i
); i
++) {
173 float support
= handler
->SupportsType(type
);
174 if (support
> 0 && support
> bestSupport
) {
175 bestHandler
= handler
;
176 bestSupport
= support
;
180 if (bestHandler
== NULL
)
181 return B_ENTRY_NOT_FOUND
;
183 bestHandler
->AcquireReference();
184 _handler
= bestHandler
;
190 TypeHandlerRoster::CreateValueNode(ValueNodeChild
* nodeChild
, Type
* type
,
193 // find the best-supporting handler
195 TypeHandler
* handler
;
196 status_t error
= FindTypeHandler(nodeChild
, type
, handler
);
198 // let the handler create the node
199 BReference
<TypeHandler
> handlerReference(handler
, true);
200 return handler
->CreateValueNode(nodeChild
, type
, _node
);
203 // not found yet -- try to strip a modifier/typedef from the type
204 Type
* nextType
= type
->ResolveRawType(true);
205 if (nextType
== NULL
|| nextType
== type
)
206 return B_UNSUPPORTED
;
214 TypeHandlerRoster::RegisterHandler(TypeHandler
* handler
)
216 if (!fTypeHandlers
.AddItem(handler
))
219 handler
->AcquireReference();
225 TypeHandlerRoster::UnregisterHandler(TypeHandler
* handler
)
227 if (fTypeHandlers
.RemoveItem(handler
))
228 handler
->ReleaseReference();