1/*
2 * Copyright 2005-2012, 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_H
9#define _MESSAGE_H
10
11
12#include <new>
13
14#include <BeBuild.h>
15#include <DataIO.h>
16#include <Flattenable.h>
17#include <OS.h>
18#include <Rect.h>
19#include <Size.h>
20
21#include <AppDefs.h>		/* For convenience */
22#include <TypeConstants.h>	/* For convenience */
23
24
25class BAlignment;
26class BBlockCache;
27class BMessenger;
28class BHandler;
29class BString;
30struct entry_ref;
31
32
33// Name lengths and Scripting specifiers
34#define B_FIELD_NAME_LENGTH			255
35#define B_PROPERTY_NAME_LENGTH		255
36
37enum {
38	B_NO_SPECIFIER = 0,
39	B_DIRECT_SPECIFIER = 1,
40	B_INDEX_SPECIFIER,
41	B_REVERSE_INDEX_SPECIFIER,
42	B_RANGE_SPECIFIER,
43	B_REVERSE_RANGE_SPECIFIER,
44	B_NAME_SPECIFIER,
45	B_ID_SPECIFIER,
46
47	B_SPECIFIERS_END = 128
48	// app-defined specifiers start at B_SPECIFIERS_END + 1
49};
50
51
52class BMessage {
53public:
54			uint32				what;
55
56								BMessage();
57								BMessage(uint32 what);
58								BMessage(const BMessage& other);
59	virtual						~BMessage();
60
61			BMessage&			operator=(const BMessage& other);
62
63	// Statistics and misc info
64			status_t			GetInfo(type_code typeRequested, int32 index,
65									char** nameFound, type_code* typeFound,
66									int32* countFound = NULL) const;
67			status_t			GetInfo(const char* name, type_code* typeFound,
68									int32* countFound = NULL) const;
69			status_t			GetInfo(const char* name, type_code* typeFound,
70									bool* fixedSize) const;
71			status_t			GetInfo(const char* name, type_code* typeFound,
72									int32* countFound, bool* fixedSize) const;
73
74			int32				CountNames(type_code type) const;
75			bool				IsEmpty() const;
76			bool				IsSystem() const;
77			bool				IsReply() const;
78			void				PrintToStream() const;
79
80			status_t			Rename(const char* oldEntry,
81									const char* newEntry);
82
83	// Delivery info
84			bool				WasDelivered() const;
85			bool				IsSourceWaiting() const;
86			bool				IsSourceRemote() const;
87			BMessenger			ReturnAddress() const;
88			const BMessage*		Previous() const;
89			bool				WasDropped() const;
90			BPoint				DropPoint(BPoint* offset = NULL) const;
91
92	// Replying
93			status_t			SendReply(uint32 command,
94									BHandler* replyTo = NULL);
95			status_t			SendReply(BMessage* reply,
96									BHandler* replyTo = NULL,
97									bigtime_t timeout = B_INFINITE_TIMEOUT);
98			status_t			SendReply(BMessage* reply, BMessenger replyTo,
99									bigtime_t timeout = B_INFINITE_TIMEOUT);
100
101			status_t			SendReply(uint32 command,
102									BMessage* replyToReply);
103			status_t			SendReply(BMessage* reply,
104									BMessage* replyToReply,
105									bigtime_t sendTimeout = B_INFINITE_TIMEOUT,
106									bigtime_t replyTimeout
107										= B_INFINITE_TIMEOUT);
108
109	// Flattening data
110			ssize_t				FlattenedSize() const;
111			status_t			Flatten(char* buffer, ssize_t size) const;
112			status_t			Flatten(BDataIO* stream,
113									ssize_t* size = NULL) const;
114			status_t			Unflatten(const char* flatBuffer);
115			status_t			Unflatten(BDataIO* stream);
116
117	// Specifiers (scripting)
118			status_t			AddSpecifier(const char* property);
119			status_t			AddSpecifier(const char* property, int32 index);
120			status_t			AddSpecifier(const char* property, int32 index,
121									int32 range);
122			status_t			AddSpecifier(const char* property,
123									const char* name);
124			status_t			AddSpecifier(const BMessage* specifier);
125
126			status_t			SetCurrentSpecifier(int32 index);
127			status_t			GetCurrentSpecifier(int32* index,
128									BMessage* specifier = NULL,
129									int32* what = NULL,
130									const char** property = NULL) const;
131			bool				HasSpecifiers() const;
132			status_t			PopSpecifier();
133
134	// Adding data
135			status_t			AddAlignment(const char* name,
136									const BAlignment& alignment);
137			status_t			AddRect(const char* name, BRect rect);
138			status_t			AddPoint(const char* name, BPoint point);
139			status_t			AddSize(const char* name, BSize size);
140			status_t			AddString(const char* name, const char* string);
141			status_t			AddString(const char* name,
142									const BString& string);
143			status_t			AddInt8(const char* name, int8 value);
144			status_t			AddUInt8(const char* name, uint8 value);
145			status_t			AddInt16(const char* name, int16 value);
146			status_t			AddUInt16(const char* name, uint16 value);
147			status_t			AddInt32(const char* name, int32 value);
148			status_t			AddUInt32(const char* name, uint32 value);
149			status_t			AddInt64(const char* name, int64 value);
150			status_t			AddUInt64(const char* name, uint64 value);
151			status_t			AddBool(const char* name, bool value);
152			status_t			AddFloat(const char* name, float value);
153			status_t			AddDouble(const char* name, double value);
154			status_t			AddPointer(const char* name,
155									const void* pointer);
156			status_t			AddMessenger(const char* name,
157									BMessenger messenger);
158			status_t			AddRef(const char* name, const entry_ref* ref);
159			status_t			AddMessage(const char* name,
160									const BMessage* message);
161			status_t			AddFlat(const char* name, BFlattenable* object,
162									int32 count = 1);
163			status_t			AddData(const char* name, type_code type,
164									const void* data, ssize_t numBytes,
165									bool isFixedSize = true, int32 count = 1);
166
167			status_t			Append(const BMessage& message);
168
169	// Removing data
170			status_t			RemoveData(const char* name, int32 index = 0);
171			status_t			RemoveName(const char* name);
172			status_t			MakeEmpty();
173
174	// Finding data
175			status_t			FindAlignment(const char* name,
176									BAlignment* alignment) const;
177			status_t			FindAlignment(const char* name, int32 index,
178									BAlignment* alignment) const;
179
180			status_t			FindRect(const char* name, BRect* rect) const;
181			status_t			FindRect(const char* name, int32 index,
182									BRect* rect) const;
183			status_t			FindPoint(const char* name,
184									BPoint* point) const;
185			status_t			FindPoint(const char* name, int32 index,
186									BPoint* point) const;
187
188			status_t			FindSize(const char* name, BSize* size) const;
189			status_t			FindSize(const char* name, int32 index,
190									BSize* size) const;
191
192			status_t			FindString(const char* name,
193									const char** string) const;
194			status_t			FindString(const char* name, int32 index,
195									const char** string) const;
196			status_t			FindString(const char* name,
197									BString* string) const;
198			status_t			FindString(const char* name, int32 index,
199									BString* string) const;
200			status_t			FindInt8(const char* name, int8* value) const;
201			status_t			FindInt8(const char* name, int32 index,
202									int8* value) const;
203			status_t			FindUInt8(const char* name, uint8* value) const;
204			status_t			FindUInt8(const char* name, int32 index,
205									uint8* value) const;
206			status_t			FindInt16(const char* name, int16* value) const;
207			status_t			FindInt16(const char* name, int32 index,
208									int16* value) const;
209			status_t			FindUInt16(const char* name,
210									uint16* value) const;
211			status_t			FindUInt16(const char* name, int32 index,
212									uint16* value) const;
213			status_t			FindInt32(const char* name, int32* value) const;
214			status_t			FindInt32(const char* name, int32 index,
215									int32* value) const;
216			status_t			FindUInt32(const char* name,
217									uint32* value) const;
218			status_t			FindUInt32(const char* name, int32 index,
219									uint32* value) const;
220			status_t			FindInt64(const char* name, int64* value) const;
221			status_t			FindInt64(const char* name, int32 index,
222									int64* value) const;
223			status_t			FindUInt64(const char* name,
224									uint64* value) const;
225			status_t			FindUInt64(const char* name, int32 index,
226									uint64* value) const;
227			status_t			FindBool(const char* name, bool* value) const;
228			status_t			FindBool(const char* name, int32 index,
229									bool* value) const;
230			status_t			FindFloat(const char* name, float* value) const;
231			status_t			FindFloat(const char* name, int32 index,
232									float* value) const;
233			status_t			FindDouble(const char* name,
234									double* value) const;
235			status_t			FindDouble(const char* name, int32 index,
236									double* value) const;
237			status_t			FindPointer(const char* name,
238									void** pointer) const;
239			status_t			FindPointer(const char* name, int32 index,
240									void** pointer) const;
241			status_t			FindMessenger(const char* name,
242									BMessenger* messenger) const;
243			status_t			FindMessenger(const char* name, int32 index,
244									BMessenger* messenger) const;
245			status_t			FindRef(const char* name, entry_ref* ref) const;
246			status_t			FindRef(const char* name, int32 index,
247									entry_ref* ref) const;
248			status_t			FindMessage(const char* name,
249									BMessage* message) const;
250			status_t			FindMessage(const char* name, int32 index,
251									BMessage* message) const;
252			status_t			FindFlat(const char* name,
253									BFlattenable* object) const;
254			status_t			FindFlat(const char* name, int32 index,
255									BFlattenable* object) const;
256			status_t			FindData(const char* name, type_code type,
257									const void** data, ssize_t* numBytes) const;
258			status_t			FindData(const char* name, type_code type,
259									int32 index, const void** data,
260									ssize_t* numBytes) const;
261
262	// Replacing data
263			status_t			ReplaceAlignment(const char* name,
264									const BAlignment& alignment);
265			status_t			ReplaceAlignment(const char* name, int32 index,
266									const BAlignment& alignment);
267
268			status_t			ReplaceRect(const char* name, BRect rect);
269			status_t			ReplaceRect(const char* name, int32 index,
270									BRect rect);
271
272			status_t			ReplacePoint(const char* name, BPoint aPoint);
273			status_t			ReplacePoint(const char* name, int32 index,
274									BPoint aPoint);
275			status_t			ReplaceSize(const char* name, BSize aSize);
276			status_t			ReplaceSize(const char* name, int32 index,
277									BSize aSize);
278
279			status_t			ReplaceString(const char* name,
280									const char* string);
281			status_t			ReplaceString(const char* name, int32 index,
282									const char* string);
283			status_t			ReplaceString(const char* name,
284									const BString& string);
285			status_t			ReplaceString(const char* name, int32 index,
286									const BString& string);
287			status_t			ReplaceInt8(const char* name, int8 value);
288			status_t			ReplaceInt8(const char* name, int32 index,
289									int8 value);
290			status_t			ReplaceUInt8(const char* name, uint8 value);
291			status_t			ReplaceUInt8(const char* name, int32 index,
292									uint8 value);
293			status_t			ReplaceInt16(const char* name, int16 value);
294			status_t			ReplaceInt16(const char* name, int32 index,
295									int16 value);
296			status_t			ReplaceUInt16(const char* name, uint16 value);
297			status_t			ReplaceUInt16(const char* name, int32 index,
298									uint16 value);
299			status_t			ReplaceInt32(const char* name, int32 value);
300			status_t			ReplaceInt32(const char* name, int32 index,
301									int32 value);
302			status_t			ReplaceUInt32(const char* name, uint32 value);
303			status_t			ReplaceUInt32(const char* name, int32 index,
304									uint32 value);
305			status_t			ReplaceInt64(const char* name, int64 value);
306			status_t			ReplaceInt64(const char* name, int32 index,
307									int64 value);
308			status_t			ReplaceUInt64(const char* name, uint64 value);
309			status_t			ReplaceUInt64(const char* name, int32 index,
310									uint64 value);
311			status_t			ReplaceBool(const char* name, bool aBoolean);
312			status_t			ReplaceBool(const char* name, int32 index,
313									bool value);
314			status_t			ReplaceFloat(const char* name, float value);
315			status_t			ReplaceFloat(const char* name, int32 index,
316									float value);
317			status_t			ReplaceDouble(const char* name, double value);
318			status_t			ReplaceDouble(const char* name, int32 index,
319									double value);
320			status_t			ReplacePointer(const char* name,
321									const void* pointer);
322			status_t			ReplacePointer(const char* name, int32 index,
323									const void* pointer);
324			status_t			ReplaceMessenger(const char* name,
325									BMessenger messenger);
326			status_t			ReplaceMessenger(const char* name, int32 index,
327									BMessenger messenger);
328			status_t			ReplaceRef(const char* name,
329									const entry_ref* ref);
330			status_t			ReplaceRef(const char* name, int32 index,
331									const entry_ref* ref);
332			status_t			ReplaceMessage(const char* name,
333									const BMessage* message);
334			status_t			ReplaceMessage(const char* name, int32 index,
335									const BMessage* message);
336			status_t			ReplaceFlat(const char* name,
337									BFlattenable* object);
338			status_t			ReplaceFlat(const char* name, int32 index,
339									BFlattenable* object);
340			status_t			ReplaceData(const char* name, type_code type,
341									const void* data, ssize_t numBytes);
342			status_t			ReplaceData(const char* name, type_code type,
343									int32 index, const void* data,
344									ssize_t numBytes);
345
346	// Comparing data - Haiku experimental API
347			bool				HasSameData(const BMessage& other,
348									bool ignoreFieldOrder = true,
349									bool deep = false) const;
350
351			void*				operator new(size_t size);
352			void*				operator new(size_t, void* pointer);
353			void*				operator new(size_t,
354									const std::nothrow_t& noThrow);
355			void				operator delete(void* pointer, size_t size);
356
357	// Private, reserved, or obsolete
358			bool				HasAlignment(const char* name,
359									int32 n = 0) const;
360			bool				HasRect(const char* name, int32 n = 0) const;
361			bool				HasPoint(const char* name, int32 n = 0) const;
362			bool				HasSize(const char* name, int32 n = 0) const;
363			bool				HasString(const char* name, int32 n = 0) const;
364			bool				HasInt8(const char* name, int32 n = 0) const;
365			bool				HasUInt8(const char* name, int32 n = 0) const;
366			bool				HasInt16(const char* name, int32 n = 0) const;
367			bool				HasUInt16(const char* name, int32 n = 0) const;
368			bool				HasInt32(const char* name, int32 n = 0) const;
369			bool				HasUInt32(const char* name, int32 n = 0) const;
370			bool				HasInt64(const char* name, int32 n = 0) const;
371			bool				HasUInt64(const char* name, int32 n = 0) const;
372			bool				HasBool(const char* name, int32 n = 0) const;
373			bool				HasFloat(const char* name, int32 n = 0) const;
374			bool				HasDouble(const char* name, int32 n = 0) const;
375			bool				HasPointer(const char* name, int32 n = 0) const;
376			bool				HasMessenger(const char* name,
377									int32 n = 0) const;
378			bool				HasRef(const char* name, int32 n = 0) const;
379			bool				HasMessage(const char* name, int32 n = 0) const;
380			bool				HasFlat(const char* name,
381									const BFlattenable* object) const;
382			bool				HasFlat(const char* name, int32 n,
383									const BFlattenable* object) const;
384			bool				HasData(const char* name, type_code ,
385									int32 n = 0) const;
386			BRect				FindRect(const char* name, int32 n = 0) const;
387			BPoint				FindPoint(const char* name, int32 n = 0) const;
388			const char*			FindString(const char* name, int32 n = 0) const;
389			int8				FindInt8(const char* name, int32 n = 0) const;
390			int16				FindInt16(const char* name, int32 n = 0) const;
391			int32				FindInt32(const char* name, int32 n = 0) const;
392			int64				FindInt64(const char* name, int32 n = 0) const;
393			bool				FindBool(const char* name, int32 n = 0) const;
394			float				FindFloat(const char* name, int32 n = 0) const;
395			double				FindDouble(const char* name, int32 n = 0) const;
396
397	// Convenience methods
398			bool				GetBool(const char* name,
399									bool defaultValue) const;
400			bool				GetBool(const char* name, int32 index,
401									bool defaultValue) const;
402			int8				GetInt8(const char* name,
403									int8 defaultValue) const;
404			int8				GetInt8(const char* name, int32 index,
405									int8 defaultValue) const;
406			uint8				GetUInt8(const char* name,
407									uint8 defaultValue) const;
408			uint8				GetUInt8(const char* name, int32 index,
409									uint8 defaultValue) const;
410			int16				GetInt16(const char* name,
411									int16 defaultValue) const;
412			int16				GetInt16(const char* name, int32 index,
413									int16 defaultValue) const;
414			uint16				GetUInt16(const char* name,
415									uint16 defaultValue) const;
416			uint16				GetUInt16(const char* name, int32 index,
417									uint16 defaultValue) const;
418			int32				GetInt32(const char* name,
419									int32 defaultValue) const;
420			int32				GetInt32(const char* name, int32 index,
421									int32 defaultValue) const;
422			uint32				GetUInt32(const char* name,
423									uint32 defaultValue) const;
424			uint32				GetUInt32(const char* name, int32 index,
425									uint32 defaultValue) const;
426			int64				GetInt64(const char* name,
427									int64 defaultValue) const;
428			int64				GetInt64(const char* name, int32 index,
429									int64 defaultValue) const;
430			uint64				GetUInt64(const char* name,
431									uint64 defaultValue) const;
432			uint64				GetUInt64(const char* name, int32 index,
433									uint64 defaultValue) const;
434			float				GetFloat(const char* name,
435									float defaultValue) const;
436			float				GetFloat(const char* name, int32 index,
437									float defaultValue) const;
438			double				GetDouble(const char* name,
439									double defaultValue) const;
440			double				GetDouble(const char* name, int32 index,
441									double defaultValue) const;
442			void*				GetPointer(const char* name,
443									const void* defaultValue) const;
444			void*				GetPointer(const char* name, int32 index,
445									const void* defaultValue) const;
446			const char*			GetString(const char* name,
447									const char* defaultValue) const;
448			const char*			GetString(const char* name, int32 index,
449									const char* defaultValue) const;
450			BAlignment			GetAlignment(const char* name, int32 index,
451									const BAlignment& defaultValue) const;
452			BAlignment			GetAlignment(const char* name,
453									const BAlignment& defaultValue) const;
454			BRect				GetRect(const char* name, int32 index,
455									const BRect& defaultValue) const;
456			BRect				GetRect(const char* name,
457									const BRect& defaultValue) const;
458			BPoint				GetPoint(const char* name, int32 index,
459									const BPoint& defaultValue) const;
460			BPoint				GetPoint(const char* name,
461									const BPoint& defaultValue) const;
462			BSize				GetSize(const char* name, int32 index,
463									const BSize& defaultValue) const;
464			BSize				GetSize(const char* name,
465									const BSize& defaultValue) const;
466
467	// fixed size fields only
468			status_t			SetBool(const char* name, bool value);
469			status_t			SetInt8(const char* name, int8 value);
470			status_t			SetUInt8(const char* name, uint8 value);
471			status_t			SetInt16(const char* name, int16 value);
472			status_t			SetUInt16(const char* name, uint16 value);
473			status_t			SetInt32(const char* name, int32 value);
474			status_t			SetUInt32(const char* name, uint32 value);
475			status_t			SetInt64(const char* name, int64 value);
476			status_t			SetUInt64(const char* name, uint64 value);
477			status_t			SetPointer(const char* name, const void* value);
478			status_t			SetString(const char* name, const char* string);
479			status_t			SetString(const char* name,
480									const BString& string);
481			status_t			SetFloat(const char* name, float value);
482			status_t			SetDouble(const char* name, double value);
483			status_t			SetAlignment(const char* name,
484									const BAlignment& value);
485			status_t			SetPoint(const char* name, const BPoint& value);
486			status_t			SetRect(const char* name, const BRect& value);
487			status_t			SetSize(const char* name, const BSize& value);
488			status_t			SetData(const char* name, type_code type,
489									const void* data, ssize_t numBytes);
490
491	class Private;
492	struct message_header;
493	struct field_header;
494
495private:
496	friend class Private;
497	friend class BMessageQueue;
498
499			status_t			_InitCommon(bool initHeader);
500			status_t			_InitHeader();
501			status_t			_Clear();
502
503			status_t			_FlattenToArea(message_header** _header) const;
504			status_t			_CopyForWrite();
505			status_t			_Reference();
506			status_t			_Dereference();
507
508			status_t			_ValidateMessage();
509
510			status_t			_ResizeData(uint32 offset, int32 change);
511
512			uint32				_HashName(const char* name) const;
513			status_t			_FindField(const char* name, type_code type,
514									field_header** _result) const;
515			status_t			_AddField(const char* name, type_code type,
516									bool isFixedSize, field_header** _result);
517			status_t			_RemoveField(field_header* field);
518
519			void				_PrintToStream(const char* indent) const;
520
521private:
522								BMessage(BMessage* message);
523									// deprecated
524
525	virtual	void				_ReservedMessage1();
526	virtual	void				_ReservedMessage2();
527	virtual	void				_ReservedMessage3();
528
529			status_t			_SendMessage(port_id port, team_id portOwner,
530									int32 token, bigtime_t timeout,
531									bool replyRequired,
532									BMessenger& replyTo) const;
533			status_t			_SendMessage(port_id port, team_id portOwner,
534									int32 token, BMessage* reply,
535									bigtime_t sendTimeout,
536									bigtime_t replyTimeout) const;
537	static	status_t			_SendFlattenedMessage(void* data, int32 size,
538									port_id port, int32 token,
539									bigtime_t timeout);
540
541	static	void				_StaticInit();
542	static	void				_StaticReInitForkedChild();
543	static	void				_StaticCleanup();
544	static	void				_StaticCacheCleanup();
545	static	int32				_StaticGetCachedReplyPort();
546
547private:
548			message_header*		fHeader;
549			field_header*		fFields;
550			uint8*				fData;
551
552			uint32				fFieldsAvailable;
553			size_t				fDataAvailable;
554
555			mutable	BMessage*	fOriginal;
556
557			BMessage*			fQueueLink;
558				// fQueueLink is used by BMessageQueue to build a linked list
559
560			void*				fArchivingPointer;
561
562			uint32				fReserved[8];
563
564			enum				{ sNumReplyPorts = 3 };
565	static	port_id				sReplyPorts[sNumReplyPorts];
566	static	int32				sReplyPortInUse[sNumReplyPorts];
567	static	int32				sGetCachedReplyPort();
568
569	static	BBlockCache*		sMsgCache;
570};
571
572
573#endif	// _MESSAGE_H
574