1 /* 2 * Copyright 2002-2012, Haiku. All Rights Reserved. 3 * This file may be used under the terms of the MIT License. 4 * 5 * Author: Zousar Shaker 6 * Axel Dörfler, axeld@pinc-software.de 7 * Marcus Overhagen 8 */ 9 10 11 /*! Implements the following classes: 12 BParameterWeb, BParameterGroup, BParameter, BNullParameter, 13 BContinuousParameter, BDiscreteParameter 14 */ 15 16 17 #include <ParameterWeb.h> 18 19 #include <new> 20 #include <string.h> 21 22 #include <MediaNode.h> 23 #include <MediaRoster.h> 24 25 #include "DataExchange.h" 26 #include "debug.h" 27 #include "MediaMisc.h" 28 29 30 /* 31 The following is documentation on the flattened format 32 of structures/classes in this module: 33 34 //--------BEGIN-CORE-BPARAMETER-STRUCT--------------------- 35 ?? (0x02040607): 4 bytes 36 BParameter Struct Size (in bytes): 4 bytes 37 ID: 4 bytes 38 Name String Length: 1 byte (??) 39 Name String: 'Name String Length' bytes 40 Kind String Length: 1 byte (??) 41 Kind String: 'Kind String Length' bytes 42 Unit String Length: 1 byte (??) 43 Unit String: 'Unit String Length' bytes 44 Inputs Count: 4 bytes 45 Inputs (pointers): ('Inputs Count')*4 bytes 46 Outputs Count: 4 bytes 47 Outputs (pointers): ('Outputs Count')*4 bytes 48 Media Type: 4 bytes 49 ChannelCount: 4 bytes 50 Flags: 4 bytes 51 //---------END-CORE-BPARAMETER-STRUCT----------------------- 52 //--------BEGIN-BCONTINUOUSPARAMETER-STRUCT--------- 53 Min: 4 bytes (as float) 54 Max: 4 bytes (as float) 55 Stepping: 4 bytes (as float) 56 Response: 4 bytes (as int or enum) 57 Factor: 4 bytes (as float) 58 Offset: 4 bytes (as float) 59 //--------END-BCONTINUOUSPARAMETER-STRUCT------------- 60 //--------BEGIN-BDISCRETEPARAMETER-STRUCT---------------- 61 NumItems: 4 bytes (as int) 62 //for each item BEGIN 63 Item Name String Length: 1 byte 64 Item Name String: 'Item Name String Length' bytes 65 Item Value: 4 bytes (as int) 66 //for each item END 67 //--------END-BDISCRETEPARAMETER-STRUCT------------------- 68 69 //--------BEGIN-CORE-BPARAMETERGROUP-STRUCT----------- 70 ?? (0x03040507 OR 0x03040509 depending if the flags field is included or not???): 4 bytes 71 (possible) Flags: 4 bytes 72 Name String Length: 1 byte (??) 73 Name String: 'Name String Length' bytes 74 Param Count: 4 bytes 75 //for each Param BEGIN 76 Pointer: 4 bytes 77 Parameter Type: 4 bytes 78 Flattened Parameter Size: 4 bytes 79 Flattened Parameter: 'Flattened Parameter Size' bytes 80 //for each Param END 81 Subgroup Count: 4 bytes 82 //for each SubGroup BEGIN 83 Pointer: 4 bytes 84 MEDIA PARAMETER GROUP TYPE('BMCG' (opposite byte order in file)): 4 bytes 85 Flattened Group Size: 4 bytes 86 Flattened Group: 'Flattened Group Size' bytes 87 //for each SubGroup END 88 89 //---------END-CORE-BPARAMETERGROUP-STRUCT-------------- 90 91 //--------BEGIN-CORE-BPARAMETERWEB-STRUCT----------- 92 ?? 0x01030506: 4 bytes 93 ??: 4 bytes (is always 1) 94 Group Count: 4 bytes 95 Node (as media_node): 0x18 bytes (decimal 24 bytes) 96 //for each Group BEGIN 97 Flattened Group Size: 4 bytes 98 Flattened Group: 'Flattened Group Size' bytes 99 //for each Group END 100 //for each Group BEGIN 101 ??: 4 bytes (never get written to (holds uninitialized value)) 102 //for each Group END 103 //---------END-CORE-BPARAMETERWEB-STRUCT-------------- 104 105 */ 106 107 108 const char * const B_GENERIC = ""; 109 const char * const B_MASTER_GAIN = "Master"; 110 const char * const B_GAIN = "Gain"; 111 const char * const B_BALANCE = "Balance"; 112 const char * const B_FREQUENCY = "Frequency"; 113 const char * const B_LEVEL = "Level"; 114 const char * const B_SHUTTLE_SPEED = "Speed"; 115 const char * const B_CROSSFADE = "XFade"; 116 const char * const B_EQUALIZATION = "EQ"; 117 const char * const B_COMPRESSION = "Compression"; 118 const char * const B_QUALITY = "Quality"; 119 const char * const B_BITRATE = "Bitrate"; 120 const char * const B_GOP_SIZE = "GOPSize"; 121 const char * const B_MUTE = "Mute"; 122 const char * const B_ENABLE = "Enable"; 123 const char * const B_INPUT_MUX = "Input"; 124 const char * const B_OUTPUT_MUX = "Output"; 125 const char * const B_TUNER_CHANNEL = "Channel"; 126 const char * const B_TRACK = "Track"; 127 const char * const B_RECSTATE = "RecState"; 128 const char * const B_SHUTTLE_MODE = "Shuttle"; 129 const char * const B_RESOLUTION = "Resolution"; 130 const char * const B_COLOR_SPACE = "Colorspace"; 131 const char * const B_FRAME_RATE = "FrameRate"; 132 const char * const B_VIDEO_FORMAT = "VideoFormat"; 133 const char * const B_WEB_PHYSICAL_INPUT = "PhysInput"; 134 const char * const B_WEB_PHYSICAL_OUTPUT = "PhysOutput"; 135 const char * const B_WEB_ADC_CONVERTER = "ADC"; 136 const char * const B_WEB_DAC_CONVERTER = "DAC"; 137 const char * const B_WEB_LOGICAL_INPUT = "LogInput"; 138 const char * const B_WEB_LOGICAL_OUTPUT = "LogOutput"; 139 const char * const B_WEB_LOGICAL_BUS = "LogBus"; 140 const char * const B_WEB_BUFFER_INPUT = "DataInput"; 141 const char * const B_WEB_BUFFER_OUTPUT = "DataOutput"; 142 const char * const B_SIMPLE_TRANSPORT = "SimpleTransport"; 143 144 // Flattened data 145 146 static const int32 kCurrentParameterWebVersion = 1; 147 static const uint32 kParameterWebMagic = 0x01030506; 148 static const uint32 kBufferGroupMagic = 0x03040509; 149 static const uint32 kBufferGroupMagicNoFlags = 0x03040507; 150 static const uint32 kParameterMagic = 0x02040607; 151 152 static const ssize_t kAdditionalParameterGroupSize = 12; 153 static const ssize_t kAdditionalParameterSize = 35; 154 155 /* BContinuousParameter - FlattenedSize() fixed part 156 * Min: 4 bytes (as float) 157 * Max: 4 bytes (as float) 158 * Stepping: 4 bytes (as float) 159 * Response: 4 bytes (as int or enum) 160 * Factor: 4 bytes (as float) 161 * Offset: 4 bytes (as float) 162 */ 163 static const ssize_t kAdditionalContinuousParameterSize = 24; 164 static const ssize_t kAdditionalDiscreteParameterSize = sizeof(ssize_t); 165 166 167 // helper functions 168 169 170 template<class Type> Type 171 read_from_buffer(const void **_buffer) 172 { 173 const Type *typedBuffer = static_cast<const Type *>(*_buffer); 174 Type value = *typedBuffer; 175 176 typedBuffer++; 177 *_buffer = static_cast<const void *>(typedBuffer); 178 179 return value; 180 } 181 182 183 static status_t 184 read_string_from_buffer(const void **_buffer, char **_string, ssize_t size) 185 { 186 if (size < 1) 187 return B_BAD_VALUE; 188 189 const uint8 *buffer = static_cast<const uint8 *>(*_buffer); 190 uint8 length = *buffer++; 191 if (length > size - 1) 192 return B_BAD_VALUE; 193 194 char *string = (char *)malloc(length + 1); 195 if (string == NULL) 196 return B_NO_MEMORY; 197 198 memcpy(string, buffer, length); 199 string[length] = '\0'; 200 201 *_buffer = static_cast<const void *>(buffer + length); 202 *_string = string; 203 return B_OK; 204 } 205 206 207 // currently unused 208 #if 0 209 template<class Type> Type * 210 reserve_in_buffer(void **_buffer) 211 { 212 Type *typedBuffer = static_cast<Type *>(*_buffer); 213 214 *typedBuffer = 0; 215 typedBuffer++; 216 217 *_buffer = static_cast<void *>(typedBuffer); 218 } 219 #endif 220 221 template<class Type> void 222 write_to_buffer(void **_buffer, Type value) 223 { 224 Type *typedBuffer = static_cast<Type *>(*_buffer); 225 226 *typedBuffer = value; 227 typedBuffer++; 228 229 *_buffer = static_cast<void *>(typedBuffer); 230 } 231 232 233 void 234 write_string_to_buffer(void **_buffer, const char *string) 235 { 236 uint8 *buffer = static_cast<uint8 *>(*_buffer); 237 uint32 length = string ? strlen(string) : 0; 238 if (length > 255) 239 length = 255; 240 241 *buffer++ = static_cast<uint8>(length); 242 if (length) { 243 memcpy(buffer, string, length); 244 buffer += length; 245 } 246 247 *_buffer = static_cast<void *>(buffer); 248 } 249 250 251 static void 252 skip_in_buffer(const void **_buffer, uint32 bytes) 253 { 254 const uint8 *buffer = static_cast<const uint8 *>(*_buffer); 255 256 buffer += bytes; 257 258 *_buffer = static_cast<const void *>(buffer); 259 } 260 261 262 static void inline 263 skip_in_buffer(void **_buffer, uint32 bytes) 264 { 265 // This actually shouldn't be necessary, but I believe it's a 266 // bug in Be's gcc - it complains about "adds cv-quals without intervening `const'" 267 // when passing a "const void **" pointer as the first argument. 268 // Maybe I am just stupid, though -- axeld. 269 270 skip_in_buffer((const void **)_buffer, bytes); 271 } 272 273 274 template<class Type> Type 275 swap32(Type value, bool doSwap) 276 { 277 STATIC_ASSERT(sizeof(Type) == 4); 278 279 if (doSwap) 280 return (Type)B_SWAP_INT32((int32)value); 281 282 return value; 283 } 284 285 286 template<class Type> Type 287 swap64(Type value, bool doSwap) 288 { 289 STATIC_ASSERT(sizeof(Type) == 8); 290 291 if (doSwap) 292 return (Type)B_SWAP_INT64((int64)value); 293 294 return value; 295 } 296 297 298 template<class Type> Type 299 read_from_buffer_swap32(const void **_buffer, bool doSwap) 300 { 301 return swap32<Type>(read_from_buffer<Type>(_buffer), doSwap); 302 } 303 304 305 template<class Type> Type 306 read_pointer_from_buffer_swap(const void **_buffer, bool doSwap) 307 { 308 #if B_HAIKU_32_BIT 309 return swap32<Type>(read_from_buffer<Type>(_buffer), doSwap); 310 #elif B_HAIKU_64_BIT 311 return swap64<Type>(read_from_buffer<Type>(_buffer), doSwap); 312 #else 313 # error Interesting 314 #endif 315 } 316 317 318 static inline ssize_t 319 size_left(ssize_t size, const void *bufferStart, const void *buffer) 320 { 321 return size - static_cast<ssize_t>((const uint8 *)buffer - (const uint8 *)bufferStart); 322 } 323 324 325 // #pragma mark - BParameterWeb 326 327 328 BParameterWeb::BParameterWeb() 329 : 330 fNode(media_node::null) 331 // fNode is set in BControllable::SetParameterWeb() 332 { 333 CALLED(); 334 335 fGroups = new BList(); 336 fOldRefs = new BList(); 337 fNewRefs = new BList(); 338 } 339 340 341 BParameterWeb::~BParameterWeb() 342 { 343 CALLED(); 344 345 for (int32 i = fGroups->CountItems(); i-- > 0;) { 346 delete static_cast<BParameterGroup*>(fGroups->ItemAt(i)); 347 } 348 349 delete fGroups; 350 delete fOldRefs; 351 delete fNewRefs; 352 } 353 354 355 media_node 356 BParameterWeb::Node() 357 { 358 return fNode; 359 } 360 361 362 BParameterGroup* 363 BParameterWeb::MakeGroup(const char* name) 364 { 365 CALLED(); 366 367 BParameterGroup* group = new(std::nothrow) BParameterGroup(this, name); 368 if (group == NULL) 369 return NULL; 370 371 if (!fGroups->AddItem(group)) { 372 delete group; 373 return NULL; 374 } 375 376 return group; 377 } 378 379 380 int32 381 BParameterWeb::CountGroups() 382 { 383 return fGroups->CountItems(); 384 } 385 386 387 BParameterGroup* 388 BParameterWeb::GroupAt(int32 index) 389 { 390 return static_cast<BParameterGroup*>(fGroups->ItemAt(index)); 391 } 392 393 394 int32 395 BParameterWeb::CountParameters() 396 { 397 CALLED(); 398 399 // Counts over all groups (and sub-groups) in the web. 400 // The "groups" list is used as count stack 401 402 BList groups(*fGroups); 403 int32 count = 0; 404 405 for (int32 i = 0; i < groups.CountItems(); i++) { 406 BParameterGroup* group 407 = static_cast<BParameterGroup*>(groups.ItemAt(i)); 408 409 count += group->CountParameters(); 410 411 if (group->fGroups != NULL) 412 groups.AddList(group->fGroups); 413 } 414 415 return count; 416 } 417 418 419 BParameter* 420 BParameterWeb::ParameterAt(int32 index) 421 { 422 CALLED(); 423 424 // Iterates over all groups (and sub-groups) in the web. 425 // The "groups" list is used as iteration stack (breadth search style) 426 // Maintains the same order as the Be implementation 427 428 BList groups(*fGroups); 429 430 for (int32 i = 0; i < groups.CountItems(); i++) { 431 BParameterGroup* group 432 = static_cast<BParameterGroup*>(groups.ItemAt(i)); 433 int32 count = group->CountParameters(); 434 if (index < count) 435 return group->ParameterAt(index); 436 437 index -= count; 438 // the index is always relative to the start of the current group 439 440 if (group->fGroups != NULL) 441 groups.AddList(group->fGroups); 442 } 443 444 TRACE("*** could not find parameter at %ld (count = %ld)\n", index, 445 CountParameters()); 446 return NULL; 447 } 448 449 450 bool 451 BParameterWeb::IsFixedSize() const 452 { 453 return false; 454 } 455 456 457 type_code 458 BParameterWeb::TypeCode() const 459 { 460 return B_MEDIA_PARAMETER_WEB_TYPE; 461 } 462 463 464 ssize_t 465 BParameterWeb::FlattenedSize() const 466 { 467 CALLED(); 468 469 /* 470 //--------BEGIN-CORE-BPARAMETERWEB-STRUCT----------- 471 ?? 0x01030506: 4 bytes 472 ??: 4 bytes (is always 1) 473 Group Count: 4 bytes 474 Node (as media_node): 0x18 bytes (decimal 24 bytes) 475 //for each Group BEGIN 476 Flattened Group Size: 4 bytes 477 Flattened Group: 'Flattened Group Size' bytes 478 //for each Group END 479 //for each Group BEGIN 480 ??: 4 bytes (never get written to (holds uninitialized value)) 481 //for each Group END 482 //---------END-CORE-BPARAMETERWEB-STRUCT-------------- 483 */ 484 //36 guaranteed bytes, variable after that. 485 ssize_t size = sizeof(int32) + 2 * sizeof(int32) + sizeof(media_node); 486 487 for (int32 i = fGroups->CountItems(); i-- > 0;) { 488 BParameterGroup* group 489 = static_cast<BParameterGroup*>(fGroups->ItemAt(i)); 490 if (group != NULL) { 491 size += 4 + group->FlattenedSize(); 492 // 4 bytes for the flattened size 493 } 494 } 495 496 return size; 497 } 498 499 500 status_t 501 BParameterWeb::Flatten(void* buffer, ssize_t size) const 502 { 503 CALLED(); 504 505 if (buffer == NULL) 506 return B_NO_INIT; 507 508 ssize_t actualSize = BParameterWeb::FlattenedSize(); 509 if (size < actualSize) 510 return B_NO_MEMORY; 511 512 void* bufferStart = buffer; 513 514 write_to_buffer<int32>(&buffer, kParameterWebMagic); 515 write_to_buffer<int32>(&buffer, kCurrentParameterWebVersion); 516 517 // flatten all groups into this buffer 518 519 int32 count = fGroups->CountItems(); 520 write_to_buffer<int32>(&buffer, count); 521 522 write_to_buffer<media_node>(&buffer, fNode); 523 524 for (int32 i = 0; i < count; i++) { 525 BParameterGroup* group 526 = static_cast<BParameterGroup*>(fGroups->ItemAt(i)); 527 if (group == NULL) { 528 ERROR("BParameterWeb::Flatten(): group is NULL\n"); 529 continue; 530 } 531 532 ssize_t groupSize = group->FlattenedSize(); 533 if (groupSize > size_left(size, bufferStart, buffer)) { 534 ERROR("BParameterWeb::Flatten(): buffer too small\n"); 535 return B_BAD_VALUE; 536 } 537 538 write_to_buffer<ssize_t>(&buffer, groupSize); 539 540 // write the flattened sub group 541 status_t status = group->Flatten(buffer, groupSize); 542 if (status < B_OK) 543 return status; 544 545 skip_in_buffer(&buffer, groupSize); 546 } 547 548 return B_OK; 549 } 550 551 552 bool 553 BParameterWeb::AllowsTypeCode(type_code code) const 554 { 555 return code == TypeCode(); 556 } 557 558 559 status_t 560 BParameterWeb::Unflatten(type_code code, const void* buffer, ssize_t size) 561 { 562 CALLED(); 563 564 if (!AllowsTypeCode(code)) { 565 ERROR("BParameterWeb::Unflatten(): wrong type code\n"); 566 return B_BAD_TYPE; 567 } 568 569 if (buffer == NULL) { 570 ERROR("BParameterWeb::Unflatten(): NULL buffer pointer\n"); 571 return B_NO_INIT; 572 } 573 574 // if the buffer is smaller than the size needed to read the 575 // signature field, the mystery field, the group count, and the Node, then there is a problem 576 if (size < static_cast<ssize_t>(sizeof(int32) + sizeof(int32) 577 + sizeof(ssize_t) + sizeof(media_node))) { 578 ERROR("BParameterWeb::Unflatten(): size to small\n"); 579 return B_ERROR; 580 } 581 582 const void* bufferStart = buffer; 583 584 uint32 magic = read_from_buffer<uint32>(&buffer); 585 bool isSwapped = false; 586 587 if (magic == B_SWAP_INT32(kParameterWebMagic)) { 588 isSwapped = true; 589 magic = B_SWAP_INT32(magic); 590 } 591 if (magic != kParameterWebMagic) 592 return B_BAD_DATA; 593 594 // Note, it's not completely sure that this field is the version 595 // information - but it doesn't seem to have another purpose 596 int32 version = read_from_buffer_swap32<int32>(&buffer, isSwapped); 597 if (version != kCurrentParameterWebVersion) { 598 ERROR("BParameterWeb::Unflatten(): wrong version %" B_PRId32 " (%" 599 B_PRIx32 ")?!\n", version, version); 600 return B_ERROR; 601 } 602 603 for (int32 i = 0; i < fGroups->CountItems(); i++) { 604 delete static_cast<BParameterGroup*>(fGroups->ItemAt(i)); 605 } 606 fGroups->MakeEmpty(); 607 608 int32 count = read_from_buffer_swap32<int32>(&buffer, isSwapped); 609 610 fNode = read_from_buffer<media_node>(&buffer); 611 if (isSwapped) 612 swap_data(B_INT32_TYPE, &fNode, sizeof(media_node), B_SWAP_ALWAYS); 613 614 for (int32 i = 0; i < count; i++) { 615 ssize_t groupSize 616 = read_pointer_from_buffer_swap<ssize_t>(&buffer, isSwapped); 617 if (groupSize > size_left(size, bufferStart, buffer)) { 618 ERROR("BParameterWeb::Unflatten(): buffer too small\n"); 619 return B_BAD_DATA; 620 } 621 622 BParameterGroup* group = new BParameterGroup(this, "unnamed"); 623 status_t status = group->Unflatten(group->TypeCode(), buffer, 624 groupSize); 625 if (status < B_OK) { 626 ERROR("BParameterWeb::Unflatten(): unflatten group failed\n"); 627 delete group; 628 return status; 629 } 630 631 skip_in_buffer(&buffer, groupSize); 632 633 fGroups->AddItem(group); 634 } 635 636 // fix all references (ParameterAt() style) 637 638 BList groups(*fGroups); 639 640 for (int32 i = 0; i < groups.CountItems(); i++) { 641 BParameterGroup* group 642 = static_cast<BParameterGroup*>(groups.ItemAt(i)); 643 644 for (int32 index = group->CountParameters(); index-- > 0;) { 645 BParameter* parameter 646 = static_cast<BParameter*>(group->ParameterAt(index)); 647 648 parameter->FixRefs(*fOldRefs, *fNewRefs); 649 } 650 651 if (group->fGroups != NULL) 652 groups.AddList(group->fGroups); 653 } 654 655 fOldRefs->MakeEmpty(); 656 fNewRefs->MakeEmpty(); 657 658 return B_OK; 659 } 660 661 662 void 663 BParameterWeb::AddRefFix(void* oldItem, void* newItem) 664 { 665 fOldRefs->AddItem(oldItem); 666 fNewRefs->AddItem(newItem); 667 } 668 669 670 // #pragma mark - BParameterGroup 671 672 673 BParameterGroup::BParameterGroup(BParameterWeb* web, const char* name) 674 : 675 fWeb(web), 676 fFlags(0) 677 { 678 CALLED(); 679 TRACE("BParameterGroup: web = %p, name = \"%s\"\n", web, name); 680 681 fName = strndup(name, 255); 682 683 fControls = new BList(); 684 fGroups = new BList(); 685 } 686 687 688 BParameterGroup::~BParameterGroup() 689 { 690 CALLED(); 691 692 for (int i = fControls->CountItems(); i-- > 0;) { 693 delete static_cast<BParameter*>(fControls->ItemAt(i)); 694 } 695 delete fControls; 696 697 for (int i = fGroups->CountItems(); i-- > 0;) { 698 delete static_cast<BParameterGroup*>(fGroups->ItemAt(i)); 699 } 700 delete fGroups; 701 702 free(fName); 703 } 704 705 706 BParameterWeb* 707 BParameterGroup::Web() const 708 { 709 return fWeb; 710 } 711 712 713 const char* 714 BParameterGroup::Name() const 715 { 716 return fName; 717 } 718 719 720 void 721 BParameterGroup::SetFlags(uint32 flags) 722 { 723 fFlags = flags; 724 } 725 726 727 uint32 728 BParameterGroup::Flags() const 729 { 730 return fFlags; 731 } 732 733 734 BNullParameter* 735 BParameterGroup::MakeNullParameter(int32 id, media_type mediaType, 736 const char* name, const char* kind) 737 { 738 CALLED(); 739 740 BNullParameter* parameter = new(std::nothrow) BNullParameter(id, mediaType, 741 fWeb, name, kind); 742 if (parameter == NULL) 743 return NULL; 744 745 parameter->fGroup = this; 746 fControls->AddItem(parameter); 747 748 return parameter; 749 } 750 751 752 BContinuousParameter* 753 BParameterGroup::MakeContinuousParameter(int32 id, media_type mediaType, 754 const char* name, const char* kind, const char* unit, 755 float minimum, float maximum, float stepping) 756 { 757 CALLED(); 758 759 BContinuousParameter* parameter 760 = new(std::nothrow) BContinuousParameter(id, mediaType, fWeb, name, 761 kind, unit, minimum, maximum, stepping); 762 if (parameter == NULL) 763 return NULL; 764 765 parameter->fGroup = this; 766 fControls->AddItem(parameter); 767 768 return parameter; 769 } 770 771 772 BDiscreteParameter* 773 BParameterGroup::MakeDiscreteParameter(int32 id, media_type mediaType, 774 const char* name, const char* kind) 775 { 776 CALLED(); 777 778 BDiscreteParameter* parameter = new(std::nothrow) BDiscreteParameter(id, 779 mediaType, fWeb, name, kind); 780 if (parameter == NULL) 781 return NULL; 782 783 parameter->fGroup = this; 784 fControls->AddItem(parameter); 785 786 return parameter; 787 } 788 789 790 BTextParameter* 791 BParameterGroup::MakeTextParameter(int32 id, media_type mediaType, 792 const char* name, const char* kind, size_t maxBytes) 793 { 794 CALLED(); 795 796 BTextParameter* parameter = new(std::nothrow) BTextParameter(id, mediaType, 797 fWeb, name, kind, maxBytes); 798 if (parameter == NULL) 799 return NULL; 800 801 parameter->fGroup = this; 802 fControls->AddItem(parameter); 803 804 return parameter; 805 } 806 807 808 BParameterGroup* 809 BParameterGroup::MakeGroup(const char* name) 810 { 811 CALLED(); 812 813 BParameterGroup* group = new(std::nothrow) BParameterGroup(fWeb, name); 814 if (group != NULL) 815 fGroups->AddItem(group); 816 817 return group; 818 } 819 820 821 int32 822 BParameterGroup::CountParameters() 823 { 824 return fControls->CountItems(); 825 } 826 827 828 BParameter* 829 BParameterGroup::ParameterAt(int32 index) 830 { 831 return static_cast<BParameter*>(fControls->ItemAt(index)); 832 } 833 834 835 int32 836 BParameterGroup::CountGroups() 837 { 838 return fGroups->CountItems(); 839 } 840 841 842 BParameterGroup* 843 BParameterGroup::GroupAt(int32 index) 844 { 845 return static_cast<BParameterGroup*>(fGroups->ItemAt(index)); 846 } 847 848 849 bool 850 BParameterGroup::IsFixedSize() const 851 { 852 return false; 853 } 854 855 856 type_code 857 BParameterGroup::TypeCode() const 858 { 859 return B_MEDIA_PARAMETER_GROUP_TYPE; 860 } 861 862 863 ssize_t 864 BParameterGroup::FlattenedSize() const 865 { 866 CALLED(); 867 868 /* 869 //--------BEGIN-CORE-BPARAMETERGROUP-STRUCT----------- 870 ?? (0x03040507 OR 0x03040509 depending if the flags field is included or not???): 4 bytes 871 (possible) Flags: 4 bytes 872 Name String Length: 1 byte (??) 873 Name String: 'Name String Length' bytes 874 Param Count: 4 bytes 875 //for each Param BEGIN 876 Pointer: 4 bytes 877 Parameter Type: 4 bytes 878 Flattened Parameter Size: 4 bytes 879 Flattened Parameter: 'Flattened Parameter Size' bytes 880 //for each Param END 881 Subgroup Count: 4 bytes 882 //for each SubGroup BEGIN 883 Pointer: 4 bytes 884 MEDIA PARAMETER GROUP TYPE('BMCG' (opposite byte order in file)): 4 bytes 885 Flattened Group Size: 4 bytes 886 Flattened Group: 'Flattened Group Size' bytes 887 //for each SubGroup END 888 889 //---------END-CORE-BPARAMETERGROUP-STRUCT-------------- 890 */ 891 //13 guaranteed bytes, variable after that. 892 ssize_t size = 13; 893 894 if (fFlags != 0) 895 size += 4; 896 897 if (fName != NULL) 898 size += min_c(strlen(fName), 255); 899 900 int limit = fControls->CountItems(); 901 for (int i = 0; i < limit; i++) { 902 BParameter* parameter = static_cast<BParameter*>(fControls->ItemAt(i)); 903 if (parameter != NULL) { 904 // overhead for each parameter flattened 905 size += 16 + parameter->FlattenedSize(); 906 } 907 } 908 909 limit = fGroups->CountItems(); 910 for (int i = 0; i < limit; i++) { 911 BParameterGroup* group 912 = static_cast<BParameterGroup*>(fGroups->ItemAt(i)); 913 if (group != NULL) { 914 // overhead for each group flattened 915 size += 16 + group->FlattenedSize(); 916 } 917 } 918 919 return size; 920 } 921 922 923 status_t 924 BParameterGroup::Flatten(void* buffer, ssize_t size) const 925 { 926 CALLED(); 927 928 if (buffer == NULL) { 929 ERROR("BParameterGroup::Flatten buffer is NULL\n"); 930 return B_NO_INIT; 931 } 932 933 // NOTICE: It is important that this value is the size returned by 934 // BParameterGroup::FlattenedSize, not by a descendent's override of this method. 935 ssize_t actualSize = BParameterGroup::FlattenedSize(); 936 if (size < actualSize) { 937 ERROR("BParameterGroup::Flatten size to small\n"); 938 return B_NO_MEMORY; 939 } 940 941 if (fFlags != 0) { 942 write_to_buffer<int32>(&buffer, kBufferGroupMagic); 943 write_to_buffer<uint32>(&buffer, fFlags); 944 } else 945 write_to_buffer<int32>(&buffer, kBufferGroupMagicNoFlags); 946 947 write_string_to_buffer(&buffer, fName); 948 949 int32 count = fControls->CountItems(); 950 write_to_buffer<int32>(&buffer, count); 951 952 for (int32 i = 0; i < count; i++) { 953 BParameter* parameter = static_cast<BParameter*>(fControls->ItemAt(i)); 954 if (parameter == NULL) { 955 ERROR("BParameterGroup::Flatten(): NULL parameter\n"); 956 continue; 957 } 958 959 write_to_buffer<BParameter*>(&buffer, parameter); 960 write_to_buffer<BParameter::media_parameter_type>(&buffer, 961 parameter->Type()); 962 963 // flatten parameter into this buffer 964 965 ssize_t parameterSize = parameter->FlattenedSize(); 966 write_to_buffer<ssize_t>(&buffer, parameterSize); 967 968 status_t status = parameter->Flatten(buffer, parameterSize); 969 // we have only that much bytes left to write in this buffer 970 if (status < B_OK) 971 return status; 972 973 skip_in_buffer(&buffer, parameterSize); 974 } 975 976 count = fGroups->CountItems(); 977 write_to_buffer<int32>(&buffer, count); 978 979 for (int32 i = 0; i < count; i++) { 980 BParameterGroup* group 981 = static_cast<BParameterGroup*>(fGroups->ItemAt(i)); 982 if (group == NULL) { 983 ERROR("BParameterGroup::Flatten(): NULL group\n"); 984 continue; 985 } 986 987 write_to_buffer<BParameterGroup*>(&buffer, group); 988 write_to_buffer<type_code>(&buffer, group->TypeCode()); 989 990 // flatten sub group into this buffer 991 992 ssize_t groupSize = group->FlattenedSize(); 993 write_to_buffer<ssize_t>(&buffer, groupSize); 994 995 status_t status = group->Flatten(buffer, groupSize); 996 // we have only that much bytes left to write in this buffer 997 if (status < B_OK) 998 return status; 999 1000 skip_in_buffer(&buffer, groupSize); 1001 } 1002 1003 return B_OK; 1004 } 1005 1006 1007 bool 1008 BParameterGroup::AllowsTypeCode(type_code code) const 1009 { 1010 return code == TypeCode(); 1011 } 1012 1013 1014 status_t 1015 BParameterGroup::Unflatten(type_code code, const void* buffer, ssize_t size) 1016 { 1017 CALLED(); 1018 1019 if (!AllowsTypeCode(code)) { 1020 ERROR("BParameterGroup::Unflatten() wrong type code\n"); 1021 return B_BAD_TYPE; 1022 } 1023 1024 if (buffer == NULL) { 1025 ERROR("BParameterGroup::Unflatten() buffer is NULL\n"); 1026 return B_NO_INIT; 1027 } 1028 1029 // if the buffer is smaller than the size needed to read the 1030 // signature field, then there is a problem 1031 if (size < static_cast<ssize_t>(sizeof(int32))) { 1032 ERROR("BParameterGroup::Unflatten() size to small\n"); 1033 return B_ERROR; 1034 } 1035 1036 const void* bufferStart = buffer; 1037 // used to compute the rest length of the buffer when needed 1038 1039 uint32 magic = read_from_buffer<uint32>(&buffer); 1040 bool isSwapped = false; 1041 1042 if (magic == B_SWAP_INT32(kBufferGroupMagic) 1043 || magic == B_SWAP_INT32(kBufferGroupMagicNoFlags)) { 1044 isSwapped = true; 1045 magic = B_SWAP_INT32(magic); 1046 } 1047 1048 if (magic == kBufferGroupMagic) 1049 fFlags = read_from_buffer_swap32<int32>(&buffer, isSwapped); 1050 else if (magic == kBufferGroupMagicNoFlags) 1051 fFlags = 0; 1052 else 1053 return B_BAD_TYPE; 1054 1055 if (read_string_from_buffer(&buffer, &fName, 1056 size - (ssize_t)((uint8*)buffer - (uint8*)bufferStart)) < B_OK) 1057 return B_BAD_VALUE; 1058 1059 // Clear all existing parameters/subgroups 1060 for (int32 i = 0; i < fControls->CountItems(); i++) { 1061 delete static_cast<BParameter*>(fControls->ItemAt(i)); 1062 } 1063 fControls->MakeEmpty(); 1064 1065 for (int32 i = 0; i < fGroups->CountItems(); i++) { 1066 delete static_cast<BParameterGroup*>(fGroups->ItemAt(i)); 1067 } 1068 fGroups->MakeEmpty(); 1069 1070 // unflatten parameter list 1071 1072 int32 count = read_from_buffer_swap32<int32>(&buffer, isSwapped); 1073 if (count < 0 || count * kAdditionalParameterSize 1074 > size_left(size, bufferStart, buffer)) 1075 return B_BAD_VALUE; 1076 1077 for (int32 i = 0; i < count; i++) { 1078 // make sure we can read as many bytes 1079 if (size_left(size, bufferStart, buffer) < 12) 1080 return B_BAD_VALUE; 1081 1082 BParameter* oldPointer = read_pointer_from_buffer_swap<BParameter*>( 1083 &buffer, isSwapped); 1084 BParameter::media_parameter_type mediaType 1085 = read_from_buffer_swap32<BParameter::media_parameter_type>(&buffer, 1086 isSwapped); 1087 1088 ssize_t parameterSize = read_pointer_from_buffer_swap<ssize_t>(&buffer, 1089 isSwapped); 1090 if (parameterSize > size_left(size, bufferStart, buffer)) 1091 return B_BAD_VALUE; 1092 1093 BParameter* parameter = MakeControl(mediaType); 1094 if (parameter == NULL) { 1095 ERROR("BParameterGroup::Unflatten(): MakeControl() failed\n"); 1096 return B_ERROR; 1097 } 1098 1099 status_t status = parameter->Unflatten(parameter->TypeCode(), buffer, 1100 parameterSize); 1101 if (status < B_OK) { 1102 ERROR("BParameterGroup::Unflatten(): parameter->Unflatten() failed\n"); 1103 delete parameter; 1104 return status; 1105 } 1106 1107 skip_in_buffer(&buffer, parameterSize); 1108 1109 // add the item to the list 1110 parameter->fGroup = this; 1111 parameter->fWeb = fWeb; 1112 fControls->AddItem(parameter); 1113 1114 // add it's old pointer value to the RefFix list kept by the owner web 1115 if (fWeb != NULL) 1116 fWeb->AddRefFix(oldPointer, parameter); 1117 } 1118 1119 // unflatten sub groups 1120 1121 count = read_from_buffer_swap32<int32>(&buffer, isSwapped); 1122 if (count < 0 || count * kAdditionalParameterGroupSize 1123 > size_left(size, bufferStart, buffer)) 1124 return B_BAD_VALUE; 1125 1126 for (int32 i = 0; i < count; i++) { 1127 // make sure we can read as many bytes 1128 if (size_left(size, bufferStart, buffer) < 12) 1129 return B_BAD_VALUE; 1130 1131 BParameterGroup* oldPointer = read_pointer_from_buffer_swap< 1132 BParameterGroup*>(&buffer, isSwapped); 1133 type_code type = read_from_buffer_swap32<type_code>(&buffer, isSwapped); 1134 1135 ssize_t groupSize 1136 = read_pointer_from_buffer_swap<ssize_t>(&buffer, isSwapped); 1137 if (groupSize > size_left(size, bufferStart, buffer)) 1138 return B_BAD_VALUE; 1139 1140 BParameterGroup* group = new BParameterGroup(fWeb, "sub-unnamed"); 1141 if (group == NULL) { 1142 ERROR("BParameterGroup::Unflatten(): MakeGroup() failed\n"); 1143 return B_ERROR; 1144 } 1145 1146 status_t status = group->Unflatten(type, buffer, groupSize); 1147 if (status != B_OK) { 1148 ERROR("BParameterGroup::Unflatten(): group->Unflatten() failed\n"); 1149 delete group; 1150 return status; 1151 } 1152 1153 skip_in_buffer(&buffer, groupSize); 1154 1155 fGroups->AddItem(group); 1156 1157 // add it's old pointer value to the RefFix list kept by the owner web 1158 if (fWeb != NULL) 1159 fWeb->AddRefFix(oldPointer, group); 1160 } 1161 1162 return B_OK; 1163 } 1164 1165 1166 /*! Creates an uninitialized parameter of the specified type. 1167 Unlike the BParameterGroup::MakeXXXParameter() type of methods, this 1168 method does not add the parameter to this group automatically. 1169 */ 1170 BParameter* 1171 BParameterGroup::MakeControl(int32 type) 1172 { 1173 CALLED(); 1174 1175 switch (type) { 1176 case BParameter::B_NULL_PARAMETER: 1177 return new BNullParameter(-1, B_MEDIA_NO_TYPE, NULL, NULL, NULL); 1178 1179 case BParameter::B_DISCRETE_PARAMETER: 1180 return new BDiscreteParameter(-1, B_MEDIA_NO_TYPE, NULL, NULL, 1181 NULL); 1182 1183 case BParameter::B_CONTINUOUS_PARAMETER: 1184 return new BContinuousParameter(-1, B_MEDIA_NO_TYPE, NULL, NULL, 1185 NULL, NULL, 0, 0, 0); 1186 1187 case BParameter::B_TEXT_PARAMETER: 1188 return new BTextParameter(-1, B_MEDIA_NO_TYPE, NULL, NULL, NULL, 0); 1189 1190 default: 1191 ERROR("BParameterGroup::MakeControl unknown type %" B_PRId32 "\n", 1192 type); 1193 return NULL; 1194 } 1195 } 1196 1197 1198 // #pragma mark - BParameter 1199 1200 1201 BParameter::media_parameter_type 1202 BParameter::Type() const 1203 { 1204 return fType; 1205 } 1206 1207 1208 BParameterWeb* 1209 BParameter::Web() const 1210 { 1211 return fWeb; 1212 } 1213 1214 1215 BParameterGroup* 1216 BParameter::Group() const 1217 { 1218 return fGroup; 1219 } 1220 1221 1222 const char* 1223 BParameter::Name() const 1224 { 1225 return fName; 1226 } 1227 1228 1229 const char* 1230 BParameter::Kind() const 1231 { 1232 return fKind; 1233 } 1234 1235 1236 const char* 1237 BParameter::Unit() const 1238 { 1239 return fUnit; 1240 } 1241 1242 1243 int32 1244 BParameter::ID() const 1245 { 1246 return fID; 1247 } 1248 1249 1250 void 1251 BParameter::SetFlags(uint32 flags) 1252 { 1253 fFlags = flags; 1254 } 1255 1256 1257 uint32 1258 BParameter::Flags() const 1259 { 1260 return fFlags; 1261 } 1262 1263 1264 status_t 1265 BParameter::GetValue(void* buffer, size_t* _size, bigtime_t* _when) 1266 { 1267 CALLED(); 1268 1269 if (buffer == NULL || _size == NULL) 1270 return B_BAD_VALUE; 1271 1272 size_t size = *_size; 1273 if (size <= 0) 1274 return B_NO_MEMORY; 1275 1276 if (fWeb == NULL) { 1277 ERROR("BParameter::GetValue: no parent BParameterWeb\n"); 1278 return B_NO_INIT; 1279 } 1280 1281 media_node node = fWeb->Node(); 1282 if (IS_INVALID_NODE(node)) { 1283 ERROR("BParameter::GetValue: the parent BParameterWeb is not assigned to a BMediaNode\n"); 1284 return B_NO_INIT; 1285 } 1286 1287 controllable_get_parameter_data_request request; 1288 controllable_get_parameter_data_reply reply; 1289 1290 area_id area; 1291 void* data; 1292 if (size > MAX_PARAMETER_DATA) { 1293 // create an area if large data needs to be transfered 1294 area = create_area("get parameter data", &data, B_ANY_ADDRESS, 1295 ROUND_UP_TO_PAGE(size), B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); 1296 if (area < B_OK) { 1297 ERROR("BParameter::GetValue can't create area of %ld bytes\n", 1298 size); 1299 return B_NO_MEMORY; 1300 } 1301 } else { 1302 area = -1; 1303 data = reply.raw_data; 1304 } 1305 1306 request.parameter_id = fID; 1307 request.request_size = size; 1308 request.area = area; 1309 1310 status_t status = QueryPort(node.port, CONTROLLABLE_GET_PARAMETER_DATA, 1311 &request, sizeof(request), &reply, sizeof(reply)); 1312 if (status == B_OK) { 1313 // we don't want to copy more than the buffer provides 1314 if (reply.size < size) 1315 size = reply.size; 1316 1317 memcpy(buffer, data, size); 1318 1319 // store reported values 1320 1321 *_size = reply.size; 1322 if (_when != NULL) 1323 *_when = reply.last_change; 1324 } else { 1325 ERROR("BParameter::GetValue parameter '%s' querying node %d, " 1326 "port %d failed: %s\n", fName, (int)node.node, (int)node.port, 1327 strerror(status)); 1328 } 1329 1330 if (area >= B_OK) 1331 delete_area(area); 1332 1333 return status; 1334 } 1335 1336 1337 status_t 1338 BParameter::SetValue(const void* buffer, size_t size, bigtime_t when) 1339 { 1340 CALLED(); 1341 1342 if (buffer == 0) 1343 return B_BAD_VALUE; 1344 if (size <= 0) 1345 return B_NO_MEMORY; 1346 1347 if (fWeb == 0) { 1348 ERROR("BParameter::SetValue: no parent BParameterWeb\n"); 1349 return B_NO_INIT; 1350 } 1351 1352 media_node node = fWeb->Node(); 1353 if (IS_INVALID_NODE(node)) { 1354 ERROR("BParameter::SetValue: the parent BParameterWeb is not assigned " 1355 "to a BMediaNode\n"); 1356 return B_NO_INIT; 1357 } 1358 1359 controllable_set_parameter_data_request request; 1360 controllable_set_parameter_data_reply reply; 1361 area_id area; 1362 void* data; 1363 1364 if (size > MAX_PARAMETER_DATA) { 1365 // create an area if large data needs to be transfered 1366 area = create_area("set parameter data", &data, B_ANY_ADDRESS, 1367 ROUND_UP_TO_PAGE(size), B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); 1368 if (area < B_OK) { 1369 ERROR("BParameter::SetValue can't create area of %ld bytes\n", size); 1370 return B_NO_MEMORY; 1371 } 1372 } else { 1373 area = -1; 1374 data = request.raw_data; 1375 } 1376 1377 memcpy(data, buffer, size); 1378 request.parameter_id = fID; 1379 request.when = when; 1380 request.area = area; 1381 request.size = size; 1382 1383 status_t status = QueryPort(node.port, CONTROLLABLE_SET_PARAMETER_DATA, 1384 &request, sizeof(request), &reply, sizeof(reply)); 1385 if (status != B_OK) { 1386 ERROR("BParameter::SetValue querying node failed: %s\n", 1387 strerror(status)); 1388 } 1389 1390 if (area != -1) 1391 delete_area(area); 1392 1393 return status; 1394 } 1395 1396 1397 int32 1398 BParameter::CountChannels() 1399 { 1400 return fChannels; 1401 } 1402 1403 1404 void 1405 BParameter::SetChannelCount(int32 count) 1406 { 1407 fChannels = count; 1408 } 1409 1410 1411 media_type 1412 BParameter::MediaType() 1413 { 1414 return fMediaType; 1415 } 1416 1417 1418 void 1419 BParameter::SetMediaType(media_type type) 1420 { 1421 fMediaType = type; 1422 } 1423 1424 1425 int32 1426 BParameter::CountInputs() 1427 { 1428 return fInputs->CountItems(); 1429 } 1430 1431 1432 BParameter* 1433 BParameter::InputAt(int32 index) 1434 { 1435 return static_cast<BParameter*>(fInputs->ItemAt(index)); 1436 } 1437 1438 1439 void 1440 BParameter::AddInput(BParameter* input) 1441 { 1442 CALLED(); 1443 1444 // BeBook has this method returning a status value, 1445 // but it should be updated 1446 if (input == NULL) 1447 return; 1448 1449 if (fInputs->HasItem(input)) { 1450 // if already in input list, don't duplicate. 1451 return; 1452 } 1453 1454 fInputs->AddItem(input); 1455 input->AddOutput(this); 1456 } 1457 1458 1459 int32 1460 BParameter::CountOutputs() 1461 { 1462 return fOutputs->CountItems(); 1463 } 1464 1465 1466 BParameter* 1467 BParameter::OutputAt(int32 index) 1468 { 1469 return static_cast<BParameter*>(fOutputs->ItemAt(index)); 1470 } 1471 1472 1473 void 1474 BParameter::AddOutput(BParameter* output) 1475 { 1476 CALLED(); 1477 1478 // BeBook has this method returning a status value, 1479 // but it should be updated 1480 if (output == NULL) 1481 return; 1482 1483 if (fOutputs->HasItem(output)) { 1484 // if already in output list, don't duplicate. 1485 return; 1486 } 1487 1488 fOutputs->AddItem(output); 1489 output->AddInput(this); 1490 } 1491 1492 1493 bool 1494 BParameter::IsFixedSize() const 1495 { 1496 return false; 1497 } 1498 1499 1500 type_code 1501 BParameter::TypeCode() const 1502 { 1503 return B_MEDIA_PARAMETER_TYPE; 1504 } 1505 1506 1507 ssize_t 1508 BParameter::FlattenedSize() const 1509 { 1510 CALLED(); 1511 /* 1512 ?? (0x02040607): 4 bytes 1513 BParameter Struct Size (in bytes): 4 bytes 1514 ID: 4 bytes 1515 Name String Length: 1 byte (??) 1516 Name String: 'Name String Length' bytes 1517 Kind String Length: 1 byte (??) 1518 Kind String: 'Kind String Length' bytes 1519 Unit String Length: 1 byte (??) 1520 Unit String: 'Unit String Length' bytes 1521 Inputs Count: 4 bytes 1522 Inputs (pointers): ('Inputs Count')*4 bytes 1523 Outputs Count: 4 bytes 1524 Outputs (pointers): ('Outputs Count')*4 bytes 1525 Media Type: 4 bytes 1526 ChannelCount: 4 bytes 1527 Flags: 4 bytes 1528 */ 1529 //35 bytes are guaranteed, after that, add the variable length parts. 1530 ssize_t size = 35; 1531 1532 if (fName != NULL) 1533 size += strlen(fName); 1534 if (fKind != NULL) 1535 size += strlen(fKind); 1536 if (fUnit != NULL) 1537 size += strlen(fUnit); 1538 1539 size += fInputs->CountItems() * sizeof(BParameter*); 1540 size += fOutputs->CountItems() * sizeof(BParameter*); 1541 1542 return size; 1543 } 1544 1545 1546 status_t 1547 BParameter::Flatten(void* buffer, ssize_t size) const 1548 { 1549 CALLED(); 1550 1551 if (buffer == NULL) { 1552 ERROR("BParameter::Flatten buffer is NULL\n"); 1553 return B_NO_INIT; 1554 } 1555 1556 // NOTICE: It is important that this value is the size returned by 1557 // BParameter::FlattenedSize(), not by a descendent's override of this method. 1558 ssize_t actualSize = BParameter::FlattenedSize(); 1559 if (size < actualSize) { 1560 ERROR("BParameter::Flatten(): size too small\n"); 1561 return B_NO_MEMORY; 1562 } 1563 1564 write_to_buffer<uint32>(&buffer, kParameterMagic); 1565 write_to_buffer<ssize_t>(&buffer, actualSize); 1566 write_to_buffer<int32>(&buffer, fID); 1567 1568 write_string_to_buffer(&buffer, fName); 1569 write_string_to_buffer(&buffer, fKind); 1570 write_string_to_buffer(&buffer, fUnit); 1571 1572 // flatten and write the list of inputs 1573 ssize_t count = fInputs->CountItems(); 1574 write_to_buffer<ssize_t>(&buffer, count); 1575 1576 if (count > 0) { 1577 memcpy(buffer, fInputs->Items(), sizeof(BParameter*) * count); 1578 skip_in_buffer(&buffer, sizeof(BParameter*) * count); 1579 } 1580 1581 // flatten and write the list of outputs 1582 count = fOutputs->CountItems(); 1583 write_to_buffer<ssize_t>(&buffer, count); 1584 1585 if (count > 0) { 1586 memcpy(buffer, fOutputs->Items(), sizeof(BParameter*) * count); 1587 skip_in_buffer(&buffer, sizeof(BParameter*) * count); 1588 } 1589 1590 write_to_buffer<media_type>(&buffer, fMediaType); 1591 write_to_buffer<int32>(&buffer, fChannels); 1592 write_to_buffer<uint32>(&buffer, fFlags); 1593 1594 return B_OK; 1595 } 1596 1597 1598 bool 1599 BParameter::AllowsTypeCode(type_code code) const 1600 { 1601 return code == TypeCode(); 1602 } 1603 1604 1605 status_t 1606 BParameter::Unflatten(type_code code, const void* buffer, ssize_t size) 1607 { 1608 CALLED(); 1609 1610 if (!AllowsTypeCode(code)) { 1611 ERROR("BParameter::Unflatten(): wrong type code\n"); 1612 return B_BAD_TYPE; 1613 } 1614 1615 if (buffer == NULL) { 1616 ERROR("BParameter::Unflatten(): buffer is NULL\n"); 1617 return B_NO_INIT; 1618 } 1619 1620 // if the buffer is smaller than the size needed to read the 1621 // signature and struct size fields, then there is a problem 1622 if (size < static_cast<ssize_t>(sizeof(int32) + sizeof(ssize_t))) { 1623 ERROR("BParameter::Unflatten() size too small\n"); 1624 return B_BAD_VALUE; 1625 } 1626 1627 const void* bufferStart = buffer; 1628 1629 // check magic 1630 1631 uint32 magic = read_from_buffer<uint32>(&buffer); 1632 if (magic == B_SWAP_INT32(kParameterMagic)) 1633 fSwapDetected = true; 1634 else if (magic == kParameterMagic) 1635 fSwapDetected = false; 1636 else { 1637 ERROR("BParameter::Unflatten(): bad magic\n"); 1638 return B_BAD_TYPE; 1639 } 1640 1641 ssize_t parameterSize = read_pointer_from_buffer_swap<ssize_t>(&buffer, 1642 fSwapDetected); 1643 if (parameterSize > size) { 1644 ERROR("BParameter::Unflatten(): buffer too small (%ld > %ld)\n", 1645 parameterSize, size); 1646 return B_BAD_VALUE; 1647 } 1648 1649 // if the struct doesn't meet the minimum size for 1650 // a flattened BParameter, then return an error. 1651 // MinFlattenedParamSize = 1652 // ID (4 bytes) 1653 // Name String Length (1 byte) 1654 // Kind String Length (1 byte) 1655 // Unit String Length (1 byte) 1656 // Inputs Count (4 bytes) 1657 // Outputs Count (4 bytes) 1658 // Media Type (4 bytes) 1659 // Channel Count (4 bytes) 1660 // Flags (4 bytes) 1661 // TOTAL: 27 bytes 1662 const ssize_t MinFlattenedParamSize(27); 1663 if (parameterSize < MinFlattenedParamSize) { 1664 ERROR("BParameter::Unflatten out of memory (2)\n"); 1665 return B_ERROR; 1666 } 1667 1668 fID = read_from_buffer_swap32<int32>(&buffer, fSwapDetected); 1669 1670 if (read_string_from_buffer(&buffer, &fName, 1671 size_left(size, bufferStart, buffer)) < B_OK 1672 || read_string_from_buffer(&buffer, &fKind, 1673 size_left(size, bufferStart, buffer)) < B_OK 1674 || read_string_from_buffer(&buffer, &fUnit, 1675 size_left(size, bufferStart, buffer)) < B_OK) 1676 return B_NO_MEMORY; 1677 1678 // read the list of inputs 1679 1680 // it will directly add the pointers in the flattened message to the list; 1681 // these will be fixed to point to the real inputs/outputs later in FixRefs() 1682 1683 int32 count = read_from_buffer_swap32<int32>(&buffer, fSwapDetected); 1684 1685 fInputs->MakeEmpty(); 1686 for (int32 i = 0; i < count; i++) { 1687 fInputs->AddItem(read_pointer_from_buffer_swap<BParameter * const>( 1688 &buffer, fSwapDetected)); 1689 } 1690 1691 // read the list of outputs 1692 1693 count = read_from_buffer_swap32<int32>(&buffer, fSwapDetected); 1694 1695 fOutputs->MakeEmpty(); 1696 for (int32 i = 0; i < count; i++) { 1697 fOutputs->AddItem(read_pointer_from_buffer_swap<BParameter * const>( 1698 &buffer, fSwapDetected)); 1699 } 1700 1701 fMediaType = read_from_buffer_swap32<media_type>(&buffer, fSwapDetected); 1702 fChannels = read_from_buffer_swap32<int32>(&buffer, fSwapDetected); 1703 fFlags = read_from_buffer_swap32<uint32>(&buffer, fSwapDetected); 1704 1705 return B_OK; 1706 } 1707 1708 1709 BParameter::BParameter(int32 id, media_type mediaType, 1710 media_parameter_type type, BParameterWeb* web, const char* name, 1711 const char* kind, const char* unit) 1712 : 1713 fID(id), 1714 fType(type), 1715 fWeb(web), 1716 fGroup(NULL), 1717 fSwapDetected(true), 1718 fMediaType(mediaType), 1719 fChannels(1), 1720 fFlags(0) 1721 { 1722 CALLED(); 1723 1724 fName = strndup(name, 255); 1725 fKind = strndup(kind, 255); 1726 fUnit = strndup(unit, 255); 1727 1728 // create empty input/output lists 1729 fInputs = new BList(); 1730 fOutputs = new BList(); 1731 } 1732 1733 1734 BParameter::~BParameter() 1735 { 1736 CALLED(); 1737 1738 // don't worry about the fWeb/fGroup properties, you don't need 1739 // to remove yourself from a web/group since the only way in which 1740 // a parameter is destroyed is when the owner web/group destroys it 1741 1742 free(fName); 1743 free(fKind); 1744 free(fUnit); 1745 1746 delete fInputs; 1747 delete fOutputs; 1748 } 1749 1750 1751 /*! Replaces references to items in the old list with the corresponding 1752 items in the updated list. The references are replaced in the input 1753 and output lists. 1754 This is called by BParameterWeb::Unflatten(). 1755 */ 1756 void 1757 BParameter::FixRefs(BList& old, BList& updated) 1758 { 1759 CALLED(); 1760 1761 // update inputs 1762 1763 void** items = static_cast<void**>(fInputs->Items()); 1764 int32 count = fInputs->CountItems(); 1765 1766 for (int32 i = 0; i < count; i++) { 1767 int32 index = old.IndexOf(items[i]); 1768 if (index >= 0) 1769 items[i] = updated.ItemAt(index); 1770 else { 1771 ERROR("BParameter::FixRefs(): No mapping found for input"); 1772 items[i] = NULL; 1773 } 1774 } 1775 1776 // remove all NULL inputs (those which couldn't be mapped) 1777 1778 for (int32 i = count; i-- > 0;) { 1779 if (items[i] == NULL) 1780 fInputs->RemoveItem(i); 1781 } 1782 1783 // update outputs 1784 1785 items = static_cast<void **>(fOutputs->Items()); 1786 count = fOutputs->CountItems(); 1787 1788 for (int32 i = 0; i < count; i++) { 1789 int32 index = old.IndexOf(items[i]); 1790 if (index >= 0) 1791 items[i] = updated.ItemAt(index); 1792 else { 1793 ERROR("BParameter::FixRefs(): No mapping found for output"); 1794 items[i] = NULL; 1795 } 1796 } 1797 1798 // remove all NULL outputs (those which couldn't be mapped) 1799 1800 for (int32 i = count; i-- > 0;) { 1801 if (items[i] == NULL) 1802 fOutputs->RemoveItem(i); 1803 } 1804 } 1805 1806 1807 // #pragma mark - public BContinuousParameter 1808 1809 1810 type_code 1811 BContinuousParameter::ValueType() 1812 { 1813 return B_FLOAT_TYPE; 1814 } 1815 1816 1817 float 1818 BContinuousParameter::MinValue() 1819 { 1820 return fMinimum; 1821 } 1822 1823 1824 float 1825 BContinuousParameter::MaxValue() 1826 { 1827 return fMaximum; 1828 } 1829 1830 1831 float 1832 BContinuousParameter::ValueStep() 1833 { 1834 return fStepping; 1835 } 1836 1837 1838 void 1839 BContinuousParameter::SetResponse(int resp, float factor, float offset) 1840 { 1841 fResponse = static_cast<response>(resp); 1842 fFactor = factor; 1843 fOffset = offset; 1844 } 1845 1846 1847 void 1848 BContinuousParameter::GetResponse(int* _resp, float* _factor, float* _offset) 1849 { 1850 if (_resp != NULL) 1851 *_resp = fResponse; 1852 if (_factor != NULL) 1853 *_factor = fFactor; 1854 if (_offset != NULL) 1855 *_offset = fOffset; 1856 } 1857 1858 1859 ssize_t 1860 BContinuousParameter::FlattenedSize() const 1861 { 1862 CALLED(); 1863 1864 // only adds a fixed amount of bytes 1865 return BParameter::FlattenedSize() + kAdditionalContinuousParameterSize; 1866 } 1867 1868 1869 status_t 1870 BContinuousParameter::Flatten(void* buffer, ssize_t size) const 1871 { 1872 CALLED(); 1873 1874 if (buffer == NULL) { 1875 ERROR("BContinuousParameter::Flatten(): buffer is NULL\n"); 1876 return B_NO_INIT; 1877 } 1878 1879 ssize_t parameterSize = BParameter::FlattenedSize(); 1880 if (size < (parameterSize + kAdditionalContinuousParameterSize)) { 1881 ERROR("BContinuousParameter::Flatten(): size to small\n"); 1882 return B_NO_MEMORY; 1883 } 1884 1885 status_t status = BParameter::Flatten(buffer, size); 1886 if (status != B_OK) { 1887 ERROR("BContinuousParameter::Flatten(): BParameter::Flatten() failed\n"); 1888 return status; 1889 } 1890 1891 // add our data to the general flattened BParameter 1892 1893 skip_in_buffer(&buffer, parameterSize); 1894 1895 write_to_buffer<float>(&buffer, fMinimum); 1896 write_to_buffer<float>(&buffer, fMaximum); 1897 write_to_buffer<float>(&buffer, fStepping); 1898 write_to_buffer<response>(&buffer, fResponse); 1899 write_to_buffer<float>(&buffer, fFactor); 1900 write_to_buffer<float>(&buffer, fOffset); 1901 1902 return B_OK; 1903 } 1904 1905 1906 status_t 1907 BContinuousParameter::Unflatten(type_code code, const void* buffer, 1908 ssize_t size) 1909 { 1910 CALLED(); 1911 1912 // we try to check if the buffer size is long enough to hold an object 1913 // as early as possible. 1914 1915 if (!AllowsTypeCode(code)) { 1916 ERROR("BContinuousParameter::Unflatten wrong type code\n"); 1917 return B_BAD_TYPE; 1918 } 1919 1920 if (buffer == NULL) { 1921 ERROR("BContinuousParameter::Unflatten buffer is NULL\n"); 1922 return B_NO_INIT; 1923 } 1924 1925 // if the buffer is smaller than the size needed to read the 1926 // signature and struct size fields, then there is a problem 1927 if (size < static_cast<ssize_t>(sizeof(int32) + sizeof(ssize_t))) { 1928 ERROR("BContinuousParameter::Unflatten size too small\n"); 1929 return B_ERROR; 1930 } 1931 1932 status_t status = BParameter::Unflatten(code, buffer, size); 1933 if (status != B_OK) { 1934 ERROR("BContinuousParameter::Unflatten(): BParameter::Unflatten " 1935 "failed: %s\n", strerror(status)); 1936 return status; 1937 } 1938 1939 ssize_t parameterSize = BParameter::FlattenedSize(); 1940 skip_in_buffer(&buffer, parameterSize); 1941 1942 if (size < (parameterSize + kAdditionalContinuousParameterSize)) { 1943 ERROR("BContinuousParameter::Unflatten(): buffer too small\n"); 1944 return B_BAD_VALUE; 1945 } 1946 1947 fMinimum = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten()); 1948 fMaximum = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten()); 1949 fStepping = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten()); 1950 fResponse = read_from_buffer_swap32<response>(&buffer, SwapOnUnflatten()); 1951 fFactor = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten()); 1952 fOffset = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten()); 1953 1954 return B_OK; 1955 } 1956 1957 1958 BContinuousParameter::BContinuousParameter(int32 id, media_type mediaType, 1959 BParameterWeb* web, const char* name, const char* kind, 1960 const char* unit, float minimum, float maximum, float stepping) 1961 : BParameter(id, mediaType, B_CONTINUOUS_PARAMETER, web, name, kind, unit), 1962 fMinimum(minimum), 1963 fMaximum(maximum), 1964 fStepping(stepping), 1965 fResponse(B_LINEAR), 1966 fFactor(1.0), 1967 fOffset(0.0) 1968 { 1969 CALLED(); 1970 } 1971 1972 1973 BContinuousParameter::~BContinuousParameter() 1974 { 1975 CALLED(); 1976 } 1977 1978 1979 // #pragma mark - public BDiscreteParameter 1980 1981 1982 type_code 1983 BDiscreteParameter::ValueType() 1984 { 1985 return B_INT32_TYPE; 1986 } 1987 1988 1989 int32 1990 BDiscreteParameter::CountItems() 1991 { 1992 return fValues->CountItems(); 1993 } 1994 1995 1996 const char* 1997 BDiscreteParameter::ItemNameAt(int32 index) 1998 { 1999 return reinterpret_cast<const char*>(fSelections->ItemAt(index)); 2000 } 2001 2002 2003 int32 2004 BDiscreteParameter::ItemValueAt(int32 index) 2005 { 2006 int32* item = static_cast<int32*>(fValues->ItemAt(index)); 2007 if (item == NULL) 2008 return 0; 2009 2010 return *item; 2011 } 2012 2013 2014 status_t 2015 BDiscreteParameter::AddItem(int32 value, const char* name) 2016 { 2017 CALLED(); 2018 2019 int32* valueCopy = new int32(value); 2020 char* nameCopy = strndup(name, 255); 2021 if (name != NULL && nameCopy == NULL) { 2022 delete valueCopy; 2023 return B_NO_MEMORY; 2024 } 2025 2026 if (!fValues->AddItem(valueCopy) || !fSelections->AddItem(nameCopy)) 2027 return B_NO_MEMORY; 2028 2029 return B_OK; 2030 } 2031 2032 2033 status_t 2034 BDiscreteParameter::MakeItemsFromInputs() 2035 { 2036 CALLED(); 2037 2038 int32 count = fInputs->CountItems(); 2039 for (int32 i = 0; i < count; i++) { 2040 BParameter* parameter = static_cast<BParameter*>(fInputs->ItemAt(i)); 2041 AddItem(i, parameter->Name()); 2042 } 2043 2044 return B_OK; 2045 } 2046 2047 2048 status_t 2049 BDiscreteParameter::MakeItemsFromOutputs() 2050 { 2051 CALLED(); 2052 2053 int32 count = fOutputs->CountItems(); 2054 for (int32 i = 0; i < count; i++) { 2055 BParameter* parameter = static_cast<BParameter*>(fOutputs->ItemAt(i)); 2056 AddItem(i, parameter->Name()); 2057 } 2058 2059 return B_OK; 2060 } 2061 2062 2063 void 2064 BDiscreteParameter::MakeEmpty() 2065 { 2066 CALLED(); 2067 2068 for (int32 i = fValues->CountItems(); i-- > 0;) { 2069 delete static_cast<int32*>(fValues->ItemAt(i)); 2070 } 2071 fValues->MakeEmpty(); 2072 2073 for (int32 i = fSelections->CountItems(); i-- > 0;) { 2074 free(static_cast<char*>(fSelections->ItemAt(i))); 2075 } 2076 fSelections->MakeEmpty(); 2077 } 2078 2079 2080 ssize_t 2081 BDiscreteParameter::FlattenedSize() const 2082 { 2083 CALLED(); 2084 2085 ssize_t size = BParameter::FlattenedSize() 2086 + kAdditionalDiscreteParameterSize; 2087 2088 int32 count = fValues->CountItems(); 2089 for (int32 i = 0; i < count; i++) { 2090 char* selection = static_cast<char*>(fSelections->ItemAt(i)); 2091 2092 if (selection != NULL) 2093 size += min_c(strlen(selection), 255); 2094 2095 size += 5; 2096 // string length + value 2097 } 2098 2099 return size; 2100 } 2101 2102 2103 status_t 2104 BDiscreteParameter::Flatten(void* buffer, ssize_t size) const 2105 { 2106 CALLED(); 2107 2108 if (buffer == NULL) { 2109 ERROR("BDiscreteParameter::Flatten(): buffer is NULL\n"); 2110 return B_NO_INIT; 2111 } 2112 2113 ssize_t parameterSize = BParameter::FlattenedSize(); 2114 2115 if (size < FlattenedSize()) { 2116 ERROR("BDiscreteParameter::Flatten(): size too small\n"); 2117 return B_NO_MEMORY; 2118 } 2119 2120 status_t status = BParameter::Flatten(buffer, size); 2121 if (status != B_OK) { 2122 ERROR("BDiscreteParameter::Flatten(): BParameter::Flatten failed\n"); 2123 return status; 2124 } 2125 2126 skip_in_buffer(&buffer, parameterSize); 2127 2128 int32 count = fValues->CountItems(); 2129 write_to_buffer<int32>(&buffer, count); 2130 2131 // write out all value/name pairs 2132 for (int32 i = 0; i < count; i++) { 2133 const char* selection = static_cast<char*>(fSelections->ItemAt(i)); 2134 const int32* value = static_cast<int32*>(fValues->ItemAt(i)); 2135 2136 write_string_to_buffer(&buffer, selection); 2137 write_to_buffer<int32>(&buffer, value ? *value : 0); 2138 } 2139 2140 return B_OK; 2141 } 2142 2143 2144 status_t 2145 BDiscreteParameter::Unflatten(type_code code, const void* buffer, ssize_t size) 2146 { 2147 CALLED(); 2148 2149 if (!AllowsTypeCode(code)) { 2150 ERROR("BDiscreteParameter::Unflatten(): bad type code\n"); 2151 return B_BAD_TYPE; 2152 } 2153 2154 if (buffer == NULL) { 2155 ERROR("BDiscreteParameter::Unflatten(): buffer is NULL\n"); 2156 return B_NO_INIT; 2157 } 2158 2159 // if the buffer is smaller than the size needed to read the 2160 // signature and struct size fields, then there is a problem 2161 if (size < static_cast<ssize_t>(sizeof(int32) + sizeof(ssize_t))) { 2162 ERROR("BDiscreteParameter::Unflatten(): size too small\n"); 2163 return B_ERROR; 2164 } 2165 2166 const void* bufferStart = buffer; 2167 2168 status_t status = BParameter::Unflatten(code, buffer, size); 2169 if (status != B_OK) { 2170 ERROR("BDiscreteParameter::Unflatten(): BParameter::Unflatten failed\n"); 2171 return status; 2172 } 2173 2174 ssize_t parameterSize = BParameter::FlattenedSize(); 2175 skip_in_buffer(&buffer, parameterSize); 2176 2177 if (size < (parameterSize + kAdditionalDiscreteParameterSize)) { 2178 ERROR("BDiscreteParameter::Unflatten(): buffer too small\n"); 2179 return B_BAD_VALUE; 2180 } 2181 2182 int32 count = read_from_buffer_swap32<int32>(&buffer, SwapOnUnflatten()); 2183 2184 // clear any existing name/value pairs 2185 MakeEmpty(); 2186 2187 for (int32 i = 0; i < count; i++) { 2188 char* name; 2189 if (read_string_from_buffer(&buffer, &name, size_left(size, bufferStart, 2190 buffer)) < B_OK) 2191 return B_BAD_DATA; 2192 2193 if (size_left(size, bufferStart, buffer) < (int)sizeof(int32)) { 2194 free(name); 2195 return B_BAD_DATA; 2196 } 2197 2198 int32 value = read_from_buffer_swap32<int32>(&buffer, 2199 SwapOnUnflatten()); 2200 2201 AddItem(value, name); 2202 free(name); 2203 } 2204 2205 return B_OK; 2206 } 2207 2208 2209 BDiscreteParameter::BDiscreteParameter(int32 id, media_type mediaType, 2210 BParameterWeb* web, const char* name, const char* kind) 2211 : BParameter(id, mediaType, B_DISCRETE_PARAMETER, web, name, kind, NULL) 2212 { 2213 CALLED(); 2214 2215 fSelections = new BList(); 2216 fValues = new BList(); 2217 } 2218 2219 2220 BDiscreteParameter::~BDiscreteParameter() 2221 { 2222 CALLED(); 2223 2224 MakeEmpty(); 2225 2226 delete fSelections; 2227 delete fValues; 2228 } 2229 2230 2231 // #pragma mark - public BTextParameter 2232 2233 2234 size_t 2235 BTextParameter::MaxBytes() const 2236 { 2237 return fMaxBytes; 2238 } 2239 2240 2241 type_code 2242 BTextParameter::ValueType() 2243 { 2244 return B_FLOAT_TYPE; 2245 } 2246 2247 2248 ssize_t 2249 BTextParameter::FlattenedSize() const 2250 { 2251 return BParameter::FlattenedSize() + sizeof(fMaxBytes); 2252 } 2253 2254 2255 status_t 2256 BTextParameter::Flatten(void* buffer, ssize_t size) const 2257 { 2258 if (buffer == NULL) { 2259 ERROR("BTextParameter::Flatten(): buffer is NULL\n"); 2260 return B_NO_INIT; 2261 } 2262 2263 ssize_t parameterSize = BParameter::FlattenedSize(); 2264 if (size < static_cast<ssize_t>(parameterSize + sizeof(fMaxBytes))) { 2265 ERROR("BContinuousParameter::Flatten(): size to small\n"); 2266 return B_NO_MEMORY; 2267 } 2268 2269 status_t status = BParameter::Flatten(buffer, size); 2270 if (status != B_OK) { 2271 ERROR("BTextParameter::Flatten(): BParameter::Flatten() failed\n"); 2272 return status; 2273 } 2274 2275 // add our data to the general flattened BParameter 2276 2277 skip_in_buffer(&buffer, parameterSize); 2278 2279 write_to_buffer<uint32>(&buffer, fMaxBytes); 2280 2281 return B_OK; 2282 } 2283 2284 2285 status_t 2286 BTextParameter::Unflatten(type_code code, const void* buffer, ssize_t size) 2287 { 2288 // we try to check if the buffer size is long enough to hold an object 2289 // as early as possible. 2290 2291 if (!AllowsTypeCode(code)) { 2292 ERROR("BTextParameter::Unflatten wrong type code\n"); 2293 return B_BAD_TYPE; 2294 } 2295 2296 if (buffer == NULL) { 2297 ERROR("BTextParameter::Unflatten buffer is NULL\n"); 2298 return B_NO_INIT; 2299 } 2300 2301 if (size < static_cast<ssize_t>(sizeof(fMaxBytes))) { 2302 ERROR("BTextParameter::Unflatten size too small\n"); 2303 return B_ERROR; 2304 } 2305 2306 status_t status = BParameter::Unflatten(code, buffer, size); 2307 if (status != B_OK) { 2308 ERROR("BTextParameter::Unflatten(): BParameter::Unflatten failed\n"); 2309 return status; 2310 } 2311 2312 ssize_t parameterSize = BParameter::FlattenedSize(); 2313 skip_in_buffer(&buffer, parameterSize); 2314 2315 if (size < static_cast<ssize_t>(parameterSize + sizeof(fMaxBytes))) { 2316 ERROR("BTextParameter::Unflatten(): buffer too small\n"); 2317 return B_BAD_VALUE; 2318 } 2319 2320 fMaxBytes = read_from_buffer_swap32<uint32>(&buffer, SwapOnUnflatten()); 2321 2322 return B_OK; 2323 } 2324 2325 2326 BTextParameter::BTextParameter(int32 id, media_type mediaType, 2327 BParameterWeb* web, const char* name, const char* kind, 2328 size_t maxBytes) 2329 : BParameter(id, mediaType, B_TEXT_PARAMETER, web, name, kind, NULL) 2330 { 2331 fMaxBytes = maxBytes; 2332 } 2333 2334 2335 BTextParameter::~BTextParameter() 2336 { 2337 } 2338 2339 2340 // #pragma mark - public BNullParameter 2341 2342 2343 type_code 2344 BNullParameter::ValueType() 2345 { 2346 // NULL parameters have no value type 2347 return 0; 2348 } 2349 2350 2351 ssize_t 2352 BNullParameter::FlattenedSize() const 2353 { 2354 return BParameter::FlattenedSize(); 2355 } 2356 2357 2358 status_t 2359 BNullParameter::Flatten(void* buffer, ssize_t size) const 2360 { 2361 return BParameter::Flatten(buffer, size); 2362 } 2363 2364 2365 status_t 2366 BNullParameter::Unflatten(type_code code, const void* buffer, ssize_t size) 2367 { 2368 return BParameter::Unflatten(code, buffer, size); 2369 } 2370 2371 2372 BNullParameter::BNullParameter(int32 id, media_type mediaType, 2373 BParameterWeb* web, const char* name, const char* kind) 2374 : BParameter(id, mediaType, B_NULL_PARAMETER, web, name, kind, NULL) 2375 { 2376 } 2377 2378 2379 BNullParameter::~BNullParameter() 2380 { 2381 } 2382 2383 2384 // #pragma mark - reserved functions 2385 2386 2387 status_t BParameterWeb::_Reserved_ControlWeb_0(void *) { return B_ERROR; } 2388 status_t BParameterWeb::_Reserved_ControlWeb_1(void *) { return B_ERROR; } 2389 status_t BParameterWeb::_Reserved_ControlWeb_2(void *) { return B_ERROR; } 2390 status_t BParameterWeb::_Reserved_ControlWeb_3(void *) { return B_ERROR; } 2391 status_t BParameterWeb::_Reserved_ControlWeb_4(void *) { return B_ERROR; } 2392 status_t BParameterWeb::_Reserved_ControlWeb_5(void *) { return B_ERROR; } 2393 status_t BParameterWeb::_Reserved_ControlWeb_6(void *) { return B_ERROR; } 2394 status_t BParameterWeb::_Reserved_ControlWeb_7(void *) { return B_ERROR; } 2395 2396 status_t BParameterGroup::_Reserved_ControlGroup_0(void *) { return B_ERROR; } 2397 status_t BParameterGroup::_Reserved_ControlGroup_1(void *) { return B_ERROR; } 2398 status_t BParameterGroup::_Reserved_ControlGroup_2(void *) { return B_ERROR; } 2399 status_t BParameterGroup::_Reserved_ControlGroup_3(void *) { return B_ERROR; } 2400 status_t BParameterGroup::_Reserved_ControlGroup_4(void *) { return B_ERROR; } 2401 status_t BParameterGroup::_Reserved_ControlGroup_5(void *) { return B_ERROR; } 2402 status_t BParameterGroup::_Reserved_ControlGroup_6(void *) { return B_ERROR; } 2403 status_t BParameterGroup::_Reserved_ControlGroup_7(void *) { return B_ERROR; } 2404 2405 status_t BParameter::_Reserved_Control_0(void *) { return B_ERROR; } 2406 status_t BParameter::_Reserved_Control_1(void *) { return B_ERROR; } 2407 status_t BParameter::_Reserved_Control_2(void *) { return B_ERROR; } 2408 status_t BParameter::_Reserved_Control_3(void *) { return B_ERROR; } 2409 status_t BParameter::_Reserved_Control_4(void *) { return B_ERROR; } 2410 status_t BParameter::_Reserved_Control_5(void *) { return B_ERROR; } 2411 status_t BParameter::_Reserved_Control_6(void *) { return B_ERROR; } 2412 status_t BParameter::_Reserved_Control_7(void *) { return B_ERROR; } 2413 2414 status_t BContinuousParameter::_Reserved_ContinuousParameter_0(void *) { return B_ERROR; } 2415 status_t BContinuousParameter::_Reserved_ContinuousParameter_1(void *) { return B_ERROR; } 2416 status_t BContinuousParameter::_Reserved_ContinuousParameter_2(void *) { return B_ERROR; } 2417 status_t BContinuousParameter::_Reserved_ContinuousParameter_3(void *) { return B_ERROR; } 2418 status_t BContinuousParameter::_Reserved_ContinuousParameter_4(void *) { return B_ERROR; } 2419 status_t BContinuousParameter::_Reserved_ContinuousParameter_5(void *) { return B_ERROR; } 2420 status_t BContinuousParameter::_Reserved_ContinuousParameter_6(void *) { return B_ERROR; } 2421 status_t BContinuousParameter::_Reserved_ContinuousParameter_7(void *) { return B_ERROR; } 2422 2423 status_t BDiscreteParameter::_Reserved_DiscreteParameter_0(void *) { return B_ERROR; } 2424 status_t BDiscreteParameter::_Reserved_DiscreteParameter_1(void *) { return B_ERROR; } 2425 status_t BDiscreteParameter::_Reserved_DiscreteParameter_2(void *) { return B_ERROR; } 2426 status_t BDiscreteParameter::_Reserved_DiscreteParameter_3(void *) { return B_ERROR; } 2427 status_t BDiscreteParameter::_Reserved_DiscreteParameter_4(void *) { return B_ERROR; } 2428 status_t BDiscreteParameter::_Reserved_DiscreteParameter_5(void *) { return B_ERROR; } 2429 status_t BDiscreteParameter::_Reserved_DiscreteParameter_6(void *) { return B_ERROR; } 2430 status_t BDiscreteParameter::_Reserved_DiscreteParameter_7(void *) { return B_ERROR; } 2431 2432 status_t BNullParameter::_Reserved_NullParameter_0(void *) { return B_ERROR; } 2433 status_t BNullParameter::_Reserved_NullParameter_1(void *) { return B_ERROR; } 2434 status_t BNullParameter::_Reserved_NullParameter_2(void *) { return B_ERROR; } 2435 status_t BNullParameter::_Reserved_NullParameter_3(void *) { return B_ERROR; } 2436 status_t BNullParameter::_Reserved_NullParameter_4(void *) { return B_ERROR; } 2437 status_t BNullParameter::_Reserved_NullParameter_5(void *) { return B_ERROR; } 2438 status_t BNullParameter::_Reserved_NullParameter_6(void *) { return B_ERROR; } 2439 status_t BNullParameter::_Reserved_NullParameter_7(void *) { return B_ERROR; } 2440 2441 status_t BTextParameter::_Reserved_TextParameter_0(void *) { return B_ERROR; } 2442 status_t BTextParameter::_Reserved_TextParameter_1(void *) { return B_ERROR; } 2443 status_t BTextParameter::_Reserved_TextParameter_2(void *) { return B_ERROR; } 2444 status_t BTextParameter::_Reserved_TextParameter_3(void *) { return B_ERROR; } 2445 status_t BTextParameter::_Reserved_TextParameter_4(void *) { return B_ERROR; } 2446 status_t BTextParameter::_Reserved_TextParameter_5(void *) { return B_ERROR; } 2447 status_t BTextParameter::_Reserved_TextParameter_6(void *) { return B_ERROR; } 2448 status_t BTextParameter::_Reserved_TextParameter_7(void *) { return B_ERROR; } 2449