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