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