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