xref: /haiku/src/kits/app/TokenSpace.cpp (revision b55a57da7173b9af0432bd3e148d03f06161d036)
1 /*
2  * Copyright 2001-2009, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Erik Jaesler (erik@cgsoftware.com)
7  *		Axel Dörfler, axeld@pinc-software.de
8  */
9 
10 
11 #include <DirectMessageTarget.h>
12 #include <TokenSpace.h>
13 
14 #include <Autolock.h>
15 
16 
17 namespace BPrivate {
18 
19 BTokenSpace gDefaultTokens;
20 	// the default token space - all handlers will go into that one
21 
22 
23 BTokenSpace::BTokenSpace()
24 	:
25 	BLocker("token space"),
26 	fTokenCount(1)
27 {
28 }
29 
30 
31 BTokenSpace::~BTokenSpace()
32 {
33 }
34 
35 
36 int32
37 BTokenSpace::NewToken(int16 type, void* object)
38 {
39 	BAutolock locker(this);
40 
41 	token_info tokenInfo = { type, object, NULL };
42 	int32 token = fTokenCount;
43 
44 	try {
45 		fTokenMap[token] = tokenInfo;
46 	} catch (std::bad_alloc& exception) {
47 		return -1;
48 	}
49 
50 	fTokenCount++;
51 
52 	return token;
53 }
54 
55 
56 /*!
57 	Inserts the specified token into the token space. If that token
58 	already exists, it will be overwritten.
59 	Don't mix NewToken() and this method unless you know what you're
60 	doing.
61 */
62 bool
63 BTokenSpace::SetToken(int32 token, int16 type, void* object)
64 {
65 	BAutolock locker(this);
66 
67 	token_info tokenInfo = { type, object, NULL };
68 
69 	try {
70 		fTokenMap[token] = tokenInfo;
71 	} catch (std::bad_alloc& exception) {
72 		return false;
73 	}
74 
75 	// this makes sure SetToken() plays more or less nice with NewToken()
76 	if (token >= fTokenCount)
77 		fTokenCount = token + 1;
78 
79 	return true;
80 }
81 
82 
83 bool
84 BTokenSpace::RemoveToken(int32 token)
85 {
86 	BAutolock locker(this);
87 
88 	TokenMap::iterator iterator = fTokenMap.find(token);
89 	if (iterator == fTokenMap.end())
90 		return false;
91 
92 	fTokenMap.erase(iterator);
93 	return true;
94 }
95 
96 
97 /*!	Checks wether or not the \a token exists with the specified
98 	\a type in the token space or not.
99 */
100 bool
101 BTokenSpace::CheckToken(int32 token, int16 type) const
102 {
103 	BAutolock locker(const_cast<BTokenSpace&>(*this));
104 
105 	TokenMap::const_iterator iterator = fTokenMap.find(token);
106 	if (iterator != fTokenMap.end() && iterator->second.type == type)
107 		return true;
108 
109 	return false;
110 }
111 
112 
113 status_t
114 BTokenSpace::GetToken(int32 token, int16 type, void** _object) const
115 {
116 	if (token < 1)
117 		return B_ENTRY_NOT_FOUND;
118 
119 	BAutolock locker(const_cast<BTokenSpace&>(*this));
120 
121 	TokenMap::const_iterator iterator = fTokenMap.find(token);
122 	if (iterator == fTokenMap.end() || iterator->second.type != type)
123 		return B_ENTRY_NOT_FOUND;
124 
125 	*_object = iterator->second.object;
126 	return B_OK;
127 }
128 
129 
130 status_t
131 BTokenSpace::SetHandlerTarget(int32 token, BDirectMessageTarget* target)
132 {
133 	if (token < 1)
134 		return B_ENTRY_NOT_FOUND;
135 
136 	BAutolock locker(const_cast<BTokenSpace&>(*this));
137 
138 	TokenMap::iterator iterator = fTokenMap.find(token);
139 	if (iterator == fTokenMap.end() || iterator->second.type != B_HANDLER_TOKEN)
140 		return B_ENTRY_NOT_FOUND;
141 
142 	if (iterator->second.target != NULL)
143 		iterator->second.target->Release();
144 
145 	iterator->second.target = target;
146 	if (target != NULL)
147 		target->Acquire();
148 
149 	return B_OK;
150 }
151 
152 
153 status_t
154 BTokenSpace::AcquireHandlerTarget(int32 token, BDirectMessageTarget** _target)
155 {
156 	if (token < 1)
157 		return B_ENTRY_NOT_FOUND;
158 
159 	BAutolock locker(const_cast<BTokenSpace&>(*this));
160 
161 	TokenMap::const_iterator iterator = fTokenMap.find(token);
162 	if (iterator == fTokenMap.end() || iterator->second.type != B_HANDLER_TOKEN)
163 		return B_ENTRY_NOT_FOUND;
164 
165 	if (iterator->second.target != NULL)
166 		iterator->second.target->Acquire();
167 
168 	*_target = iterator->second.target;
169 	return B_OK;
170 }
171 
172 }	// namespace BPrivate
173