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