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: PortLink.cpp 23 // Author: DarkWyrm <bpmagic@columbus.rr.com> 24 // Description: A helper class for port-based messaging 25 // 26 //------------------------------------------------------------------------------ 27 #include <PortLink.h> 28 #include <PortMessage.h> 29 #include <string.h> 30 #include <stdio.h> 31 #include <malloc.h> 32 33 //#define PLDEBUG 34 //#define PLD_DEBUG 35 36 //#define CAPACITY_CHECKING 37 38 #ifdef PLDEBUG 39 #include <stdio.h> 40 #endif 41 42 #ifdef PLD_DEBUG 43 #include <stdio.h> 44 #endif 45 46 /*! 47 \class PortLinkData PortLink.cpp 48 \brief Internal data storage class 49 50 PortLinkData objects serve to hold attached data whilst it is waiting to be Flattened() 51 and then Flushed(). There is no need for this to be used outside the PortLink class. 52 */ 53 class PortLinkData 54 { 55 public: 56 PortLinkData(void); 57 ~PortLinkData(void); 58 status_t Set(const void *data, size_t size); 59 char *buffer; 60 size_t buffersize; 61 }; 62 63 /*! 64 \brief Constructor 65 \param port A valid target port_id 66 */ 67 PortLink::PortLink(port_id port) 68 { 69 #ifdef PLDEBUG 70 printf("PortLink(%lu)\n",port); 71 #endif 72 target=port; 73 port_info pi; 74 port_ok=(get_port_info(target,&pi)==B_OK)?true:false; 75 capacity=pi.capacity; 76 77 // We start out without any data attached to the port message 78 opcode=0; 79 bufferlength=0; 80 replyport=create_port(30,"PortLink reply port"); 81 attachlist=new BList(0); 82 #ifdef PLDEBUG 83 printf("\tPort valid: %s\n",(port_ok)?"true":"false"); 84 printf("\tReply port: %lu\n",replyport); 85 #endif 86 87 // TODO: initialize all attachments pointers to NULL 88 } 89 90 /*! 91 \brief Copy Constructor 92 \param port A valid target port_id 93 94 The copy constructor copies everything except a PortLink's attachments. 95 */ 96 PortLink::PortLink(const PortLink &link) 97 { 98 #ifdef PLDEBUG 99 printf("PortLink(PortLink*)\n"); 100 #endif 101 target=link.target; 102 opcode=link.opcode; 103 port_ok=link.port_ok; 104 capacity=link.capacity; 105 bufferlength=0; 106 replyport=create_port(30,"PortLink reply port"); 107 attachlist=new BList(0); 108 #ifdef PLDEBUG 109 printf("\tOpcode: %lu\n",opcode); 110 printf("\tTarget port: %lu\n",target); 111 printf("\tCapacity: %lu\n",capacity); 112 printf("\tPort valid: %s\n",(port_ok)?"true":"false"); 113 printf("\tReply port: %lu\n",replyport); 114 #endif 115 // TODO: initialize all attachments pointers to NULL 116 } 117 118 //! Empties all attachments in addition to deleting the attachment list itself 119 PortLink::~PortLink(void) 120 { 121 #ifdef PLDEBUG 122 printf("~PortLink()\n"); 123 #endif 124 // If, for some odd reason, this is deleted with something attached, 125 // free the memory used by the attachments. We do not flush the queue 126 // because the port may no longer be valid in cases such as the app 127 // is in the process of quitting 128 if(attachlist->CountItems()>0) 129 MakeEmpty(); 130 131 delete attachlist; 132 } 133 134 /*! 135 \brief Sets the link's message code 136 \param code Message code to use 137 138 This code is persistent over sending messages - it will not change unless 139 SetOpCode is called again. 140 */ 141 void PortLink::SetOpCode(int32 code) 142 { 143 #ifdef PLDEBUG 144 printf("PortLink::SetOpCode(%c%c%c%c)\n", 145 (char)((code & 0xFF000000) >> 24), 146 (char)((code & 0x00FF0000) >> 16), 147 (char)((code & 0x0000FF00) >> 8), 148 (char)((code & 0x000000FF)) ); 149 #endif 150 // Sets the message code. This does not change once the message is sent. 151 // Another call to SetOpCode() is required for such things. 152 opcode=code; 153 } 154 155 /*! 156 \brief Changes the PortLink's target port 157 \param port A valid target port_id 158 */ 159 void PortLink::SetPort(port_id port) 160 { 161 #ifdef PLDEBUG 162 printf("PortLink::SetPort(%lu)\n",port); 163 #endif 164 // Sets the target port. While not necessary in most uses, this exists 165 // mostly to prevent flexibility problems 166 target=port; 167 port_info pi; 168 port_ok=(get_port_info(target,&pi)==B_OK)?true:false; 169 capacity=pi.capacity; 170 } 171 172 /*! 173 \brief Returns the PortLink's target port 174 \return The PortLink's target port 175 */ 176 port_id PortLink::GetPort(void) 177 { 178 #ifdef PLDEBUG 179 printf("PortLink::GetPort() returned %lu\n",target); 180 #endif 181 // Simply returns the port at which the object is pointed. 182 return target; 183 } 184 185 status_t PortLink::Flush(bigtime_t timeout=B_INFINITE_TIMEOUT) 186 { 187 #ifdef PLDEBUG 188 printf("PortLink::Flush()\n"); 189 #endif 190 // Fires a message off to the target, complete with attachments. 191 int8 *msgbuffer; 192 int32 size; 193 status_t write_stat=B_OK; 194 195 if(!port_ok) 196 { 197 #ifdef PLDEBUG 198 printf("\tFlush(): invalid port\n"); 199 #endif 200 return B_BAD_VALUE; 201 } 202 203 if(attachlist->CountItems()>0) 204 { 205 #ifdef PLDEBUG 206 printf("\tFlush(): flushing %d attachments\n",num_attachments); 207 #endif 208 FlattenData(&msgbuffer,&size); 209 210 // Dump message to port, reset attachments, and clean up 211 if(timeout!=B_INFINITE_TIMEOUT) 212 write_stat=write_port_etc(target,opcode,msgbuffer,size,B_TIMEOUT, timeout); 213 else 214 write_stat=write_port(target,opcode,msgbuffer,size); 215 MakeEmpty(); 216 } 217 else 218 { 219 #ifdef PLDEBUG 220 printf("\tFlush(): flushing without attachments\n"); 221 #endif 222 if(timeout!=B_INFINITE_TIMEOUT) 223 write_stat=write_port_etc(target,opcode,NULL,0,B_TIMEOUT, timeout); 224 else 225 write_stat=write_port(target,opcode,NULL,0); 226 } 227 return write_stat; 228 } 229 230 231 int8* PortLink::FlushWithReply(int32 *code, status_t *status, ssize_t *buffersize, bigtime_t timeout=B_INFINITE_TIMEOUT) 232 { 233 // Deprecated call which functions exactly like PortLink(PortLink::ReplyData *data) 234 #ifdef PLDEBUG 235 printf("PortLink::FlushWithReply(int32*,status_t*,ssize_t*,bigtime_t)\n"); 236 #endif 237 238 if(!port_ok) 239 { 240 #ifdef PLDEBUG 241 printf("PortLink::FlushWithReply(): bad port\n"); 242 #endif 243 *status=B_BAD_VALUE; 244 return NULL; 245 } 246 247 // create a new storage object and stash the data 248 PortLinkData *pld=new PortLinkData; 249 if(pld->Set(&replyport,sizeof(port_id))==B_OK) 250 { 251 bufferlength+=sizeof(port_id); 252 } 253 else 254 { 255 delete pld; 256 *status=B_ERROR; 257 return NULL; 258 } 259 260 // Flatten() inlined to make some necessary changes 261 int8 *buffer=new int8[bufferlength]; 262 int8 *bufferindex=buffer; 263 size_t size=0; 264 265 // attach our port_id first 266 memcpy(bufferindex, pld->buffer, pld->buffersize); 267 bufferindex += pld->buffersize; 268 size+=pld->buffersize; 269 270 // attach everything else 271 for(int i=0;i<attachlist->CountItems();i++) 272 { 273 pld=(PortLinkData*)attachlist->ItemAt(i); 274 memcpy(bufferindex, pld->buffer, pld->buffersize); 275 bufferindex += pld->buffersize; 276 size+=pld->buffersize; 277 } 278 279 // Flush the thing....FOOSH! :P 280 write_port(target,opcode,buffer,size); 281 MakeEmpty(); 282 delete buffer; 283 284 // Now we wait for the reply 285 buffer=NULL; 286 if(timeout==B_INFINITE_TIMEOUT) 287 { 288 *buffersize=port_buffer_size(replyport); 289 if(*buffersize>0) 290 buffer=(int8*)new int8[*buffersize]; 291 read_port(replyport,code, buffer, *buffersize); 292 } 293 else 294 { 295 *buffersize=port_buffer_size_etc(replyport,0,timeout); 296 if(*buffersize==B_TIMED_OUT) 297 { 298 *status=*buffersize; 299 return NULL; 300 } 301 if(*buffersize>0) 302 buffer=(int8*)new int8[*buffersize]; 303 read_port(replyport,code, buffer, *buffersize); 304 } 305 306 // We got this far, so we apparently have some data 307 *status=B_OK; 308 return buffer; 309 } 310 311 312 status_t PortLink::FlushWithReply(PortLink::ReplyData *data,bigtime_t timeout=B_INFINITE_TIMEOUT) 313 { 314 #ifdef PLDEBUG 315 printf("PortLink::FlushWithReply(ReplyData*,bigtime_t)\n"); 316 #endif 317 // Fires a message to the target and then waits for a reply. The target will 318 // receive a message with the first item being the port_id to reply to. 319 // NOTE: like Flush(), any attached data must be deleted. 320 321 // Effectively, an Attach() call inlined for changes 322 323 if(!port_ok) 324 { 325 #ifdef PLDEBUG 326 printf("\tFlushWithReply(): invalid port\n"); 327 #endif 328 return B_BAD_VALUE; 329 } 330 331 // create a new storage object and stash the data 332 PortLinkData *pld=new PortLinkData; 333 if(pld->Set(&replyport,sizeof(port_id))==B_OK) 334 { 335 bufferlength+=sizeof(port_id); 336 } 337 else 338 { 339 #ifdef PLDEBUG 340 printf("\tFlushWithReply(): unable to assign reply port to data\n"); 341 #endif 342 delete pld; 343 return B_ERROR; 344 } 345 346 // Flatten() inlined to make some necessary changes 347 int8 *buffer=new int8[bufferlength]; 348 int8 *bufferindex=buffer; 349 size_t size=0; 350 351 // attach our port_id first 352 memcpy(bufferindex, pld->buffer, pld->buffersize); 353 bufferindex += pld->buffersize; 354 size+=pld->buffersize; 355 356 // attach everything else 357 for(int i=0;i<attachlist->CountItems();i++) 358 { 359 pld=(PortLinkData*)attachlist->ItemAt(i); 360 memcpy(bufferindex, pld->buffer, pld->buffersize); 361 bufferindex += pld->buffersize; 362 size+=pld->buffersize; 363 } 364 365 // Flush the thing....FOOSH! :P 366 write_port(target,opcode,buffer,size); 367 MakeEmpty(); 368 delete buffer; 369 370 // Now we wait for the reply 371 if(timeout==B_INFINITE_TIMEOUT) 372 { 373 data->buffersize=port_buffer_size(replyport); 374 if(data->buffersize>0) 375 { 376 if(data->buffer) 377 delete data->buffer; 378 data->buffer=(int8*)new int8[data->buffersize]; 379 } 380 read_port(replyport,&(data->code),data->buffer, data->buffersize); 381 } 382 else 383 { 384 data->buffersize=port_buffer_size_etc(replyport,0,timeout); 385 if(data->buffersize==B_TIMED_OUT) 386 return B_TIMED_OUT; 387 388 if(data->buffersize>0) 389 { 390 data->buffer=(int8*)new int8[data->buffersize]; 391 } 392 read_port(replyport,&(data->code),data->buffer, data->buffersize); 393 } 394 395 // We got this far, so we apparently have some data 396 return B_OK; 397 } 398 399 status_t PortLink::FlushWithReply(PortMessage *msg,bigtime_t timeout=B_INFINITE_TIMEOUT) 400 { 401 #ifdef PLDEBUG 402 printf("PortLink::FlushWithReply(PortMessage*,bigtime_t)\n"); 403 #endif 404 // Fires a message to the target and then waits for a reply. The target will 405 // receive a message with the first item being the port_id to reply to. 406 407 // Effectively, an Attach() call inlined for changes 408 if(!port_ok || !msg) 409 { 410 #ifdef PLDEBUG 411 printf("\tFlushWithReply(): invalid port\n"); 412 #endif 413 return B_BAD_VALUE; 414 } 415 416 // create a new storage object and stash the data 417 PortLinkData *pld=new PortLinkData; 418 if(pld->Set(&replyport,sizeof(port_id))==B_OK) 419 { 420 bufferlength+=sizeof(port_id); 421 } 422 else 423 { 424 #ifdef PLDEBUG 425 printf("\tFlushWithReply(): unable to assign reply port to data\n"); 426 #endif 427 delete pld; 428 return B_ERROR; 429 } 430 431 // Flatten() inlined to make some necessary changes 432 int8 *buffer=new int8[bufferlength]; 433 int8 *bufferindex=buffer; 434 size_t size=0; 435 436 // attach our port_id first 437 memcpy(bufferindex, pld->buffer, pld->buffersize); 438 bufferindex += pld->buffersize; 439 size+=pld->buffersize; 440 441 // attach everything else 442 for(int i=0;i<attachlist->CountItems();i++) 443 { 444 pld=(PortLinkData*)attachlist->ItemAt(i); 445 memcpy(bufferindex, pld->buffer, pld->buffersize); 446 bufferindex += pld->buffersize; 447 size+=pld->buffersize; 448 } 449 450 // Flush the thing....FOOSH! :P 451 write_port(target,opcode,buffer,size); 452 MakeEmpty(); 453 delete buffer; 454 455 // Now we wait for the reply 456 ssize_t rbuffersize; 457 int8 *rbuffer=NULL; 458 int32 rcode; 459 460 if(timeout==B_INFINITE_TIMEOUT) 461 { 462 rbuffersize=port_buffer_size(replyport); 463 if(rbuffersize>0) 464 rbuffer=(int8*)new int8[rbuffersize]; 465 466 read_port(replyport,&rcode,rbuffer,rbuffersize); 467 } 468 else 469 { 470 rbuffersize=port_buffer_size_etc(replyport,0,timeout); 471 if(rbuffersize==B_TIMED_OUT) 472 return B_TIMED_OUT; 473 474 if(rbuffersize>0) 475 rbuffer=(int8*)new int8[rbuffersize]; 476 477 read_port(replyport,&rcode,rbuffer,rbuffersize); 478 } 479 480 // We got this far, so we apparently have some data 481 msg->SetCode(rcode); 482 msg->SetBuffer(rbuffer,rbuffersize,false); 483 484 return B_OK; 485 } 486 487 status_t PortLink::Attach(const void *data, size_t size) 488 { 489 #ifdef PLDEBUG 490 printf("Attach(%p,%ld)\n",data,size); 491 #endif 492 // This is the member called to attach data to a message. Attachments are 493 // treated to be in 'Append' mode, tacking on each attached piece of data 494 // to the end of the list. 495 496 // Prevent parameter problems 497 if(size==0) 498 { 499 #ifdef PLDEBUG 500 printf("\tAttach(): size invalid -> size=0\n"); 501 #endif 502 return B_ERROR; 503 } 504 505 #ifdef CAPACITY_CHECKING 506 if(bufferlength+size>capacity) 507 { 508 #ifdef PLDEBUG 509 printf("\tAttach(): bufferlength+size > port capacity\n"); 510 #endif 511 return B_NO_MEMORY; 512 } 513 #endif 514 515 // create a new storage object and stash the data 516 PortLinkData *pld=new PortLinkData; 517 if(pld->Set(data,size)==B_OK) 518 { 519 attachlist->AddItem(pld); 520 bufferlength+=size; 521 #ifdef PLDEBUG 522 printf("\tAttach(): successful\n"); 523 printf("\t\tAttach(): attachments now %u\n", num_attachments); 524 printf("\t\tAttach(): buffer length is %lu\n", bufferlength); 525 #endif 526 } 527 else 528 { 529 #ifdef PLDEBUG 530 printf("\tAttach(): Couldn't assign data to PortLinkData object\n"); 531 #endif 532 delete pld; 533 return B_ERROR; 534 } 535 536 return B_OK; 537 } 538 539 // These functions were added for a major convenience in passing common types 540 // Eventually, I'd like to templatize these, but for now, this'll do 541 542 status_t PortLink::Attach(int32 data) 543 { 544 #ifdef PLDEBUG 545 printf("Attach(%ld)\n",data); 546 #endif 547 int32 size=sizeof(int32); 548 549 #ifdef CAPACITY_CHECKING 550 if(bufferlength+size>capacity) 551 return B_NO_MEMORY; 552 #endif 553 554 // create a new storage object and stash the data 555 PortLinkData *pld=new PortLinkData; 556 if(pld->Set(&data,size)==B_OK) 557 { 558 attachlist->AddItem(pld); 559 bufferlength+=size; 560 } 561 else 562 { 563 delete pld; 564 return B_ERROR; 565 } 566 return B_OK; 567 } 568 569 status_t PortLink::Attach(int16 data) 570 { 571 #ifdef PLDEBUG 572 printf("Attach(%d)\n",data); 573 #endif 574 int32 size=sizeof(int16); 575 576 #ifdef CAPACITY_CHECKING 577 if(bufferlength+size>capacity) 578 return B_NO_MEMORY; 579 #endif 580 581 // create a new storage object and stash the data 582 PortLinkData *pld=new PortLinkData; 583 if(pld->Set(&data,size)==B_OK) 584 { 585 attachlist->AddItem(pld); 586 bufferlength+=size; 587 } 588 else 589 { 590 delete pld; 591 return B_ERROR; 592 } 593 return B_OK; 594 } 595 596 status_t PortLink::Attach(int8 data) 597 { 598 #ifdef PLDEBUG 599 printf("Attach(%d)\n",data); 600 #endif 601 int32 size=sizeof(int8); 602 603 #ifdef CAPACITY_CHECKING 604 if(bufferlength+size>capacity) 605 return B_NO_MEMORY; 606 #endif 607 608 // create a new storage object and stash the data 609 PortLinkData *pld=new PortLinkData; 610 if(pld->Set(&data,size)==B_OK) 611 { 612 attachlist->AddItem(pld); 613 bufferlength+=size; 614 } 615 else 616 { 617 delete pld; 618 return B_ERROR; 619 } 620 return B_OK; 621 } 622 623 status_t PortLink::Attach(float data) 624 { 625 #ifdef PLDEBUG 626 printf("Attach(%f)\n",data); 627 #endif 628 int32 size=sizeof(float); 629 630 #ifdef CAPACITY_CHECKING 631 if(bufferlength+size>capacity) 632 return B_NO_MEMORY; 633 #endif 634 635 // create a new storage object and stash the data 636 PortLinkData *pld=new PortLinkData; 637 if(pld->Set(&data,size)==B_OK) 638 { 639 attachlist->AddItem(pld); 640 bufferlength+=size; 641 } 642 else 643 { 644 delete pld; 645 return B_ERROR; 646 } 647 return B_OK; 648 } 649 650 status_t PortLink::Attach(bool data) 651 { 652 #ifdef PLDEBUG 653 printf("Attach(%s)\n",(data)?"true":"false"); 654 #endif 655 656 int32 size=sizeof(bool); 657 658 #ifdef CAPACITY_CHECKING 659 if(bufferlength+size>capacity) 660 return B_NO_MEMORY; 661 #endif 662 663 // create a new storage object and stash the data 664 PortLinkData *pld=new PortLinkData; 665 if(pld->Set(&data,size)==B_OK) 666 { 667 attachlist->AddItem(pld); 668 bufferlength+=size; 669 } 670 else 671 { 672 delete pld; 673 return B_ERROR; 674 } 675 return B_OK; 676 } 677 678 status_t PortLink::Attach(BRect data) 679 { 680 #ifdef PLDEBUG 681 printf("Attach(BRect(%f,%f,%f,%f))\n",data.left,data.top,data.right,data.bottom); 682 #endif 683 int32 size=sizeof(BRect); 684 685 #ifdef CAPACITY_CHECKING 686 if(bufferlength+size>capacity) 687 return B_NO_MEMORY; 688 #endif 689 690 // create a new storage object and stash the data 691 PortLinkData *pld=new PortLinkData; 692 if(pld->Set(&data,size)==B_OK) 693 { 694 attachlist->AddItem(pld); 695 bufferlength+=size; 696 } 697 else 698 { 699 delete pld; 700 return B_ERROR; 701 } 702 return B_OK; 703 } 704 705 status_t PortLink::Attach(BPoint data) 706 { 707 #ifdef PLDEBUG 708 printf("Attach(BPoint(%f,%f))\n",data.x,data.y); 709 #endif 710 int32 size=sizeof(BPoint); 711 712 #ifdef CAPACITY_CHECKING 713 if(bufferlength+size>capacity) 714 return B_NO_MEMORY; 715 #endif 716 717 // create a new storage object and stash the data 718 PortLinkData *pld=new PortLinkData; 719 if(pld->Set(&data,size)==B_OK) 720 { 721 attachlist->AddItem(pld); 722 bufferlength+=size; 723 } 724 else 725 { 726 delete pld; 727 return B_ERROR; 728 } 729 return B_OK; 730 } 731 732 void PortLink::FlattenData(int8 **buffer,int32 *size) 733 { 734 // This function is where all the magic happens, but it is strictly internal. 735 // It iterates through each PortLinkData object and copies it to the main buffer 736 // which ends up, ultimately, being written to the PortLink's target port. 737 738 // skip if there aree no attachments 739 if(bufferlength<1) 740 { 741 #ifdef PLDEBUG 742 printf("PortLink::FlattenData: bufferlength<1\n"); 743 #endif 744 return; 745 } 746 747 *buffer=new int8[bufferlength]; 748 int8 *bufferindex=*buffer; 749 PortLinkData *pld; 750 *size=0; 751 752 int32 count=attachlist->CountItems(); 753 for(int i=0;i<count;i++) 754 { 755 pld=(PortLinkData*)attachlist->ItemAt(i); 756 memcpy(bufferindex, pld->buffer, pld->buffersize); 757 bufferindex += pld->buffersize; 758 *size+=pld->buffersize; 759 } 760 } 761 762 void PortLink::MakeEmpty(void) 763 { 764 #ifdef PLDEBUG 765 printf("PortLink::MakeEmpty\n"); 766 #endif 767 // Nukes all the attachments currently held by the PortLink class 768 PortLinkData *pld; 769 int32 count=attachlist->CountItems(); 770 for(int32 i=0; i<count; i++) 771 { 772 pld=(PortLinkData*)attachlist->ItemAt(i); 773 if(pld) 774 delete pld; 775 } 776 attachlist->MakeEmpty(); 777 bufferlength=0; 778 } 779 780 PortLinkData::PortLinkData(void) 781 { 782 // Initialize object to empty 783 buffersize=0; 784 buffer=NULL; 785 } 786 787 PortLinkData::~PortLinkData(void) 788 { 789 // Frees the buffer if we actually used the class to store data 790 if(buffersize>0 && buffer!=NULL) 791 free(buffer); 792 } 793 794 status_t PortLinkData::Set(const void *data, size_t size) 795 { 796 #ifdef PLD_DEBUG 797 printf("PortLinkData::Set(%p,%lu)\n",data,size); 798 #endif 799 // Function copies the passed to the internal buffers for storage 800 if(size>0 && buffersize==0 && data!=NULL) 801 { 802 buffer=(char *)malloc(size); 803 if(!buffer) 804 { 805 #ifdef PLD_DEBUG 806 printf("\tSet(): Couldn't allocate buffer\n"); 807 #endif 808 return B_NO_MEMORY; 809 } 810 memcpy(buffer, data, size); 811 buffersize=size; 812 #ifdef PLD_DEBUG 813 printf("\tSet(): SUCCESS\n"); 814 #endif 815 return B_OK; 816 } 817 818 #ifdef PLD_DEBUG 819 if(size==0) 820 printf("\tSet(): given an invalid size\n"); 821 if(buffersize>0) 822 printf("\tSet(): buffersize is nonzero\n"); 823 if(buffersize>0) 824 printf("\tSet(): data is NULL\n"); 825 #endif 826 827 return B_ERROR; 828 } 829