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