xref: /haiku/headers/os/app/Message.h (revision 37d96a4c637d81f25dec869941892f8f8c5e4d42)
1 /*
2  * Copyright 2001-2005, Haiku Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *	Erik Jaesler (erik@cgsoftware.com)
7  *	DarkWyrm <bpmagic@columbus.rr.com>
8  */
9 #ifndef _MESSAGE_H
10 #define _MESSAGE_H
11 
12 #include <DataIO.h>
13 #include <Flattenable.h>
14 #include <Messenger.h>
15 #include <OS.h>
16 #include <Rect.h>
17 
18 // for convenience
19 #include <AppDefs.h>
20 #include <TypeConstants.h>
21 
22 
23 class BBlockCache;
24 class BMessenger;
25 class BHandler;
26 class BString;
27 struct entry_ref;
28 
29 // Private or reserved ---------------------------------------------------------
30 extern "C" void _msg_cache_cleanup_();
31 extern "C" int _init_message_();
32 extern "C" int _delete_message_();
33 
34 
35 // Name lengths and Scripting specifiers ---------------------------------------
36 #define B_FIELD_NAME_LENGTH			255
37 #define B_PROPERTY_NAME_LENGTH		255
38 
39 enum {
40 	B_NO_SPECIFIER = 0,
41 	B_DIRECT_SPECIFIER,
42 	B_INDEX_SPECIFIER,
43 	B_REVERSE_INDEX_SPECIFIER,
44 	B_RANGE_SPECIFIER,
45 	B_REVERSE_RANGE_SPECIFIER,
46 	B_NAME_SPECIFIER,
47 	B_ID_SPECIFIER,
48 
49 	B_SPECIFIERS_END = 128
50 	// app-defined specifiers start at B_SPECIFIERS_END+1
51 };
52 
53 namespace BPrivate {
54 	class BMessageBody;
55 }
56 
57 // BMessage class --------------------------------------------------------------
58 class BMessage {
59 public:
60 		uint32		what;
61 
62 					BMessage();
63 					BMessage(uint32 what);
64 					BMessage(const BMessage &a_message);
65 virtual				~BMessage();
66 
67 		BMessage	&operator=(const BMessage &msg);
68 
69 // Statistics and misc info
70 		status_t	GetInfo(type_code typeRequested, int32 which, char **name,
71 							type_code *typeReturned, int32 *count = NULL) const;
72 
73 		status_t	GetInfo(const char *name, type_code *type, int32 *c = 0) const;
74 		status_t	GetInfo(const char *name, type_code *type, bool *fixed_size) const;
75 
76 		int32		CountNames(type_code type) const;
77 		bool		IsEmpty() const;
78 		bool		IsSystem() const;
79 		bool		IsReply() const;
80 		void		PrintToStream() const;
81 
82 		status_t	Rename(const char *old_entry, const char *new_entry);
83 
84 // Delivery info
85 		bool		WasDelivered() const;
86 		bool		IsSourceWaiting() const;
87 		bool		IsSourceRemote() const;
88 		BMessenger	ReturnAddress() const;
89 		const BMessage	*Previous() const;
90 		bool		WasDropped() const;
91 		BPoint		DropPoint(BPoint *offset = NULL) const;
92 
93 // Replying
94 		status_t	SendReply(uint32 command, BHandler *reply_to = NULL);
95 		status_t	SendReply(BMessage *the_reply, BHandler *reply_to = NULL,
96 							bigtime_t timeout = B_INFINITE_TIMEOUT);
97 		status_t	SendReply(BMessage *the_reply, BMessenger reply_to,
98 							bigtime_t timeout = B_INFINITE_TIMEOUT);
99 
100 		status_t	SendReply(uint32 command, BMessage *reply_to_reply);
101 		status_t	SendReply(BMessage *the_reply, BMessage *reply_to_reply,
102 							bigtime_t send_timeout = B_INFINITE_TIMEOUT,
103 							bigtime_t reply_timeout = B_INFINITE_TIMEOUT);
104 
105 // Flattening data
106 		ssize_t		FlattenedSize() const;
107 		status_t	Flatten(char *buffer, ssize_t size) const;
108 		status_t	Flatten(BDataIO *stream, ssize_t *size = NULL) const;
109 		status_t	Unflatten(const char *flat_buffer);
110 		status_t	Unflatten(BDataIO *stream);
111 
112 
113 // Specifiers (scripting)
114 		status_t	AddSpecifier(const char *property);
115 		status_t	AddSpecifier(const char *property, int32 index);
116 		status_t	AddSpecifier(const char *property, int32 index, int32 range);
117 		status_t	AddSpecifier(const char *property, const char *name);
118 		status_t	AddSpecifier(const BMessage *specifier);
119 
120 		status_t	SetCurrentSpecifier(int32 index);
121 		status_t	GetCurrentSpecifier(int32 *index, BMessage *specifier = NULL,
122 							int32 *form = NULL, const char **property = NULL) const;
123 		bool		HasSpecifiers() const;
124 		status_t	PopSpecifier();
125 
126 // Adding data
127 		status_t	AddRect(const char *name, BRect a_rect);
128 		status_t	AddPoint(const char *name, BPoint a_point);
129 		status_t	AddString(const char *name, const char *a_string);
130 		status_t	AddString(const char *name, const BString& a_string);
131 		status_t	AddInt8(const char *name, int8 val);
132 		status_t	AddInt16(const char *name, int16 val);
133 		status_t	AddInt32(const char *name, int32 val);
134 		status_t	AddInt64(const char *name, int64 val);
135 		status_t	AddBool(const char *name, bool a_boolean);
136 		status_t	AddFloat(const char *name, float a_float);
137 		status_t	AddDouble(const char *name, double a_double);
138 		status_t	AddPointer(const char *name, const void *ptr);
139 		status_t	AddMessenger(const char *name, BMessenger messenger);
140 		status_t	AddRef(const char *name, const entry_ref *ref);
141 		status_t	AddMessage(const char *name, const BMessage *msg);
142 		status_t	AddFlat(const char *name, BFlattenable *obj, int32 count = 1);
143 		status_t	AddData(const char *name, type_code type, const void *data,
144 						ssize_t numBytes, bool is_fixed_size = true, int32 count = 1);
145 
146 // Removing data
147 		status_t	RemoveData(const char *name, int32 index = 0);
148 		status_t	RemoveName(const char *name);
149 		status_t	MakeEmpty();
150 
151 // Finding data
152 		status_t	FindRect(const char *name, BRect *rect) const;
153 		status_t	FindRect(const char *name, int32 index, BRect *rect) const;
154 		status_t	FindPoint(const char *name, BPoint *pt) const;
155 		status_t	FindPoint(const char *name, int32 index, BPoint *pt) const;
156 		status_t	FindString(const char *name, const char **str) const;
157 		status_t	FindString(const char *name, int32 index, const char **str) const;
158 		status_t	FindString(const char *name, BString *str) const;
159 		status_t	FindString(const char *name, int32 index, BString *str) const;
160 		status_t	FindInt8(const char *name, int8 *value) const;
161 		status_t	FindInt8(const char *name, int32 index, int8 *val) const;
162 		status_t	FindInt16(const char *name, int16 *value) const;
163 		status_t	FindInt16(const char *name, int32 index, int16 *val) const;
164 		status_t	FindInt32(const char *name, int32 *value) const;
165 		status_t	FindInt32(const char *name, int32 index, int32 *val) const;
166 		status_t	FindInt64(const char *name, int64 *value) const;
167 		status_t	FindInt64(const char *name, int32 index, int64 *val) const;
168 		status_t	FindBool(const char *name, bool *value) const;
169 		status_t	FindBool(const char *name, int32 index, bool *value) const;
170 		status_t	FindFloat(const char *name, float *f) const;
171 		status_t	FindFloat(const char *name, int32 index, float *f) const;
172 		status_t	FindDouble(const char *name, double *d) const;
173 		status_t	FindDouble(const char *name, int32 index, double *d) const;
174 		status_t	FindPointer(const char *name, void **ptr) const;
175 		status_t	FindPointer(const char *name, int32 index,  void **ptr) const;
176 		status_t	FindMessenger(const char *name, BMessenger *m) const;
177 		status_t	FindMessenger(const char *name, int32 index, BMessenger *m) const;
178 		status_t	FindRef(const char *name, entry_ref *ref) const;
179 		status_t	FindRef(const char *name, int32 index, entry_ref *ref) const;
180 		status_t	FindMessage(const char *name, BMessage *msg) const;
181 		status_t	FindMessage(const char *name, int32 index, BMessage *msg) const;
182 		status_t	FindFlat(const char *name, BFlattenable *obj) const;
183 		status_t	FindFlat(const char *name, int32 index, BFlattenable *obj) const;
184 		status_t	FindData(const char *name, type_code type,
185 							const void **data, ssize_t *numBytes) const;
186 		status_t	FindData(const char *name, type_code type, int32 index,
187 							const void **data, ssize_t *numBytes) const;
188 
189 // Replacing data
190 		status_t	ReplaceRect(const char *name, BRect a_rect);
191 		status_t	ReplaceRect(const char *name, int32 index, BRect a_rect);
192 		status_t	ReplacePoint(const char *name, BPoint a_point);
193 		status_t	ReplacePoint(const char *name, int32 index, BPoint a_point);
194 		status_t	ReplaceString(const char *name, const char *string);
195 		status_t	ReplaceString(const char *name, int32 index, const char *string);
196 		status_t	ReplaceString(const char *name, const BString& string);
197 		status_t	ReplaceString(const char *name, int32 index, const BString& string);
198 		status_t	ReplaceInt8(const char *name, int8 val);
199 		status_t	ReplaceInt8(const char *name, int32 index, int8 val);
200 		status_t	ReplaceInt16(const char *name, int16 val);
201 		status_t	ReplaceInt16(const char *name, int32 index, int16 val);
202 		status_t	ReplaceInt32(const char *name, int32 val);
203 		status_t	ReplaceInt32(const char *name, int32 index, int32 val);
204 		status_t	ReplaceInt64(const char *name, int64 val);
205 		status_t	ReplaceInt64(const char *name, int32 index, int64 val);
206 		status_t	ReplaceBool(const char *name, bool a_bool);
207 		status_t	ReplaceBool(const char *name, int32 index, bool a_bool);
208 		status_t	ReplaceFloat(const char *name, float a_float);
209 		status_t	ReplaceFloat(const char *name, int32 index, float a_float);
210 		status_t	ReplaceDouble(const char *name, double a_double);
211 		status_t	ReplaceDouble(const char *name, int32 index, double a_double);
212 		status_t	ReplacePointer(const char *name, const void *ptr);
213 		status_t	ReplacePointer(const char *name,int32 index,const void *ptr);
214 		status_t	ReplaceMessenger(const char *name, BMessenger messenger);
215 		status_t	ReplaceMessenger(const char *name, int32 index, BMessenger msngr);
216 		status_t	ReplaceRef(	const char *name,const entry_ref *ref);
217 		status_t	ReplaceRef(	const char *name, int32 index, const entry_ref *ref);
218 		status_t	ReplaceMessage(const char *name, const BMessage *msg);
219 		status_t	ReplaceMessage(const char *name, int32 index, const BMessage *msg);
220 		status_t	ReplaceFlat(const char *name, BFlattenable *obj);
221 		status_t	ReplaceFlat(const char *name, int32 index, BFlattenable *obj);
222 		status_t	ReplaceData(const char *name, type_code type,
223 								const void *data, ssize_t data_size);
224 		status_t	ReplaceData(const char *name, type_code type, int32 index,
225 								const void *data, ssize_t data_size);
226 
227 		void		*operator new(size_t size);
228 		void		*operator new(size_t, void* p);
229 		void		operator delete(void *ptr, size_t size);
230 
231 // Private, reserved, or obsolete ----------------------------------------------
232 		bool		HasRect(const char *, int32 n = 0) const;
233 		bool		HasPoint(const char *, int32 n = 0) const;
234 		bool		HasString(const char *, int32 n = 0) const;
235 		bool		HasInt8(const char *, int32 n = 0) const;
236 		bool		HasInt16(const char *, int32 n = 0) const;
237 		bool		HasInt32(const char *, int32 n = 0) const;
238 		bool		HasInt64(const char *, int32 n = 0) const;
239 		bool		HasBool(const char *, int32 n = 0) const;
240 		bool		HasFloat(const char *, int32 n = 0) const;
241 		bool		HasDouble(const char *, int32 n = 0) const;
242 		bool		HasPointer(const char *, int32 n = 0) const;
243 		bool		HasMessenger(const char *, int32 n = 0) const;
244 		bool		HasRef(const char *, int32 n = 0) const;
245 		bool		HasMessage(const char *, int32 n = 0) const;
246 		bool		HasFlat(const char *, const BFlattenable *) const;
247 		bool		HasFlat(const char *,int32 ,const BFlattenable *) const;
248 		bool		HasData(const char *, type_code , int32 n = 0) const;
249 		BRect		FindRect(const char *, int32 n = 0) const;
250 		BPoint		FindPoint(const char *, int32 n = 0) const;
251 		const char	*FindString(const char *, int32 n = 0) const;
252 		int8		FindInt8(const char *, int32 n = 0) const;
253 		int16		FindInt16(const char *, int32 n = 0) const;
254 		int32		FindInt32(const char *, int32 n = 0) const;
255 		int64		FindInt64(const char *, int32 n = 0) const;
256 		bool		FindBool(const char *, int32 n = 0) const;
257 		float		FindFloat(const char *, int32 n = 0) const;
258 		double		FindDouble(const char *, int32 n = 0) const;
259 
260 		class Private;
261 
262 private:
263 		class Header;
264 
265 friend class	BMessageQueue;
266 friend class	BMessenger;
267 friend class	BApplication;
268 friend class	Header;
269 friend class	Private;
270 
271 friend inline	void		_set_message_target_(BMessage *, int32, bool);
272 friend inline	void		_set_message_reply_(BMessage *, BMessenger);
273 friend inline	int32		_get_message_target_(BMessage *);
274 friend inline	bool		_use_preferred_target_(BMessage *);
275 
276 					// deprecated
277 					BMessage(BMessage *a_message);
278 
279 virtual	void		_ReservedMessage1();
280 virtual	void		_ReservedMessage2();
281 virtual	void		_ReservedMessage3();
282 
283 		void		init_data();
284 		status_t	flatten_target_info(BDataIO *stream,
285 										ssize_t size,
286 										uchar flags) const;
287 		status_t	real_flatten(char *result,
288 								ssize_t size) const;
289 		status_t	real_flatten(BDataIO *stream) const;
290 		char		*stack_flatten(char *stack_ptr,
291 									ssize_t stack_size,
292 									bool incl_reply,
293 									ssize_t *size = NULL) const;
294 
295 		status_t	_UnflattenKMessage(const char *buffer);
296 
297 		ssize_t		calc_size(uchar flags) const;
298 		ssize_t		calc_hdr_size(uchar flags) const;
299 		status_t	nfind_data(	const char *name,
300 								type_code type,
301 								int32 index,
302 								const void **data,
303 								ssize_t *data_size) const;
304 		status_t	copy_data(	const char *name,
305 								type_code type,
306 								int32 index,
307 								void *data,
308 								ssize_t data_size) const;
309 
310 		status_t	_send_(port_id port,
311 							int32 token,
312 							bool preferred,
313 							bigtime_t timeout,
314 							bool reply_required,
315 							BMessenger &reply_to) const;
316 		status_t	send_message(port_id port,
317 								team_id port_owner,
318 								int32 token,
319 								bool preferred,
320 								BMessage *reply,
321 								bigtime_t send_timeout,
322 								bigtime_t reply_timeout) const;
323 static	status_t	_SendFlattenedMessage(void *data, int32 size,
324 						port_id port, int32 token, bool preferred,
325 						bigtime_t timeout);
326 
327 static	void		_StaticInit();
328 static	void		_StaticCleanup();
329 static	void		_StaticCacheCleanup();
330 
331 		enum		{ sNumReplyPorts = 3 };
332 static	port_id		sReplyPorts[sNumReplyPorts];
333 static	long		sReplyPortInUse[sNumReplyPorts];
334 static	int32		sGetCachedReplyPort();
335 
336 static	BBlockCache	*sMsgCache;
337 
338 		struct dyn_array {
339 			int32		fLogicalBytes;
340 			int32		fPhysicalBytes;
341 			int32		fChunkSize;
342 			int32		fCount;
343 			int32		fEntryHdrSize;
344 		};
345 
346 		struct entry_hdr  : public dyn_array {
347 			entry_hdr	*fNext;
348 			uint32		fType;
349 			uchar		fNameLength;
350 			char		fName[1];
351 		};
352 
353 		struct var_chunk {
354 			int32	fDataSize;
355 			char	fData[1];
356 		};
357 
358 		entry_hdr 	*entry_find(const char *name, uint32 type,status_t *result=NULL) const;
359 		void 		entry_remove(entry_hdr *entry);
360 
361 		void		*da_create(int32 header_size, int32 chunk_size,
362 								bool fixed, int32 nchunks);
363 		status_t	da_add_data(dyn_array **da, const void *data, int32 size);
364 		void		*da_find_data(dyn_array *da, int32 index,
365 									int32 *size = NULL) const;
366 		status_t	da_delete_data(dyn_array **pda, int32 index);
367 		status_t	da_replace_data(dyn_array **pda, int32 index,
368 									const void *data, int32 dsize);
369 		int32		da_calc_size(int32 hdr_size, int32 chunksize,
370 								bool is_fixed, int32 nchunks) const;
371 		void		*da_grow(dyn_array **pda, int32 increase);
372 		void		da_dump(dyn_array *da);
373 
374 		int32		da_chunk_hdr_size() const
375 						{ return sizeof(int32); }
376 		int32		da_chunk_size(var_chunk *v) const
377 						{ return (v->fDataSize + da_chunk_hdr_size() + 7) & ~7; }
378 		var_chunk	*da_first_chunk(dyn_array *da) const
379 						{ return (var_chunk *) da_start_of_data(da); }
380 		var_chunk	*da_next_chunk(var_chunk *v) const
381 						{ return (var_chunk *) (((char*) v) + da_chunk_size(v)); }
382 		var_chunk	*da_chunk_ptr(void *data) const
383 						{ return (var_chunk*) (((char *) data) - da_chunk_hdr_size()); }
384 
385 		int32		da_pad_8(int32 val) const
386 						{ return (val + 7) & ~7; }
387 		int32		da_total_size(dyn_array *da) const
388 						{ return (int32)sizeof(dyn_array) + da->fEntryHdrSize +
389 											da->fPhysicalBytes; }
390 		int32		da_total_logical_size(dyn_array *da) const
391 						{ return (int32)sizeof(dyn_array) + da->fEntryHdrSize +
392 											da->fLogicalBytes; }
393 		char		*da_start_of_data(dyn_array *da) const
394 						{ return ((char *) da) + (sizeof(dyn_array) +
395 											da->fEntryHdrSize); }
396 		bool		da_is_mini_data(dyn_array *da) const
397 						{ return ((da->fLogicalBytes <= (int32) UCHAR_MAX) &&
398 											(da->fCount <= (int32) UCHAR_MAX));}
399 		void		da_swap_var_sized(dyn_array *da);
400 		void		da_swap_fixed_sized(dyn_array *da);
401 
402 		BMessage			*fQueueLink;
403 		int32				fTarget;
404 		BMessage			*fOriginal;
405 		uint32				fChangeCount;
406 		int32				fCurSpecifier;
407 		uint32				fPtrOffset;
408 
409 		// ejaesler: Stealing one for my whacky BMessageBody l33tness
410 		uint32				_reserved[2];
411 		BPrivate::BMessageBody*	fBody;
412 
413 		BMessage::entry_hdr	*fEntries;
414 
415 		struct reply_to_info {
416 			port_id				port;
417 			int32				target;
418 			team_id				team;
419 			bool				preferred;
420 		} fReplyTo;
421 
422 		bool				fPreferred;
423 		bool				fReplyRequired;
424 		bool				fReplyDone;
425 		bool				fIsReply;
426 		bool				fWasDelivered;
427 		bool				fReadOnly;
428 		bool				fHasSpecifiers;
429 };
430 
431 #endif	// _MESSAGE_H
432