xref: /haiku/headers/private/app/MessagePrivate.h (revision 89755088d790ff4fe36f8aa77dacb2bd15507108)
1 /*
2  * Copyright 2005-2007, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Lotz <mmlr@mlotz.ch>
7  */
8 #ifndef _MESSAGE_PRIVATE_H_
9 #define _MESSAGE_PRIVATE_H_
10 
11 #include <Message.h>
12 #include <Messenger.h>
13 #include <MessengerPrivate.h>
14 #include <TokenSpace.h>
15 
16 
17 #define MESSAGE_BODY_HASH_TABLE_SIZE	10
18 #define MAX_DATA_PREALLOCATION			B_PAGE_SIZE * 10
19 #define MAX_FIELD_PREALLOCATION			50
20 #define MAX_ITEM_PREALLOCATION			B_PAGE_SIZE
21 
22 
23 static const int32 kPortMessageCode = 'pjpp';
24 
25 
26 enum {
27 	MESSAGE_FLAG_VALID = 0x0001,
28 	MESSAGE_FLAG_REPLY_REQUIRED = 0x0002,
29 	MESSAGE_FLAG_REPLY_DONE = 0x0004,
30 	MESSAGE_FLAG_IS_REPLY = 0x0008,
31 	MESSAGE_FLAG_WAS_DELIVERED = 0x0010,
32 	MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020,
33 	MESSAGE_FLAG_WAS_DROPPED = 0x0080,
34 	MESSAGE_FLAG_PASS_BY_AREA = 0x0100
35 };
36 
37 
38 enum {
39 	FIELD_FLAG_VALID = 0x0001,
40 	FIELD_FLAG_FIXED_SIZE = 0x0002,
41 };
42 
43 
44 struct BMessage::field_header {
45 	uint32		flags;
46 	type_code	type;
47 	int32		name_length;
48 	int32		count;
49 	ssize_t		data_size;
50 	ssize_t		allocated;
51 	int32		offset;
52 	int32		next_field;
53 };
54 
55 
56 struct BMessage::message_header {
57 	uint32		format;
58 	uint32		what;
59 	uint32		flags;
60 
61 	ssize_t		fields_size;
62 	ssize_t		data_size;
63 	ssize_t		fields_available;
64 	ssize_t		data_available;
65 
66 	uint32		fields_checksum;
67 	uint32		data_checksum;
68 
69 	int32		target;
70 	int32		current_specifier;
71 	area_id		message_area;
72 
73 	// reply info
74 	port_id		reply_port;
75 	int32		reply_target;
76 	team_id		reply_team;
77 
78 	// body info
79 	int32		field_count;
80 	int32		hash_table_size;
81 	int32		hash_table[MESSAGE_BODY_HASH_TABLE_SIZE];
82 
83 	/*	The hash table does contain indexes into the field list and
84 		not direct offsets to the fields. This has the advantage
85 		of not needing to update offsets in two locations.
86 		The hash table must be reevaluated when we remove a field
87 		though.
88 	*/
89 };
90 
91 
92 class BMessage::Private {
93 	public:
94 		Private(BMessage *msg)
95 			: fMessage(msg)
96 		{
97 		}
98 
99 		Private(BMessage &msg)
100 			: fMessage(&msg)
101 		{
102 		}
103 
104 		void
105 		SetTarget(int32 token)
106 		{
107 			fMessage->fHeader->target = token;
108 		}
109 
110 		void
111 		SetReply(BMessenger messenger)
112 		{
113 			BMessenger::Private messengerPrivate(messenger);
114 			fMessage->fHeader->reply_port = messengerPrivate.Port();
115 			fMessage->fHeader->reply_target = messengerPrivate.Token();
116 			fMessage->fHeader->reply_team = messengerPrivate.Team();
117 		}
118 
119 		void
120 		SetReply(team_id team, port_id port, int32 target)
121 		{
122 			fMessage->fHeader->reply_port = port;
123 			fMessage->fHeader->reply_target = target;
124 			fMessage->fHeader->reply_team = team;
125 		}
126 
127 		int32
128 		GetTarget()
129 		{
130 			return fMessage->fHeader->target;
131 		}
132 
133 		bool
134 		UsePreferredTarget()
135 		{
136 			return fMessage->fHeader->target == B_PREFERRED_TOKEN;
137 		}
138 
139 		void
140 		SetWasDropped(bool wasDropped)
141 		{
142 			if (wasDropped)
143 				fMessage->fHeader->flags |= MESSAGE_FLAG_WAS_DROPPED;
144 			else
145 				fMessage->fHeader->flags &= ~MESSAGE_FLAG_WAS_DROPPED;
146 		}
147 
148 		status_t
149 		Clear()
150 		{
151 			return fMessage->_Clear();
152 		}
153 
154 		status_t
155 		InitHeader()
156 		{
157 			return fMessage->_InitHeader();
158 		}
159 
160 		BMessage::message_header*
161 		GetMessageHeader()
162 		{
163 			return fMessage->fHeader;
164 		}
165 
166 		BMessage::field_header*
167 		GetMessageFields()
168 		{
169 			return fMessage->fFields;
170 		}
171 
172 		uint8*
173 		GetMessageData()
174 		{
175 			return fMessage->fData;
176 		}
177 
178 		ssize_t
179 		NativeFlattenedSize() const
180 		{
181 			return fMessage->_NativeFlattenedSize();
182 		}
183 
184 		status_t
185 		NativeFlatten(char *buffer, ssize_t size) const
186 		{
187 			return fMessage->_NativeFlatten(buffer, size);
188 		}
189 
190 		status_t
191 		NativeFlatten(BDataIO *stream, ssize_t *size) const
192 		{
193 			return fMessage->_NativeFlatten(stream, size);
194 		}
195 
196 		status_t
197 		FlattenToArea(message_header **header) const
198 		{
199 			return fMessage->_FlattenToArea(header);
200 		}
201 
202 		status_t
203 		SendMessage(port_id port, team_id portOwner, int32 token,
204 			bigtime_t timeout, bool replyRequired, BMessenger &replyTo) const
205 		{
206 			return fMessage->_SendMessage(port, portOwner, token,
207 				timeout, replyRequired, replyTo);
208 		}
209 
210 		status_t
211 		SendMessage(port_id port, team_id portOwner, int32 token,
212 			BMessage *reply, bigtime_t sendTimeout,
213 			bigtime_t replyTimeout) const
214 		{
215 			return fMessage->_SendMessage(port, portOwner, token,
216 				reply, sendTimeout, replyTimeout);
217 		}
218 
219 		// static methods
220 
221 		static status_t
222 		SendFlattenedMessage(void *data, int32 size, port_id port,
223 			int32 token, bigtime_t timeout)
224 		{
225 			return BMessage::_SendFlattenedMessage(data, size,
226 				port, token, timeout);
227 		}
228 
229 		static void
230 		StaticInit()
231 		{
232 			BMessage::_StaticInit();
233 		}
234 
235 		static void
236 		StaticCleanup()
237 		{
238 			BMessage::_StaticCleanup();
239 		}
240 
241 		static void
242 		StaticCacheCleanup()
243 		{
244 			BMessage::_StaticCacheCleanup();
245 		}
246 
247 	private:
248 		BMessage* fMessage;
249 };
250 
251 #endif	// _MESSAGE_PRIVATE_H_
252