xref: /haiku/headers/build/private/app/MessagePrivate.h (revision fce4895d1884da5ae6fb299d23c735c598e690b1)
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 	private:
174 		BMessage* fMessage;
175 };
176 
177 #endif	// _MESSAGE_PRIVATE_H_
178