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