xref: /haiku/src/kits/app/Message.cpp (revision e5430a086c769ea76c3944046b1f07cf049c1ae0)
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 #define USING_TEMPLATE_MADNESS
32 
33 // Standard Includes -----------------------------------------------------------
34 #include <stdio.h>
35 
36 // System Includes -------------------------------------------------------------
37 #include <ByteOrder.h>
38 #include <Errors.h>
39 #include <Message.h>
40 #include <Messenger.h>
41 #include <String.h>
42 
43 //#include <CRTDBG.H>
44 
45 // Project Includes ------------------------------------------------------------
46 #ifdef USING_TEMPLATE_MADNESS
47 #include <AppMisc.h>
48 #include <DataBuffer.h>
49 #include <MessageBody.h>
50 #include <MessageUtils.h>
51 #include <TokenSpace.h>
52 #endif	// USING_TEMPLATE_MADNESS
53 
54 // Local Includes --------------------------------------------------------------
55 
56 // Local Defines ---------------------------------------------------------------
57 #define	MSG_FIELD_VERSION		'FOB1'
58 
59 // flags for the overall message (the bitfield is 1 byte)
60 #define MSG_FLAG_BIG_ENDIAN		0x01
61 #define MSG_FLAG_INCL_TARGET	0x02
62 #define MSG_FLAG_INCL_REPLY		0x04
63 #define MSG_FLAG_SCRIPT_MSG		0x08
64 // These are for future improvement
65 #if 0
66 #define MSG_FLAG_USE_PREFERRED	0x10
67 #define MSG_FLAG_REPLY_WANTED	0x20
68 #define MSG_FLAG_REPLY_DONE		0x40
69 #define MSG_FLAG_IS_REPLY		0x80
70 
71 #define MSG_FLAG_HDR_MASK		0xF0
72 #endif
73 
74 #define MSG_HEADER_MAX_SIZE		38
75 #define MSG_NAME_MAX_SIZE		256
76 
77 // Globals ---------------------------------------------------------------------
78 
79 #ifdef USING_TEMPLATE_MADNESS
80 using namespace BPrivate;
81 #endif	// USING_TEMPLATE_MADNESS
82 const char* B_SPECIFIER_ENTRY = "specifiers";
83 const char* B_PROPERTY_ENTRY = "property";
84 const char* B_PROPERTY_NAME_ENTRY = "name";
85 
86 //------------------------------------------------------------------------------
87 void _msg_cache_cleanup_()
88 {
89 }
90 //------------------------------------------------------------------------------
91 BMessage *_reconstruct_msg_(uint32,uint32,uint32)
92 {
93 	return NULL;
94 }
95 //------------------------------------------------------------------------------
96 
97 #ifdef USING_TEMPLATE_MADNESS
98 //------------------------------------------------------------------------------
99 BMessage::BMessage()
100 	:	what(0)
101 {
102 	init_data();
103 }
104 //------------------------------------------------------------------------------
105 BMessage::BMessage(uint32 w)
106 {
107 	init_data();
108 	what = w;
109 }
110 //------------------------------------------------------------------------------
111 BMessage::BMessage(const BMessage& a_message)
112 {
113 	init_data();
114 	*this = a_message;
115 }
116 //------------------------------------------------------------------------------
117 BMessage::BMessage(BMessage *a_message)
118 {
119 	init_data();
120 	*this = *a_message;
121 }
122 //------------------------------------------------------------------------------
123 BMessage::~BMessage()
124 {
125 	if (fBody)
126 		delete fBody;
127 }
128 //------------------------------------------------------------------------------
129 BMessage& BMessage::operator=(const BMessage& msg)
130 {
131 	what = msg.what;
132 
133 	link = msg.link;
134 	fTarget = msg.fTarget;
135 	fOriginal = msg.fOriginal;
136 	fChangeCount = msg.fChangeCount;
137 	fCurSpecifier = msg.fCurSpecifier;
138 	fPtrOffset = msg.fPtrOffset;
139 
140 	fEntries = msg.fEntries;
141 
142 	fReplyTo.port = msg.fReplyTo.port;
143 	fReplyTo.target = msg.fReplyTo.target;
144 	fReplyTo.team = msg.fReplyTo.team;
145 	fReplyTo.preferred = msg.fReplyTo.preferred;
146 
147 	fPreferred = msg.fPreferred;
148 	fReplyRequired = msg.fReplyRequired;
149 	fReplyDone = msg.fReplyDone;
150 	fIsReply = msg.fIsReply;
151 	fWasDelivered = msg.fWasDelivered;
152 	fReadOnly = msg.fReadOnly;
153 	fHasSpecifiers = msg.fHasSpecifiers;
154 
155 	*fBody = *(msg.fBody);
156 }
157 //------------------------------------------------------------------------------
158 void BMessage::init_data()
159 {
160 	what = 0;
161 
162 	link = NULL;
163 	fTarget = B_NULL_TOKEN;
164 	fOriginal = NULL;
165 	fChangeCount = 0;
166 	fCurSpecifier = -1;
167 	fPtrOffset = 0;
168 
169 	fEntries = NULL;
170 
171 	fReplyTo.port = -1;
172 	fReplyTo.target = B_NULL_TOKEN;
173 	fReplyTo.team = -1;
174 	fReplyTo.preferred = false;
175 
176 	fPreferred = false;
177 	fReplyRequired = false;
178 	fReplyDone = false;
179 	fIsReply = false;
180 	fWasDelivered = false;
181 	fReadOnly = false;
182 	fHasSpecifiers = false;
183 
184 	fBody = new BPrivate::BMessageBody;
185 }
186 //------------------------------------------------------------------------------
187 status_t BMessage::GetInfo(type_code typeRequested, int32 which, char** name,
188 						   type_code* typeReturned, int32* count) const
189 {
190 	return fBody->GetInfo(typeRequested, which, name, typeReturned, count);
191 }
192 //------------------------------------------------------------------------------
193 status_t BMessage::GetInfo(const char* name, type_code* type, int32* c) const
194 {
195 	return fBody->GetInfo(name, type, c);
196 }
197 //------------------------------------------------------------------------------
198 status_t BMessage::GetInfo(const char* name, type_code* type,
199 						   bool* fixed_size) const
200 {
201 	return fBody->GetInfo(name, type, fixed_size);
202 }
203 //------------------------------------------------------------------------------
204 int32 BMessage::CountNames(type_code type) const
205 {
206 	return fBody->CountNames(type);
207 }
208 //------------------------------------------------------------------------------
209 bool BMessage::IsEmpty() const
210 {
211 	return fBody->IsEmpty();
212 }
213 //------------------------------------------------------------------------------
214 bool BMessage::IsSystem() const
215 {
216 	char a = char(what >> 24);
217 	char b = char(what >> 16);
218 	char c = char(what >> 8);
219 	char d = char(what);
220 
221 	// The BeBook says:
222 	//		... we've adopted a strict convention for assigning values to all
223 	//		Be-defined constants.  The value assigned will always be formed by
224 	//		combining four characters into a multicharacter constant, with the
225 	//		characters limited to uppercase letters and the underbar
226 	// Between that and what's in AppDefs.h, this algo seems like a safe bet:
227 	if (a == '_' && isupper(b) && isupper(c) && isupper(d))
228 	{
229 		return true;
230 	}
231 
232 	return false;
233 }
234 //------------------------------------------------------------------------------
235 bool BMessage::IsReply() const
236 {
237 	return fIsReply;
238 }
239 //------------------------------------------------------------------------------
240 void BMessage::PrintToStream() const
241 {
242 	printf("\nBMessage: what =  (0x%lX or %ld)\n", what, what);
243 	fBody->PrintToStream();
244 }
245 //------------------------------------------------------------------------------
246 status_t BMessage::Rename(const char* old_entry, const char* new_entry)
247 {
248 	return fBody->Rename(old_entry, new_entry);
249 }
250 //------------------------------------------------------------------------------
251 bool BMessage::WasDelivered() const
252 {
253 	return fWasDelivered;
254 }
255 //------------------------------------------------------------------------------
256 bool BMessage::IsSourceWaiting() const
257 {
258 	return fReplyRequired && !fReplyDone;
259 }
260 //------------------------------------------------------------------------------
261 bool BMessage::IsSourceRemote() const
262 {
263 	return WasDelivered() && fReplyTo.team != BPrivate::current_team();
264 }
265 //------------------------------------------------------------------------------
266 BMessenger BMessage::ReturnAddress() const
267 {
268 	if (WasDelivered())
269 	{
270 		return BMessenger(fReplyTo.team, fReplyTo.port, fReplyTo.target,
271 						  fReplyTo.preferred);
272 	}
273 
274 	return BMessenger();
275 }
276 //------------------------------------------------------------------------------
277 const BMessage* BMessage::Previous() const
278 {
279 	// TODO: test
280 	// In particular, look to see if the "_previous_" field is used in R5
281 	if (!fOriginal)
282 	{
283 		BMessage* fOriginal = new BMessage;
284 		if (FindMessage("_previous_", fOriginal) != B_OK)
285 		{
286 			delete fOriginal;
287 			fOriginal = NULL;
288 		}
289 	}
290 
291 	return fOriginal;
292 }
293 //------------------------------------------------------------------------------
294 bool BMessage::WasDropped() const
295 {
296 	return fReadOnly;
297 }
298 //------------------------------------------------------------------------------
299 BPoint BMessage::DropPoint(BPoint* offset) const
300 {
301 	// TODO: Where do we get this stuff???
302 	if (offset)
303 	{
304 		*offset = FindPoint("_drop_offset_");
305 	}
306 	return FindPoint("_drop_point_");
307 }
308 //------------------------------------------------------------------------------
309 status_t BMessage::SendReply(uint32 command, BHandler* reply_to)
310 {
311 	BMessage msg(command);
312 	return SendReply(&msg, reply_to);
313 }
314 //------------------------------------------------------------------------------
315 status_t BMessage::SendReply(BMessage* the_reply, BHandler* reply_to,
316 							 bigtime_t timeout)
317 {
318 	BMessenger messenger(fReplyTo.team, fReplyTo.port, fReplyTo.target,
319 						 fReplyTo.preferred);
320 	return SendReply(the_reply, messenger, timeout);
321 }
322 //------------------------------------------------------------------------------
323 status_t BMessage::SendReply(BMessage* the_reply, BMessenger reply_to,
324 							 bigtime_t timeout)
325 {
326 	// TODO: implement *
327 }
328 //------------------------------------------------------------------------------
329 status_t BMessage::SendReply(uint32 command, BMessage* reply_to_reply)
330 {
331 	BMessage msg(command);
332 	return SendReply(&msg, reply_to_reply);
333 }
334 //------------------------------------------------------------------------------
335 status_t BMessage::SendReply(BMessage* the_reply, BMessage* reply_to_reply,
336 							 bigtime_t send_timeout, bigtime_t reply_timeout)
337 {
338 	// TODO: implement *
339 }
340 //------------------------------------------------------------------------------
341 ssize_t BMessage::FlattenedSize() const
342 {
343 	return calc_hdr_size(0) + fBody->FlattenedSize();
344 }
345 //------------------------------------------------------------------------------
346 status_t BMessage::Flatten(char* buffer, ssize_t size) const
347 {
348 	return real_flatten(buffer, size);
349 }
350 //------------------------------------------------------------------------------
351 status_t BMessage::Flatten(BDataIO* stream, ssize_t* size) const
352 {
353 	status_t err = B_OK;
354 	ssize_t len = FlattenedSize();
355 	char* buffer = new(nothrow) char[len];
356 	if (buffer)
357 	{
358 		err = Flatten(buffer, len);
359 		if (!err)
360 		{
361 			*size = len;
362 			err = stream->Write(buffer, len);
363 			if (err > B_OK)
364 				err = B_OK;
365 		}
366 
367 		delete[] buffer;
368 	}
369 	else
370 	{
371 		err = B_NO_MEMORY;
372 	}
373 
374 	return err;
375 }
376 //------------------------------------------------------------------------------
377 status_t BMessage::Unflatten(const char* flat_buffer)
378 {
379 	uint32 size = ((uint32*)flat_buffer)[2];
380 
381 	BMemoryIO MemIO(flat_buffer, size);
382 	return Unflatten(&MemIO);
383 }
384 //------------------------------------------------------------------------------
385 status_t BMessage::Unflatten(BDataIO* stream)
386 {
387 	bool swap;
388 	status_t err = unflatten_hdr(stream, swap);
389 
390 	if (!err)
391 	{
392 		TReadHelper reader(stream, swap);
393 		int8 flags;
394 		type_code type;
395 		uint32 count;
396 		uint32 dataLen;
397 		uint8 nameLen;
398 		char name[MSG_NAME_MAX_SIZE];
399 		unsigned char* databuffer = NULL;
400 
401 		try
402 		{
403 			reader(flags);
404 			while (flags != MSG_LAST_ENTRY)
405 			{
406 				reader(type);
407 				// Is there more than one data item? (!flags & MSG_FLAG_SINGLE_ITEM)
408 				if (flags & MSG_FLAG_SINGLE_ITEM)
409 				{
410 					count = 1;
411 					if (flags & MSG_FLAG_MINI_DATA)
412 					{
413 						uint8 littleLen;
414 						reader(littleLen);
415 						dataLen = littleLen;
416 					}
417 					else
418 					{
419 						reader(dataLen);
420 					}
421 				}
422 				else
423 				{
424 					// Is there a little data? (flags & MSG_FLAG_MINI_DATA)
425 					if (flags & MSG_FLAG_MINI_DATA)
426 					{
427 						// Get item count (1 byte)
428 						uint8 littleCount;
429 						reader(littleCount);
430 						count = littleCount;
431 
432 						// Get data length (1 byte)
433 						uint8 littleLen;
434 						reader(littleLen);
435 						dataLen = littleLen;
436 					}
437 					else
438 					{
439 					// Is there a lot of data? (!flags & MSG_FLAG_MINI_DATA)
440 						// Get item count (4 bytes)
441 						reader(count);
442 						// Get data length (4 bytes)
443 						reader(dataLen);
444 					}
445 				}
446 
447 				// Get the name length (1 byte)
448 				reader(nameLen);
449 				// Get the name (name length bytes)
450 				reader(name, nameLen);
451 				name[nameLen] = '\0';
452 
453 				// Copy the data into a new buffer to byte align it
454 				databuffer = (unsigned char*)realloc(databuffer, dataLen);
455 				if (!databuffer)
456 					throw B_NO_MEMORY;
457 				// Get the data
458 				reader(databuffer, dataLen);
459 
460 				// Is the data fixed size? (flags & MSG_FLAG_FIXED_SIZE)
461 				if (flags & MSG_FLAG_FIXED_SIZE && swap)
462 				{
463 					// Make sure to swap the data
464 					err = swap_data(type, (void*)databuffer, dataLen,
465 									B_SWAP_ALWAYS);
466 					if (err)
467 						throw err;
468 				}
469 				// Is the data variable size? (!flags & MSG_FLAG_FIXED_SIZE)
470 				else if (swap && type == B_REF_TYPE)
471 				{
472 					// Apparently, entry_refs are the only variable-length data
473 					// 	  explicitely swapped -- the dev_t and ino_t
474 					//    specifically
475 					byte_swap(*(entry_ref*)databuffer);
476 				}
477 
478 				// Add each data field to the message
479 				uint32 itemSize;
480 				if (flags & MSG_FLAG_FIXED_SIZE)
481 				{
482 					itemSize = dataLen / count;
483 				}
484 				unsigned char* dataPtr = databuffer;
485 				for (uint32 i = 0; i < count; ++i)
486 				{
487 					// Line up for the next item
488 					if (i)
489 					{
490 						if (flags & MSG_FLAG_FIXED_SIZE)
491 						{
492 							dataPtr += itemSize;
493 						}
494 						else
495 						{
496 							// Have to account for 8-byte boundary padding
497 							dataPtr += itemSize + (8 - (itemSize % 8));
498 						}
499 					}
500 
501 					if ((flags & MSG_FLAG_FIXED_SIZE) == 0)
502 					{
503 						itemSize = *(uint32*)dataPtr;
504 						dataPtr += sizeof (uint32);
505 					}
506 
507 					err = AddData(name, type, dataPtr, itemSize,
508 								  flags & MSG_FLAG_FIXED_SIZE);
509 					if (err)
510 						throw err;
511 				}
512 
513 				reader(flags);
514 			}
515 		}
516 		catch (status_t& e)
517 		{
518 			err = e;
519 		}
520 	}
521 
522 	return err;
523 }
524 //------------------------------------------------------------------------------
525 status_t BMessage::AddSpecifier(const char* property)
526 {
527 	BMessage message(B_DIRECT_SPECIFIER);
528 	status_t err = message.AddString(B_PROPERTY_ENTRY, property);
529 	if (err)
530 		return err;
531 
532 	return AddSpecifier(&message);
533 }
534 //------------------------------------------------------------------------------
535 status_t BMessage::AddSpecifier(const char* property, int32 index)
536 {
537 	BMessage message(B_INDEX_SPECIFIER);
538 	status_t err = message.AddString(B_PROPERTY_ENTRY, property);
539 	if (err)
540 		return err;
541 
542 	err = message.AddInt32("index", index);
543 	if (err)
544 		return err;
545 
546 	return AddSpecifier(&message);
547 }
548 //------------------------------------------------------------------------------
549 status_t BMessage::AddSpecifier(const char* property, int32 index, int32 range)
550 {
551 	if (range < 0)
552 		return B_BAD_VALUE;
553 
554 	BMessage message(B_RANGE_SPECIFIER);
555 	status_t err = message.AddString(B_PROPERTY_ENTRY, property);
556 	if (err)
557 		return err;
558 
559 	err = message.AddInt32("index", index);
560 	if (err)
561 		return err;
562 
563 	err = message.AddInt32("range", range);
564 	if (err)
565 		return err;
566 
567 	return AddSpecifier(&message);
568 }
569 //------------------------------------------------------------------------------
570 status_t BMessage::AddSpecifier(const char* property, const char* name)
571 {
572 	BMessage message(B_NAME_SPECIFIER);
573 	status_t err = message.AddString(B_PROPERTY_ENTRY, property);
574 	if (err)
575 		return err;
576 
577 	err = message.AddString(B_PROPERTY_NAME_ENTRY, name);
578 	if (err)
579 		return err;
580 
581 	return AddSpecifier(&message);
582 }
583 //------------------------------------------------------------------------------
584 status_t BMessage::AddSpecifier(const BMessage* specifier)
585 {
586 	status_t err = AddMessage(B_SPECIFIER_ENTRY, specifier);
587 	if (!err)
588 	{
589 		++fCurSpecifier;
590 		fHasSpecifiers = true;
591 	}
592 	return err;
593 }
594 //------------------------------------------------------------------------------
595 status_t BMessage::SetCurrentSpecifier(int32 index)
596 {
597 	type_code	type;
598 	int32		count;
599 	status_t	err = GetInfo(B_SPECIFIER_ENTRY, &type, &count);
600 	if (err)
601 		return err;
602 
603 	if (index < 0 || index >= count)
604 		return B_BAD_INDEX;
605 
606 	fCurSpecifier = index;
607 
608 	return B_OK;
609 }
610 //------------------------------------------------------------------------------
611 status_t BMessage::GetCurrentSpecifier(int32* index, BMessage* specifier,
612 									   int32* what, const char** property) const
613 {
614 	if (fCurSpecifier == -1 || !WasDelivered())
615 		return B_BAD_SCRIPT_SYNTAX;
616 
617 	if (index)
618 		*index = fCurSpecifier;
619 
620 	if (specifier)
621 	{
622 		if (FindMessage(B_SPECIFIER_ENTRY, fCurSpecifier, specifier))
623 			return B_BAD_SCRIPT_SYNTAX;
624 
625 		if (what)
626 			*what = specifier->what;
627 
628 		if (property)
629 		{
630 			if (specifier->FindString(B_PROPERTY_ENTRY, property))
631 				return B_BAD_SCRIPT_SYNTAX;
632 		}
633 	}
634 
635 	return B_OK;
636 }
637 //------------------------------------------------------------------------------
638 bool BMessage::HasSpecifiers() const
639 {
640 	return fHasSpecifiers;
641 }
642 //------------------------------------------------------------------------------
643 status_t BMessage::PopSpecifier()
644 {
645 	if (fCurSpecifier < 0 || !WasDelivered())
646 	{
647 		return B_BAD_VALUE;
648 	}
649 
650 	--fCurSpecifier;
651 	return B_OK;
652 }
653 //------------------------------------------------------------------------------
654 //	return fBody->AddData<TYPE>(name, val, TYPESPEC);
655 //	return fBody->FindData<TYPE>(name, index, val, TYPESPEC);
656 //	return fBody->ReplaceData<TYPE>(name, index, val, TYPESPEC);
657 //	return fBody->HasData(name, TYPESPEC, n);
658 
659 #define DEFINE_FUNCTIONS(TYPE, fnName, TYPESPEC)									\
660 	status_t BMessage::Add ## fnName(const char* name, TYPE val)					\
661 	{ return fBody->AddData<TYPE>(name, val, TYPESPEC); }							\
662 	status_t BMessage::Find ## fnName(const char* name, TYPE* p) const				\
663 	{ return Find ## fnName(name, 0, p); }											\
664 	status_t BMessage::Find ## fnName(const char* name, int32 index, TYPE* p) const	\
665 	{																				\
666 		*p = TYPE();																\
667 		return fBody->FindData<TYPE>(name, index, p, TYPESPEC);						\
668 	}																				\
669 	status_t BMessage::Replace ## fnName(const char* name, TYPE val)				\
670 	{ return Replace ## fnName(name, 0, val); }										\
671 	status_t BMessage::Replace ## fnName(const char *name, int32 index, TYPE val)	\
672 	{  return fBody->ReplaceData<TYPE>(name, index, val, TYPESPEC); }				\
673 	bool BMessage::Has ## fnName(const char* name, int32 n) const					\
674 	{ return fBody->HasData(name, TYPESPEC, n); }
675 
676 DEFINE_FUNCTIONS(int8  , Int8  , B_INT8_TYPE)
677 DEFINE_FUNCTIONS(int16 , Int16 , B_INT16_TYPE)
678 DEFINE_FUNCTIONS(int32 , Int32 , B_INT32_TYPE)
679 DEFINE_FUNCTIONS(int64 , Int64 , B_INT64_TYPE)
680 DEFINE_FUNCTIONS(BPoint, Point , B_POINT_TYPE)
681 DEFINE_FUNCTIONS(BRect , Rect  , B_RECT_TYPE)
682 DEFINE_FUNCTIONS(float , Float , B_FLOAT_TYPE)
683 DEFINE_FUNCTIONS(double, Double, B_DOUBLE_TYPE)
684 DEFINE_FUNCTIONS(bool  , Bool  , B_BOOL_TYPE)
685 
686 #undef DEFINE_FUNCTIONS
687 
688 
689 #define DEFINE_HAS_FUNCTION(fnName, TYPESPEC)						\
690 	bool BMessage::Has ## fnName(const char* name, int32 n) const	\
691 	{ return HasData(name, TYPESPEC, n); }
692 
693 DEFINE_HAS_FUNCTION(Message  , B_MESSAGE_TYPE)
694 DEFINE_HAS_FUNCTION(String   , B_STRING_TYPE)
695 DEFINE_HAS_FUNCTION(Pointer  , B_POINTER_TYPE)
696 DEFINE_HAS_FUNCTION(Messenger, B_MESSENGER_TYPE)
697 DEFINE_HAS_FUNCTION(Ref      , B_REF_TYPE)
698 
699 #undef DEFINE_HAS_FUNCTION
700 
701 #define DEFINE_LAZY_FIND_FUNCTION(TYPE, fnName)						\
702 	TYPE BMessage::Find ## fnName(const char* name, int32 n) const	\
703 	{																\
704 		TYPE i = 0;													\
705 		Find ## fnName(name, n, &i);								\
706 		return i;													\
707 	}
708 
709 DEFINE_LAZY_FIND_FUNCTION(int8			, Int8)
710 DEFINE_LAZY_FIND_FUNCTION(int16			, Int16)
711 DEFINE_LAZY_FIND_FUNCTION(int32			, Int32)
712 DEFINE_LAZY_FIND_FUNCTION(int64			, Int64)
713 DEFINE_LAZY_FIND_FUNCTION(float			, Float)
714 DEFINE_LAZY_FIND_FUNCTION(double		, Double)
715 DEFINE_LAZY_FIND_FUNCTION(bool			, Bool)
716 DEFINE_LAZY_FIND_FUNCTION(const char*	, String)
717 
718 #undef DEFINE_LAZY_FIND_FUNCTION
719 
720 //------------------------------------------------------------------------------
721 status_t BMessage::AddString(const char* name, const char* a_string)
722 {
723 	return fBody->AddData<BString>(name, a_string, B_STRING_TYPE);
724 }
725 //------------------------------------------------------------------------------
726 status_t BMessage::AddString(const char* name, const BString& a_string)
727 {
728 	return AddString(name, a_string.String());
729 }
730 //------------------------------------------------------------------------------
731 status_t BMessage::AddPointer(const char* name, const void* ptr)
732 {
733 	return fBody->AddData<void*>(name, (void*)ptr, B_POINTER_TYPE);
734 }
735 //------------------------------------------------------------------------------
736 status_t BMessage::AddMessenger(const char* name, BMessenger messenger)
737 {
738 	return fBody->AddData<BMessenger>(name, messenger, B_MESSENGER_TYPE);
739 }
740 //------------------------------------------------------------------------------
741 status_t BMessage::AddRef(const char* name, const entry_ref* ref)
742 {
743 #if 0
744 	return fBody->AddData<entry_ref>(name, *ref, B_REF_TYPE);
745 #endif
746 	char* buffer = new(nothrow) char[sizeof (entry_ref) + B_PATH_NAME_LENGTH];
747 	size_t size;
748 	status_t err = entry_ref_flatten(buffer, &size, ref);
749 	if (!err)
750 	{
751 		BDataBuffer DB((void*)buffer, size);
752 		err = fBody->AddData<BDataBuffer>(name, DB, B_REF_TYPE);
753 	}
754 
755 	return err;
756 }
757 //------------------------------------------------------------------------------
758 status_t BMessage::AddMessage(const char* name, const BMessage* msg)
759 {
760 #if 0
761 	return fBody->AddData<BMessage>(name, *msg, B_MESSAGE_TYPE);
762 #endif
763 	status_t err = B_OK;
764 	ssize_t size = msg->FlattenedSize();
765 	char* buffer = new(nothrow) char[size];
766 	if (buffer)
767 	{
768 		err = msg->Flatten(buffer, size);
769 		if (!err)
770 		{
771 			BDataBuffer DB((void*)buffer, size);
772 			err = fBody->AddData<BDataBuffer>(name, DB, B_MESSAGE_TYPE);
773 		}
774 	}
775 	else
776 	{
777 		err = B_NO_MEMORY;
778 	}
779 
780 	return err;
781 }
782 //------------------------------------------------------------------------------
783 status_t BMessage::AddFlat(const char* name, BFlattenable* obj, int32 count)
784 {
785 	status_t err = B_OK;
786 	ssize_t size = obj->FlattenedSize();
787 	char* buffer = new(nothrow) char[size];
788 	if (buffer)
789 	{
790 		err = obj->Flatten((void*)buffer, size);
791 		if (!err)
792 		{
793 			err = AddData(name, obj->TypeCode(), (void*)buffer, size,
794 						  obj->IsFixedSize(), count);
795 		}
796 		delete[] buffer;
797 	}
798 	else
799 	{
800 		err = B_NO_MEMORY;
801 	}
802 
803 	return err;
804 }
805 //------------------------------------------------------------------------------
806 status_t BMessage::AddData(const char* name, type_code type, const void* data,
807 						   ssize_t numBytes, bool is_fixed_size, int32 /*count*/)
808 {
809 /**
810 	@note	Because we're using vectors for our item storage, the count param
811 			is no longer useful to us:  dynamically adding more items is not
812 			really a performance issue, so pre-allocating space for objects
813 			gives us no real advantage.
814  */
815 
816 	// TODO: test
817 	// In particular, we want to see what happens if is_fixed_size == true and
818 	// the user attempts to add something bigger or smaller.  We may need to
819 	// enforce the size thing.
820 	//--------------------------------------------------------------------------
821 	// voidref suggests creating a BDataBuffer type which we can use here to
822 	// avoid having to specialize BMessageBody::AddData().
823 	//--------------------------------------------------------------------------
824 
825 	// TODO: Fix this horrible hack
826 	status_t err = B_OK;
827 	switch (type)
828 	{
829 		case B_BOOL_TYPE:
830 			err = AddBool(name, *(bool*)data);
831 			break;
832 		case B_INT8_TYPE:
833 		case B_UINT8_TYPE:
834 			err = AddInt8(name, *(int8*)data);
835 			break;
836 		case B_INT16_TYPE:
837 		case B_UINT16_TYPE:
838 			err = AddInt16(name, *(int16*)data);
839 			break;
840 		case B_INT32_TYPE:
841 		case B_UINT32_TYPE:
842 			err = AddInt32(name, *(int32*)data);
843 			break;
844 		case B_INT64_TYPE:
845 		case B_UINT64_TYPE:
846 			err = AddInt64(name, *(int64*)data);
847 			break;
848 		case B_FLOAT_TYPE:
849 			err = AddFloat(name, *(float*)data);
850 			break;
851 		case B_DOUBLE_TYPE:
852 			err = AddDouble(name, *(double*)data);
853 			break;
854 		case B_POINT_TYPE:
855 			err = AddPoint(name, *(BPoint*)data);
856 			break;
857 		case B_RECT_TYPE:
858 			err = AddRect(name, *(BRect*)data);
859 			break;
860 		case B_REF_TYPE:
861 		{
862 //			err = AddRef(name, (entry_ref*)data);
863 			BDataBuffer DB((void*)data, numBytes, true);
864 			err = fBody->AddData<BDataBuffer>(name, DB, type);
865 			break;
866 		}
867 		case B_MESSAGE_TYPE:
868 		{
869 //			BMessage msg;
870 //			msg.Unflatten((const char*)data);
871 //			err = AddMessage(name, &msg);
872 //			err = AddMessage(name, (BMessage*)data);
873 			BDataBuffer DB((void*)data, numBytes, true);
874 			err = fBody->AddData<BDataBuffer>(name, DB, type);
875 			break;
876 		}
877 		case B_MESSENGER_TYPE:
878 			err = AddMessenger(name, *(BMessenger*)data);
879 			break;
880 		case B_POINTER_TYPE:
881 			err = AddPointer(name, *(void**)data);
882 			break;
883 		case B_STRING_TYPE:
884 			err = AddString(name, (const char*)data);
885 			break;
886 		default:
887 			// TODO: test
888 			// Using the mythical BDataBuffer
889 			BDataBuffer DB((void*)data, numBytes, true);
890 			err = fBody->AddData<BDataBuffer>(name, DB, type);
891 			break;
892 	}
893 
894 	return err;
895 }
896 //------------------------------------------------------------------------------
897 status_t BMessage::RemoveData(const char* name, int32 index)
898 {
899 	return fReadOnly ? B_ERROR : fBody->RemoveData(name, index);
900 }
901 //------------------------------------------------------------------------------
902 status_t BMessage::RemoveName(const char* name)
903 {
904 	return fReadOnly ? B_ERROR : fBody->RemoveName(name);
905 }
906 //------------------------------------------------------------------------------
907 status_t BMessage::MakeEmpty()
908 {
909 	return fReadOnly ? B_ERROR : fBody->MakeEmpty();
910 }
911 //------------------------------------------------------------------------------
912 status_t BMessage::FindString(const char* name, const char** str) const
913 {
914 	return FindString(name, 0, str);
915 }
916 //------------------------------------------------------------------------------
917 status_t BMessage::FindString(const char* name, int32 index,
918 							  const char** str) const
919 {
920 	ssize_t bytes;
921 	return FindData(name, B_STRING_TYPE, index,
922 					(const void**)str, &bytes);
923 }
924 //------------------------------------------------------------------------------
925 status_t BMessage::FindString(const char* name, BString* str) const
926 {
927 	return FindString(name, 0, str);
928 }
929 //------------------------------------------------------------------------------
930 status_t BMessage::FindString(const char* name, int32 index, BString* str) const
931 {
932 	const char* cstr;
933 	status_t err = FindString(name, index, &cstr);
934 	if (!err)
935 	{
936 		*str = cstr;
937 	}
938 
939 	return err;
940 }
941 //------------------------------------------------------------------------------
942 status_t BMessage::FindPointer(const char* name, void** ptr) const
943 {
944 	return FindPointer(name, 0, ptr);
945 }
946 //------------------------------------------------------------------------------
947 status_t BMessage::FindPointer(const char* name, int32 index, void** ptr) const
948 {
949 	*ptr = NULL;
950 	return fBody->FindData<void*>(name, index, ptr, B_POINTER_TYPE);
951 }
952 //------------------------------------------------------------------------------
953 status_t BMessage::FindMessenger(const char* name, BMessenger* m) const
954 {
955 	return FindMessenger(name, 0, m);
956 }
957 //------------------------------------------------------------------------------
958 status_t BMessage::FindMessenger(const char* name, int32 index, BMessenger* m) const
959 {
960 	return fBody->FindData<BMessenger>(name, index, m, B_MESSENGER_TYPE);
961 }
962 //------------------------------------------------------------------------------
963 status_t BMessage::FindRef(const char* name, entry_ref* ref) const
964 {
965 	return FindRef(name, 0, ref);
966 }
967 //------------------------------------------------------------------------------
968 status_t BMessage::FindRef(const char* name, int32 index, entry_ref* ref) const
969 {
970 #if 0
971 	return fBody->FindData<entry_ref>(name, index, ref, B_REF_TYPE);
972 #endif
973 	void* data = NULL;
974 	ssize_t size = 0;
975 	status_t err = FindData(name, B_REF_TYPE, index, (const void**)&data, &size);
976 	if (!err)
977 	{
978 		err = entry_ref_unflatten(ref, (char*)data, size);
979 	}
980 
981 	return err;
982 }
983 //------------------------------------------------------------------------------
984 status_t BMessage::FindMessage(const char* name, BMessage* msg) const
985 {
986 	return FindMessage(name, 0, msg);
987 }
988 //------------------------------------------------------------------------------
989 status_t BMessage::FindMessage(const char* name, int32 index, BMessage* msg) const
990 {
991 #if 0
992 	return fBody->FindData<BMessage>(name, index, msg, B_MESSAGE_TYPE);
993 #endif
994 	void* data = NULL;
995 	ssize_t size = 0;
996 	status_t err = FindData(name, B_MESSAGE_TYPE, index,
997 							(const void**)&data, &size);
998 	if (!err)
999 	{
1000 		err = msg->Unflatten((const char*)data);
1001 	}
1002 
1003 	return err;
1004 }
1005 //------------------------------------------------------------------------------
1006 status_t BMessage::FindFlat(const char* name, BFlattenable* obj) const
1007 {
1008 	return FindFlat(name, 0, obj);
1009 }
1010 //------------------------------------------------------------------------------
1011 status_t BMessage::FindFlat(const char* name, int32 index,
1012 							BFlattenable* obj) const
1013 {
1014 	const void* data;
1015 	ssize_t numBytes;
1016 	status_t err = FindData(name, obj->TypeCode(), index, &data, &numBytes);
1017 	if (!err)
1018 	{
1019 		err = obj->Unflatten(obj->TypeCode(), data, numBytes);
1020 	}
1021 
1022 	return err;
1023 }
1024 //------------------------------------------------------------------------------
1025 status_t BMessage::FindData(const char* name, type_code type, const void** data,
1026 							ssize_t* numBytes) const
1027 {
1028 	return FindData(name, type, 0, data, numBytes);
1029 }
1030 //------------------------------------------------------------------------------
1031 status_t BMessage::FindData(const char* name, type_code type, int32 index,
1032 							const void** data, ssize_t* numBytes) const
1033 {
1034 	status_t err = B_OK;
1035 	// Oh, the humanity!
1036 	err = fBody->FindData(name, type, index, data, numBytes);
1037 
1038 	return err;
1039 }
1040 //------------------------------------------------------------------------------
1041 status_t BMessage::ReplaceString(const char* name, const char* string)
1042 {
1043 	return ReplaceString(name, 0, string);
1044 }
1045 //------------------------------------------------------------------------------
1046 status_t BMessage::ReplaceString(const char* name, int32 index,
1047 								 const char* string)
1048 {
1049 	return fBody->ReplaceData<BString>(name, index, string, B_STRING_TYPE);
1050 }
1051 //------------------------------------------------------------------------------
1052 status_t BMessage::ReplaceString(const char* name, const BString& string)
1053 {
1054 	return ReplaceString(name, 0, string);
1055 }
1056 //------------------------------------------------------------------------------
1057 status_t BMessage::ReplaceString(const char* name, int32 index, const BString& string)
1058 {
1059 	return fBody->ReplaceData<BString>(name, index, string, B_STRING_TYPE);
1060 }
1061 //------------------------------------------------------------------------------
1062 status_t BMessage::ReplacePointer(const char* name, const void* ptr)
1063 {
1064 	return ReplacePointer(name, 0, ptr);
1065 }
1066 //------------------------------------------------------------------------------
1067 status_t BMessage::ReplacePointer(const char* name, int32 index,
1068 								  const void* ptr)
1069 {
1070 	return fBody->ReplaceData<void*>(name, index, (void*)ptr, B_POINTER_TYPE);
1071 }
1072 //------------------------------------------------------------------------------
1073 status_t BMessage::ReplaceMessenger(const char* name, BMessenger messenger)
1074 {
1075 	// Don't want to copy the BMessenger
1076 	return fBody->ReplaceData<BMessenger>(name, 0, messenger, B_MESSENGER_TYPE);
1077 }
1078 //------------------------------------------------------------------------------
1079 status_t BMessage::ReplaceMessenger(const char* name, int32 index,
1080 									BMessenger msngr)
1081 {
1082 	return fBody->ReplaceData<BMessenger>(name, index, msngr, B_MESSENGER_TYPE);
1083 }
1084 //------------------------------------------------------------------------------
1085 status_t BMessage::ReplaceRef(const char* name, const entry_ref* ref)
1086 {
1087 	return ReplaceRef(name, 0, ref);
1088 }
1089 //------------------------------------------------------------------------------
1090 status_t BMessage::ReplaceRef(const char* name, int32 index, const entry_ref* ref)
1091 {
1092 	// TODO: test
1093 	// Use voidref's theoretical BDataBuffer
1094 #if 0
1095 	return fBody->ReplaceData<entry_ref>(name, index, *ref, B_REF_TYPE);
1096 #endif
1097 	char* buffer = new(nothrow) char[sizeof (entry_ref) + B_PATH_NAME_LENGTH];
1098 	size_t size;
1099 	status_t err = entry_ref_flatten(buffer, &size, ref);
1100 	if (!err)
1101 	{
1102 		BDataBuffer DB((void*)buffer, size);
1103 		err = fBody->ReplaceData<BDataBuffer>(name, index, DB, B_REF_TYPE);
1104 	}
1105 
1106 	return err;
1107 }
1108 //------------------------------------------------------------------------------
1109 status_t BMessage::ReplaceMessage(const char* name, const BMessage* msg)
1110 {
1111 	return ReplaceMessage(name, 0, msg);
1112 }
1113 //------------------------------------------------------------------------------
1114 status_t BMessage::ReplaceMessage(const char* name, int32 index,
1115 								  const BMessage* msg)
1116 {
1117 #if 0
1118 	return fBody->ReplaceData<BMessage>(name, index, *msg, B_MESSAGE_TYPE);
1119 #endif
1120 	status_t err = B_OK;
1121 	ssize_t size = msg->FlattenedSize();
1122 	char* buffer = new(nothrow) char[size];
1123 	if (buffer)
1124 	{
1125 		err = msg->Flatten(buffer, size);
1126 		if (!err)
1127 		{
1128 			BDataBuffer DB((void*)buffer, size);
1129 			err = fBody->ReplaceData<BDataBuffer>(name, index, DB,
1130 												  B_MESSAGE_TYPE);
1131 		}
1132 	}
1133 	else
1134 	{
1135 		err = B_NO_MEMORY;
1136 	}
1137 
1138 	return err;
1139 }
1140 //------------------------------------------------------------------------------
1141 status_t BMessage::ReplaceFlat(const char* name, BFlattenable* obj)
1142 {
1143 	return ReplaceFlat(name, 0, obj);
1144 }
1145 //------------------------------------------------------------------------------
1146 status_t BMessage::ReplaceFlat(const char* name, int32 index, BFlattenable* obj)
1147 {
1148 	// TODO: test
1149 	status_t err = B_OK;
1150 	ssize_t size = obj->FlattenedSize();
1151 	char* buffer = new(nothrow) char[size];
1152 	if (buffer)
1153 	{
1154 		err = obj->Flatten(buffer, size);
1155 		if (!err)
1156 		{
1157 			err = ReplaceData(name, obj->TypeCode(), index, (void*)buffer, size);
1158 		}
1159 		delete[] buffer;
1160 	}
1161 
1162 	return err;
1163 }
1164 //------------------------------------------------------------------------------
1165 status_t BMessage::ReplaceData(const char* name, type_code type,
1166 							   const void* data, ssize_t data_size)
1167 {
1168 	return ReplaceData(name, type, 0, data, data_size);
1169 }
1170 //------------------------------------------------------------------------------
1171 status_t BMessage::ReplaceData(const char* name, type_code type, int32 index,
1172 							   const void* data, ssize_t data_size)
1173 {
1174 	// TODO: Fix this horrible hack
1175 	status_t err = B_OK;
1176 	switch (type)
1177 	{
1178 		case B_BOOL_TYPE:
1179 			err = ReplaceBool(name, index, *(bool*)data);
1180 			break;
1181 		case B_INT8_TYPE:
1182 		case B_UINT8_TYPE:
1183 			err = ReplaceInt8(name, index, *(int8*)data);
1184 			break;
1185 		case B_INT16_TYPE:
1186 		case B_UINT16_TYPE:
1187 			err = ReplaceInt16(name, index, *(int16*)data);
1188 			break;
1189 		case B_INT32_TYPE:
1190 		case B_UINT32_TYPE:
1191 			err = ReplaceInt32(name, index, *(int32*)data);
1192 			break;
1193 		case B_INT64_TYPE:
1194 		case B_UINT64_TYPE:
1195 			err = ReplaceInt64(name, index, *(int64*)data);
1196 			break;
1197 		case B_FLOAT_TYPE:
1198 			err = ReplaceFloat(name, index, *(float*)data);
1199 			break;
1200 		case B_DOUBLE_TYPE:
1201 			err = ReplaceDouble(name, index, *(double*)data);
1202 			break;
1203 		case B_POINT_TYPE:
1204 			err = ReplacePoint(name, index, *(BPoint*)data);
1205 			break;
1206 		case B_RECT_TYPE:
1207 			err = ReplaceRect(name, index, *(BRect*)data);
1208 			break;
1209 		case B_REF_TYPE:
1210 			err = ReplaceRef(name, index, (entry_ref*)data);
1211 			break;
1212 		case B_MESSAGE_TYPE:
1213 			err = ReplaceMessage(name, index, (BMessage*)data);
1214 			break;
1215 		case B_MESSENGER_TYPE:
1216 			err = ReplaceMessenger(name, index, *(BMessenger*)data);
1217 			break;
1218 		case B_POINTER_TYPE:
1219 			err = ReplacePointer(name, index, (void**)data);
1220 			break;
1221 		default:
1222 			// TODO: test
1223 			// Using the mythical BDataBuffer
1224 			BDataBuffer DB((void*)data, data_size, true);
1225 			err = fBody->ReplaceData<BDataBuffer>(name, index, DB, type);
1226 			break;
1227 	}
1228 
1229 	return err;
1230 }
1231 //------------------------------------------------------------------------------
1232 void* BMessage::operator new(size_t size)
1233 {
1234 	return ::new char[size];
1235 }
1236 //------------------------------------------------------------------------------
1237 void* BMessage::operator new(size_t, void* p)
1238 {
1239 	return p;
1240 }
1241 //------------------------------------------------------------------------------
1242 void BMessage::operator delete(void* ptr, size_t size)
1243 {
1244 	::delete(ptr);
1245 }
1246 //------------------------------------------------------------------------------
1247 bool BMessage::HasFlat(const char* name, const BFlattenable* flat) const
1248 {
1249 	return HasFlat(name, 0, flat);
1250 }
1251 //------------------------------------------------------------------------------
1252 bool BMessage::HasFlat(const char* name, int32 n, const BFlattenable* flat) const
1253 {
1254 	return fBody->HasData(name, flat->TypeCode(), n);
1255 }
1256 //------------------------------------------------------------------------------
1257 bool BMessage::HasData(const char* name, type_code t, int32 n) const
1258 {
1259 	return fBody->HasData(name, t, n);
1260 }
1261 //------------------------------------------------------------------------------
1262 BRect BMessage::FindRect(const char* name, int32 n) const
1263 {
1264 	BRect r(0, 0, -1, -1);
1265 	FindRect(name, n, &r);
1266 	return r;
1267 }
1268 //------------------------------------------------------------------------------
1269 BPoint BMessage::FindPoint(const char* name, int32 n) const
1270 {
1271 	BPoint p(0, 0);
1272 	FindPoint(name, n, &p);
1273 	return p;
1274 }
1275 //------------------------------------------------------------------------------
1276 status_t BMessage::flatten_hdr(BDataIO* stream) const
1277 {
1278 	status_t err = B_OK;
1279 	int32 data = MSG_FIELD_VERSION;
1280 
1281 	write_helper(stream, (const void*)&data, sizeof (data), err);
1282 	if (!err)
1283 	{
1284 		// faked up checksum; we'll fix it up later
1285 		write_helper(stream, (const void*)&data, sizeof (data), err);
1286 	}
1287 	if (!err)
1288 	{
1289 		data = fBody->FlattenedSize() + calc_hdr_size(0);
1290 		write_helper(stream, (const void*)&data, sizeof (data), err);
1291 	}
1292 	if (!err)
1293 	{
1294 		write_helper(stream, (const void*)&what, sizeof (what), err);
1295 	}
1296 
1297 	uint8 flags = 0;
1298 #ifdef B_HOST_IS_BENDIAN
1299 	flags |= MSG_FLAG_BIG_ENDIAN;
1300 #endif
1301 	if (HasSpecifiers())
1302 	{
1303 		flags |= MSG_FLAG_SCRIPT_MSG;
1304 	}
1305 
1306 	if (fTarget != B_NULL_TOKEN)
1307 	{
1308 		flags |= MSG_FLAG_INCL_TARGET;
1309 	}
1310 
1311 	if (fReplyTo.port >= 0 &&
1312 		fReplyTo.target != B_NULL_TOKEN &&
1313 		fReplyTo.team >= 0)
1314 	{
1315 		flags |= MSG_FLAG_INCL_REPLY;
1316 	}
1317 
1318 	write_helper(stream, (const void*)&flags, sizeof (flags), err);
1319 
1320 	// Write targeting and reply info if necessary
1321 	if (!err && (flags & MSG_FLAG_INCL_TARGET))
1322 	{
1323 		data = fPreferred ? B_PREFERRED_TOKEN : fTarget;
1324 		write_helper(stream, (const void*)&data, sizeof (data), err);
1325 	}
1326 
1327 	if (!err && (flags & MSG_FLAG_INCL_REPLY))
1328 	{
1329 		write_helper(stream, (const void*)&fReplyTo.port,
1330 					 sizeof (fReplyTo.port), err);
1331 		if (!err)
1332 		{
1333 			write_helper(stream, (const void*)&fReplyTo.target,
1334 						 sizeof (fReplyTo.target), err);
1335 		}
1336 		if (!err)
1337 		{
1338 			write_helper(stream, (const void*)&fReplyTo.team,
1339 						 sizeof (fReplyTo.team), err);
1340 		}
1341 
1342 		uint8 bigFlags;
1343 		if (!err)
1344 		{
1345 			bigFlags = fPreferred ? 1 : 0;
1346 			write_helper(stream, (const void*)&bigFlags,
1347 						 sizeof (bigFlags), err);
1348 		}
1349 		if (!err)
1350 		{
1351 			bigFlags = fReplyRequired ? 1 : 0;
1352 			write_helper(stream, (const void*)&bigFlags,
1353 						 sizeof (bigFlags), err);
1354 		}
1355 		if (!err)
1356 		{
1357 			bigFlags = fReplyDone ? 1 : 0;
1358 			write_helper(stream, (const void*)&bigFlags,
1359 						 sizeof (bigFlags), err);
1360 		}
1361 		if (!err)
1362 		{
1363 			bigFlags = fIsReply ? 1 : 0;
1364 			write_helper(stream, (const void*)&bigFlags,
1365 						 sizeof (bigFlags), err);
1366 		}
1367 	}
1368 
1369 	return err;
1370 }
1371 //------------------------------------------------------------------------------
1372 status_t BMessage::unflatten_hdr(BDataIO* stream, bool& swap)
1373 {
1374 	status_t err = B_OK;
1375 	int32 data;
1376 	int32 checksum;
1377 	uchar csBuffer[MSG_HEADER_MAX_SIZE];
1378 
1379 	TReadHelper read_helper(stream);
1380 	TChecksumHelper checksum_helper(csBuffer);
1381 
1382 	try {
1383 
1384 	// Get the message version
1385 	read_helper(data);
1386 	if (data == '1BOF')
1387 	{
1388 		swap = true;
1389 	}
1390 	else if (data == 'FOB1')
1391 	{
1392 		swap = false;
1393 	}
1394 	else
1395 	{
1396 		// This is *not* a message
1397 		return B_NOT_A_MESSAGE;
1398 	}
1399 
1400 	// Make way for the new data
1401 	MakeEmpty();
1402 
1403 	read_helper.SetSwap(swap);
1404 
1405 	// get the checksum
1406 	read_helper(checksum);
1407 	// get the size
1408 	read_helper(data);
1409 	checksum_helper.Cache(data);
1410 	// Get the what
1411 	read_helper(what);
1412 	checksum_helper.Cache(what);
1413 	// Get the flags
1414 	uint8 flags = 0;
1415 	read_helper(flags);
1416 	checksum_helper.Cache(flags);
1417 
1418 	fHasSpecifiers = flags & MSG_FLAG_SCRIPT_MSG;
1419 
1420 	if (flags & MSG_FLAG_BIG_ENDIAN)
1421 	{
1422 		// TODO: ???
1423 		// Isn't this already indicated by the byte order of the message version?
1424 	}
1425 	if (flags & MSG_FLAG_INCL_TARGET)
1426 	{
1427 		// Get the target data
1428 		read_helper(data);
1429 		checksum_helper.Cache(data);
1430 		fTarget = data;
1431 	}
1432 	if (flags & MSG_FLAG_INCL_REPLY)
1433 	{
1434 		// Get the reply port
1435 		read_helper(fReplyTo.port);
1436 		read_helper(fReplyTo.target);
1437 		read_helper(fReplyTo.team);
1438 		checksum_helper.Cache(fReplyTo.port);
1439 		checksum_helper.Cache(fReplyTo.target);
1440 		checksum_helper.Cache(fReplyTo.team);
1441 
1442 		// Get the "big flags"
1443 		uint8 bigFlags;
1444 		// Get the preferred flag
1445 		read_helper(bigFlags);
1446 		checksum_helper.Cache(bigFlags);
1447 		fPreferred = bigFlags;
1448 		if (fPreferred)
1449 		{
1450 			fTarget = B_PREFERRED_TOKEN;
1451 		}
1452 		// Get the reply requirement flag
1453 		read_helper(bigFlags);
1454 		checksum_helper.Cache(bigFlags);
1455 		fReplyRequired = bigFlags;
1456 		// Get the reply done flag
1457 		read_helper(bigFlags);
1458 		checksum_helper.Cache(bigFlags);
1459 		fReplyDone = bigFlags;
1460 		// Get the "is reply" flag
1461 		read_helper(bigFlags);
1462 		checksum_helper.Cache(bigFlags);
1463 		fIsReply = bigFlags;
1464 	}
1465 	}
1466 	catch (status_t& e)
1467 	{
1468 		err = e;
1469 	}
1470 
1471 	if (checksum != checksum_helper.CheckSum())
1472 		err = B_NOT_A_MESSAGE;
1473 
1474 	return err;
1475 }
1476 //------------------------------------------------------------------------------
1477 status_t BMessage::real_flatten(char* result, ssize_t size) const
1478 {
1479 	BMemoryIO stream((void*)result, size);
1480 	status_t err = real_flatten(&stream);
1481 
1482 	if (!err)
1483 	{
1484 		// Fixup the checksum; it is calculated on data size, what, flags,
1485 		// and target info (including big flags if appropriate)
1486 		((uint32*)result)[1] = _checksum_((uchar*)result + (sizeof (uint32) * 2),
1487 										  calc_hdr_size(0) - (sizeof (uint32) * 2));
1488 	}
1489 
1490 	return err;
1491 }
1492 //------------------------------------------------------------------------------
1493 status_t BMessage::real_flatten(BDataIO* stream) const
1494 {
1495 	status_t err = flatten_hdr(stream);
1496 
1497 	if (!err)
1498 	{
1499 		err = fBody->Flatten(stream);
1500 	}
1501 
1502 	return err;
1503 }
1504 //------------------------------------------------------------------------------
1505 ssize_t BMessage::calc_hdr_size(uchar flags) const
1506 {
1507 	ssize_t size = min_hdr_size();
1508 
1509 	if (fTarget != B_NULL_TOKEN)
1510 	{
1511 		size += sizeof (fTarget);
1512 	}
1513 
1514 	if (fReplyTo.port >= 0 &&
1515 		fReplyTo.target != B_NULL_TOKEN &&
1516 		fReplyTo.team >= 0)
1517 	{
1518 		size += sizeof (fReplyTo.port);
1519 		size += sizeof (fReplyTo.target);
1520 		size += sizeof (fReplyTo.team);
1521 
1522 		size += 4;	// For the "big" flags
1523 	}
1524 
1525 	return size;
1526 }
1527 //------------------------------------------------------------------------------
1528 ssize_t BMessage::min_hdr_size() const
1529 {
1530 	ssize_t size = 0;
1531 
1532 	size += 4;	// version
1533 	size += 4;	// checksum
1534 	size += 4;	// flattened size
1535 	size += 4;	// 'what'
1536 	size += 1;	// flags
1537 
1538 	return size;
1539 }
1540 //------------------------------------------------------------------------------
1541 
1542 #else	// USING_TEMPLATE_MADNESS
1543 
1544 //------------------------------------------------------------------------------
1545 BMessage::BMessage(uint32 command)
1546 {
1547 	init_data();
1548 
1549 	what = command;
1550 }
1551 //------------------------------------------------------------------------------
1552 BMessage::BMessage(const BMessage &message)
1553 {
1554 	*this = message;
1555 }
1556 //------------------------------------------------------------------------------
1557 BMessage::BMessage()
1558 {
1559 	init_data();
1560 }
1561 //------------------------------------------------------------------------------
1562 BMessage::~BMessage ()
1563 {
1564 }
1565 //------------------------------------------------------------------------------
1566 BMessage &BMessage::operator=(const BMessage &message)
1567 {
1568 	what = message.what;
1569 
1570 	link = message.link;
1571 	fTarget = message.fTarget;
1572 	fOriginal = message.fOriginal;
1573 	fChangeCount = message.fChangeCount;
1574 	fCurSpecifier = message.fCurSpecifier;
1575 	fPtrOffset = message.fPtrOffset;
1576 
1577 	fEntries = NULL;
1578 
1579     entry_hdr *src_entry;
1580 
1581     for ( src_entry = message.fEntries; src_entry != NULL; src_entry = src_entry->fNext )
1582 	{
1583 		entry_hdr* new_entry = (entry_hdr*)new char[da_total_logical_size ( src_entry )];
1584 
1585 		if ( new_entry != NULL )
1586 		{
1587 			memcpy ( new_entry, src_entry, da_total_logical_size ( src_entry ) );
1588 
1589 			new_entry->fNext = fEntries;
1590 			new_entry->fPhysicalBytes = src_entry->fLogicalBytes;
1591 
1592 			fEntries = new_entry;
1593 		}
1594     }
1595 
1596 	fReplyTo.port = message.fReplyTo.port;
1597 	fReplyTo.target = message.fReplyTo.target;
1598 	fReplyTo.team = message.fReplyTo.team;
1599 	fReplyTo.preferred = message.fReplyTo.preferred;
1600 
1601 	fPreferred = message.fPreferred;
1602 	fReplyRequired = message.fReplyRequired;
1603 	fReplyDone = message.fReplyDone;
1604 	fIsReply = message.fIsReply;
1605 	fWasDelivered = message.fWasDelivered;
1606 	fReadOnly = message.fReadOnly;
1607 	fHasSpecifiers = message.fHasSpecifiers;
1608 
1609     return *this;
1610 }
1611 //------------------------------------------------------------------------------
1612 status_t BMessage::GetInfo(const char *name, type_code *typeFound,
1613 							int32 *countFound) const
1614 {
1615 	for(entry_hdr *entry = fEntries; entry != NULL; entry = entry->fNext)
1616 	{
1617 		if (entry->fNameLength == strlen(name) &&
1618 			strncmp(entry->fName, name, entry->fNameLength) == 0)
1619 		{
1620 			if (typeFound)
1621 				*typeFound = entry->fType;
1622 
1623 			if (countFound)
1624 				*countFound = entry->fCount;
1625 
1626 			return B_OK;
1627 		}
1628 	}
1629 
1630 	return B_NAME_NOT_FOUND;
1631 }
1632 //------------------------------------------------------------------------------
1633 status_t BMessage::GetInfo(const char *name, type_code *typeFound, bool *fixedSize) const
1634 {
1635 	return B_ERROR;
1636 }
1637 //------------------------------------------------------------------------------
1638 status_t BMessage::GetInfo(type_code type, int32 index, char **nameFound, type_code *typeFound,
1639 	int32 *countFound) const
1640 {
1641 	return B_ERROR;
1642 }
1643 //------------------------------------------------------------------------------
1644 int32 BMessage::CountNames(type_code type) const
1645 {
1646 	return -1;
1647 }
1648 //------------------------------------------------------------------------------
1649 //bool BMessage::IsEmpty () const;
1650 //------------------------------------------------------------------------------
1651 //bool BMessage::IsSystem () const;
1652 //------------------------------------------------------------------------------
1653 bool BMessage::IsReply() const
1654 {
1655 	return fIsReply;
1656 }
1657 //------------------------------------------------------------------------------
1658 void BMessage::PrintToStream() const
1659 {
1660 	char name[256];
1661 
1662 	for (entry_hdr *entry = fEntries; entry != NULL; entry = entry->fNext)
1663 	{
1664 		memcpy(name, entry->fName, entry->fNameLength);
1665 		name[entry->fNameLength] = 0;
1666 
1667 		printf("#entry %s, type = %c%c%c%c, count = %d\n", name,
1668 			(entry->fType & 0xFF000000) >> 24, (entry->fType & 0x00FF0000) >> 16,
1669 			(entry->fType & 0x0000FF00) >> 8, entry->fType & 0x000000FF, entry->fCount);
1670 
1671 		((BMessage*)this)->da_dump((dyn_array*)entry);
1672 	}
1673 }
1674 //------------------------------------------------------------------------------
1675 //status_t BMessage::Rename(const char *old_entry, const char *new_entry);
1676 //------------------------------------------------------------------------------
1677 //------------------------------------------------------------------------------
1678 bool BMessage::WasDelivered () const
1679 {
1680 	return fWasDelivered;
1681 }
1682 //------------------------------------------------------------------------------
1683 //bool BMessage::IsSourceWaiting() const;
1684 //------------------------------------------------------------------------------
1685 //bool BMessage::IsSourceRemote() const;
1686 //------------------------------------------------------------------------------
1687 BMessenger BMessage::ReturnAddress() const
1688 {
1689 	return BMessenger(fReplyTo.team, fReplyTo.port, fReplyTo.target,
1690 		fReplyTo.preferred);
1691 }
1692 //------------------------------------------------------------------------------
1693 const BMessage *BMessage::Previous () const
1694 {
1695 	return fOriginal;
1696 }
1697 //------------------------------------------------------------------------------
1698 bool BMessage::WasDropped () const
1699 {
1700 	if (GetInfo("_drop_point_", NULL, (int32*)NULL) == B_OK)
1701 		return true;
1702 	else
1703 		return false;
1704 }
1705 //------------------------------------------------------------------------------
1706 BPoint BMessage::DropPoint(BPoint *offset) const
1707 {
1708 	BPoint point;
1709 
1710 	FindPoint("_drop_point_", &point);
1711 
1712 	if (offset)
1713 		FindPoint("_drop_offset_", offset);
1714 
1715 	return point;
1716 }
1717 //------------------------------------------------------------------------------
1718 status_t BMessage::SendReply(uint32 command, BHandler *reply_to)
1719 {
1720 	return B_ERROR;
1721 }
1722 //------------------------------------------------------------------------------
1723 status_t BMessage::SendReply(BMessage *the_reply, BHandler *reply_to,
1724 					bigtime_t timeout)
1725 {
1726 	return B_ERROR;
1727 }
1728 //------------------------------------------------------------------------------
1729 status_t BMessage::SendReply(BMessage *the_reply, BMessenger reply_to,
1730 					bigtime_t timeout)
1731 {
1732 	return B_ERROR;
1733 }
1734 //------------------------------------------------------------------------------
1735 status_t BMessage::SendReply(uint32 command, BMessage *reply_to_reply)
1736 {
1737 	return B_ERROR;
1738 }
1739 //------------------------------------------------------------------------------
1740 status_t BMessage::SendReply(BMessage *the_reply, BMessage *reply_to_reply,
1741 					bigtime_t send_timeout,
1742 					bigtime_t reply_timeout)
1743 {
1744 	return B_ERROR;
1745 }
1746 //------------------------------------------------------------------------------
1747 ssize_t BMessage::FlattenedSize() const
1748 {
1749 	ssize_t size = 7 * sizeof(int32);
1750 
1751 	for (entry_hdr *entry = fEntries; entry != NULL; entry = entry->fNext)
1752 		size += da_total_logical_size(entry);
1753 
1754 	return size;
1755 }
1756 //------------------------------------------------------------------------------
1757 status_t BMessage::Flatten(char *address, ssize_t numBytes) const
1758 {
1759 	if (address!= NULL && numBytes < FlattenedSize())
1760 		return B_NO_MEMORY;
1761 
1762 	int position = 7 * sizeof(int32);
1763 
1764 	((int32*)address)[1] = what;
1765 	((int32*)address)[2] = fCurSpecifier;
1766 	((int32*)address)[3] = fHasSpecifiers;
1767 	((int32*)address)[4] = 0;
1768 	((int32*)address)[5] = 0;
1769 	((int32*)address)[6] = 0;
1770 
1771 	for (entry_hdr *entry = fEntries; entry != NULL; entry = entry->fNext)
1772 	{
1773 		memcpy(address + position, entry, da_total_logical_size(entry));
1774 
1775 		position += da_total_logical_size(entry);
1776     }
1777 
1778     ((size_t*)address)[0] = position;
1779 
1780 	return B_OK;
1781 }
1782 //------------------------------------------------------------------------------
1783 status_t BMessage::Flatten(BDataIO *object, ssize_t *numBytes) const
1784 {
1785 	if (numBytes != NULL && *numBytes < FlattenedSize())
1786 		return B_NO_MEMORY;
1787 
1788 	int32 size = FlattenedSize();
1789 	char *buffer = new char[size];
1790 
1791 	Flatten(buffer, size);
1792 
1793 	object->Write(buffer, size);
1794 
1795 	delete buffer;
1796 
1797 	return B_OK;
1798 }
1799 //------------------------------------------------------------------------------
1800 status_t BMessage::Unflatten(const char *address)
1801 {
1802 	size_t size;
1803 
1804     MakeEmpty();
1805 
1806     size = ((size_t*)address)[0];
1807     what = ((int32*)address)[1];
1808 	fCurSpecifier = ((int32*)address)[2];
1809 	fHasSpecifiers = ((int32*)address)[3];
1810 
1811     size_t position = 7 * sizeof(int32);
1812 
1813     while (position < size)
1814 	{
1815 		entry_hdr* src_entry = (entry_hdr*)&address[position];
1816 		entry_hdr* new_entry = (entry_hdr*)new char[da_total_logical_size ( src_entry )];
1817 
1818 		if (new_entry != NULL)
1819 		{
1820 			memcpy(new_entry, src_entry, da_total_logical_size(src_entry));
1821 
1822 			new_entry->fNext = fEntries;
1823 			new_entry->fPhysicalBytes = src_entry->fLogicalBytes;
1824 			position += da_total_logical_size(src_entry);
1825 
1826 			fEntries = new_entry;
1827 		}
1828 		else
1829 			return B_NO_MEMORY;
1830     }
1831 
1832     if (position != size)
1833 	{
1834 		MakeEmpty();
1835 		return B_BAD_VALUE;
1836     }
1837 
1838     return B_OK;
1839 }
1840 //------------------------------------------------------------------------------
1841 status_t BMessage::Unflatten(BDataIO *object)
1842 {
1843 	size_t size;
1844 
1845 	object->Read(&size, sizeof(int32));
1846 
1847 	char *buffer = new char[size];
1848 
1849 	*(int32*)buffer = size;
1850 
1851 	object->Read(buffer + sizeof(int32), size - sizeof(int32));
1852 
1853 	status_t status =  Unflatten(buffer);
1854 
1855 	delete[] buffer;
1856 
1857     return status;
1858 }
1859 //------------------------------------------------------------------------------
1860 status_t BMessage::AddSpecifier(const char *property)
1861 {
1862 	BMessage message(B_DIRECT_SPECIFIER);
1863 	message.AddString("property", property);
1864 
1865 	fCurSpecifier ++;
1866 	fHasSpecifiers = true;
1867 
1868 	return AddMessage("specifiers", &message);
1869 }
1870 //------------------------------------------------------------------------------
1871 status_t BMessage::AddSpecifier(const char *property, int32 index)
1872 {
1873 	BMessage message(B_INDEX_SPECIFIER);
1874 	message.AddString("property", property);
1875 	message.AddInt32("index", index);
1876 
1877 	fCurSpecifier++;
1878 	fHasSpecifiers = true;
1879 
1880 	return AddMessage("specifiers", &message);
1881 }
1882 //------------------------------------------------------------------------------
1883 status_t BMessage::AddSpecifier(const char *property, int32 index, int32 range)
1884 {
1885 	BMessage message(B_RANGE_SPECIFIER);
1886 	message.AddString("property", property);
1887 	message.AddInt32("index", index);
1888 	message.AddInt32("range", range);
1889 
1890 	fCurSpecifier ++;
1891 	fHasSpecifiers = true;
1892 
1893 	return AddMessage("specifiers", &message);
1894 }
1895 //------------------------------------------------------------------------------
1896 status_t BMessage::AddSpecifier(const char *property, const char *name)
1897 {
1898 	BMessage message(B_NAME_SPECIFIER);
1899 	message.AddString("property", property);
1900 	message.AddString("name", name);
1901 
1902 	fCurSpecifier ++;
1903 	fHasSpecifiers = true;
1904 
1905 	return AddMessage("specifiers", &message);
1906 }
1907 //------------------------------------------------------------------------------
1908 //status_t BMessage::AddSpecifier(const BMessage *message);
1909 //------------------------------------------------------------------------------
1910 status_t SetCurrentSpecifier(int32 index)
1911 {
1912 	return B_ERROR;
1913 }
1914 //------------------------------------------------------------------------------
1915 status_t BMessage::GetCurrentSpecifier(int32 *index, BMessage *specifier,
1916 									   int32 *what, const char **property) const
1917 {
1918 	if (fCurSpecifier == -1)
1919 		return B_BAD_SCRIPT_SYNTAX;
1920 
1921 	if (index)
1922 		*index = fCurSpecifier;
1923 
1924 	if (specifier)
1925 	{
1926 		FindMessage("specifiers", fCurSpecifier, specifier);
1927 
1928 		if (what)
1929 			*what = specifier->what;
1930 
1931 		if (property)
1932 			specifier->FindString("property", property);
1933 	}
1934 
1935 	return B_OK;
1936 }
1937 //------------------------------------------------------------------------------
1938 bool BMessage::HasSpecifiers() const
1939 {
1940 	return fHasSpecifiers;
1941 }
1942 //------------------------------------------------------------------------------
1943 status_t BMessage::PopSpecifier()
1944 {
1945 	if (fCurSpecifier)
1946 	{
1947 		fCurSpecifier--;
1948 		return B_OK;
1949 	}
1950 	else
1951 		return B_BAD_VALUE;
1952 }
1953 //------------------------------------------------------------------------------
1954 status_t BMessage::AddRect(const char *name, BRect rect)
1955 {
1956 	return AddData(name, B_RECT_TYPE, &rect, sizeof(BRect), true);
1957 }
1958 //------------------------------------------------------------------------------
1959 status_t BMessage::AddPoint(const char *name, BPoint point)
1960 {
1961 	return AddData(name, B_POINT_TYPE, &point, sizeof(BPoint), true);
1962 }
1963 //------------------------------------------------------------------------------
1964 status_t BMessage::AddString(const char *name, const char *string)
1965 {
1966 	return AddData(name, B_STRING_TYPE, string, strlen(string) + 1, false);
1967 }
1968 //------------------------------------------------------------------------------
1969 //status_t BMessage::AddString(const char *name, const CString &string);
1970 //------------------------------------------------------------------------------
1971 status_t BMessage::AddInt8(const char *name, int8 anInt8)
1972 {
1973 	return AddData(name, B_INT8_TYPE, &anInt8, sizeof(int8));
1974 }
1975 //------------------------------------------------------------------------------
1976 status_t BMessage::AddInt16(const char *name, int16 anInt16)
1977 {
1978 	return AddData(name, B_INT16_TYPE, &anInt16, sizeof(int16));
1979 }
1980 //------------------------------------------------------------------------------
1981 status_t BMessage::AddInt32(const char *name, int32 anInt32)
1982 {
1983 	return AddData(name, B_INT32_TYPE, &anInt32, sizeof(int32));
1984 }
1985 //------------------------------------------------------------------------------
1986 status_t BMessage::AddInt64(const char *name, int64 anInt64)
1987 {
1988 	return AddData(name, B_INT64_TYPE, &anInt64, sizeof(int64));
1989 }
1990 //------------------------------------------------------------------------------
1991 status_t BMessage::AddBool(const char *name, bool aBool)
1992 {
1993 	return AddData(name, B_BOOL_TYPE, &aBool, sizeof(bool));
1994 }
1995 //------------------------------------------------------------------------------
1996 status_t BMessage::AddFloat ( const char *name, float aFloat)
1997 {
1998 	return AddData(name, B_FLOAT_TYPE, &aFloat, sizeof(float));
1999 }
2000 //------------------------------------------------------------------------------
2001 status_t BMessage::AddDouble ( const char *name, double aDouble)
2002 {
2003 	return AddData(name, B_DOUBLE_TYPE, &aDouble, sizeof(double));
2004 }
2005 //------------------------------------------------------------------------------
2006 status_t BMessage::AddPointer(const char *name, const void *pointer)
2007 {
2008 	return AddData(name, B_POINTER_TYPE, &pointer, sizeof(void*), true);
2009 }
2010 //------------------------------------------------------------------------------
2011 status_t BMessage::AddMessenger(const char *name, BMessenger messenger)
2012 {
2013 	return B_OK;
2014 }
2015 //------------------------------------------------------------------------------
2016 //status_t BMessage::AddRef(const char *name, const entry_ref *ref);
2017 //------------------------------------------------------------------------------
2018 status_t BMessage::AddMessage(const char *name, const BMessage *message)
2019 {
2020 	int32 size = message->FlattenedSize();
2021 	char *buffer = new char[size];
2022 
2023 	message->Flatten (buffer, size);
2024 
2025 	return AddData(name, B_MESSAGE_TYPE, buffer, size, false);
2026 }
2027 //------------------------------------------------------------------------------
2028 status_t BMessage::AddFlat(const char *name, BFlattenable *object,
2029 						   int32 numItems)
2030 {
2031 	int32 size = object->FlattenedSize ();
2032 	char *buffer = new char[size];
2033 
2034 	object->Flatten(buffer, size);
2035 
2036 	return AddData(name, object->TypeCode(), buffer, size,
2037 		object->IsFixedSize(), numItems);
2038 }
2039 //------------------------------------------------------------------------------
2040 status_t BMessage::AddData(const char *name, type_code type, const void *data,
2041 						   ssize_t numBytes, bool fixedSize, int32 numItems)
2042 {
2043 	entry_hdr *entry = entry_find(name, type);
2044 
2045 	if (entry == NULL)
2046 	{
2047 		if ( strlen(name) > 255)
2048 			return B_BAD_VALUE;
2049 
2050 		entry = (entry_hdr*)da_create(sizeof(entry_hdr) - sizeof(dyn_array) +
2051 			strlen(name), numBytes, fixedSize, numItems);
2052 
2053 		entry->fNext = fEntries;
2054 		entry->fType = type;
2055 		entry->fNameLength = strlen(name);
2056 		memcpy(entry->fName, name, entry->fNameLength);
2057 
2058 		fEntries = entry;
2059 	}
2060 
2061 	return da_add_data((dyn_array**)&entry, data, numBytes);
2062 }
2063 //------------------------------------------------------------------------------
2064 //status_t BMessage::RemoveData(const char *name, int32 index);
2065 //status_t BMessage::RemoveName(const char *name);
2066 //------------------------------------------------------------------------------
2067 status_t BMessage::MakeEmpty()
2068 {
2069 	entry_hdr *entry;
2070 
2071     while(entry = fEntries)
2072 	{
2073 		fEntries = entry->fNext;
2074 		delete entry;
2075     }
2076 
2077 	return B_OK;
2078 }
2079 //------------------------------------------------------------------------------
2080 status_t BMessage::FindRect(const char *name, BRect *rect) const
2081 {
2082 	entry_hdr *entry = entry_find(name, B_RECT_TYPE);
2083 
2084 	if (entry == NULL)
2085 		return B_NAME_NOT_FOUND;
2086 
2087 	*rect = *(BRect*)da_first_chunk(entry);
2088 
2089 	return B_OK;
2090 }
2091 //------------------------------------------------------------------------------
2092 status_t BMessage::FindRect(const char *name, int32 index, BRect *rect) const
2093 {
2094 	entry_hdr *entry = entry_find(name, B_RECT_TYPE);
2095 
2096 	if (entry == NULL)
2097 		return B_NAME_NOT_FOUND;
2098 
2099 	if (index < entry->fCount)
2100 	{
2101 		BRect* data = (BRect*)da_first_chunk(entry);
2102 		*rect = data[index];
2103 
2104 		return B_OK;
2105 	}
2106 
2107 	return B_BAD_INDEX;
2108 }
2109 //------------------------------------------------------------------------------
2110 status_t BMessage::FindPoint(const char *name, BPoint *point) const
2111 {
2112 	entry_hdr *entry = entry_find(name, B_POINT_TYPE);
2113 
2114 	if (entry == NULL)
2115 		return B_NAME_NOT_FOUND;
2116 
2117 	*point = *(BPoint*)da_first_chunk(entry);
2118 
2119 	return B_OK;
2120 }
2121 //------------------------------------------------------------------------------
2122 status_t BMessage::FindPoint(const char *name, int32 index, BPoint *point) const
2123 {
2124 	entry_hdr *entry = entry_find(name, B_POINT_TYPE);
2125 
2126 	if (entry == NULL)
2127 		return B_NAME_NOT_FOUND;
2128 
2129 	if (index < entry->fCount)
2130 	{
2131 		BPoint* data = (BPoint*)da_first_chunk(entry);
2132 		*point = data[index];
2133 
2134 		return B_OK;
2135 	}
2136 
2137 	return B_BAD_INDEX;
2138 }
2139 //------------------------------------------------------------------------------
2140 status_t BMessage::FindString(const char *name, int32 index,
2141 							  const char **string) const
2142 {
2143 	return FindData(name, B_STRING_TYPE, index, (const void**)string, NULL);
2144 }
2145 //------------------------------------------------------------------------------
2146 status_t BMessage::FindString(const char *name, const char **string) const
2147 {
2148 	return FindData(name, B_STRING_TYPE, (const void**)string, NULL);
2149 }
2150 //------------------------------------------------------------------------------
2151 //status_t BMessage::FindString ( const char *name, int32 index,
2152 //CString *string ) const;
2153 //------------------------------------------------------------------------------
2154 //status_t BMessage::FindString ( const char *name, CString *string ) const;
2155 //------------------------------------------------------------------------------
2156 status_t BMessage::FindInt8(const char *name, int8 *anInt8) const
2157 {
2158 	entry_hdr *entry = entry_find(name, B_INT8_TYPE);
2159 
2160 	if (entry == NULL)
2161 		return B_NAME_NOT_FOUND;
2162 
2163 	*anInt8 = *(int8*)da_first_chunk(entry);
2164 
2165 	return B_OK;
2166 }
2167 //------------------------------------------------------------------------------
2168 status_t BMessage::FindInt8(const char *name, int32 index, int8 *anInt8) const
2169 {
2170 	entry_hdr *entry = entry_find(name, B_INT8_TYPE);
2171 
2172 	if (entry == NULL)
2173 		return B_NAME_NOT_FOUND;
2174 
2175 	if (index < entry->fCount)
2176 	{
2177 		int8* data = (int8*)da_first_chunk(entry);
2178 		*anInt8 = data[index];
2179 
2180 		return B_OK;
2181 	}
2182 
2183 	return B_BAD_INDEX;
2184 }
2185 //------------------------------------------------------------------------------
2186 status_t BMessage::FindInt16(const char *name, int16 *anInt16) const
2187 {
2188 	entry_hdr *entry = entry_find(name, B_INT16_TYPE);
2189 
2190 	if (entry == NULL)
2191 		return B_NAME_NOT_FOUND;
2192 
2193 	*anInt16 = *(int16*)da_first_chunk(entry);
2194 
2195 	return B_OK;
2196 }
2197 //------------------------------------------------------------------------------
2198 status_t BMessage::FindInt16(const char *name, int32 index, int16 *anInt16) const
2199 {
2200 	entry_hdr *entry = entry_find(name, B_INT16_TYPE);
2201 
2202 	if (entry == NULL)
2203 		return B_NAME_NOT_FOUND;
2204 
2205 	if (index < entry->fCount)
2206 	{
2207 		int16* data = (int16*)da_first_chunk(entry);
2208 		*anInt16 = data[index];
2209 
2210 		return B_OK;
2211 	}
2212 
2213 	return B_BAD_INDEX;
2214 }
2215 //------------------------------------------------------------------------------
2216 status_t BMessage::FindInt32(const char *name, int32 *anInt32) const
2217 {
2218 	entry_hdr *entry = entry_find(name, B_INT32_TYPE);
2219 
2220 	if (entry == NULL)
2221 		return B_NAME_NOT_FOUND;
2222 
2223 	*anInt32 = *(int32*)da_first_chunk(entry);
2224 
2225 	return B_OK;
2226 }
2227 //------------------------------------------------------------------------------
2228 status_t BMessage::FindInt32(const char *name, int32 index,
2229 							 int32 *anInt32) const
2230 {
2231 	entry_hdr *entry = entry_find(name, B_INT32_TYPE);
2232 
2233 	if (entry == NULL)
2234 		return B_NAME_NOT_FOUND;
2235 
2236 	if (index < entry->fCount)
2237 	{
2238 		int32* data = (int32*)da_first_chunk(entry);
2239 		*anInt32 = data[index];
2240 
2241 		return B_OK;
2242 	}
2243 
2244 	return B_BAD_INDEX;
2245 }
2246 //------------------------------------------------------------------------------
2247 //status_t BMessage::FindInt64 ( const char *name, int64 *anInt64) const;
2248 //------------------------------------------------------------------------------
2249 //status_t BMessage::FindInt64 ( const char *name, int32 index,
2250 //							  int64 *anInt64 ) const;
2251 //------------------------------------------------------------------------------
2252 status_t BMessage::FindBool(const char *name, bool *aBool) const
2253 {
2254 	entry_hdr *entry = entry_find(name, B_BOOL_TYPE);
2255 
2256 	if (entry == NULL)
2257 		return B_NAME_NOT_FOUND;
2258 
2259 	*aBool = *(bool*)da_first_chunk(entry);
2260 
2261 	return B_OK;
2262 }
2263 //------------------------------------------------------------------------------
2264 status_t BMessage::FindBool(const char *name, int32 index, bool *aBool) const
2265 {
2266 	entry_hdr *entry = entry_find(name, B_BOOL_TYPE);
2267 
2268 	if (entry == NULL)
2269 		return B_NAME_NOT_FOUND;
2270 
2271 	if (index < entry->fCount)
2272 	{
2273 		bool* data = (bool*)da_first_chunk(entry);
2274 		*aBool = data[index];
2275 
2276 		return B_OK;
2277 	}
2278 
2279 	return B_BAD_INDEX;
2280 }
2281 //------------------------------------------------------------------------------
2282 status_t BMessage::FindFloat(const char *name, float *aFloat) const
2283 {
2284 	entry_hdr *entry = entry_find(name, B_FLOAT_TYPE);
2285 
2286 	if (entry == NULL)
2287 		return B_NAME_NOT_FOUND;
2288 
2289 	*aFloat = *(float*)da_first_chunk(entry);
2290 
2291 	return B_OK;
2292 }
2293 //------------------------------------------------------------------------------
2294 status_t BMessage::FindFloat(const char *name, int32 index, float *aFloat) const
2295 {
2296 	entry_hdr *entry = entry_find(name, B_FLOAT_TYPE);
2297 
2298 	if (entry == NULL)
2299 		return B_NAME_NOT_FOUND;
2300 
2301 	if (index < entry->fCount)
2302 	{
2303 		float* data = (float*)da_first_chunk(entry);
2304 		*aFloat = data[index];
2305 
2306 		return B_OK;
2307 	}
2308 
2309 	return B_BAD_INDEX;
2310 }
2311 //------------------------------------------------------------------------------
2312 status_t BMessage::FindDouble(const char *name, double *aDouble) const
2313 {
2314 	entry_hdr *entry = entry_find(name, B_DOUBLE_TYPE);
2315 
2316 	if (entry == NULL)
2317 		return B_NAME_NOT_FOUND;
2318 
2319 	*aDouble = *(double*)da_first_chunk(entry);
2320 
2321 	return B_OK;
2322 }
2323 //------------------------------------------------------------------------------
2324 status_t BMessage::FindDouble(const char *name, int32 index,
2325 							  double *aDouble) const
2326 {
2327 	entry_hdr *entry = entry_find(name, B_DOUBLE_TYPE);
2328 
2329 	if (entry == NULL)
2330 		return B_NAME_NOT_FOUND;
2331 
2332 	if (index < entry->fCount)
2333 	{
2334 		double* data = (double*)da_first_chunk(entry);
2335 		*aDouble = data[index];
2336 
2337 		return B_OK;
2338 	}
2339 
2340 	return B_BAD_INDEX;
2341 }
2342 //------------------------------------------------------------------------------
2343 status_t BMessage::FindPointer(const char *name, void **pointer) const
2344 {
2345 	entry_hdr *entry = entry_find(name, B_POINTER_TYPE);
2346 
2347 	if (entry == NULL)
2348 	{
2349 		*pointer = NULL;
2350 		return B_NAME_NOT_FOUND;
2351 	}
2352 
2353 	*pointer = *(void**)da_first_chunk(entry);
2354 
2355 	return B_OK;
2356 }
2357 //------------------------------------------------------------------------------
2358 status_t BMessage::FindPointer(const char *name, int32 index,
2359 							   void **pointer) const
2360 {
2361 	entry_hdr *entry = entry_find(name, B_POINTER_TYPE);
2362 
2363 	if (entry == NULL)
2364 	{
2365 		*pointer = NULL;
2366 		return B_NAME_NOT_FOUND;
2367 	}
2368 
2369 	if (index >= entry->fCount)
2370 	{
2371 		*pointer = NULL;
2372 		return B_BAD_INDEX;
2373 	}
2374 
2375 	void** data = (void**)da_first_chunk(entry);
2376 	*pointer = data[index];
2377 
2378 	return B_OK;
2379 }
2380 //------------------------------------------------------------------------------
2381 //status_t BMessage::FindMessenger ( const char *name, CMessenger *messenger ) const;
2382 //------------------------------------------------------------------------------
2383 //status_t BMessage::FindMessenger ( const char *name, int32 index, CMessenger *messenger ) const;
2384 //------------------------------------------------------------------------------
2385 //status_t BMessage::FindRef ( const char *name, entry_ref *ref ) const;
2386 //------------------------------------------------------------------------------
2387 //status_t BMessage::FindRef ( const char *name, int32 index, entry_ref *ref ) const;
2388 //------------------------------------------------------------------------------
2389 status_t BMessage::FindMessage(const char *name, BMessage *message) const
2390 {
2391 	const char *data;
2392 
2393 	if ( FindData(name, B_MESSAGE_TYPE, (const void**)&data, NULL) != B_OK)
2394 		return B_NAME_NOT_FOUND;
2395 
2396 	return message->Unflatten(data);
2397 }
2398 //------------------------------------------------------------------------------
2399 status_t BMessage::FindMessage(const char *name, int32 index,
2400 							   BMessage *message) const
2401 {
2402 	const char *data;
2403 
2404 	if ( FindData(name, B_MESSAGE_TYPE, index, (const void**)&data,
2405 		NULL) != B_OK)
2406 		return B_NAME_NOT_FOUND;
2407 
2408 	return message->Unflatten(data);
2409 }
2410 //------------------------------------------------------------------------------
2411 status_t BMessage::FindFlat(const char *name, BFlattenable *object) const
2412 {
2413 	status_t ret;
2414 	const void *data;
2415 	ssize_t numBytes;
2416 
2417 	ret = FindData(name, object->TypeCode (), &data, &numBytes);
2418 
2419 	if ( ret != B_OK )
2420 		return ret;
2421 
2422 	if ( object->Unflatten(object->TypeCode (), data, numBytes) != B_OK)
2423 		return B_BAD_VALUE;
2424 
2425 	return B_OK;
2426 }
2427 //------------------------------------------------------------------------------
2428 status_t BMessage::FindFlat(const char *name, int32 index,
2429 							BFlattenable *object) const
2430 {
2431 	status_t ret;
2432 	const void *data;
2433 	ssize_t numBytes;
2434 
2435 	ret = FindData(name, object->TypeCode(), index, &data, &numBytes);
2436 
2437 	if (ret != B_OK)
2438 		return ret;
2439 
2440 	if (object->Unflatten(object->TypeCode(), data, numBytes) != B_OK)
2441 		return B_BAD_VALUE;
2442 
2443 	return B_OK;
2444 }
2445 //------------------------------------------------------------------------------
2446 status_t BMessage::FindData(const char *name, type_code type, const void **data,
2447 							ssize_t *numBytes) const
2448 {
2449 	entry_hdr *entry = entry_find(name, type);
2450 
2451 	if (entry == NULL)
2452 	{
2453 		*data = NULL;
2454 		return B_NAME_NOT_FOUND;
2455 	}
2456 
2457 	int32 size;
2458 
2459 	*data = da_find_data(entry, 0, &size);
2460 
2461 	if (numBytes)
2462 		*numBytes = size;
2463 
2464 	return B_OK;
2465 }
2466 //------------------------------------------------------------------------------
2467 status_t BMessage::FindData(const char *name, type_code type, int32 index,
2468 							const void **data, ssize_t *numBytes) const
2469 {
2470 	entry_hdr *entry = entry_find(name, type);
2471 
2472 	if (entry == NULL)
2473 	{
2474 		*data = NULL;
2475 		return B_NAME_NOT_FOUND;
2476 	}
2477 
2478 	if (index >= entry->fCount)
2479 	{
2480 		*data = NULL;
2481 		return B_BAD_INDEX;
2482 	}
2483 
2484 	int32 size;
2485 
2486 	*data = da_find_data(entry, index, &size);
2487 
2488 	if (numBytes)
2489 		*numBytes = size;
2490 
2491 	return B_OK;
2492 }
2493 //------------------------------------------------------------------------------
2494 //status_t BMessage::ReplaceRect(const char *name, BRect rect);
2495 //------------------------------------------------------------------------------
2496 //status_t BMessage::ReplaceRect(const char *name, int32 index, BRect rect);
2497 //------------------------------------------------------------------------------
2498 status_t BMessage::ReplacePoint(const char *name, BPoint point)
2499 {
2500 	return ReplaceData(name, B_POINT_TYPE, &point, sizeof(BPoint));
2501 }
2502 //------------------------------------------------------------------------------
2503 //status_t BMessage::ReplacePoint(const char *name, int32 index, BPoint point);
2504 //------------------------------------------------------------------------------
2505 status_t BMessage::ReplaceString(const char *name, const char *string)
2506 {
2507 	return B_ERROR;
2508 }
2509 //------------------------------------------------------------------------------
2510 //status_t BMessage::ReplaceString(const char *name, int32 index,
2511 //								 const char *string);
2512 //------------------------------------------------------------------------------
2513 //status_t BMessage::ReplaceString(const char *name, CString &string);
2514 //------------------------------------------------------------------------------
2515 //status_t BMessage::ReplaceString(const char *name, int32 index, CString &string);
2516 //------------------------------------------------------------------------------
2517 status_t BMessage::ReplaceInt8(const char *name, int8 anInt8)
2518 {
2519 	return ReplaceData(name, B_INT8_TYPE, &anInt8, sizeof(int8));
2520 }
2521 //------------------------------------------------------------------------------
2522 //status_t BMessage::ReplaceInt8(const char *name, int32 index, int8 anInt8);
2523 //------------------------------------------------------------------------------
2524 //status_t BMessage::ReplaceInt16(const char *name, int16 anInt16);
2525 //------------------------------------------------------------------------------
2526 //status_t BMessage::ReplaceInt16(const char *name, int32 index, int16 anInt16);
2527 //------------------------------------------------------------------------------
2528 status_t BMessage::ReplaceInt32(const char *name, long anInt32)
2529 {
2530 	return ReplaceData(name, B_INT32_TYPE, &anInt32, sizeof(int32));
2531 }
2532 //------------------------------------------------------------------------------
2533 //status_t BMessage::ReplaceInt32(const char *name, int32 index, int32 anInt32);
2534 //------------------------------------------------------------------------------
2535 status_t BMessage::ReplaceInt64(const char *name, int64 anInt64)
2536 {
2537 	return ReplaceData(name, B_INT64_TYPE, &anInt64, sizeof(int64));
2538 }
2539 //------------------------------------------------------------------------------
2540 //status_t BMessage::ReplaceInt64(const char *name, int32 index, int64 anInt64);
2541 //------------------------------------------------------------------------------
2542 //status_t BMessage::ReplaceBool(const char *name, bool aBool);
2543 //------------------------------------------------------------------------------
2544 //status_t BMessage::ReplaceBool(const char *name, int32 index, bool aBool);
2545 //------------------------------------------------------------------------------
2546 //status_t BMessage::ReplaceFloat(const char *name, float aFloat);
2547 //------------------------------------------------------------------------------
2548 //status_t BMessage::ReplaceFloat(const char *name, int32 index, float aFloat);
2549 //------------------------------------------------------------------------------
2550 //status_t BMessage::ReplaceDouble(const char *name, double aDouble);
2551 //------------------------------------------------------------------------------
2552 //status_t BMessage::ReplaceDouble(const char *name, int32 index, double aDouble);
2553 //------------------------------------------------------------------------------
2554 //status_t BMessage::ReplacePointer(const char *name, const void *pointer);
2555 //------------------------------------------------------------------------------
2556 //status_t BMessage::ReplacePointer(const char *name, int32 index,
2557 //								  const void *pointer);
2558 //------------------------------------------------------------------------------
2559 //status_t BMessage::ReplaceMessenger(const char *name, BMessenger messenger);
2560 //------------------------------------------------------------------------------
2561 //status_t BMessage::ReplaceMessenger(const char *name, int32 index,
2562 //									BMessenger messenger);
2563 //------------------------------------------------------------------------------
2564 //status_t BMessage::ReplaceRef(const char *name, entry_ref *ref);
2565 //------------------------------------------------------------------------------
2566 //status_t BMessage::ReplaceRef(const char *name, int32 index, entry_ref *ref);
2567 //------------------------------------------------------------------------------
2568 //status_t ReplaceMessage(const char *name, const BMessage *msg);
2569 //------------------------------------------------------------------------------
2570 //status_t ReplaceMessage(const char *name, int32 index, const BMessage *msg);
2571 //------------------------------------------------------------------------------
2572 //status_t BMessage::ReplaceFlat(const char *name, BFlattenable *object);
2573 //------------------------------------------------------------------------------
2574 //status_t BMessage::ReplaceFlat(const char *name, int32 index,
2575 //							   BFlattenable *object);
2576 //------------------------------------------------------------------------------
2577 status_t BMessage::ReplaceData(const char *name, type_code type,
2578 							   const void *data, ssize_t numBytes)
2579 {
2580 	entry_hdr *entry = entry_find(name, type);
2581 
2582 	if (entry == NULL)
2583 		return B_NAME_NOT_FOUND;
2584 
2585 	if (entry->fType != type)
2586 		return B_BAD_TYPE;
2587 
2588 	da_replace_data((dyn_array**)&entry, 0, data, numBytes);
2589 
2590 	return B_OK;
2591 }
2592 //------------------------------------------------------------------------------
2593 //status_t BMessage::ReplaceData(const char *name, type_code type, int32 index,
2594 //							   const void *data, size_t numBytes);
2595 //------------------------------------------------------------------------------
2596 //void *BMessage::operator new(size_t numBytes);
2597 //------------------------------------------------------------------------------
2598 //void BMessage::operator delete(void *memory, size_t numBytes);
2599 //------------------------------------------------------------------------------
2600 /*bool		HasRect(const char *, int32 n = 0) const;
2601 bool		HasPoint(const char *, int32 n = 0) const;
2602 bool		HasString(const char *, int32 n = 0) const;
2603 bool		HasInt8(const char *, int32 n = 0) const;
2604 bool		HasInt16(const char *, int32 n = 0) const;
2605 bool		HasInt32(const char *, int32 n = 0) const;
2606 bool		HasInt64(const char *, int32 n = 0) const;
2607 bool		HasBool(const char *, int32 n = 0) const;
2608 bool		HasFloat(const char *, int32 n = 0) const;
2609 bool		HasDouble(const char *, int32 n = 0) const;
2610 bool		HasPointer(const char *, int32 n = 0) const;
2611 bool		HasMessenger(const char *, int32 n = 0) const;
2612 bool		HasRef(const char *, int32 n = 0) const;
2613 bool		HasMessage(const char *, int32 n = 0) const;
2614 bool		HasFlat(const char *, const BFlattenable *) const;
2615 bool		HasFlat(const char *,int32 ,const BFlattenable *) const;
2616 bool		HasData(const char *, type_code , int32 n = 0) const;
2617 BRect		FindRect(const char *, int32 n = 0) const;
2618 BPoint		FindPoint(const char *, int32 n = 0) const;
2619 const char	*FindString(const char *, int32 n = 0) const;
2620 int8		FindInt8(const char *, int32 n = 0) const;
2621 int16		FindInt16(const char *, int32 n = 0) const;*/
2622 //------------------------------------------------------------------------------
2623 int32 BMessage::FindInt32(const char *name, int32 index) const
2624 {
2625 	int32 anInt32 = 0;
2626 
2627 	BMessage::FindInt32(name, index, &anInt32);
2628 
2629 	return anInt32;
2630 }
2631 //------------------------------------------------------------------------------
2632 /*int64		FindInt64(const char *, int32 n = 0) const;
2633 bool		FindBool(const char *, int32 n = 0) const;
2634 float		FindFloat(const char *, int32 n = 0) const;
2635 double		FindDouble(const char *, int32 n = 0) const;*/
2636 //------------------------------------------------------------------------------
2637 BMessage::BMessage(BMessage *a_message)
2638 {
2639 	*this=*a_message;
2640 }
2641 //------------------------------------------------------------------------------
2642 void BMessage::_ReservedMessage1() {}
2643 void BMessage::_ReservedMessage2() {}
2644 void BMessage::_ReservedMessage3() {}
2645 //------------------------------------------------------------------------------
2646 void BMessage::init_data()
2647 {
2648 	what = 0;
2649 
2650 	link = NULL;
2651 	fTarget = -1;
2652 	fOriginal = NULL;
2653 	fChangeCount = 0;
2654 	fCurSpecifier = -1;
2655 	fPtrOffset = 0;
2656 
2657 	fEntries = NULL;
2658 
2659 	fReplyTo.port = -1;
2660 	fReplyTo.target = -1;
2661 	fReplyTo.team = -1;
2662 	fReplyTo.preferred = false;
2663 
2664 	fPreferred = false;
2665 	fReplyRequired = false;
2666 	fReplyDone = false;
2667 	fIsReply = false;
2668 	fWasDelivered = false;
2669 	fReadOnly = false;
2670 	fHasSpecifiers = false;
2671 }
2672 //------------------------------------------------------------------------------
2673 //	These are not declared in the header anymore and aren't actually used by the
2674 //	"old" implementation.
2675 #if 0
2676 int32 BMessage::flatten_hdr(uchar *result, ssize_t size, uchar flags) const
2677 {
2678 	return -1;
2679 }
2680 //------------------------------------------------------------------------------
2681 status_t BMessage::real_flatten(char *result, ssize_t size, uchar flags) const
2682 {
2683 	return B_ERROR;
2684 }
2685 //------------------------------------------------------------------------------
2686 status_t BMessage::real_flatten(BDataIO *stream, ssize_t size,
2687 								uchar flags) const
2688 {
2689 	return B_ERROR;
2690 }
2691 #endif
2692 //------------------------------------------------------------------------------
2693 char *BMessage::stack_flatten(char *stack_ptr, ssize_t stack_size,
2694 							  bool incl_reply, ssize_t *size) const
2695 {
2696 	return NULL;
2697 }
2698 //------------------------------------------------------------------------------
2699 ssize_t BMessage::calc_size(uchar flags) const
2700 {
2701 	return -1;
2702 }
2703 //------------------------------------------------------------------------------
2704 ssize_t BMessage::calc_hdr_size(uchar flags) const
2705 {
2706 	return -1;
2707 }
2708 //------------------------------------------------------------------------------
2709 ssize_t BMessage::min_hdr_size() const
2710 {
2711 	return -1;
2712 }
2713 //------------------------------------------------------------------------------
2714 status_t BMessage::nfind_data(const char *name, type_code type, int32 index,
2715 							  const void **data, ssize_t *data_size) const
2716 {
2717 	return B_ERROR;
2718 }
2719 //------------------------------------------------------------------------------
2720 status_t BMessage::copy_data(const char *name, type_code type, int32 index,
2721 							 void *data, ssize_t data_size) const
2722 {
2723 	return B_ERROR;
2724 }
2725 //------------------------------------------------------------------------------
2726 status_t BMessage::_send_(port_id port, int32 token, bool preferred,
2727 						  bigtime_t timeout, bool reply_required,
2728 						  BMessenger &reply_to) const
2729 {
2730 	/*_set_message_target_(this, token, preferred);
2731 	_set_message_reply_(this, reply_to);
2732 
2733 	int32 size;
2734 	char *buffer;
2735 
2736 	write_port_etc(port, what, buffer, size, B_TIMEOUT, timeout);*/
2737 
2738 	return B_ERROR;
2739 }
2740 //------------------------------------------------------------------------------
2741 status_t BMessage::send_message(port_id port, team_id port_owner, int32 token,
2742 								bool preferred, BMessage *reply,
2743 								bigtime_t send_timeout,
2744 								bigtime_t reply_timeout) const
2745 {
2746 	return B_ERROR;
2747 }
2748 //------------------------------------------------------------------------------
2749 BMessage::entry_hdr * BMessage::entry_find(const char *name, uint32 type,
2750 											status_t *result) const
2751 {
2752 	for (entry_hdr *entry = fEntries; entry != NULL; entry = entry->fNext)
2753 		if (entry->fType ==type && entry->fNameLength == strlen(name) &&
2754 			strncmp(entry->fName, name, entry->fNameLength) == 0)
2755 		{
2756 			if (result)
2757 				*result = B_OK;
2758 
2759 			return entry;
2760 		}
2761 
2762 	if (result)
2763 		*result = B_NAME_NOT_FOUND;
2764 
2765 	return NULL;
2766 }
2767 //------------------------------------------------------------------------------
2768 void BMessage::entry_remove(entry_hdr *entry)
2769 {
2770 	if (entry == fEntries)
2771 		fEntries = entry->fNext;
2772 	else
2773 	{
2774 		for (entry_hdr *entry_ptr = fEntries; entry_ptr != NULL; entry_ptr = entry_ptr->fNext)
2775 			if (entry_ptr->fNext == entry)
2776 				entry_ptr->fNext = entry->fNext;
2777 	}
2778 }
2779 //------------------------------------------------------------------------------
2780 void *BMessage::da_create(int32 header_size, int32 chunk_size, bool fixed,
2781 						  int32 nchunks)
2782 {
2783 	int size = da_calc_size(header_size, chunk_size, fixed, nchunks);
2784 
2785 	dyn_array *da = (dyn_array*)new char[size];
2786 
2787 	da->fLogicalBytes = 0;
2788 	da->fPhysicalBytes = size - sizeof(dyn_array) - header_size;
2789 
2790 	if ( fixed )
2791 		da->fChunkSize = chunk_size;
2792 	else
2793 		da->fChunkSize = 0;
2794 
2795 	da->fCount = 0;
2796 	da->fEntryHdrSize = header_size;
2797 
2798 	return da;
2799 }
2800 //------------------------------------------------------------------------------
2801 status_t BMessage::da_add_data(dyn_array **da, const void *data, int32 size )
2802 {
2803 //	_ASSERT(_CrtCheckMemory());
2804 
2805 	int32 new_size = (*da)->fLogicalBytes + ((*da)->fChunkSize ? (*da)->fChunkSize :
2806 		da_pad_8(size + da_chunk_hdr_size()));
2807 
2808 	if (new_size > (*da)->fPhysicalBytes)
2809 		da_grow(da, new_size - (*da)->fPhysicalBytes);
2810 
2811 	void *ptr = da_find_data(*da, (*da)->fCount++, NULL);
2812 
2813 	memcpy(ptr, data, size);
2814 
2815 	if ((*da)->fChunkSize)
2816 		(*da)->fLogicalBytes += size;
2817 	else
2818 	{
2819 		da_chunk_ptr(ptr)->fDataSize = size;
2820 		(*da)->fLogicalBytes += da_chunk_size(da_chunk_ptr(ptr));
2821 	}
2822 
2823 //	_ASSERT(_CrtCheckMemory());
2824 
2825 	return B_OK;
2826 }
2827 //------------------------------------------------------------------------------
2828 void *BMessage::da_find_data(dyn_array *da, int32 index, int32 *size) const
2829 {
2830 	if (da->fChunkSize)
2831 	{
2832 		if (size)
2833 			*size = da->fChunkSize;
2834 
2835 		return (char*)da_start_of_data(da) + index * da->fChunkSize;
2836 	}
2837 	else
2838 	{
2839 		var_chunk *chunk = da_first_chunk(da);
2840 
2841 		for (int i = 0; i < index; i++)
2842 			chunk = da_next_chunk(chunk);
2843 
2844 		if (size)
2845 			*size = chunk->fDataSize;
2846 
2847 		return chunk->fData;
2848 	}
2849 }
2850 //------------------------------------------------------------------------------
2851 status_t BMessage::da_delete_data(dyn_array **pda, int32 index)
2852 {
2853 	return 0;
2854 }
2855 //------------------------------------------------------------------------------
2856 status_t BMessage::da_replace_data(dyn_array **pda, int32 index,
2857 								   const void *data, int32 dsize)
2858 {
2859 	void *ptr = da_find_data(*pda, index, NULL);
2860 
2861 	memcpy(ptr, data, dsize);
2862 
2863 	return B_OK;
2864 }
2865 //------------------------------------------------------------------------------
2866 int32 BMessage::da_calc_size(int32 hdr_size, int32 chunksize, bool is_fixed,
2867 							  int32 nchunks) const
2868 {
2869 	int size = sizeof(dyn_array) + hdr_size;
2870 
2871 	if (is_fixed)
2872 		size += chunksize * nchunks;
2873 	else
2874 		size += (chunksize + da_chunk_hdr_size()) * nchunks;
2875 
2876 	return size;
2877 }
2878 //------------------------------------------------------------------------------
2879 void *BMessage::da_grow(dyn_array **pda, int32 increase)
2880 {
2881 	dyn_array *da = (dyn_array*)new char[da_total_size(*pda) + increase];
2882 	dyn_array *old_da = *pda;
2883 
2884 	memcpy(da, *pda, da_total_size(*pda));
2885 
2886 	*pda = da;
2887 	(*pda)->fPhysicalBytes += increase;
2888 
2889 	entry_remove((entry_hdr*)old_da);
2890 
2891 	delete old_da;
2892 
2893 	((entry_hdr*)*pda)->fNext = fEntries;
2894 	fEntries = (entry_hdr*)*pda;
2895 
2896 	return *pda;
2897 }
2898 //------------------------------------------------------------------------------
2899 void BMessage::da_dump(dyn_array *da)
2900 {
2901 	entry_hdr *entry = (entry_hdr*)da;
2902 
2903 	printf("\tLogicalBytes=%d\n\tPhysicalBytes=%d\n\tChunkSize=%d\n\tCount=%d\n\tEntryHdrSize=%d\n",
2904 		entry->fLogicalBytes, entry->fPhysicalBytes, entry->fChunkSize, entry->fCount,
2905 		entry->fEntryHdrSize);
2906 	printf("\tNext=%p\n\tType=%c%c%c%c\n\tNameLength=%d\n\tName=%s\n",
2907 		entry->fNext, (entry->fType & 0xFF000000) >> 24, (entry->fType & 0x00FF0000) >> 16,
2908 			(entry->fType & 0x0000FF00) >> 8, entry->fType & 0x000000FF, entry->fNameLength,
2909 			entry->fName);
2910 
2911 	printf("\tData=");
2912 
2913 	switch (entry->fType)
2914 	{
2915 		case B_BOOL_TYPE:
2916 		{
2917 			printf("%s", *(bool*)da_find_data(entry, 0, NULL) ? "true" : "false");
2918 
2919 			for (int i = 1; i < entry->fCount; i++)
2920 				printf(", %s", *(bool*)da_find_data ( entry, i, NULL ) ? "true" : "false");
2921 			break;
2922 		}
2923 		case B_INT32_TYPE:
2924 		{
2925 			printf("%d", *(int32*)da_find_data(entry, 0, NULL));
2926 
2927 			for (int i = 1; i < entry->fCount; i++)
2928 				printf(", %d", *(int32*)da_find_data(entry, i, NULL));
2929 			break;
2930 		}
2931 		case B_FLOAT_TYPE:
2932 		{
2933 			printf("%f", *(float*)da_find_data(entry, 0, NULL));
2934 
2935 			for (int i = 1; i < entry->fCount; i++)
2936 				printf(", %f", *(float*)da_find_data ( entry, i, NULL));
2937 			break;
2938 		}
2939 		case B_STRING_TYPE:
2940 		{
2941 			printf("%s", da_find_data(entry, 0, NULL));
2942 
2943 			for (int i = 1; i < entry->fCount; i++)
2944 				printf(", %s", da_find_data(entry, i, NULL));
2945 			break;
2946 		}
2947 		case B_POINT_TYPE:
2948 		{
2949 			float *data = (float*)da_find_data(entry, 0, NULL);
2950 
2951 			printf("[%f,%f]", data[0], data[1]);
2952 
2953 			for (int i = 1; i < entry->fCount; i++)
2954 			{
2955 				data = (float*)da_find_data ( entry, i, NULL);
2956 				printf(", [%f,%f]", data[0], data[1]);
2957 			}
2958 			break;
2959 		}
2960 		case B_RECT_TYPE:
2961 		{
2962 			float *data = (float*)da_find_data(entry, 0, NULL);
2963 
2964 			printf("[%f,%f,%f,%f]", data[0], data[1], data[2], data[3]);
2965 
2966 			for (int i = 1; i < entry->fCount; i++)
2967 			{
2968 				data = (float*)da_find_data ( entry, i, NULL);
2969 				printf(", [%f,%f,%f,%f]", data[0], data[1], data[2], data[3]);
2970 			}
2971 			break;
2972 		}
2973 	}
2974 
2975 	printf("\n");
2976 }
2977 //------------------------------------------------------------------------------
2978 void BMessage::da_swap_var_sized(dyn_array *da)
2979 {
2980 }
2981 //------------------------------------------------------------------------------
2982 void BMessage::da_swap_fixed_sized(dyn_array *da)
2983 {
2984 }
2985 //------------------------------------------------------------------------------
2986 
2987 #endif	// USING_TEMPLATE_MADNESS
2988