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 free(buffer); 445 return error; 446 } 447 448 // SetSupportedTypes 449 /*! \brief Sets the MIME types supported by the application. 450 451 If \a types is \c NULL the application's supported types are unset. 452 453 The supported MIME types must be stored in a field "types" of type 454 \c B_STRING_TYPE in \a types. 455 456 The method informs the registrar about this news. 457 For each supported type the result of BMimeType::GetSupportingApps() will 458 afterwards include the signature of this application. That is, the 459 application file needs to have a signature set. 460 461 \a syncAll specifies whether the not longer supported types shall be 462 updated as well, i.e. whether this application shall be remove from the 463 lists of supporting applications. 464 465 \param types The supported types to be assigned to the file. 466 May be \c NULL. 467 \param syncAll \c true to also synchronize the not longer supported 468 types, \c false otherwise. 469 \return 470 - \c B_OK: Everything went fine. 471 - \c B_NO_INIT: The object is not properly initialized. 472 - other error codes 473 */ 474 status_t 475 BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll) 476 { 477 // check initialization 478 status_t error = B_OK; 479 if (error == B_OK && InitCheck() != B_OK) 480 error = B_NO_INIT; 481 BMimeType mimeType; 482 if (error == B_OK) 483 error = GetMetaMime(&mimeType); 484 if (error == B_OK || error == B_ENTRY_NOT_FOUND) { 485 error = B_OK; 486 if (types) { 487 // check param -- supported types must be valid 488 const char *type; 489 for (int32 i = 0; 490 error == B_OK && types->FindString("types", i, &type) == B_OK; 491 i++) { 492 if (!BMimeType::IsValid(type)) 493 error = B_BAD_VALUE; 494 } 495 // get flattened size 496 ssize_t size = 0; 497 if (error == B_OK) { 498 size = types->FlattenedSize(); 499 if (size < 0) 500 error = size; 501 } 502 // allocate a buffer for the flattened data 503 char *buffer = NULL; 504 if (error == B_OK) { 505 buffer = new(nothrow) char[size]; 506 if (!buffer) 507 error = B_NO_MEMORY; 508 } 509 // flatten the message 510 if (error == B_OK) 511 error = types->Flatten(buffer, size); 512 // write the data 513 if (error == B_OK) { 514 error = _WriteData(kSupportedTypesAttribute, 515 kSupportedTypesResourceID, B_MESSAGE_TYPE, 516 buffer, size); 517 } 518 // clean up 519 delete[] buffer; 520 } else 521 error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE); 522 // update the MIME database, if the app signature is installed 523 if (error == B_OK && mimeType.IsInstalled()) 524 error = mimeType.SetSupportedTypes(types, syncAll); 525 } 526 return error; 527 } 528 529 // SetSupportedTypes 530 /*! \brief Sets the MIME types supported by the application. 531 532 This method is a short-hand for SetSupportedTypes(types, false). 533 \see SetSupportedType(const BMessage*, bool) for detailed information. 534 535 \param types The supported types to be assigned to the file. 536 May be \c NULL. 537 \return 538 - \c B_OK: Everything went fine. 539 - \c B_NO_INIT: The object is not properly initialized. 540 - other error codes 541 */ 542 status_t 543 BAppFileInfo::SetSupportedTypes(const BMessage *types) 544 { 545 return SetSupportedTypes(types, false); 546 } 547 548 // IsSupportedType 549 /*! \brief Returns whether the application supports the supplied MIME type. 550 551 If the application supports the wildcard type "application/octet-stream" 552 any this method returns \c true for any MIME type. 553 554 \param type The MIME type in question. 555 \return \c true, if \a type is a valid MIME type and it is supported by 556 the application, \c false otherwise. 557 */ 558 bool 559 BAppFileInfo::IsSupportedType(const char *type) const 560 { 561 status_t error = (type ? B_OK : B_BAD_VALUE); 562 // get the supported types 563 BMessage types; 564 if (error == B_OK) 565 error = GetSupportedTypes(&types); 566 // turn type into a BMimeType 567 BMimeType mimeType; 568 if (error == B_OK) 569 error = mimeType.SetTo(type); 570 // iterate through the supported types 571 bool found = false; 572 if (error == B_OK) { 573 const char *supportedType; 574 for (int32 i = 0; 575 !found && types.FindString("types", i, &supportedType) == B_OK; 576 i++) { 577 found = !strcmp(supportedType, "application/octet-stream") 578 || BMimeType(supportedType).Contains(&mimeType); 579 } 580 } 581 return found; 582 } 583 584 // Supports 585 /*! \brief Returns whether the application supports the supplied MIME type 586 explicitly. 587 588 Unlike IsSupportedType(), this method returns \c true, only if the type 589 is explicitly supported, regardless of whether it supports 590 "application/octet-stream". 591 592 \param type The MIME type in question. 593 \return \c true, if \a type is a valid MIME type and it is explicitly 594 supported by the application, \c false otherwise. 595 */ 596 bool 597 BAppFileInfo::Supports(BMimeType *type) const 598 { 599 status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 600 // get the supported types 601 BMessage types; 602 if (error == B_OK) 603 error = GetSupportedTypes(&types); 604 // iterate through the supported types 605 bool found = false; 606 if (error == B_OK) { 607 const char *supportedType; 608 for (int32 i = 0; 609 !found && types.FindString("types", i, &supportedType) == B_OK; 610 i++) { 611 found = BMimeType(supportedType).Contains(type); 612 } 613 } 614 return found; 615 } 616 617 // GetIcon 618 /*! \brief Gets the file's icon. 619 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 620 to store the requested icon (16x16 for the mini and 32x32 for the 621 large icon). 622 \param which Specifies the size of the icon to be retrieved: 623 \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 624 \return 625 - \c B_OK: Everything went fine. 626 - \c B_NO_INIT: The object is not properly initialized. 627 - \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap 628 dimensions (\a icon) and icon size (\a which) do not match. 629 - other error codes 630 */ 631 status_t 632 BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const 633 { 634 return GetIconForType(NULL, icon, which); 635 } 636 637 // GetIcon 638 /*! \brief Gets the file's icon. 639 \param data The pointer in which the flat icon data will be returned. 640 \param size The pointer in which the size of the data found will be returned. 641 \return 642 - \c B_OK: Everything went fine. 643 - \c B_NO_INIT: The object is not properly initialized. 644 - \c B_BAD_VALUE: \c NULL \a data or \c NULL size. 645 - other error codes 646 */ 647 status_t 648 BAppFileInfo::GetIcon(uint8** data, size_t* size) const 649 { 650 return GetIconForType(NULL, data, size); 651 } 652 653 // SetIcon 654 /*! \brief Sets the file's icon. 655 656 If \a icon is \c NULL the file's icon is unset. 657 658 \param icon A pointer to the BBitmap containing the icon to be set. 659 May be \c NULL. 660 \param which Specifies the size of the icon to be set: \c B_MINI_ICON 661 for the mini and \c B_LARGE_ICON for the large icon. 662 \return 663 - \c B_OK: Everything went fine. 664 - \c B_NO_INIT: The object is not properly initialized. 665 - \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon) 666 and icon size (\a which) do not match. 667 - other error codes 668 */ 669 status_t 670 BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which) 671 { 672 return SetIconForType(NULL, icon, which); 673 } 674 675 // SetIcon 676 /*! \brief Sets the file's icon. 677 678 If \a icon is \c NULL the file's icon is unset. 679 680 \param data A pointer to the data buffer containing the vector icon 681 to be set. May be \c NULL. 682 \param size Specifies the size of buffer pointed to by \a data. 683 \return 684 - \c B_OK: Everything went fine. 685 - \c B_NO_INIT: The object is not properly initialized. 686 - \c B_BAD_VALUE: \c NULL data. 687 - other error codes 688 */ 689 status_t 690 BAppFileInfo::SetIcon(const uint8* data, size_t size) 691 { 692 return SetIconForType(NULL, data, size); 693 } 694 695 // GetVersionInfo 696 /*! \brief Gets the file's version info. 697 \param info A pointer to a pre-allocated version_info structure into which 698 the version info should be written. 699 \param kind Specifies the kind of the version info to be retrieved: 700 \c B_APP_VERSION_KIND for the application's version info and 701 \c B_SYSTEM_VERSION_KIND for the suite's info the application 702 belongs to. 703 \return 704 - \c B_OK: Everything went fine. 705 - \c B_NO_INIT: The object is not properly initialized. 706 - \c B_BAD_VALUE: \c NULL \a info. 707 - other error codes 708 */ 709 status_t 710 BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const 711 { 712 // check params and initialization 713 if (!info) 714 return B_BAD_VALUE; 715 716 int32 index = 0; 717 switch (kind) { 718 case B_APP_VERSION_KIND: 719 index = 0; 720 break; 721 case B_SYSTEM_VERSION_KIND: 722 index = 1; 723 break; 724 default: 725 return B_BAD_VALUE; 726 } 727 728 if (InitCheck() != B_OK) 729 return B_NO_INIT; 730 731 // read the data 732 size_t read = 0; 733 version_info infos[2]; 734 status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, 735 B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read); 736 if (error != B_OK) 737 return error; 738 739 // check the read data 740 if (read == sizeof(version_info)) { 741 // only the app version info is there -- return a cleared system info 742 if (index == 0) 743 *info = infos[index]; 744 else if (index == 1) 745 memset(info, 0, sizeof(version_info)); 746 } else if (read == 2 * sizeof(version_info)) { 747 *info = infos[index]; 748 } else 749 return B_ERROR; 750 751 // return result 752 return B_OK; 753 } 754 755 // SetVersionInfo 756 /*! \brief Sets the file's version info. 757 758 If \a info is \c NULL the file's version info is unset. 759 760 \param info The version info to be set. May be \c NULL. 761 \param kind Specifies kind of version info to be set: 762 \c B_APP_VERSION_KIND for the application's version info and 763 \c B_SYSTEM_VERSION_KIND for the suite's info the application 764 belongs to. 765 \return 766 - \c B_OK: Everything went fine. 767 - \c B_NO_INIT: The object is not properly initialized. 768 - other error codes 769 */ 770 status_t 771 BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind) 772 { 773 // check initialization 774 status_t error = B_OK; 775 if (error == B_OK && InitCheck() != B_OK) 776 error = B_NO_INIT; 777 if (error == B_OK) { 778 if (info) { 779 // check param 780 int32 index = 0; 781 if (error == B_OK) { 782 switch (kind) { 783 case B_APP_VERSION_KIND: 784 index = 0; 785 break; 786 case B_SYSTEM_VERSION_KIND: 787 index = 1; 788 break; 789 default: 790 error = B_BAD_VALUE; 791 break; 792 } 793 } 794 // read both infos 795 version_info infos[2]; 796 if (error == B_OK) { 797 size_t read; 798 if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID, 799 B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), 800 read) == B_OK) { 801 // clear the part that hasn't been read 802 if (read < sizeof(infos)) 803 memset((char*)infos + read, 0, sizeof(infos) - read); 804 } else { 805 // failed to read -- clear 806 memset(infos, 0, sizeof(infos)); 807 } 808 } 809 infos[index] = *info; 810 // write the data 811 if (error == B_OK) { 812 error = _WriteData(kVersionInfoAttribute, 813 kVersionInfoResourceID, 814 B_VERSION_INFO_TYPE, infos, 815 2 * sizeof(version_info)); 816 } 817 } else 818 error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE); 819 } 820 return error; 821 } 822 823 // GetIconForType 824 /*! \brief Gets the icon the application provides for a given MIME type. 825 826 If \a type is \c NULL, the application's icon is retrieved. 827 828 \param type The MIME type in question. May be \c NULL. 829 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 830 to store the requested icon (16x16 for the mini and 32x32 for the 831 large icon). 832 \param which Specifies the size of the icon to be retrieved: 833 \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 834 \return 835 - \c B_OK: Everything went fine. 836 - \c B_NO_INIT: The object is not properly initialized. 837 - \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size 838 \a which or bitmap dimensions (\a icon) and icon size (\a which) do 839 not match. 840 - other error codes 841 */ 842 status_t 843 BAppFileInfo::GetIconForType(const char* type, BBitmap* icon, 844 icon_size size) const 845 { 846 if (InitCheck() != B_OK) 847 return B_NO_INIT; 848 849 if (!icon || icon->InitCheck() != B_OK) 850 return B_BAD_VALUE; 851 852 // TODO: for consistency with attribute based icon reading, we 853 // could also prefer B_CMAP8 icons here if the provided bitmap 854 // is in that format. Right now, an existing B_CMAP8 icon resource 855 // would be ignored as soon as a vector icon is present. On the other 856 // hand, maybe this still results in a more consistent user interface, 857 // since Tracker/Deskbar would surely show the vector icon. 858 859 // try vector icon first 860 BString vectorAttributeName(kIconAttribute); 861 862 // check type param 863 if (type) { 864 if (BMimeType::IsValid(type)) 865 vectorAttributeName += type; 866 else 867 return B_BAD_VALUE; 868 } else { 869 vectorAttributeName += kIconType; 870 } 871 const char* attribute = vectorAttributeName.String(); 872 873 size_t bytesRead; 874 void* allocatedBuffer; 875 status_t error = _ReadData(attribute, -1, B_VECTOR_ICON_TYPE, NULL, 0, 876 bytesRead, &allocatedBuffer); 877 if (error == B_OK) { 878 error = BIconUtils::GetVectorIcon((uint8*)allocatedBuffer, 879 bytesRead, icon); 880 free(allocatedBuffer); 881 return error; 882 } 883 884 // no vector icon if we got this far, 885 // align size argument just in case 886 if (size < B_LARGE_ICON) 887 size = B_MINI_ICON; 888 else 889 size = B_LARGE_ICON; 890 891 error = B_OK; 892 // set some icon size related variables 893 BString attributeString; 894 BRect bounds; 895 uint32 attrType = 0; 896 size_t attrSize = 0; 897 switch (size) { 898 case B_MINI_ICON: 899 attributeString = kMiniIconAttribute; 900 bounds.Set(0, 0, 15, 15); 901 attrType = B_MINI_ICON_TYPE; 902 attrSize = 16 * 16; 903 break; 904 case B_LARGE_ICON: 905 attributeString = kLargeIconAttribute; 906 bounds.Set(0, 0, 31, 31); 907 attrType = B_LARGE_ICON_TYPE; 908 attrSize = 32 * 32; 909 break; 910 default: 911 return B_BAD_VALUE; 912 } 913 // check type param 914 if (type) { 915 if (BMimeType::IsValid(type)) 916 attributeString += type; 917 else 918 return B_BAD_VALUE; 919 } else 920 attributeString += kStandardIconType; 921 922 attribute = attributeString.String(); 923 924 // check parameters 925 // currently, scaling B_CMAP8 icons is not supported 926 if (icon->ColorSpace() == B_CMAP8 && icon->Bounds() != bounds) 927 return B_BAD_VALUE; 928 929 // read the data 930 if (error == B_OK) { 931 bool tempBuffer = (icon->ColorSpace() != B_CMAP8 932 || icon->Bounds() != bounds); 933 uint8* buffer = NULL; 934 size_t read; 935 if (tempBuffer) { 936 // other color space or bitmap size than stored in attribute 937 buffer = new(nothrow) uint8[attrSize]; 938 if (!buffer) { 939 error = B_NO_MEMORY; 940 } else { 941 error = _ReadData(attribute, -1, attrType, buffer, attrSize, 942 read); 943 } 944 } else { 945 error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize, 946 read); 947 } 948 if (error == B_OK && read != attrSize) 949 error = B_ERROR; 950 if (tempBuffer) { 951 // other color space than stored in attribute 952 if (error == B_OK) { 953 error = BIconUtils::ConvertFromCMAP8(buffer, 954 (uint32)size, 955 (uint32)size, 956 (uint32)size, 957 icon); 958 } 959 delete[] buffer; 960 } 961 } 962 return error; 963 } 964 965 // GetIconForType 966 /*! \brief Gets the icon the application provides for a given MIME type. 967 968 If \a type is \c NULL, the application's icon is retrieved. 969 970 \param type The MIME type in question. May be \c NULL. 971 \param data A pointer in which the icon data will be returned. When you 972 are done with the data, you should use free() to deallocate it. 973 \param size A pointer in which the size of the retrieved data is returned. 974 \return 975 - \c B_OK: Everything went fine. 976 - \c B_NO_INIT: The object is not properly initialized. 977 - \c B_BAD_VALUE: \c NULL \a data and/or \a size. Or the supplied 978 \a type is not a valid MIME type. 979 - other error codes 980 */ 981 status_t 982 BAppFileInfo::GetIconForType(const char *type, uint8** data, 983 size_t* size) const 984 { 985 if (InitCheck() != B_OK) 986 return B_NO_INIT; 987 988 if (!data || !size) 989 return B_BAD_VALUE; 990 991 // get vector icon 992 BString attributeName(kIconAttribute); 993 994 // check type param 995 if (type) { 996 if (BMimeType::IsValid(type)) 997 attributeName += type; 998 else 999 return B_BAD_VALUE; 1000 } else { 1001 attributeName += kIconType; 1002 } 1003 1004 void* allocatedBuffer = NULL; 1005 status_t ret = _ReadData(attributeName.String(), -1, 1006 B_VECTOR_ICON_TYPE, NULL, 0, *size, &allocatedBuffer); 1007 1008 if (ret < B_OK) 1009 return ret; 1010 1011 *data = (uint8*)allocatedBuffer; 1012 return B_OK; 1013 } 1014 1015 // SetIconForType 1016 /*! \brief Sets the icon the application provides for a given MIME type. 1017 1018 If \a type is \c NULL, the application's icon is set. 1019 If \a icon is \c NULL the icon is unset. 1020 1021 If the file has a signature, then the icon is also set on the MIME type. 1022 If the type for the signature has not been installed yet, it is installed 1023 before. 1024 1025 \param type The MIME type in question. May be \c NULL. 1026 \param icon A pointer to the BBitmap containing the icon to be set. 1027 May be \c NULL. 1028 \param which Specifies the size of the icon to be set: \c B_MINI_ICON 1029 for the mini and \c B_LARGE_ICON for the large icon. 1030 \return 1031 - \c B_OK: Everything went fine. 1032 - \c B_NO_INIT: The object is not properly initialized. 1033 - \c B_BAD_VALUE: Either the icon size \a which is unkown, bitmap dimensions (\a icon) 1034 and icon size (\a which) do not match, or the provided \a type is 1035 not a valid MIME type. 1036 - other error codes 1037 */ 1038 status_t 1039 BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon, 1040 icon_size which) 1041 { 1042 status_t error = B_OK; 1043 // set some icon size related variables 1044 BString attributeString; 1045 BRect bounds; 1046 uint32 attrType = 0; 1047 size_t attrSize = 0; 1048 int32 resourceID = 0; 1049 switch (which) { 1050 case B_MINI_ICON: 1051 attributeString = kMiniIconAttribute; 1052 bounds.Set(0, 0, 15, 15); 1053 attrType = B_MINI_ICON_TYPE; 1054 attrSize = 16 * 16; 1055 resourceID = (type ? kMiniIconForTypeResourceID 1056 : kMiniIconResourceID); 1057 break; 1058 case B_LARGE_ICON: 1059 attributeString = kLargeIconAttribute; 1060 bounds.Set(0, 0, 31, 31); 1061 attrType = B_LARGE_ICON_TYPE; 1062 attrSize = 32 * 32; 1063 resourceID = (type ? kLargeIconForTypeResourceID 1064 : kLargeIconResourceID); 1065 break; 1066 default: 1067 error = B_BAD_VALUE; 1068 break; 1069 } 1070 // check type param 1071 if (error == B_OK) { 1072 if (type) { 1073 if (BMimeType::IsValid(type)) 1074 attributeString += type; 1075 else 1076 error = B_BAD_VALUE; 1077 } else 1078 attributeString += kStandardIconType; 1079 } 1080 const char *attribute = attributeString.String(); 1081 // check parameter and initialization 1082 if (error == B_OK && icon 1083 && (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) { 1084 error = B_BAD_VALUE; 1085 } 1086 if (error == B_OK && InitCheck() != B_OK) 1087 error = B_NO_INIT; 1088 // write/remove the attribute 1089 if (error == B_OK) { 1090 if (icon) { 1091 bool otherColorSpace = (icon->ColorSpace() != B_CMAP8); 1092 if (otherColorSpace) { 1093 BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8); 1094 error = bitmap.InitCheck(); 1095 if (error == B_OK) 1096 error = bitmap.ImportBits(icon); 1097 if (error == B_OK) { 1098 error = _WriteData(attribute, resourceID, attrType, 1099 bitmap.Bits(), attrSize, true); 1100 } 1101 } else { 1102 error = _WriteData(attribute, resourceID, attrType, 1103 icon->Bits(), attrSize, true); 1104 } 1105 } else // no icon given => remove 1106 error = _RemoveData(attribute, attrType); 1107 } 1108 // set the attribute on the MIME type, if the file has a signature 1109 BMimeType mimeType; 1110 if (error == B_OK && GetMetaMime(&mimeType) == B_OK) { 1111 if (!mimeType.IsInstalled()) 1112 error = mimeType.Install(); 1113 if (error == B_OK) 1114 error = mimeType.SetIconForType(type, icon, which); 1115 } 1116 return error; 1117 } 1118 1119 // SetIconForType 1120 /*! \brief Sets the icon the application provides for a given MIME type. 1121 1122 If \a type is \c NULL, the application's icon is set. 1123 If \a data is \c NULL the icon is unset. 1124 1125 If the file has a signature, then the icon is also set on the MIME type. 1126 If the type for the signature has not been installed yet, it is installed 1127 before. 1128 1129 \param type The MIME type in question. May be \c NULL. 1130 \param data A pointer to the data containing the icon to be set. 1131 May be \c NULL. 1132 \param size Specifies the size of buffer provided in \a data. 1133 \return 1134 - \c B_OK: Everything went fine. 1135 - \c B_NO_INIT: The object is not properly initialized. 1136 - \c B_BAD_VALUE: The provided \a type is not a valid MIME type. 1137 - other error codes 1138 */ 1139 status_t 1140 BAppFileInfo::SetIconForType(const char* type, const uint8* data, 1141 size_t size) 1142 { 1143 if (InitCheck() != B_OK) 1144 return B_NO_INIT; 1145 1146 // set some icon related variables 1147 BString attributeString = kIconAttribute; 1148 int32 resourceID = type ? kIconForTypeResourceID : kIconResourceID; 1149 uint32 attrType = B_VECTOR_ICON_TYPE; 1150 1151 // check type param 1152 if (type) { 1153 if (BMimeType::IsValid(type)) 1154 attributeString += type; 1155 else 1156 return B_BAD_VALUE; 1157 } else 1158 attributeString += kIconType; 1159 1160 const char *attribute = attributeString.String(); 1161 1162 status_t error; 1163 // write/remove the attribute 1164 if (data) 1165 error = _WriteData(attribute, resourceID, attrType, data, size, true); 1166 else // no icon given => remove 1167 error = _RemoveData(attribute, attrType); 1168 1169 // set the attribute on the MIME type, if the file has a signature 1170 BMimeType mimeType; 1171 if (error == B_OK && GetMetaMime(&mimeType) == B_OK) { 1172 if (!mimeType.IsInstalled()) 1173 error = mimeType.Install(); 1174 if (error == B_OK) 1175 error = mimeType.SetIconForType(type, data, size); 1176 } 1177 return error; 1178 } 1179 1180 // SetInfoLocation 1181 /*! \brief Specifies the location where the meta data shall be stored. 1182 1183 The options for \a location are: 1184 - \c B_USE_ATTRIBUTES: Store the data in the attributes. 1185 - \c B_USE_RESOURCES: Store the data in the resources. 1186 - \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources. 1187 1188 \param location The location where the meta data shall be stored. 1189 */ 1190 void 1191 BAppFileInfo::SetInfoLocation(info_location location) 1192 { 1193 // if the resources failed to initialize, we must not use them 1194 if (fResources == NULL) 1195 location = info_location(location & ~B_USE_RESOURCES); 1196 1197 fWhere = location; 1198 } 1199 1200 // IsUsingAttributes 1201 /*! \brief Returns whether the object stores the meta data (also) in the 1202 file's attributes. 1203 \return \c true, if the meta data are (also) stored in the file's 1204 attributes, \c false otherwise. 1205 */ 1206 bool 1207 BAppFileInfo::IsUsingAttributes() const 1208 { 1209 return (fWhere & B_USE_ATTRIBUTES) != 0; 1210 } 1211 1212 // IsUsingResources 1213 /*! \brief Returns whether the object stores the meta data (also) in the 1214 file's resources. 1215 \return \c true, if the meta data are (also) stored in the file's 1216 resources, \c false otherwise. 1217 */ 1218 bool 1219 BAppFileInfo::IsUsingResources() const 1220 { 1221 return (fWhere & B_USE_RESOURCES) != 0; 1222 } 1223 1224 // FBC 1225 void BAppFileInfo::_ReservedAppFileInfo1() {} 1226 void BAppFileInfo::_ReservedAppFileInfo2() {} 1227 void BAppFileInfo::_ReservedAppFileInfo3() {} 1228 1229 // = 1230 /*! \brief Privatized assignment operator to prevent usage. 1231 */ 1232 BAppFileInfo & 1233 BAppFileInfo::operator=(const BAppFileInfo &) 1234 { 1235 return *this; 1236 } 1237 1238 // copy constructor 1239 /*! \brief Privatized copy constructor to prevent usage. 1240 */ 1241 BAppFileInfo::BAppFileInfo(const BAppFileInfo &) 1242 { 1243 } 1244 1245 // GetMetaMime 1246 /*! \brief Initializes a BMimeType to the file's signature. 1247 1248 The parameter \a meta is not checked. 1249 1250 \param meta A pointer to a pre-allocated BMimeType that shall be 1251 initialized to the file's signature. 1252 \return 1253 - \c B_OK: Everything went fine. 1254 - \c B_BAD_VALUE: \c NULL \a meta 1255 - \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is 1256 ( not installed in the MIME database.) 1257 no valid MIME string. 1258 - other error codes 1259 */ 1260 status_t 1261 BAppFileInfo::GetMetaMime(BMimeType *meta) const 1262 { 1263 char signature[B_MIME_TYPE_LENGTH]; 1264 status_t error = GetSignature(signature); 1265 if (error == B_OK) 1266 error = meta->SetTo(signature); 1267 else if (error == B_BAD_VALUE) 1268 error = B_ENTRY_NOT_FOUND; 1269 if (error == B_OK && !meta->IsValid()) 1270 error = B_BAD_VALUE; 1271 return error; 1272 } 1273 1274 // _ReadData 1275 /*! \brief Reads data from an attribute or resource. 1276 1277 The data are read from the location specified by \a fWhere. 1278 1279 The object must be properly initialized. The parameters are NOT checked. 1280 1281 \param name The name of the attribute/resource to be read. 1282 \param id The resource ID of the resource to be read. Is ignored, when 1283 < 0. 1284 \param type The type of the attribute/resource to be read. 1285 \param buffer A pre-allocated buffer for the data to be read. 1286 \param bufferSize The size of the supplied buffer. 1287 \param bytesRead A reference parameter, set to the number of bytes 1288 actually read. 1289 \param allocatedBuffer If not \c NULL, the method allocates a buffer 1290 large enough too store the whole data and writes a pointer to it 1291 into this variable. If \c NULL, the supplied buffer is used. 1292 \return 1293 - \c B_OK: Everything went fine. 1294 - error code 1295 */ 1296 status_t 1297 BAppFileInfo::_ReadData(const char *name, int32 id, type_code type, 1298 void *buffer, size_t bufferSize, 1299 size_t &bytesRead, void **allocatedBuffer) const 1300 { 1301 status_t error = B_OK; 1302 1303 if (allocatedBuffer) 1304 buffer = NULL; 1305 1306 bool foundData = false; 1307 1308 if (IsUsingAttributes()) { 1309 // get an attribute info 1310 attr_info info; 1311 if (error == B_OK) 1312 error = fNode->GetAttrInfo(name, &info); 1313 1314 // check type and size, allocate a buffer, if required 1315 if (error == B_OK && info.type != type) 1316 error = B_BAD_VALUE; 1317 if (error == B_OK && allocatedBuffer) { 1318 buffer = malloc(info.size); 1319 if (!buffer) 1320 error = B_NO_MEMORY; 1321 bufferSize = info.size; 1322 } 1323 if (error == B_OK && bufferSize < info.size) 1324 error = B_BAD_VALUE; 1325 1326 // read the data 1327 if (error == B_OK) { 1328 ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size); 1329 if (read < 0) 1330 error = read; 1331 else if (read != info.size) 1332 error = B_ERROR; 1333 else 1334 bytesRead = read; 1335 } 1336 1337 foundData = (error == B_OK); 1338 1339 // free the allocated buffer on error 1340 if (!foundData && allocatedBuffer && buffer) { 1341 free(buffer); 1342 buffer = NULL; 1343 } 1344 } 1345 1346 if (!foundData && IsUsingResources()) { 1347 // get a resource info 1348 error = B_OK; 1349 int32 idFound; 1350 size_t sizeFound; 1351 if (error == B_OK) { 1352 if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 1353 error = B_ENTRY_NOT_FOUND; 1354 } 1355 1356 // check id and size, allocate a buffer, if required 1357 if (error == B_OK && id >= 0 && idFound != id) 1358 error = B_ENTRY_NOT_FOUND; 1359 if (error == B_OK && allocatedBuffer) { 1360 buffer = malloc(sizeFound); 1361 if (!buffer) 1362 error = B_NO_MEMORY; 1363 bufferSize = sizeFound; 1364 } 1365 if (error == B_OK && bufferSize < sizeFound) 1366 error = B_BAD_VALUE; 1367 1368 // load resource 1369 const void *resourceData = NULL; 1370 if (error == B_OK) { 1371 resourceData = fResources->LoadResource(type, name, &bytesRead); 1372 if (resourceData && sizeFound == bytesRead) 1373 memcpy(buffer, resourceData, bytesRead); 1374 else 1375 error = B_ERROR; 1376 } 1377 } else if (!foundData) 1378 error = B_BAD_VALUE; 1379 1380 // return the allocated buffer, or free it on error 1381 if (allocatedBuffer) { 1382 if (error == B_OK) 1383 *allocatedBuffer = buffer; 1384 else 1385 free(buffer); 1386 } 1387 1388 return error; 1389 } 1390 1391 // _WriteData 1392 /*! \brief Writes data to an attribute or resource. 1393 1394 The data are written to the location(s) specified by \a fWhere. 1395 1396 The object must be properly initialized. The parameters are NOT checked. 1397 1398 \param name The name of the attribute/resource to be written. 1399 \param id The resource ID of the resource to be written. 1400 \param type The type of the attribute/resource to be written. 1401 \param buffer A buffer containing the data to be written. 1402 \param bufferSize The size of the supplied buffer. 1403 \param findID If set to \c true use the ID that is already assigned to the 1404 \a name / \a type pair or take the first unused ID >= \a id. 1405 If \c false, \a id is used. 1406 If \a id is already in use and . 1407 \return 1408 - \c B_OK: Everything went fine. 1409 - error code 1410 */ 1411 status_t 1412 BAppFileInfo::_WriteData(const char *name, int32 id, type_code type, 1413 const void *buffer, size_t bufferSize, bool findID) 1414 { 1415 if (!IsUsingAttributes() && !IsUsingResources()) 1416 return B_NO_INIT; 1417 1418 status_t error = B_OK; 1419 1420 // write to attribute 1421 if (IsUsingAttributes()) { 1422 ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize); 1423 if (written < 0) 1424 error = written; 1425 else if (written != (ssize_t)bufferSize) 1426 error = B_ERROR; 1427 } 1428 // write to resource 1429 if (IsUsingResources() && error == B_OK) { 1430 if (findID) { 1431 // get the resource info 1432 int32 idFound; 1433 size_t sizeFound; 1434 if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 1435 id = idFound; 1436 else { 1437 // type-name pair doesn't exist yet -- find unused ID 1438 while (fResources->HasResource(type, id)) 1439 id++; 1440 } 1441 } 1442 error = fResources->AddResource(type, id, buffer, bufferSize, name); 1443 } 1444 return error; 1445 } 1446 1447 // _RemoveData 1448 /*! \brief Removes an attribute or resource. 1449 1450 The removal location is specified by \a fWhere. 1451 1452 The object must be properly initialized. The parameters are NOT checked. 1453 1454 \param name The name of the attribute/resource to be remove. 1455 \param type The type of the attribute/resource to be removed. 1456 \return 1457 - \c B_OK: Everything went fine. 1458 - error code 1459 */ 1460 status_t 1461 BAppFileInfo::_RemoveData(const char *name, type_code type) 1462 { 1463 if (!IsUsingAttributes() && !IsUsingResources()) 1464 return B_NO_INIT; 1465 1466 status_t error = B_OK; 1467 1468 // remove the attribute 1469 if (IsUsingAttributes()) { 1470 error = fNode->RemoveAttr(name); 1471 // It's no error, if there has been no attribute. 1472 if (error == B_ENTRY_NOT_FOUND) 1473 error = B_OK; 1474 } 1475 // remove the resource 1476 if (IsUsingResources() && error == B_OK) { 1477 // get a resource info 1478 int32 idFound; 1479 size_t sizeFound; 1480 if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 1481 error = fResources->RemoveResource(type, idFound); 1482 } 1483 return error; 1484 } 1485 1486