1 /* 2 * Copyright 2002-2007, Haiku Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ingo Weinhold, bonefish@users.sf.net 7 */ 8 9 10 #include <new> 11 #include <set> 12 #include <stdlib.h> 13 #include <string> 14 15 #include <AppFileInfo.h> 16 #include <Bitmap.h> 17 #include <File.h> 18 #include <fs_attr.h> 19 #include <IconUtils.h> 20 #include <MimeType.h> 21 #include <RegistrarDefs.h> 22 #include <Resources.h> 23 #include <Roster.h> 24 #include <String.h> 25 26 using namespace std; 27 28 // attributes 29 static const char *kTypeAttribute = "BEOS:TYPE"; 30 static const char *kSignatureAttribute = "BEOS:APP_SIG"; 31 static const char *kAppFlagsAttribute = "BEOS:APP_FLAGS"; 32 static const char *kSupportedTypesAttribute = "BEOS:FILE_TYPES"; 33 static const char *kVersionInfoAttribute = "BEOS:APP_VERSION"; 34 static const char *kMiniIconAttribute = "BEOS:M:"; 35 static const char *kLargeIconAttribute = "BEOS:L:"; 36 static const char *kIconAttribute = "BEOS:"; 37 static const char *kStandardIconType = "STD_ICON"; 38 static const char *kIconType = "ICON"; 39 40 // resource IDs 41 static const int32 kTypeResourceID = 2; 42 static const int32 kSignatureResourceID = 1; 43 static const int32 kAppFlagsResourceID = 1; 44 static const int32 kSupportedTypesResourceID = 1; 45 static const int32 kMiniIconResourceID = 101; 46 static const int32 kLargeIconResourceID = 101; 47 static const int32 kIconResourceID = 101; 48 static const int32 kVersionInfoResourceID = 1; 49 static const int32 kMiniIconForTypeResourceID = 0; 50 static const int32 kLargeIconForTypeResourceID = 0; 51 static const int32 kIconForTypeResourceID = 0; 52 53 // type codes 54 enum { 55 B_APP_FLAGS_TYPE = 'APPF', 56 B_VERSION_INFO_TYPE = 'APPV', 57 }; 58 59 // R5 also exports these (Tracker is using them): 60 // (maybe we better want to drop them silently and declare 61 // the above in a public Haiku header - and use that one in 62 // Tracker when compiled for Haiku) 63 extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE; 64 const uint32 MINI_ICON_TYPE = 'MICN'; 65 const uint32 LARGE_ICON_TYPE = 'ICON'; 66 67 // debugging 68 //#define DBG(x) x 69 #define DBG(x) 70 #define OUT printf 71 72 // constructor 73 /*! \brief Creates an uninitialized BAppFileInfo object. 74 */ 75 BAppFileInfo::BAppFileInfo() 76 : fResources(NULL), 77 fWhere(B_USE_BOTH_LOCATIONS) 78 { 79 } 80 81 // constructor 82 /*! \brief Creates an BAppFileInfo object and initializes it to the supplied 83 file. 84 85 The caller retains ownership of the supplied BFile object. It must not 86 be deleted during the life time of the BAppFileInfo. It is not deleted 87 when the BAppFileInfo is destroyed. 88 89 \param file The file the object shall be initialized to. 90 */ 91 BAppFileInfo::BAppFileInfo(BFile *file) 92 : fResources(NULL), 93 fWhere(B_USE_BOTH_LOCATIONS) 94 { 95 SetTo(file); 96 } 97 98 // destructor 99 /*! \brief Frees all resources associated with this object. 100 101 The BFile the object is set to is not deleted. 102 */ 103 BAppFileInfo::~BAppFileInfo() 104 { 105 delete fResources; 106 } 107 108 // SetTo 109 /*! \brief Initializes the BAppFileInfo to the supplied file. 110 111 The caller retains ownership of the supplied BFile object. It must not 112 be deleted during the life time of the BAppFileInfo. It is not deleted 113 when the BAppFileInfo is destroyed. 114 115 \param file The file the object shall be initialized to. 116 117 \return 118 - \c B_OK: Everything went fine. 119 - \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized. 120 */ 121 status_t 122 BAppFileInfo::SetTo(BFile *file) 123 { 124 // unset the old file 125 BNodeInfo::SetTo(NULL); 126 if (fResources) { 127 delete fResources; 128 fResources = NULL; 129 } 130 131 // check param 132 status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 133 134 info_location where = B_USE_BOTH_LOCATIONS; 135 136 // create resources 137 if (error == B_OK) { 138 fResources = new(nothrow) BResources(); 139 if (fResources) { 140 error = fResources->SetTo(file); 141 if (error != B_OK) { 142 // no resources - this is no critical error, we'll just use 143 // attributes only, then 144 where = B_USE_ATTRIBUTES; 145 error = B_OK; 146 } 147 } else 148 error = B_NO_MEMORY; 149 } 150 151 // set node info 152 if (error == B_OK) 153 error = BNodeInfo::SetTo(file); 154 155 if (error != B_OK || (where & B_USE_RESOURCES) == 0) { 156 delete fResources; 157 fResources = NULL; 158 } 159 160 // clean up on error 161 if (error != B_OK) { 162 if (InitCheck() == B_OK) 163 BNodeInfo::SetTo(NULL); 164 } 165 166 // set data location 167 if (error == B_OK) 168 SetInfoLocation(where); 169 170 // set error 171 fCStatus = error; 172 return error; 173 } 174 175 // GetType 176 /*! \brief Gets the file's MIME type. 177 178 \param type A pointer to a pre-allocated character buffer of size 179 \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the 180 file shall be written. 181 \return 182 - \c B_OK: Everything went fine. 183 - \c B_NO_INIT: The object is not properly initialized. 184 - \c B_BAD_VALUE: \c NULL \a type or the type string stored in the 185 attribute/resources is longer than \c B_MIME_TYPE_LENGTH. 186 - \c B_BAD_TYPE: The attribute/resources the type string is stored in have 187 the wrong type. 188 - \c B_ENTRY_NOT_FOUND: No type is set on the file. 189 - other error codes 190 */ 191 status_t 192 BAppFileInfo::GetType(char *type) const 193 { 194 // check param and initialization 195 status_t error = (type ? B_OK : B_BAD_VALUE); 196 if (error == B_OK && InitCheck() != B_OK) 197 error = B_NO_INIT; 198 // read the data 199 size_t read = 0; 200 if (error == B_OK) { 201 error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE, 202 type, B_MIME_TYPE_LENGTH, read); 203 } 204 // check the read data -- null terminate the string 205 if (error == B_OK && type[read - 1] != '\0') { 206 if (read == B_MIME_TYPE_LENGTH) 207 error = B_ERROR; 208 else 209 type[read] = '\0'; 210 } 211 return error; 212 } 213 214 // SetType 215 /*! \brief Sets the file's MIME type. 216 217 If \a type is \c NULL the file's MIME type is unset. 218 219 \param type The MIME type to be assigned to the file. Must not be longer 220 than \c B_MIME_TYPE_LENGTH (including the terminating null). 221 May be \c NULL. 222 \return 223 - \c B_OK: Everything went fine. 224 - \c B_NO_INIT: The object is not properly initialized. 225 - \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH. 226 - other error codes 227 */ 228 status_t 229 BAppFileInfo::SetType(const char *type) 230 { 231 // check initialization 232 status_t error = B_OK; 233 if (error == B_OK && InitCheck() != B_OK) 234 error = B_NO_INIT; 235 if (error == B_OK) { 236 if (type) { 237 // check param 238 size_t typeLen = strlen(type); 239 if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH) 240 error = B_BAD_VALUE; 241 // write the data 242 if (error == B_OK) { 243 error = _WriteData(kTypeAttribute, kTypeResourceID, 244 B_MIME_STRING_TYPE, type, typeLen + 1); 245 } 246 } else 247 error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE); 248 } 249 return error; 250 } 251 252 // GetSignature 253 /*! \brief Gets the file's application signature. 254 255 \param signature A pointer to a pre-allocated character buffer of size 256 \c B_MIME_TYPE_LENGTH or larger into which the application 257 signature of the file shall be written. 258 \return 259 - \c B_OK: Everything went fine. 260 - \c B_NO_INIT: The object is not properly initialized. 261 - \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the 262 attribute/resources is longer than \c B_MIME_TYPE_LENGTH. 263 - \c B_BAD_TYPE: The attribute/resources the signature is stored in have 264 the wrong type. 265 - \c B_ENTRY_NOT_FOUND: No signature is set on the file. 266 - other error codes 267 */ 268 status_t 269 BAppFileInfo::GetSignature(char *signature) const 270 { 271 // check param and initialization 272 status_t error = (signature ? B_OK : B_BAD_VALUE); 273 if (error == B_OK && InitCheck() != B_OK) 274 error = B_NO_INIT; 275 // read the data 276 size_t read = 0; 277 if (error == B_OK) { 278 error = _ReadData(kSignatureAttribute, kSignatureResourceID, 279 B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH, 280 read); 281 } 282 // check the read data -- null terminate the string 283 if (error == B_OK && signature[read - 1] != '\0') { 284 if (read == B_MIME_TYPE_LENGTH) 285 error = B_ERROR; 286 else 287 signature[read] = '\0'; 288 } 289 return error; 290 } 291 292 // SetSignature 293 /*! \brief Sets the file's application signature. 294 295 If \a signature is \c NULL the file's application signature is unset. 296 297 \param signature The application signature to be assigned to the file. 298 Must not be longer than \c B_MIME_TYPE_LENGTH (including the 299 terminating null). May be \c NULL. 300 \return 301 - \c B_OK: Everything went fine. 302 - \c B_NO_INIT: The object is not properly initialized. 303 - \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH. 304 - other error codes 305 */ 306 status_t 307 BAppFileInfo::SetSignature(const char *signature) 308 { 309 // check initialization 310 status_t error = B_OK; 311 if (error == B_OK && InitCheck() != B_OK) 312 error = B_NO_INIT; 313 if (error == B_OK) { 314 if (signature) { 315 // check param 316 size_t signatureLen = strlen(signature); 317 if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH) 318 error = B_BAD_VALUE; 319 // write the data 320 if (error == B_OK) { 321 error = _WriteData(kSignatureAttribute, kSignatureResourceID, 322 B_MIME_STRING_TYPE, signature, 323 signatureLen + 1); 324 } 325 } else 326 error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE); 327 } 328 return error; 329 } 330 331 // GetAppFlags 332 /*! \brief Gets the file's application flags. 333 334 \param flags A pointer to a pre-allocated uint32 into which the application 335 flags of the file shall be written. 336 \return 337 - \c B_OK: Everything went fine. 338 - \c B_NO_INIT: The object is not properly initialized. 339 - \c B_BAD_VALUE: \c NULL \a flags. 340 - \c B_BAD_TYPE: The attribute/resources the flags are stored in have 341 the wrong type. 342 - \c B_ENTRY_NOT_FOUND: No application flags are set on the file. 343 - other error codes 344 */ 345 status_t 346 BAppFileInfo::GetAppFlags(uint32 *flags) const 347 { 348 // check param and initialization 349 status_t error = (flags ? B_OK : B_BAD_VALUE); 350 if (error == B_OK && InitCheck() != B_OK) 351 error = B_NO_INIT; 352 // read the data 353 size_t read = 0; 354 if (error == B_OK) { 355 error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID, 356 B_APP_FLAGS_TYPE, flags, sizeof(uint32), 357 read); 358 } 359 // check the read data 360 if (error == B_OK && read != sizeof(uint32)) 361 error = B_ERROR; 362 return error; 363 } 364 365 // SetAppFlags 366 /*! \brief Sets the file's application flags. 367 \param flags The application flags to be assigned to the file. 368 \return 369 - \c B_OK: Everything went fine. 370 - \c B_NO_INIT: The object is not properly initialized. 371 - other error codes 372 */ 373 status_t 374 BAppFileInfo::SetAppFlags(uint32 flags) 375 { 376 // check initialization 377 status_t error = B_OK; 378 if (error == B_OK && InitCheck() != B_OK) 379 error = B_NO_INIT; 380 if (error == B_OK) { 381 // write the data 382 error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID, 383 B_APP_FLAGS_TYPE, &flags, sizeof(uint32)); 384 } 385 return error; 386 } 387 388 // RemoveAppFlags 389 /*! \brief Removes the file's application flags. 390 \return 391 - \c B_OK: Everything went fine. 392 - \c B_NO_INIT: The object is not properly initialized. 393 - other error codes 394 */ 395 status_t 396 BAppFileInfo::RemoveAppFlags() 397 { 398 // check initialization 399 status_t error = B_OK; 400 if (error == B_OK && InitCheck() != B_OK) 401 error = B_NO_INIT; 402 if (error == B_OK) { 403 // remove the data 404 error = _RemoveData(kAppFlagsAttribute, B_APP_FLAGS_TYPE); 405 } 406 return error; 407 } 408 409 // GetSupportedTypes 410 /*! \brief Gets the MIME types supported by the application. 411 412 The supported MIME types are added to a field "types" of type 413 \c B_STRING_TYPE in \a types. 414 415 \param types A pointer to a pre-allocated BMessage into which the 416 MIME types supported by the appplication shall be written. 417 \return 418 - \c B_OK: Everything went fine. 419 - \c B_NO_INIT: The object is not properly initialized. 420 - \c B_BAD_VALUE: \c NULL \a types. 421 - \c B_BAD_TYPE: The attribute/resources the supported types are stored in 422 have the wrong type. 423 - \c B_ENTRY_NOT_FOUND: No supported types are set on the file. 424 - other error codes 425 */ 426 status_t 427 BAppFileInfo::GetSupportedTypes(BMessage *types) const 428 { 429 // check param and initialization 430 status_t error = (types ? B_OK : B_BAD_VALUE); 431 if (error == B_OK && InitCheck() != B_OK) 432 error = B_NO_INIT; 433 // read the data 434 size_t read = 0; 435 void *buffer = NULL; 436 if (error == B_OK) { 437 error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID, 438 B_MESSAGE_TYPE, NULL, 0, read, &buffer); 439 } 440 // unflatten the buffer 441 if (error == B_OK) 442 error = types->Unflatten((const char*)buffer); 443 // clean up 444 if (buffer) 445 free(buffer); 446 return error; 447 } 448 449 // SetSupportedTypes 450 /*! \brief Sets the MIME types supported by the application. 451 452 If \a types is \c NULL the application's supported types are unset. 453 454 The supported MIME types must be stored in a field "types" of type 455 \c B_STRING_TYPE in \a types. 456 457 The method informs the registrar about this news. 458 For each supported type the result of BMimeType::GetSupportingApps() will 459 afterwards include the signature of this application. That is, the 460 application file needs to have a signature set. 461 462 \a syncAll specifies whether the not longer supported types shall be 463 updated as well, i.e. whether this application shall be remove from the 464 lists of supporting applications. 465 466 \param types The supported types to be assigned to the file. 467 May be \c NULL. 468 \param syncAll \c true to also synchronize the not longer supported 469 types, \c false otherwise. 470 \return 471 - \c B_OK: Everything went fine. 472 - \c B_NO_INIT: The object is not properly initialized. 473 - other error codes 474 */ 475 status_t 476 BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll) 477 { 478 // check initialization 479 status_t error = B_OK; 480 if (error == B_OK && InitCheck() != B_OK) 481 error = B_NO_INIT; 482 BMimeType mimeType; 483 if (error == B_OK) 484 error = GetMetaMime(&mimeType); 485 if (error == B_OK || error == B_ENTRY_NOT_FOUND) { 486 error = B_OK; 487 if (types) { 488 // check param -- supported types must be valid 489 const char *type; 490 for (int32 i = 0; 491 error == B_OK && types->FindString("types", i, &type) == B_OK; 492 i++) { 493 if (!BMimeType::IsValid(type)) 494 error = B_BAD_VALUE; 495 } 496 // get flattened size 497 ssize_t size = 0; 498 if (error == B_OK) { 499 size = types->FlattenedSize(); 500 if (size < 0) 501 error = size; 502 } 503 // allocate a buffer for the flattened data 504 char *buffer = NULL; 505 if (error == B_OK) { 506 buffer = new(nothrow) char[size]; 507 if (!buffer) 508 error = B_NO_MEMORY; 509 } 510 // flatten the message 511 if (error == B_OK) 512 error = types->Flatten(buffer, size); 513 // write the data 514 if (error == B_OK) { 515 error = _WriteData(kSupportedTypesAttribute, 516 kSupportedTypesResourceID, B_MESSAGE_TYPE, 517 buffer, size); 518 } 519 // clean up 520 if (buffer) 521 delete[] buffer; 522 } else 523 error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE); 524 // update the MIME database, if the app signature is installed 525 if (error == B_OK && mimeType.IsInstalled()) 526 error = mimeType.SetSupportedTypes(types, syncAll); 527 } 528 return error; 529 } 530 531 // SetSupportedTypes 532 /*! \brief Sets the MIME types supported by the application. 533 534 This method is a short-hand for SetSupportedTypes(types, false). 535 \see SetSupportedType(const BMessage*, bool) for detailed information. 536 537 \param types The supported types to be assigned to the file. 538 May be \c NULL. 539 \return 540 - \c B_OK: Everything went fine. 541 - \c B_NO_INIT: The object is not properly initialized. 542 - other error codes 543 */ 544 status_t 545 BAppFileInfo::SetSupportedTypes(const BMessage *types) 546 { 547 return SetSupportedTypes(types, false); 548 } 549 550 // IsSupportedType 551 /*! \brief Returns whether the application supports the supplied MIME type. 552 553 If the application supports the wildcard type "application/octet-stream" 554 any this method returns \c true for any MIME type. 555 556 \param type The MIME type in question. 557 \return \c true, if \a type is a valid MIME type and it is supported by 558 the application, \c false otherwise. 559 */ 560 bool 561 BAppFileInfo::IsSupportedType(const char *type) const 562 { 563 status_t error = (type ? B_OK : B_BAD_VALUE); 564 // get the supported types 565 BMessage types; 566 if (error == B_OK) 567 error = GetSupportedTypes(&types); 568 // turn type into a BMimeType 569 BMimeType mimeType; 570 if (error == B_OK) 571 error = mimeType.SetTo(type); 572 // iterate through the supported types 573 bool found = false; 574 if (error == B_OK) { 575 const char *supportedType; 576 for (int32 i = 0; 577 !found && types.FindString("types", i, &supportedType) == B_OK; 578 i++) { 579 found = !strcmp(supportedType, "application/octet-stream") 580 || BMimeType(supportedType).Contains(&mimeType); 581 } 582 } 583 return found; 584 } 585 586 // Supports 587 /*! \brief Returns whether the application supports the supplied MIME type 588 explicitly. 589 590 Unlike IsSupportedType(), this method returns \c true, only if the type 591 is explicitly supported, regardless of whether it supports 592 "application/octet-stream". 593 594 \param type The MIME type in question. 595 \return \c true, if \a type is a valid MIME type and it is explicitly 596 supported by the application, \c false otherwise. 597 */ 598 bool 599 BAppFileInfo::Supports(BMimeType *type) const 600 { 601 status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 602 // get the supported types 603 BMessage types; 604 if (error == B_OK) 605 error = GetSupportedTypes(&types); 606 // iterate through the supported types 607 bool found = false; 608 if (error == B_OK) { 609 const char *supportedType; 610 for (int32 i = 0; 611 !found && types.FindString("types", i, &supportedType) == B_OK; 612 i++) { 613 found = BMimeType(supportedType).Contains(type); 614 } 615 } 616 return found; 617 } 618 619 // GetIcon 620 /*! \brief Gets the file's icon. 621 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 622 to store the requested icon (16x16 for the mini and 32x32 for the 623 large icon). 624 \param which Specifies the size of the icon to be retrieved: 625 \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 626 \return 627 - \c B_OK: Everything went fine. 628 - \c B_NO_INIT: The object is not properly initialized. 629 - \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap 630 dimensions (\a icon) and icon size (\a which) do not match. 631 - other error codes 632 */ 633 status_t 634 BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const 635 { 636 return GetIconForType(NULL, icon, which); 637 } 638 639 // GetIcon 640 /*! \brief Gets the file's icon. 641 \param data The pointer in which the flat icon data will be returned. 642 \param size The pointer in which the size of the data found will be returned. 643 \return 644 - \c B_OK: Everything went fine. 645 - \c B_NO_INIT: The object is not properly initialized. 646 - \c B_BAD_VALUE: \c NULL \a data or \c NULL size. 647 - other error codes 648 */ 649 status_t 650 BAppFileInfo::GetIcon(uint8** data, size_t* size) const 651 { 652 return GetIconForType(NULL, data, size); 653 } 654 655 // SetIcon 656 /*! \brief Sets the file's icon. 657 658 If \a icon is \c NULL the file's icon is unset. 659 660 \param icon A pointer to the BBitmap containing the icon to be set. 661 May be \c NULL. 662 \param which Specifies the size of the icon to be set: \c B_MINI_ICON 663 for the mini and \c B_LARGE_ICON for the large icon. 664 \return 665 - \c B_OK: Everything went fine. 666 - \c B_NO_INIT: The object is not properly initialized. 667 - \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon) 668 and icon size (\a which) do not match. 669 - other error codes 670 */ 671 status_t 672 BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which) 673 { 674 return SetIconForType(NULL, icon, which); 675 } 676 677 // SetIcon 678 /*! \brief Sets the file's icon. 679 680 If \a icon is \c NULL the file's icon is unset. 681 682 \param data A pointer to the data buffer containing the vector icon 683 to be set. May be \c NULL. 684 \param size Specifies the size of buffer pointed to by \a data. 685 \return 686 - \c B_OK: Everything went fine. 687 - \c B_NO_INIT: The object is not properly initialized. 688 - \c B_BAD_VALUE: \c NULL data. 689 - other error codes 690 */ 691 status_t 692 BAppFileInfo::SetIcon(const uint8* data, size_t size) 693 { 694 return SetIconForType(NULL, data, size); 695 } 696 697 // GetVersionInfo 698 /*! \brief Gets the file's version info. 699 \param info A pointer to a pre-allocated version_info structure into which 700 the version info should be written. 701 \param kind Specifies the kind of the version info to be retrieved: 702 \c B_APP_VERSION_KIND for the application's version info and 703 \c B_SYSTEM_VERSION_KIND for the suite's info the application 704 belongs to. 705 \return 706 - \c B_OK: Everything went fine. 707 - \c B_NO_INIT: The object is not properly initialized. 708 - \c B_BAD_VALUE: \c NULL \a info. 709 - other error codes 710 */ 711 status_t 712 BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const 713 { 714 // check params and initialization 715 if (!info) 716 return B_BAD_VALUE; 717 718 int32 index = 0; 719 switch (kind) { 720 case B_APP_VERSION_KIND: 721 index = 0; 722 break; 723 case B_SYSTEM_VERSION_KIND: 724 index = 1; 725 break; 726 default: 727 return B_BAD_VALUE; 728 } 729 730 if (InitCheck() != B_OK) 731 return B_NO_INIT; 732 733 // read the data 734 size_t read = 0; 735 version_info infos[2]; 736 status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, 737 B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read); 738 if (error != B_OK) 739 return error; 740 741 // check the read data 742 if (read == sizeof(version_info)) { 743 // only the app version info is there -- return a cleared system info 744 if (index == 0) 745 *info = infos[index]; 746 else if (index == 1) 747 memset(info, 0, sizeof(version_info)); 748 } else if (read == 2 * sizeof(version_info)) { 749 *info = infos[index]; 750 } else 751 return B_ERROR; 752 753 // return result 754 return B_OK; 755 } 756 757 // SetVersionInfo 758 /*! \brief Sets the file's version info. 759 760 If \a info is \c NULL the file's version info is unset. 761 762 \param info The version info to be set. May be \c NULL. 763 \param kind Specifies kind of version info to be set: 764 \c B_APP_VERSION_KIND for the application's version info and 765 \c B_SYSTEM_VERSION_KIND for the suite's info the application 766 belongs to. 767 \return 768 - \c B_OK: Everything went fine. 769 - \c B_NO_INIT: The object is not properly initialized. 770 - other error codes 771 */ 772 status_t 773 BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind) 774 { 775 // check initialization 776 status_t error = B_OK; 777 if (error == B_OK && InitCheck() != B_OK) 778 error = B_NO_INIT; 779 if (error == B_OK) { 780 if (info) { 781 // check param 782 int32 index = 0; 783 if (error == B_OK) { 784 switch (kind) { 785 case B_APP_VERSION_KIND: 786 index = 0; 787 break; 788 case B_SYSTEM_VERSION_KIND: 789 index = 1; 790 break; 791 default: 792 error = B_BAD_VALUE; 793 break; 794 } 795 } 796 // read both infos 797 version_info infos[2]; 798 if (error == B_OK) { 799 size_t read; 800 if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID, 801 B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), 802 read) == B_OK) { 803 // clear the part that hasn't been read 804 if (read < sizeof(infos)) 805 memset((char*)infos + read, 0, sizeof(infos) - read); 806 } else { 807 // failed to read -- clear 808 memset(infos, 0, sizeof(infos)); 809 } 810 } 811 infos[index] = *info; 812 // write the data 813 if (error == B_OK) { 814 error = _WriteData(kVersionInfoAttribute, 815 kVersionInfoResourceID, 816 B_VERSION_INFO_TYPE, infos, 817 2 * sizeof(version_info)); 818 } 819 } else 820 error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE); 821 } 822 return error; 823 } 824 825 // GetIconForType 826 /*! \brief Gets the icon the application provides for a given MIME type. 827 828 If \a type is \c NULL, the application's icon is retrieved. 829 830 \param type The MIME type in question. May be \c NULL. 831 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 832 to store the requested icon (16x16 for the mini and 32x32 for the 833 large icon). 834 \param which Specifies the size of the icon to be retrieved: 835 \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 836 \return 837 - \c B_OK: Everything went fine. 838 - \c B_NO_INIT: The object is not properly initialized. 839 - \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size 840 \a which or bitmap dimensions (\a icon) and icon size (\a which) do 841 not match. 842 - other error codes 843 */ 844 status_t 845 BAppFileInfo::GetIconForType(const char* type, BBitmap* icon, 846 icon_size size) const 847 { 848 if (InitCheck() != B_OK) 849 return B_NO_INIT; 850 851 if (!icon || icon->InitCheck() != B_OK) 852 return B_BAD_VALUE; 853 854 // TODO: for consistency with attribute based icon reading, we 855 // could also prefer B_CMAP8 icons here if the provided bitmap 856 // is in that format. Right now, an existing B_CMAP8 icon resource 857 // would be ignored as soon as a vector icon is present. On the other 858 // hand, maybe this still results in a more consistent user interface, 859 // since Tracker/Deskbar would surely show the vector icon. 860 861 // try vector icon first 862 BString vectorAttributeName(kIconAttribute); 863 864 // check type param 865 if (type) { 866 if (BMimeType::IsValid(type)) 867 vectorAttributeName += type; 868 else 869 return B_BAD_VALUE; 870 } else { 871 vectorAttributeName += kIconType; 872 } 873 const char* attribute = vectorAttributeName.String(); 874 875 size_t bytesRead; 876 void* allocatedBuffer; 877 status_t error = _ReadData(attribute, -1, B_VECTOR_ICON_TYPE, NULL, 0, 878 bytesRead, &allocatedBuffer); 879 if (error == B_OK) { 880 error = BIconUtils::GetVectorIcon((uint8*)allocatedBuffer, 881 bytesRead, icon); 882 free(allocatedBuffer); 883 return error; 884 } 885 886 // no vector icon if we got this far, 887 // align size argument just in case 888 if (size < B_LARGE_ICON) 889 size = B_MINI_ICON; 890 else 891 size = B_LARGE_ICON; 892 893 error = B_OK; 894 // set some icon size related variables 895 BString attributeString; 896 BRect bounds; 897 uint32 attrType = 0; 898 size_t attrSize = 0; 899 switch (size) { 900 case B_MINI_ICON: 901 attributeString = kMiniIconAttribute; 902 bounds.Set(0, 0, 15, 15); 903 attrType = B_MINI_ICON_TYPE; 904 attrSize = 16 * 16; 905 break; 906 case B_LARGE_ICON: 907 attributeString = kLargeIconAttribute; 908 bounds.Set(0, 0, 31, 31); 909 attrType = B_LARGE_ICON_TYPE; 910 attrSize = 32 * 32; 911 break; 912 default: 913 return B_BAD_VALUE; 914 } 915 // check type param 916 if (type) { 917 if (BMimeType::IsValid(type)) 918 attributeString += type; 919 else 920 return B_BAD_VALUE; 921 } else 922 attributeString += kStandardIconType; 923 924 attribute = attributeString.String(); 925 926 // check parameters 927 // currently, scaling B_CMAP8 icons is not supported 928 if (icon->ColorSpace() == B_CMAP8 && icon->Bounds() != bounds) 929 return B_BAD_VALUE; 930 931 // read the data 932 if (error == B_OK) { 933 bool tempBuffer = (icon->ColorSpace() != B_CMAP8 934 || icon->Bounds() != bounds); 935 uint8* buffer = NULL; 936 size_t read; 937 if (tempBuffer) { 938 // other color space or bitmap size than stored in attribute 939 buffer = new(nothrow) uint8[attrSize]; 940 if (!buffer) { 941 error = B_NO_MEMORY; 942 } else { 943 error = _ReadData(attribute, -1, attrType, buffer, attrSize, 944 read); 945 } 946 } else { 947 error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize, 948 read); 949 } 950 if (error == B_OK && read != attrSize) 951 error = B_ERROR; 952 if (tempBuffer) { 953 // other color space than stored in attribute 954 if (error == B_OK) { 955 error = BIconUtils::ConvertFromCMAP8(buffer, 956 (uint32)size, 957 (uint32)size, 958 (uint32)size, 959 icon); 960 } 961 delete[] buffer; 962 } 963 } 964 return error; 965 } 966 967 // GetIconForType 968 /*! \brief Gets the icon the application provides for a given MIME type. 969 970 If \a type is \c NULL, the application's icon is retrieved. 971 972 \param type The MIME type in question. May be \c NULL. 973 \param data A pointer in which the icon data will be returned. When you 974 are done with the data, you should use free() to deallocate it. 975 \param size A pointer in which the size of the retrieved data is returned. 976 \return 977 - \c B_OK: Everything went fine. 978 - \c B_NO_INIT: The object is not properly initialized. 979 - \c B_BAD_VALUE: \c NULL \a data and/or \a size. Or the supplied 980 \a type is not a valid MIME type. 981 - other error codes 982 */ 983 status_t 984 BAppFileInfo::GetIconForType(const char *type, uint8** data, 985 size_t* size) const 986 { 987 if (InitCheck() != B_OK) 988 return B_NO_INIT; 989 990 if (!data || !size) 991 return B_BAD_VALUE; 992 993 // get vector icon 994 BString attributeName(kIconAttribute); 995 996 // check type param 997 if (type) { 998 if (BMimeType::IsValid(type)) 999 attributeName += type; 1000 else 1001 return B_BAD_VALUE; 1002 } else { 1003 attributeName += kIconType; 1004 } 1005 1006 void* allocatedBuffer = NULL; 1007 status_t ret = _ReadData(attributeName.String(), -1, 1008 B_VECTOR_ICON_TYPE, NULL, 0, *size, &allocatedBuffer); 1009 1010 if (ret < B_OK) 1011 return ret; 1012 1013 *data = (uint8*)allocatedBuffer; 1014 return B_OK; 1015 } 1016 1017 // SetIconForType 1018 /*! \brief Sets the icon the application provides for a given MIME type. 1019 1020 If \a type is \c NULL, the application's icon is set. 1021 If \a icon is \c NULL the icon is unset. 1022 1023 If the file has a signature, then the icon is also set on the MIME type. 1024 If the type for the signature has not been installed yet, it is installed 1025 before. 1026 1027 \param type The MIME type in question. May be \c NULL. 1028 \param icon A pointer to the BBitmap containing the icon to be set. 1029 May be \c NULL. 1030 \param which Specifies the size of the icon to be set: \c B_MINI_ICON 1031 for the mini and \c B_LARGE_ICON for the large icon. 1032 \return 1033 - \c B_OK: Everything went fine. 1034 - \c B_NO_INIT: The object is not properly initialized. 1035 - \c B_BAD_VALUE: Either the icon size \a which is unkown, bitmap dimensions (\a icon) 1036 and icon size (\a which) do not match, or the provided \a type is 1037 not a valid MIME type. 1038 - other error codes 1039 */ 1040 status_t 1041 BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon, 1042 icon_size which) 1043 { 1044 status_t error = B_OK; 1045 // set some icon size related variables 1046 BString attributeString; 1047 BRect bounds; 1048 uint32 attrType = 0; 1049 size_t attrSize = 0; 1050 int32 resourceID = 0; 1051 switch (which) { 1052 case B_MINI_ICON: 1053 attributeString = kMiniIconAttribute; 1054 bounds.Set(0, 0, 15, 15); 1055 attrType = B_MINI_ICON_TYPE; 1056 attrSize = 16 * 16; 1057 resourceID = (type ? kMiniIconForTypeResourceID 1058 : kMiniIconResourceID); 1059 break; 1060 case B_LARGE_ICON: 1061 attributeString = kLargeIconAttribute; 1062 bounds.Set(0, 0, 31, 31); 1063 attrType = B_LARGE_ICON_TYPE; 1064 attrSize = 32 * 32; 1065 resourceID = (type ? kLargeIconForTypeResourceID 1066 : kLargeIconResourceID); 1067 break; 1068 default: 1069 error = B_BAD_VALUE; 1070 break; 1071 } 1072 // check type param 1073 if (error == B_OK) { 1074 if (type) { 1075 if (BMimeType::IsValid(type)) 1076 attributeString += type; 1077 else 1078 error = B_BAD_VALUE; 1079 } else 1080 attributeString += kStandardIconType; 1081 } 1082 const char *attribute = attributeString.String(); 1083 // check parameter and initialization 1084 if (error == B_OK && icon 1085 && (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) { 1086 error = B_BAD_VALUE; 1087 } 1088 if (error == B_OK && InitCheck() != B_OK) 1089 error = B_NO_INIT; 1090 // write/remove the attribute 1091 if (error == B_OK) { 1092 if (icon) { 1093 bool otherColorSpace = (icon->ColorSpace() != B_CMAP8); 1094 if (otherColorSpace) { 1095 BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8); 1096 error = bitmap.InitCheck(); 1097 if (error == B_OK) 1098 error = bitmap.ImportBits(icon); 1099 if (error == B_OK) { 1100 error = _WriteData(attribute, resourceID, attrType, 1101 bitmap.Bits(), attrSize, true); 1102 } 1103 } else { 1104 error = _WriteData(attribute, resourceID, attrType, 1105 icon->Bits(), attrSize, true); 1106 } 1107 } else // no icon given => remove 1108 error = _RemoveData(attribute, attrType); 1109 } 1110 // set the attribute on the MIME type, if the file has a signature 1111 BMimeType mimeType; 1112 if (error == B_OK && GetMetaMime(&mimeType) == B_OK) { 1113 if (!mimeType.IsInstalled()) 1114 error = mimeType.Install(); 1115 if (error == B_OK) 1116 error = mimeType.SetIconForType(type, icon, which); 1117 } 1118 return error; 1119 } 1120 1121 // SetIconForType 1122 /*! \brief Sets the icon the application provides for a given MIME type. 1123 1124 If \a type is \c NULL, the application's icon is set. 1125 If \a data is \c NULL the icon is unset. 1126 1127 If the file has a signature, then the icon is also set on the MIME type. 1128 If the type for the signature has not been installed yet, it is installed 1129 before. 1130 1131 \param type The MIME type in question. May be \c NULL. 1132 \param data A pointer to the data containing the icon to be set. 1133 May be \c NULL. 1134 \param size Specifies the size of buffer provided in \a data. 1135 \return 1136 - \c B_OK: Everything went fine. 1137 - \c B_NO_INIT: The object is not properly initialized. 1138 - \c B_BAD_VALUE: The provided \a type is not a valid MIME type. 1139 - other error codes 1140 */ 1141 status_t 1142 BAppFileInfo::SetIconForType(const char* type, const uint8* data, 1143 size_t size) 1144 { 1145 if (InitCheck() != B_OK) 1146 return B_NO_INIT; 1147 1148 // set some icon related variables 1149 BString attributeString = kIconAttribute; 1150 int32 resourceID = type ? kIconForTypeResourceID : kIconResourceID; 1151 uint32 attrType = B_VECTOR_ICON_TYPE; 1152 1153 // check type param 1154 if (type) { 1155 if (BMimeType::IsValid(type)) 1156 attributeString += type; 1157 else 1158 return B_BAD_VALUE; 1159 } else 1160 attributeString += kIconType; 1161 1162 const char *attribute = attributeString.String(); 1163 1164 status_t error; 1165 // write/remove the attribute 1166 if (data) 1167 error = _WriteData(attribute, resourceID, attrType, data, size, true); 1168 else // no icon given => remove 1169 error = _RemoveData(attribute, attrType); 1170 1171 // set the attribute on the MIME type, if the file has a signature 1172 BMimeType mimeType; 1173 if (error == B_OK && GetMetaMime(&mimeType) == B_OK) { 1174 if (!mimeType.IsInstalled()) 1175 error = mimeType.Install(); 1176 if (error == B_OK) 1177 error = mimeType.SetIconForType(type, data, size); 1178 } 1179 return error; 1180 } 1181 1182 // SetInfoLocation 1183 /*! \brief Specifies the location where the meta data shall be stored. 1184 1185 The options for \a location are: 1186 - \c B_USE_ATTRIBUTES: Store the data in the attributes. 1187 - \c B_USE_RESOURCES: Store the data in the resources. 1188 - \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources. 1189 1190 \param location The location where the meta data shall be stored. 1191 */ 1192 void 1193 BAppFileInfo::SetInfoLocation(info_location location) 1194 { 1195 // if the resources failed to initialize, we must not use them 1196 if (fResources == NULL) 1197 location = info_location(location & ~B_USE_RESOURCES); 1198 1199 fWhere = location; 1200 } 1201 1202 // IsUsingAttributes 1203 /*! \brief Returns whether the object stores the meta data (also) in the 1204 file's attributes. 1205 \return \c true, if the meta data are (also) stored in the file's 1206 attributes, \c false otherwise. 1207 */ 1208 bool 1209 BAppFileInfo::IsUsingAttributes() const 1210 { 1211 return (fWhere & B_USE_ATTRIBUTES) != 0; 1212 } 1213 1214 // IsUsingResources 1215 /*! \brief Returns whether the object stores the meta data (also) in the 1216 file's resources. 1217 \return \c true, if the meta data are (also) stored in the file's 1218 resources, \c false otherwise. 1219 */ 1220 bool 1221 BAppFileInfo::IsUsingResources() const 1222 { 1223 return (fWhere & B_USE_RESOURCES) != 0; 1224 } 1225 1226 // FBC 1227 void BAppFileInfo::_ReservedAppFileInfo1() {} 1228 void BAppFileInfo::_ReservedAppFileInfo2() {} 1229 void BAppFileInfo::_ReservedAppFileInfo3() {} 1230 1231 // = 1232 /*! \brief Privatized assignment operator to prevent usage. 1233 */ 1234 BAppFileInfo & 1235 BAppFileInfo::operator=(const BAppFileInfo &) 1236 { 1237 return *this; 1238 } 1239 1240 // copy constructor 1241 /*! \brief Privatized copy constructor to prevent usage. 1242 */ 1243 BAppFileInfo::BAppFileInfo(const BAppFileInfo &) 1244 { 1245 } 1246 1247 // GetMetaMime 1248 /*! \brief Initializes a BMimeType to the file's signature. 1249 1250 The parameter \a meta is not checked. 1251 1252 \param meta A pointer to a pre-allocated BMimeType that shall be 1253 initialized to the file's signature. 1254 \return 1255 - \c B_OK: Everything went fine. 1256 - \c B_BAD_VALUE: \c NULL \a meta 1257 - \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is 1258 ( not installed in the MIME database.) 1259 no valid MIME string. 1260 - other error codes 1261 */ 1262 status_t 1263 BAppFileInfo::GetMetaMime(BMimeType *meta) const 1264 { 1265 char signature[B_MIME_TYPE_LENGTH]; 1266 status_t error = GetSignature(signature); 1267 if (error == B_OK) 1268 error = meta->SetTo(signature); 1269 else if (error == B_BAD_VALUE) 1270 error = B_ENTRY_NOT_FOUND; 1271 if (error == B_OK && !meta->IsValid()) 1272 error = B_BAD_VALUE; 1273 return error; 1274 } 1275 1276 // _ReadData 1277 /*! \brief Reads data from an attribute or resource. 1278 1279 The data are read from the location specified by \a fWhere. 1280 1281 The object must be properly initialized. The parameters are NOT checked. 1282 1283 \param name The name of the attribute/resource to be read. 1284 \param id The resource ID of the resource to be read. Is ignored, when 1285 < 0. 1286 \param type The type of the attribute/resource to be read. 1287 \param buffer A pre-allocated buffer for the data to be read. 1288 \param bufferSize The size of the supplied buffer. 1289 \param bytesRead A reference parameter, set to the number of bytes 1290 actually read. 1291 \param allocatedBuffer If not \c NULL, the method allocates a buffer 1292 large enough too store the whole data and writes a pointer to it 1293 into this variable. If \c NULL, the supplied buffer is used. 1294 \return 1295 - \c B_OK: Everything went fine. 1296 - error code 1297 */ 1298 status_t 1299 BAppFileInfo::_ReadData(const char *name, int32 id, type_code type, 1300 void *buffer, size_t bufferSize, 1301 size_t &bytesRead, void **allocatedBuffer) const 1302 { 1303 status_t error = B_OK; 1304 1305 if (allocatedBuffer) 1306 buffer = NULL; 1307 1308 bool foundData = false; 1309 1310 if (IsUsingAttributes()) { 1311 // get an attribute info 1312 attr_info info; 1313 if (error == B_OK) 1314 error = fNode->GetAttrInfo(name, &info); 1315 1316 // check type and size, allocate a buffer, if required 1317 if (error == B_OK && info.type != type) 1318 error = B_BAD_VALUE; 1319 if (error == B_OK && allocatedBuffer) { 1320 buffer = malloc(info.size); 1321 if (!buffer) 1322 error = B_NO_MEMORY; 1323 bufferSize = info.size; 1324 } 1325 if (error == B_OK && bufferSize < info.size) 1326 error = B_BAD_VALUE; 1327 1328 // read the data 1329 if (error == B_OK) { 1330 ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size); 1331 if (read < 0) 1332 error = read; 1333 else if (read != info.size) 1334 error = B_ERROR; 1335 else 1336 bytesRead = read; 1337 } 1338 1339 foundData = (error == B_OK); 1340 1341 // free the allocated buffer on error 1342 if (!foundData && allocatedBuffer && buffer) { 1343 free(buffer); 1344 buffer = NULL; 1345 } 1346 } 1347 1348 if (!foundData && IsUsingResources()) { 1349 // get a resource info 1350 error = B_OK; 1351 int32 idFound; 1352 size_t sizeFound; 1353 if (error == B_OK) { 1354 if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 1355 error = B_ENTRY_NOT_FOUND; 1356 } 1357 1358 // check id and size, allocate a buffer, if required 1359 if (error == B_OK && id >= 0 && idFound != id) 1360 error = B_ENTRY_NOT_FOUND; 1361 if (error == B_OK && allocatedBuffer) { 1362 buffer = malloc(sizeFound); 1363 if (!buffer) 1364 error = B_NO_MEMORY; 1365 bufferSize = sizeFound; 1366 } 1367 if (error == B_OK && bufferSize < sizeFound) 1368 error = B_BAD_VALUE; 1369 1370 // load resource 1371 const void *resourceData = NULL; 1372 if (error == B_OK) { 1373 resourceData = fResources->LoadResource(type, name, &bytesRead); 1374 if (resourceData && sizeFound == bytesRead) 1375 memcpy(buffer, resourceData, bytesRead); 1376 else 1377 error = B_ERROR; 1378 } 1379 } else if (!foundData) 1380 error = B_BAD_VALUE; 1381 1382 // return the allocated buffer, or free it on error 1383 if (allocatedBuffer) { 1384 if (error == B_OK) 1385 *allocatedBuffer = buffer; 1386 else 1387 free(buffer); 1388 } 1389 1390 return error; 1391 } 1392 1393 // _WriteData 1394 /*! \brief Writes data to an attribute or resource. 1395 1396 The data are written to the location(s) specified by \a fWhere. 1397 1398 The object must be properly initialized. The parameters are NOT checked. 1399 1400 \param name The name of the attribute/resource to be written. 1401 \param id The resource ID of the resource to be written. 1402 \param type The type of the attribute/resource to be written. 1403 \param buffer A buffer containing the data to be written. 1404 \param bufferSize The size of the supplied buffer. 1405 \param findID If set to \c true use the ID that is already assigned to the 1406 \a name / \a type pair or take the first unused ID >= \a id. 1407 If \c false, \a id is used. 1408 If \a id is already in use and . 1409 \return 1410 - \c B_OK: Everything went fine. 1411 - error code 1412 */ 1413 status_t 1414 BAppFileInfo::_WriteData(const char *name, int32 id, type_code type, 1415 const void *buffer, size_t bufferSize, bool findID) 1416 { 1417 if (!IsUsingAttributes() && !IsUsingResources()) 1418 return B_NO_INIT; 1419 1420 status_t error = B_OK; 1421 1422 // write to attribute 1423 if (IsUsingAttributes()) { 1424 ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize); 1425 if (written < 0) 1426 error = written; 1427 else if (written != (ssize_t)bufferSize) 1428 error = B_ERROR; 1429 } 1430 // write to resource 1431 if (IsUsingResources() && error == B_OK) { 1432 if (findID) { 1433 // get the resource info 1434 int32 idFound; 1435 size_t sizeFound; 1436 if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 1437 id = idFound; 1438 else { 1439 // type-name pair doesn't exist yet -- find unused ID 1440 while (fResources->HasResource(type, id)) 1441 id++; 1442 } 1443 } 1444 error = fResources->AddResource(type, id, buffer, bufferSize, name); 1445 } 1446 return error; 1447 } 1448 1449 // _RemoveData 1450 /*! \brief Removes an attribute or resource. 1451 1452 The removal location is specified by \a fWhere. 1453 1454 The object must be properly initialized. The parameters are NOT checked. 1455 1456 \param name The name of the attribute/resource to be remove. 1457 \param type The type of the attribute/resource to be removed. 1458 \return 1459 - \c B_OK: Everything went fine. 1460 - error code 1461 */ 1462 status_t 1463 BAppFileInfo::_RemoveData(const char *name, type_code type) 1464 { 1465 if (!IsUsingAttributes() && !IsUsingResources()) 1466 return B_NO_INIT; 1467 1468 status_t error = B_OK; 1469 1470 // remove the attribute 1471 if (IsUsingAttributes()) { 1472 error = fNode->RemoveAttr(name); 1473 // It's no error, if there has been no attribute. 1474 if (error == B_ENTRY_NOT_FOUND) 1475 error = B_OK; 1476 } 1477 // remove the resource 1478 if (IsUsingResources() && error == B_OK) { 1479 // get a resource info 1480 int32 idFound; 1481 size_t sizeFound; 1482 if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 1483 error = fResources->RemoveResource(type, idFound); 1484 } 1485 return error; 1486 } 1487 1488