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