131dc79a1SAxel Dörfler /* 231dc79a1SAxel Dörfler * Copyright 2002-2006, Haiku Inc. 331dc79a1SAxel Dörfler * Distributed under the terms of the MIT License. 431dc79a1SAxel Dörfler * 531dc79a1SAxel Dörfler * Authors: 631dc79a1SAxel Dörfler * Ingo Weinhold, bonefish@users.sf.net 721881ce5SIngo Weinhold */ 8d6b205f3SIngo Weinhold 931dc79a1SAxel Dörfler 1098da112cSIngo Weinhold #include <new> 1198da112cSIngo Weinhold #include <set> 1298da112cSIngo Weinhold #include <string> 1398da112cSIngo Weinhold 14d6b205f3SIngo Weinhold #include <AppFileInfo.h> 1598da112cSIngo Weinhold #include <Bitmap.h> 1698da112cSIngo Weinhold #include <File.h> 1798da112cSIngo Weinhold #include <fs_attr.h> 18*9ecf9d1cSIngo Weinhold #include <IconUtils.h> 1998da112cSIngo Weinhold #include <MimeType.h> 2098da112cSIngo Weinhold #include <RegistrarDefs.h> 2198da112cSIngo Weinhold #include <Resources.h> 2298da112cSIngo Weinhold #include <Roster.h> 2398da112cSIngo Weinhold #include <String.h> 2498da112cSIngo Weinhold 2550f17542Shaydentech using namespace std; 2650f17542Shaydentech 2798da112cSIngo Weinhold // attributes 2898da112cSIngo Weinhold static const char *kTypeAttribute = "BEOS:TYPE"; 2998da112cSIngo Weinhold static const char *kSignatureAttribute = "BEOS:APP_SIG"; 3098da112cSIngo Weinhold static const char *kAppFlagsAttribute = "BEOS:APP_FLAGS"; 3198da112cSIngo Weinhold static const char *kSupportedTypesAttribute = "BEOS:FILE_TYPES"; 3298da112cSIngo Weinhold static const char *kVersionInfoAttribute = "BEOS:APP_VERSION"; 3398da112cSIngo Weinhold static const char *kMiniIconAttribute = "BEOS:M:"; 3498da112cSIngo Weinhold static const char *kLargeIconAttribute = "BEOS:L:"; 35*9ecf9d1cSIngo Weinhold static const char *kIconAttribute = "BEOS:"; 3698da112cSIngo Weinhold static const char *kStandardIconType = "STD_ICON"; 37*9ecf9d1cSIngo Weinhold static const char *kIconType = "ICON"; 3898da112cSIngo Weinhold 3998da112cSIngo Weinhold // resource IDs 4098da112cSIngo Weinhold static const int32 kTypeResourceID = 2; 4198da112cSIngo Weinhold static const int32 kSignatureResourceID = 1; 4298da112cSIngo Weinhold static const int32 kAppFlagsResourceID = 1; 4398da112cSIngo Weinhold static const int32 kSupportedTypesResourceID = 1; 4498da112cSIngo Weinhold static const int32 kMiniIconResourceID = 101; 4598da112cSIngo Weinhold static const int32 kLargeIconResourceID = 101; 4698da112cSIngo Weinhold static const int32 kVersionInfoResourceID = 1; 4798da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID = 0; 4898da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID = 0; 4998da112cSIngo Weinhold 5098da112cSIngo Weinhold // type codes 5198da112cSIngo Weinhold enum { 5298da112cSIngo Weinhold B_APP_FLAGS_TYPE = 'APPF', 5398da112cSIngo Weinhold B_VERSION_INFO_TYPE = 'APPV', 5498da112cSIngo Weinhold }; 5598da112cSIngo Weinhold 5688706bbeSAxel Dörfler // R5 also exports these (Tracker is using them): 5788706bbeSAxel Dörfler // (maybe we better want to drop them silently and declare 5888706bbeSAxel Dörfler // the above in a public Haiku header - and use that one in 5988706bbeSAxel Dörfler // Tracker when compiled for Haiku) 6088706bbeSAxel Dörfler extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE; 6188706bbeSAxel Dörfler const uint32 MINI_ICON_TYPE = 'MICN'; 6288706bbeSAxel Dörfler const uint32 LARGE_ICON_TYPE = 'ICON'; 6388706bbeSAxel Dörfler 6478b31a7cSIngo Weinhold // debugging 6578b31a7cSIngo Weinhold //#define DBG(x) x 6678b31a7cSIngo Weinhold #define DBG(x) 6778b31a7cSIngo Weinhold #define OUT printf 68d6b205f3SIngo Weinhold 69d6b205f3SIngo Weinhold // constructor 70d6b205f3SIngo Weinhold /*! \brief Creates an uninitialized BAppFileInfo object. 71d6b205f3SIngo Weinhold */ 72d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo() 73d6b205f3SIngo Weinhold : fResources(NULL), 74d6b205f3SIngo Weinhold fWhere(B_USE_BOTH_LOCATIONS) 75d6b205f3SIngo Weinhold { 76d6b205f3SIngo Weinhold } 77d6b205f3SIngo Weinhold 78d6b205f3SIngo Weinhold // constructor 79d6b205f3SIngo Weinhold /*! \brief Creates an BAppFileInfo object and initializes it to the supplied 80d6b205f3SIngo Weinhold file. 81d6b205f3SIngo Weinhold 82d6b205f3SIngo Weinhold The caller retains ownership of the supplied BFile object. It must not 83d6b205f3SIngo Weinhold be deleted during the life time of the BAppFileInfo. It is not deleted 84d6b205f3SIngo Weinhold when the BAppFileInfo is destroyed. 85d6b205f3SIngo Weinhold 86d6b205f3SIngo Weinhold \param file The file the object shall be initialized to. 87d6b205f3SIngo Weinhold */ 88d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile *file) 89d6b205f3SIngo Weinhold : fResources(NULL), 90d6b205f3SIngo Weinhold fWhere(B_USE_BOTH_LOCATIONS) 91d6b205f3SIngo Weinhold { 9298da112cSIngo Weinhold SetTo(file); 93d6b205f3SIngo Weinhold } 94d6b205f3SIngo Weinhold 95d6b205f3SIngo Weinhold // destructor 96d6b205f3SIngo Weinhold /*! \brief Frees all resources associated with this object. 97d6b205f3SIngo Weinhold 98d6b205f3SIngo Weinhold The BFile the object is set to is not deleted. 99d6b205f3SIngo Weinhold */ 100d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo() 101d6b205f3SIngo Weinhold { 10298da112cSIngo Weinhold if (fResources) 10398da112cSIngo Weinhold delete fResources; 104d6b205f3SIngo Weinhold } 105d6b205f3SIngo Weinhold 106d6b205f3SIngo Weinhold // SetTo 107d6b205f3SIngo Weinhold /*! \brief Initializes the BAppFileInfo to the supplied file. 108d6b205f3SIngo Weinhold 109d6b205f3SIngo Weinhold The caller retains ownership of the supplied BFile object. It must not 110d6b205f3SIngo Weinhold be deleted during the life time of the BAppFileInfo. It is not deleted 111d6b205f3SIngo Weinhold when the BAppFileInfo is destroyed. 112d6b205f3SIngo Weinhold 113d6b205f3SIngo Weinhold \param file The file the object shall be initialized to. 114d6b205f3SIngo Weinhold 115d6b205f3SIngo Weinhold \return 116d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 117d6b205f3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized. 118d6b205f3SIngo Weinhold */ 119d6b205f3SIngo Weinhold status_t 120d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile *file) 121d6b205f3SIngo Weinhold { 12298da112cSIngo Weinhold // unset the old file 12398da112cSIngo Weinhold BNodeInfo::SetTo(NULL); 12498da112cSIngo Weinhold if (fResources) { 12598da112cSIngo Weinhold delete fResources; 12698da112cSIngo Weinhold fResources = NULL; 12798da112cSIngo Weinhold } 128c2a2369dSAxel Dörfler 12998da112cSIngo Weinhold // check param 13098da112cSIngo Weinhold status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 131c2a2369dSAxel Dörfler 132c2a2369dSAxel Dörfler info_location where = B_USE_BOTH_LOCATIONS; 133c2a2369dSAxel Dörfler 13498da112cSIngo Weinhold // create resources 13598da112cSIngo Weinhold if (error == B_OK) { 13698da112cSIngo Weinhold fResources = new(nothrow) BResources(); 137c2a2369dSAxel Dörfler if (fResources) { 13898da112cSIngo Weinhold error = fResources->SetTo(file); 139c2a2369dSAxel Dörfler if (error != B_OK) { 140c2a2369dSAxel Dörfler // no resources - this is no critical error, we'll just use 141c2a2369dSAxel Dörfler // attributes only, then 142c2a2369dSAxel Dörfler where = B_USE_ATTRIBUTES; 143c2a2369dSAxel Dörfler error = B_OK; 144c2a2369dSAxel Dörfler } 145c2a2369dSAxel Dörfler } else 14698da112cSIngo Weinhold error = B_NO_MEMORY; 14798da112cSIngo Weinhold } 148c2a2369dSAxel Dörfler 14998da112cSIngo Weinhold // set node info 15098da112cSIngo Weinhold if (error == B_OK) 15198da112cSIngo Weinhold error = BNodeInfo::SetTo(file); 152c2a2369dSAxel Dörfler 153c2a2369dSAxel Dörfler if (error != B_OK || (where & B_USE_RESOURCES) == 0) { 15498da112cSIngo Weinhold delete fResources; 15598da112cSIngo Weinhold fResources = NULL; 15698da112cSIngo Weinhold } 157c2a2369dSAxel Dörfler 158c2a2369dSAxel Dörfler // clean up on error 159c2a2369dSAxel Dörfler if (error != B_OK) { 16098da112cSIngo Weinhold if (InitCheck() == B_OK) 16198da112cSIngo Weinhold BNodeInfo::SetTo(NULL); 16298da112cSIngo Weinhold } 163c2a2369dSAxel Dörfler 16498da112cSIngo Weinhold // set data location 16598da112cSIngo Weinhold if (error == B_OK) 166c2a2369dSAxel Dörfler SetInfoLocation(where); 167c2a2369dSAxel Dörfler 16898da112cSIngo Weinhold // set error 16998da112cSIngo Weinhold fCStatus = error; 17098da112cSIngo Weinhold return error; 171d6b205f3SIngo Weinhold } 172d6b205f3SIngo Weinhold 173d6b205f3SIngo Weinhold // GetType 174d6b205f3SIngo Weinhold /*! \brief Gets the file's MIME type. 175d6b205f3SIngo Weinhold 176d6b205f3SIngo Weinhold \param type A pointer to a pre-allocated character buffer of size 177d6b205f3SIngo Weinhold \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the 178d6b205f3SIngo Weinhold file shall be written. 179d6b205f3SIngo Weinhold \return 180d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 181d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 182d6b205f3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a type or the type string stored in the 183d6b205f3SIngo Weinhold attribute/resources is longer than \c B_MIME_TYPE_LENGTH. 184d6b205f3SIngo Weinhold - \c B_BAD_TYPE: The attribute/resources the type string is stored in have 185d6b205f3SIngo Weinhold the wrong type. 186d6b205f3SIngo Weinhold - \c B_ENTRY_NOT_FOUND: No type is set on the file. 187d6b205f3SIngo Weinhold - other error codes 188d6b205f3SIngo Weinhold */ 189d6b205f3SIngo Weinhold status_t 190d6b205f3SIngo Weinhold BAppFileInfo::GetType(char *type) const 191d6b205f3SIngo Weinhold { 19298da112cSIngo Weinhold // check param and initialization 19398da112cSIngo Weinhold status_t error = (type ? B_OK : B_BAD_VALUE); 19498da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 19598da112cSIngo Weinhold error = B_NO_INIT; 19698da112cSIngo Weinhold // read the data 19798da112cSIngo Weinhold size_t read = 0; 19898da112cSIngo Weinhold if (error == B_OK) { 19998da112cSIngo Weinhold error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE, 20098da112cSIngo Weinhold type, B_MIME_TYPE_LENGTH, read); 20198da112cSIngo Weinhold } 20298da112cSIngo Weinhold // check the read data -- null terminate the string 20398da112cSIngo Weinhold if (error == B_OK && type[read - 1] != '\0') { 20498da112cSIngo Weinhold if (read == B_MIME_TYPE_LENGTH) 20598da112cSIngo Weinhold error = B_ERROR; 20698da112cSIngo Weinhold else 20798da112cSIngo Weinhold type[read] = '\0'; 20898da112cSIngo Weinhold } 20998da112cSIngo Weinhold return error; 210d6b205f3SIngo Weinhold } 211d6b205f3SIngo Weinhold 212d6b205f3SIngo Weinhold // SetType 213d6b205f3SIngo Weinhold /*! \brief Sets the file's MIME type. 214d6b205f3SIngo Weinhold 215d6b205f3SIngo Weinhold If \a type is \c NULL the file's MIME type is unset. 216d6b205f3SIngo Weinhold 217d6b205f3SIngo Weinhold \param type The MIME type to be assigned to the file. Must not be longer 218d6b205f3SIngo Weinhold than \c B_MIME_TYPE_LENGTH (including the terminating null). 219d6b205f3SIngo Weinhold May be \c NULL. 220d6b205f3SIngo Weinhold \return 221d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 222d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 223d6b205f3SIngo Weinhold - \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH. 224d6b205f3SIngo Weinhold - other error codes 225d6b205f3SIngo Weinhold */ 226d6b205f3SIngo Weinhold status_t 227d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char *type) 228d6b205f3SIngo Weinhold { 22998da112cSIngo Weinhold // check initialization 23098da112cSIngo Weinhold status_t error = B_OK; 23198da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 23298da112cSIngo Weinhold error = B_NO_INIT; 23398da112cSIngo Weinhold if (error == B_OK) { 23498da112cSIngo Weinhold if (type) { 23598da112cSIngo Weinhold // check param 23698da112cSIngo Weinhold size_t typeLen = strlen(type); 23798da112cSIngo Weinhold if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH) 23898da112cSIngo Weinhold error = B_BAD_VALUE; 23998da112cSIngo Weinhold // write the data 24098da112cSIngo Weinhold if (error == B_OK) { 24198da112cSIngo Weinhold error = _WriteData(kTypeAttribute, kTypeResourceID, 24298da112cSIngo Weinhold B_MIME_STRING_TYPE, type, typeLen + 1); 24398da112cSIngo Weinhold } 24498da112cSIngo Weinhold } else 24598da112cSIngo Weinhold error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE); 24698da112cSIngo Weinhold } 24798da112cSIngo Weinhold return error; 248d6b205f3SIngo Weinhold } 249d6b205f3SIngo Weinhold 250d6b205f3SIngo Weinhold // GetSignature 251d6b205f3SIngo Weinhold /*! \brief Gets the file's application signature. 252d6b205f3SIngo Weinhold 253d6b205f3SIngo Weinhold \param signature A pointer to a pre-allocated character buffer of size 254d6b205f3SIngo Weinhold \c B_MIME_TYPE_LENGTH or larger into which the application 255d6b205f3SIngo Weinhold signature of the file shall be written. 256d6b205f3SIngo Weinhold \return 257d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 258d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 259d6b205f3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the 260d6b205f3SIngo Weinhold attribute/resources is longer than \c B_MIME_TYPE_LENGTH. 261d6b205f3SIngo Weinhold - \c B_BAD_TYPE: The attribute/resources the signature is stored in have 262d6b205f3SIngo Weinhold the wrong type. 263d6b205f3SIngo Weinhold - \c B_ENTRY_NOT_FOUND: No signature is set on the file. 264d6b205f3SIngo Weinhold - other error codes 265d6b205f3SIngo Weinhold */ 266d6b205f3SIngo Weinhold status_t 267d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char *signature) const 268d6b205f3SIngo Weinhold { 26998da112cSIngo Weinhold // check param and initialization 27098da112cSIngo Weinhold status_t error = (signature ? B_OK : B_BAD_VALUE); 27198da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 27298da112cSIngo Weinhold error = B_NO_INIT; 27398da112cSIngo Weinhold // read the data 27498da112cSIngo Weinhold size_t read = 0; 27598da112cSIngo Weinhold if (error == B_OK) { 27698da112cSIngo Weinhold error = _ReadData(kSignatureAttribute, kSignatureResourceID, 27798da112cSIngo Weinhold B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH, 27898da112cSIngo Weinhold read); 27998da112cSIngo Weinhold } 28098da112cSIngo Weinhold // check the read data -- null terminate the string 28198da112cSIngo Weinhold if (error == B_OK && signature[read - 1] != '\0') { 28298da112cSIngo Weinhold if (read == B_MIME_TYPE_LENGTH) 28398da112cSIngo Weinhold error = B_ERROR; 28498da112cSIngo Weinhold else 28598da112cSIngo Weinhold signature[read] = '\0'; 28698da112cSIngo Weinhold } 28798da112cSIngo Weinhold return error; 288d6b205f3SIngo Weinhold } 289d6b205f3SIngo Weinhold 290d6b205f3SIngo Weinhold // SetSignature 291d6b205f3SIngo Weinhold /*! \brief Sets the file's application signature. 292d6b205f3SIngo Weinhold 293d6b205f3SIngo Weinhold If \a signature is \c NULL the file's application signature is unset. 294d6b205f3SIngo Weinhold 295d6b205f3SIngo Weinhold \param signature The application signature to be assigned to the file. 296d6b205f3SIngo Weinhold Must not be longer than \c B_MIME_TYPE_LENGTH (including the 297d6b205f3SIngo Weinhold terminating null). May be \c NULL. 298d6b205f3SIngo Weinhold \return 299d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 300d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 301d6b205f3SIngo Weinhold - \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH. 302d6b205f3SIngo Weinhold - other error codes 303d6b205f3SIngo Weinhold */ 304d6b205f3SIngo Weinhold status_t 305d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char *signature) 306d6b205f3SIngo Weinhold { 30798da112cSIngo Weinhold // check initialization 30898da112cSIngo Weinhold status_t error = B_OK; 30998da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 31098da112cSIngo Weinhold error = B_NO_INIT; 31198da112cSIngo Weinhold if (error == B_OK) { 31298da112cSIngo Weinhold if (signature) { 31398da112cSIngo Weinhold // check param 31498da112cSIngo Weinhold size_t signatureLen = strlen(signature); 31598da112cSIngo Weinhold if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH) 31698da112cSIngo Weinhold error = B_BAD_VALUE; 31798da112cSIngo Weinhold // write the data 31898da112cSIngo Weinhold if (error == B_OK) { 31998da112cSIngo Weinhold error = _WriteData(kSignatureAttribute, kSignatureResourceID, 32098da112cSIngo Weinhold B_MIME_STRING_TYPE, signature, 32198da112cSIngo Weinhold signatureLen + 1); 32298da112cSIngo Weinhold } 32398da112cSIngo Weinhold } else 32498da112cSIngo Weinhold error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE); 32598da112cSIngo Weinhold } 32698da112cSIngo Weinhold return error; 327d6b205f3SIngo Weinhold } 328d6b205f3SIngo Weinhold 329d6b205f3SIngo Weinhold // GetAppFlags 330d6b205f3SIngo Weinhold /*! \brief Gets the file's application flags. 331d6b205f3SIngo Weinhold 332d6b205f3SIngo Weinhold \param flags A pointer to a pre-allocated uint32 into which the application 333d6b205f3SIngo Weinhold flags of the file shall be written. 334d6b205f3SIngo Weinhold \return 335d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 336d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 337d6b205f3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a flags. 338d6b205f3SIngo Weinhold - \c B_BAD_TYPE: The attribute/resources the flags are stored in have 339d6b205f3SIngo Weinhold the wrong type. 340d6b205f3SIngo Weinhold - \c B_ENTRY_NOT_FOUND: No application flags are set on the file. 341d6b205f3SIngo Weinhold - other error codes 342d6b205f3SIngo Weinhold */ 343d6b205f3SIngo Weinhold status_t 344d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32 *flags) const 345d6b205f3SIngo Weinhold { 34698da112cSIngo Weinhold // check param and initialization 34798da112cSIngo Weinhold status_t error = (flags ? B_OK : B_BAD_VALUE); 34898da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 34998da112cSIngo Weinhold error = B_NO_INIT; 35098da112cSIngo Weinhold // read the data 35198da112cSIngo Weinhold size_t read = 0; 35298da112cSIngo Weinhold if (error == B_OK) { 35398da112cSIngo Weinhold error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID, 35498da112cSIngo Weinhold B_APP_FLAGS_TYPE, flags, sizeof(uint32), 35598da112cSIngo Weinhold read); 35698da112cSIngo Weinhold } 35798da112cSIngo Weinhold // check the read data 35898da112cSIngo Weinhold if (error == B_OK && read != sizeof(uint32)) 35998da112cSIngo Weinhold error = B_ERROR; 36098da112cSIngo Weinhold return error; 361d6b205f3SIngo Weinhold } 362d6b205f3SIngo Weinhold 363d6b205f3SIngo Weinhold // SetAppFlags 364d6b205f3SIngo Weinhold /*! \brief Sets the file's application flags. 365d6b205f3SIngo Weinhold \param flags The application flags to be assigned to the file. 366d6b205f3SIngo Weinhold \return 367d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 368d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 369d6b205f3SIngo Weinhold - other error codes 370d6b205f3SIngo Weinhold */ 371d6b205f3SIngo Weinhold status_t 372d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags) 373d6b205f3SIngo Weinhold { 37498da112cSIngo Weinhold // check initialization 37598da112cSIngo Weinhold status_t error = B_OK; 37698da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 37798da112cSIngo Weinhold error = B_NO_INIT; 37898da112cSIngo Weinhold if (error == B_OK) { 37998da112cSIngo Weinhold // write the data 38098da112cSIngo Weinhold if (error == B_OK) { 38198da112cSIngo Weinhold error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID, 38298da112cSIngo Weinhold B_APP_FLAGS_TYPE, &flags, sizeof(uint32)); 38398da112cSIngo Weinhold } 38498da112cSIngo Weinhold } 38598da112cSIngo Weinhold return error; 386d6b205f3SIngo Weinhold } 387d6b205f3SIngo Weinhold 388d6b205f3SIngo Weinhold // GetSupportedTypes 389d6b205f3SIngo Weinhold /*! \brief Gets the MIME types supported by the application. 390d6b205f3SIngo Weinhold 391d6b205f3SIngo Weinhold The supported MIME types are added to a field "types" of type 392d6b205f3SIngo Weinhold \c B_STRING_TYPE in \a types. 393d6b205f3SIngo Weinhold 394d6b205f3SIngo Weinhold \param types A pointer to a pre-allocated BMessage into which the 395d6b205f3SIngo Weinhold MIME types supported by the appplication shall be written. 396d6b205f3SIngo Weinhold \return 397d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 398d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 399d6b205f3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a types. 400d6b205f3SIngo Weinhold - \c B_BAD_TYPE: The attribute/resources the supported types are stored in 401d6b205f3SIngo Weinhold have the wrong type. 402d6b205f3SIngo Weinhold - \c B_ENTRY_NOT_FOUND: No supported types are set on the file. 403d6b205f3SIngo Weinhold - other error codes 404d6b205f3SIngo Weinhold */ 405d6b205f3SIngo Weinhold status_t 406d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage *types) const 407d6b205f3SIngo Weinhold { 40898da112cSIngo Weinhold // check param and initialization 40998da112cSIngo Weinhold status_t error = (types ? B_OK : B_BAD_VALUE); 41098da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 41198da112cSIngo Weinhold error = B_NO_INIT; 41298da112cSIngo Weinhold // read the data 41398da112cSIngo Weinhold size_t read = 0; 41498da112cSIngo Weinhold void *buffer = NULL; 41598da112cSIngo Weinhold if (error == B_OK) { 41698da112cSIngo Weinhold error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID, 41798da112cSIngo Weinhold B_MESSAGE_TYPE, NULL, 0, read, &buffer); 41898da112cSIngo Weinhold } 41998da112cSIngo Weinhold // unflatten the buffer 42098da112cSIngo Weinhold if (error == B_OK) 42198da112cSIngo Weinhold error = types->Unflatten((const char*)buffer); 42298da112cSIngo Weinhold // clean up 42398da112cSIngo Weinhold if (buffer) 42498da112cSIngo Weinhold free(buffer); 42598da112cSIngo Weinhold return error; 426d6b205f3SIngo Weinhold } 427d6b205f3SIngo Weinhold 428d6b205f3SIngo Weinhold // SetSupportedTypes 429d6b205f3SIngo Weinhold /*! \brief Sets the MIME types supported by the application. 430d6b205f3SIngo Weinhold 431d6b205f3SIngo Weinhold If \a types is \c NULL the application's supported types are unset. 432d6b205f3SIngo Weinhold 433d6b205f3SIngo Weinhold The supported MIME types must be stored in a field "types" of type 434d6b205f3SIngo Weinhold \c B_STRING_TYPE in \a types. 435d6b205f3SIngo Weinhold 43683a812a1SIngo Weinhold The method informs the registrar about this news. 43783a812a1SIngo Weinhold For each supported type the result of BMimeType::GetSupportingApps() will 43883a812a1SIngo Weinhold afterwards include the signature of this application. That is, the 43983a812a1SIngo Weinhold application file needs to have a signature set. 44083a812a1SIngo Weinhold 44183a812a1SIngo Weinhold \a syncAll specifies whether the not longer supported types shall be 44283a812a1SIngo Weinhold updated as well, i.e. whether this application shall be remove from the 44383a812a1SIngo Weinhold lists of supporting applications. 44483a812a1SIngo Weinhold 445d6b205f3SIngo Weinhold \param types The supported types to be assigned to the file. 446d6b205f3SIngo Weinhold May be \c NULL. 44783a812a1SIngo Weinhold \param syncAll \c true to also synchronize the not longer supported 44883a812a1SIngo Weinhold types, \c false otherwise. 449d6b205f3SIngo Weinhold \return 450d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 451d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 452d6b205f3SIngo Weinhold - other error codes 453d6b205f3SIngo Weinhold */ 454d6b205f3SIngo Weinhold status_t 455d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll) 456d6b205f3SIngo Weinhold { 45798da112cSIngo Weinhold // check initialization 45898da112cSIngo Weinhold status_t error = B_OK; 45998da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 46098da112cSIngo Weinhold error = B_NO_INIT; 46198da112cSIngo Weinhold BMimeType mimeType; 46298da112cSIngo Weinhold if (error == B_OK) 46398da112cSIngo Weinhold error = GetMetaMime(&mimeType); 4647f20062dSJérôme Duval if (error == B_OK || error == B_ENTRY_NOT_FOUND) { 4657f20062dSJérôme Duval error = B_OK; 46698da112cSIngo Weinhold if (types) { 46717819be3SIngo Weinhold // check param -- supported types must be valid 46817819be3SIngo Weinhold const char *type; 46917819be3SIngo Weinhold for (int32 i = 0; 47017819be3SIngo Weinhold error == B_OK && types->FindString("types", i, &type) == B_OK; 47117819be3SIngo Weinhold i++) { 47217819be3SIngo Weinhold if (!BMimeType::IsValid(type)) 47317819be3SIngo Weinhold error = B_BAD_VALUE; 47417819be3SIngo Weinhold } 47517819be3SIngo Weinhold // get flattened size 47617819be3SIngo Weinhold ssize_t size = 0; 47717819be3SIngo Weinhold if (error == B_OK) { 47817819be3SIngo Weinhold size = types->FlattenedSize(); 47998da112cSIngo Weinhold if (size < 0) 48098da112cSIngo Weinhold error = size; 48117819be3SIngo Weinhold } 48298da112cSIngo Weinhold // allocate a buffer for the flattened data 48398da112cSIngo Weinhold char *buffer = NULL; 48498da112cSIngo Weinhold if (error == B_OK) { 48598da112cSIngo Weinhold buffer = new(nothrow) char[size]; 48698da112cSIngo Weinhold if (!buffer) 48798da112cSIngo Weinhold error = B_NO_MEMORY; 48898da112cSIngo Weinhold } 48998da112cSIngo Weinhold // flatten the message 49098da112cSIngo Weinhold if (error == B_OK) 49198da112cSIngo Weinhold error = types->Flatten(buffer, size); 49298da112cSIngo Weinhold // write the data 49398da112cSIngo Weinhold if (error == B_OK) { 49498da112cSIngo Weinhold error = _WriteData(kSupportedTypesAttribute, 49598da112cSIngo Weinhold kSupportedTypesResourceID, B_MESSAGE_TYPE, 49698da112cSIngo Weinhold buffer, size); 49798da112cSIngo Weinhold } 49898da112cSIngo Weinhold // clean up 49998da112cSIngo Weinhold if (buffer) 50098da112cSIngo Weinhold delete[] buffer; 50198da112cSIngo Weinhold } else 50298da112cSIngo Weinhold error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE); 50398da112cSIngo Weinhold // update the MIME database, if the app signature is installed 50417819be3SIngo Weinhold if (error == B_OK && mimeType.IsInstalled()) 50517819be3SIngo Weinhold error = mimeType.SetSupportedTypes(types, syncAll); 50698da112cSIngo Weinhold } 50798da112cSIngo Weinhold return error; 508d6b205f3SIngo Weinhold } 509d6b205f3SIngo Weinhold 510d6b205f3SIngo Weinhold // SetSupportedTypes 511d6b205f3SIngo Weinhold /*! \brief Sets the MIME types supported by the application. 512d6b205f3SIngo Weinhold 51398da112cSIngo Weinhold This method is a short-hand for SetSupportedTypes(types, false). 51483a812a1SIngo Weinhold \see SetSupportedType(const BMessage*, bool) for detailed information. 515d6b205f3SIngo Weinhold 516d6b205f3SIngo Weinhold \param types The supported types to be assigned to the file. 517d6b205f3SIngo Weinhold May be \c NULL. 518d6b205f3SIngo Weinhold \return 519d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 520d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 521d6b205f3SIngo Weinhold - other error codes 522d6b205f3SIngo Weinhold */ 523d6b205f3SIngo Weinhold status_t 524d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types) 525d6b205f3SIngo Weinhold { 52698da112cSIngo Weinhold return SetSupportedTypes(types, false); 527d6b205f3SIngo Weinhold } 528d6b205f3SIngo Weinhold 529d6b205f3SIngo Weinhold // IsSupportedType 530d6b205f3SIngo Weinhold /*! \brief Returns whether the application supports the supplied MIME type. 531d6b205f3SIngo Weinhold 532d6b205f3SIngo Weinhold If the application supports the wildcard type "application/octet-stream" 533d6b205f3SIngo Weinhold any this method returns \c true for any MIME type. 534d6b205f3SIngo Weinhold 535d6b205f3SIngo Weinhold \param type The MIME type in question. 536d6b205f3SIngo Weinhold \return \c true, if \a type is a valid MIME type and it is supported by 537d6b205f3SIngo Weinhold the application, \c false otherwise. 538d6b205f3SIngo Weinhold */ 539d6b205f3SIngo Weinhold bool 540d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char *type) const 541d6b205f3SIngo Weinhold { 54298da112cSIngo Weinhold status_t error = (type ? B_OK : B_BAD_VALUE); 54398da112cSIngo Weinhold // get the supported types 54498da112cSIngo Weinhold BMessage types; 54598da112cSIngo Weinhold if (error == B_OK) 54698da112cSIngo Weinhold error = GetSupportedTypes(&types); 54798da112cSIngo Weinhold // turn type into a BMimeType 54898da112cSIngo Weinhold BMimeType mimeType; 54998da112cSIngo Weinhold if (error == B_OK) 55098da112cSIngo Weinhold error = mimeType.SetTo(type); 55198da112cSIngo Weinhold // iterate through the supported types 55298da112cSIngo Weinhold bool found = false; 55398da112cSIngo Weinhold if (error == B_OK) { 55498da112cSIngo Weinhold const char *supportedType; 55598da112cSIngo Weinhold for (int32 i = 0; 55698da112cSIngo Weinhold !found && types.FindString("types", i, &supportedType) == B_OK; 55798da112cSIngo Weinhold i++) { 55898da112cSIngo Weinhold found = !strcmp(supportedType, "application/octet-stream") 55998da112cSIngo Weinhold || BMimeType(supportedType).Contains(&mimeType); 56098da112cSIngo Weinhold } 56198da112cSIngo Weinhold } 56298da112cSIngo Weinhold return found; 563d6b205f3SIngo Weinhold } 564d6b205f3SIngo Weinhold 565d6b205f3SIngo Weinhold // Supports 566d6b205f3SIngo Weinhold /*! \brief Returns whether the application supports the supplied MIME type 567d6b205f3SIngo Weinhold explicitly. 568d6b205f3SIngo Weinhold 569d6b205f3SIngo Weinhold Unlike IsSupportedType(), this method returns \c true, only if the type 570d6b205f3SIngo Weinhold is explicitly supported, regardless of whether it supports 571d6b205f3SIngo Weinhold "application/octet-stream". 572d6b205f3SIngo Weinhold 573d6b205f3SIngo Weinhold \param type The MIME type in question. 574d6b205f3SIngo Weinhold \return \c true, if \a type is a valid MIME type and it is explicitly 575d6b205f3SIngo Weinhold supported by the application, \c false otherwise. 576d6b205f3SIngo Weinhold */ 577d6b205f3SIngo Weinhold bool 578d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType *type) const 579d6b205f3SIngo Weinhold { 58098da112cSIngo Weinhold status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 58198da112cSIngo Weinhold // get the supported types 58298da112cSIngo Weinhold BMessage types; 58398da112cSIngo Weinhold if (error == B_OK) 58498da112cSIngo Weinhold error = GetSupportedTypes(&types); 58598da112cSIngo Weinhold // iterate through the supported types 58698da112cSIngo Weinhold bool found = false; 58798da112cSIngo Weinhold if (error == B_OK) { 58898da112cSIngo Weinhold const char *supportedType; 58998da112cSIngo Weinhold for (int32 i = 0; 59098da112cSIngo Weinhold !found && types.FindString("types", i, &supportedType) == B_OK; 59198da112cSIngo Weinhold i++) { 59298da112cSIngo Weinhold found = BMimeType(supportedType).Contains(type); 59398da112cSIngo Weinhold } 59498da112cSIngo Weinhold } 59598da112cSIngo Weinhold return found; 596d6b205f3SIngo Weinhold } 597d6b205f3SIngo Weinhold 598d6b205f3SIngo Weinhold // GetIcon 599d6b205f3SIngo Weinhold /*! \brief Gets the file's icon. 600d6b205f3SIngo Weinhold \param icon A pointer to a pre-allocated BBitmap of the correct dimension 601d6b205f3SIngo Weinhold to store the requested icon (16x16 for the mini and 32x32 for the 602d6b205f3SIngo Weinhold large icon). 603d6b205f3SIngo Weinhold \param which Specifies the size of the icon to be retrieved: 604d6b205f3SIngo Weinhold \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 605d6b205f3SIngo Weinhold \return 606d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 607d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 608d6b205f3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap 609d6b205f3SIngo Weinhold dimensions (\a icon) and icon size (\a which) do not match. 610d6b205f3SIngo Weinhold - other error codes 611d6b205f3SIngo Weinhold */ 612d6b205f3SIngo Weinhold status_t 613d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const 614d6b205f3SIngo Weinhold { 61598da112cSIngo Weinhold return GetIconForType(NULL, icon, which); 616d6b205f3SIngo Weinhold } 617d6b205f3SIngo Weinhold 618d6b205f3SIngo Weinhold // SetIcon 619d6b205f3SIngo Weinhold /*! \brief Sets the file's icon. 620d6b205f3SIngo Weinhold 621d6b205f3SIngo Weinhold If \a icon is \c NULL the file's icon is unset. 622d6b205f3SIngo Weinhold 623d6b205f3SIngo Weinhold \param icon A pointer to the BBitmap containing the icon to be set. 624d6b205f3SIngo Weinhold May be \c NULL. 625d6b205f3SIngo Weinhold \param which Specifies the size of the icon to be set: \c B_MINI_ICON 626d6b205f3SIngo Weinhold for the mini and \c B_LARGE_ICON for the large icon. 627d6b205f3SIngo Weinhold \return 628d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 629d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 630d6b205f3SIngo Weinhold - \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon) 631d6b205f3SIngo Weinhold and icon size (\a which) do not match. 632d6b205f3SIngo Weinhold - other error codes 633d6b205f3SIngo Weinhold */ 634d6b205f3SIngo Weinhold status_t 635d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which) 636d6b205f3SIngo Weinhold { 63798da112cSIngo Weinhold return SetIconForType(NULL, icon, which); 638d6b205f3SIngo Weinhold } 639d6b205f3SIngo Weinhold 640d6b205f3SIngo Weinhold // GetVersionInfo 641d6b205f3SIngo Weinhold /*! \brief Gets the file's version info. 642d6b205f3SIngo Weinhold \param info A pointer to a pre-allocated version_info structure into which 643d6b205f3SIngo Weinhold the version info should be written. 644d6b205f3SIngo Weinhold \param kind Specifies the kind of the version info to be retrieved: 645d6b205f3SIngo Weinhold \c B_APP_VERSION_KIND for the application's version info and 646d6b205f3SIngo Weinhold \c B_SYSTEM_VERSION_KIND for the suite's info the application 647d6b205f3SIngo Weinhold belongs to. 648d6b205f3SIngo Weinhold \return 649d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 650d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 651d6b205f3SIngo Weinhold - \c B_BAD_VALUE: \c NULL \a info. 652d6b205f3SIngo Weinhold - other error codes 653d6b205f3SIngo Weinhold */ 654d6b205f3SIngo Weinhold status_t 655d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const 656d6b205f3SIngo Weinhold { 65798da112cSIngo Weinhold // check params and initialization 658b1970bb8SIngo Weinhold if (!info) 659b1970bb8SIngo Weinhold return B_BAD_VALUE; 660b1970bb8SIngo Weinhold 66198da112cSIngo Weinhold int32 index = 0; 66298da112cSIngo Weinhold switch (kind) { 66398da112cSIngo Weinhold case B_APP_VERSION_KIND: 66498da112cSIngo Weinhold index = 0; 66598da112cSIngo Weinhold break; 66698da112cSIngo Weinhold case B_SYSTEM_VERSION_KIND: 66798da112cSIngo Weinhold index = 1; 66898da112cSIngo Weinhold break; 66998da112cSIngo Weinhold default: 670b1970bb8SIngo Weinhold return B_BAD_VALUE; 67198da112cSIngo Weinhold } 672b1970bb8SIngo Weinhold 673b1970bb8SIngo Weinhold if (InitCheck() != B_OK) 674b1970bb8SIngo Weinhold return B_NO_INIT; 675b1970bb8SIngo Weinhold 67698da112cSIngo Weinhold // read the data 67798da112cSIngo Weinhold size_t read = 0; 67898da112cSIngo Weinhold version_info infos[2]; 679b1970bb8SIngo Weinhold status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, 680b1970bb8SIngo Weinhold B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read); 681b1970bb8SIngo Weinhold if (error != B_OK) 68298da112cSIngo Weinhold return error; 683b1970bb8SIngo Weinhold 684b1970bb8SIngo Weinhold // check the read data 685b1970bb8SIngo Weinhold if (read == sizeof(version_info)) { 686b1970bb8SIngo Weinhold // only the app version info is there -- return a cleared system info 687b1970bb8SIngo Weinhold if (index == 0) 688b1970bb8SIngo Weinhold *info = infos[index]; 689b1970bb8SIngo Weinhold else if (index == 1) 690b1970bb8SIngo Weinhold memset(info, 0, sizeof(version_info)); 691b1970bb8SIngo Weinhold } else if (read == 2 * sizeof(version_info)) { 692b1970bb8SIngo Weinhold *info = infos[index]; 693b1970bb8SIngo Weinhold } else 694b1970bb8SIngo Weinhold return B_ERROR; 695b1970bb8SIngo Weinhold 696b1970bb8SIngo Weinhold // return result 697b1970bb8SIngo Weinhold return B_OK; 698d6b205f3SIngo Weinhold } 699d6b205f3SIngo Weinhold 700d6b205f3SIngo Weinhold // SetVersionInfo 701d6b205f3SIngo Weinhold /*! \brief Sets the file's version info. 702d6b205f3SIngo Weinhold 703d6b205f3SIngo Weinhold If \a info is \c NULL the file's version info is unset. 704d6b205f3SIngo Weinhold 705d6b205f3SIngo Weinhold \param info The version info to be set. May be \c NULL. 706d6b205f3SIngo Weinhold \param kind Specifies kind of version info to be set: 707d6b205f3SIngo Weinhold \c B_APP_VERSION_KIND for the application's version info and 708d6b205f3SIngo Weinhold \c B_SYSTEM_VERSION_KIND for the suite's info the application 709d6b205f3SIngo Weinhold belongs to. 710d6b205f3SIngo Weinhold \return 711d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 712d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 713d6b205f3SIngo Weinhold - other error codes 714d6b205f3SIngo Weinhold */ 715d6b205f3SIngo Weinhold status_t 716d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind) 717d6b205f3SIngo Weinhold { 71898da112cSIngo Weinhold // check initialization 71998da112cSIngo Weinhold status_t error = B_OK; 72098da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 72198da112cSIngo Weinhold error = B_NO_INIT; 72298da112cSIngo Weinhold if (error == B_OK) { 72398da112cSIngo Weinhold if (info) { 72498da112cSIngo Weinhold // check param 72598da112cSIngo Weinhold int32 index = 0; 72698da112cSIngo Weinhold if (error == B_OK) { 72798da112cSIngo Weinhold switch (kind) { 72898da112cSIngo Weinhold case B_APP_VERSION_KIND: 72998da112cSIngo Weinhold index = 0; 73098da112cSIngo Weinhold break; 73198da112cSIngo Weinhold case B_SYSTEM_VERSION_KIND: 73298da112cSIngo Weinhold index = 1; 73398da112cSIngo Weinhold break; 73498da112cSIngo Weinhold default: 73598da112cSIngo Weinhold error = B_BAD_VALUE; 73698da112cSIngo Weinhold break; 73798da112cSIngo Weinhold } 73898da112cSIngo Weinhold } 73998da112cSIngo Weinhold // read both infos 74098da112cSIngo Weinhold version_info infos[2]; 74198da112cSIngo Weinhold if (error == B_OK) { 74298da112cSIngo Weinhold size_t read; 743b1970bb8SIngo Weinhold if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID, 744b1970bb8SIngo Weinhold B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), 745b1970bb8SIngo Weinhold read) == B_OK) { 746b1970bb8SIngo Weinhold // clear the part that hasn't been read 747b1970bb8SIngo Weinhold if (read < sizeof(infos)) 748b1970bb8SIngo Weinhold memset((char*)infos + read, 0, sizeof(infos) - read); 749b1970bb8SIngo Weinhold } else { 750b1970bb8SIngo Weinhold // failed to read -- clear 751b1970bb8SIngo Weinhold memset(infos, 0, sizeof(infos)); 752b1970bb8SIngo Weinhold } 75398da112cSIngo Weinhold } 75498da112cSIngo Weinhold infos[index] = *info; 75598da112cSIngo Weinhold // write the data 75698da112cSIngo Weinhold if (error == B_OK) { 75798da112cSIngo Weinhold error = _WriteData(kVersionInfoAttribute, 75898da112cSIngo Weinhold kVersionInfoResourceID, 75998da112cSIngo Weinhold B_VERSION_INFO_TYPE, infos, 76098da112cSIngo Weinhold 2 * sizeof(version_info)); 76198da112cSIngo Weinhold } 76298da112cSIngo Weinhold } else 76398da112cSIngo Weinhold error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE); 76498da112cSIngo Weinhold } 76598da112cSIngo Weinhold return error; 766d6b205f3SIngo Weinhold } 767d6b205f3SIngo Weinhold 768d6b205f3SIngo Weinhold // GetIconForType 769d6b205f3SIngo Weinhold /*! \brief Gets the icon the application provides for a given MIME type. 77098da112cSIngo Weinhold 77198da112cSIngo Weinhold If \a type is \c NULL, the application's icon is retrieved. 77298da112cSIngo Weinhold 77398da112cSIngo Weinhold \param type The MIME type in question. May be \c NULL. 774d6b205f3SIngo Weinhold \param icon A pointer to a pre-allocated BBitmap of the correct dimension 775d6b205f3SIngo Weinhold to store the requested icon (16x16 for the mini and 32x32 for the 776d6b205f3SIngo Weinhold large icon). 777d6b205f3SIngo Weinhold \param which Specifies the size of the icon to be retrieved: 778d6b205f3SIngo Weinhold \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 779d6b205f3SIngo Weinhold \return 780d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 781d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 78298da112cSIngo Weinhold - \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size 783d6b205f3SIngo Weinhold \a which or bitmap dimensions (\a icon) and icon size (\a which) do 784d6b205f3SIngo Weinhold not match. 785d6b205f3SIngo Weinhold - other error codes 786d6b205f3SIngo Weinhold */ 787d6b205f3SIngo Weinhold status_t 788d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char *type, BBitmap *icon, 789d6b205f3SIngo Weinhold icon_size which) const 790d6b205f3SIngo Weinhold { 791*9ecf9d1cSIngo Weinhold if (InitCheck() != B_OK) 792*9ecf9d1cSIngo Weinhold return B_NO_INIT; 793*9ecf9d1cSIngo Weinhold 794*9ecf9d1cSIngo Weinhold if (!icon || icon->InitCheck() != B_OK) 795*9ecf9d1cSIngo Weinhold return B_BAD_VALUE; 796*9ecf9d1cSIngo Weinhold 797*9ecf9d1cSIngo Weinhold // try vector icon first 798*9ecf9d1cSIngo Weinhold BString vectorAttributeName(kIconAttribute); 799*9ecf9d1cSIngo Weinhold 800*9ecf9d1cSIngo Weinhold // check type param 801*9ecf9d1cSIngo Weinhold if (type) { 802*9ecf9d1cSIngo Weinhold if (BMimeType::IsValid(type)) 803*9ecf9d1cSIngo Weinhold vectorAttributeName += type; 804*9ecf9d1cSIngo Weinhold else 805*9ecf9d1cSIngo Weinhold return B_BAD_VALUE; 806*9ecf9d1cSIngo Weinhold } else { 807*9ecf9d1cSIngo Weinhold vectorAttributeName += kIconType; 808*9ecf9d1cSIngo Weinhold } 809*9ecf9d1cSIngo Weinhold const char* attribute = vectorAttributeName.String(); 810*9ecf9d1cSIngo Weinhold 811*9ecf9d1cSIngo Weinhold size_t bytesRead; 812*9ecf9d1cSIngo Weinhold void* allocatedBuffer; 813*9ecf9d1cSIngo Weinhold status_t error = _ReadData(attribute, -1, B_RAW_TYPE, NULL, 0, 814*9ecf9d1cSIngo Weinhold bytesRead, &allocatedBuffer); 815*9ecf9d1cSIngo Weinhold if (error == B_OK) { 816*9ecf9d1cSIngo Weinhold return BIconUtils::GetVectorIcon((uint8*)allocatedBuffer, 817*9ecf9d1cSIngo Weinhold bytesRead, icon); 818*9ecf9d1cSIngo Weinhold } 819*9ecf9d1cSIngo Weinhold 820*9ecf9d1cSIngo Weinhold // no vector icon if we got this far 821*9ecf9d1cSIngo Weinhold 822*9ecf9d1cSIngo Weinhold error = B_OK; 82398da112cSIngo Weinhold // set some icon size related variables 82498da112cSIngo Weinhold BString attributeString; 82598da112cSIngo Weinhold BRect bounds; 826a04efc92SIngo Weinhold uint32 attrType = 0; 827a04efc92SIngo Weinhold size_t attrSize = 0; 82898da112cSIngo Weinhold switch (which) { 82998da112cSIngo Weinhold case B_MINI_ICON: 83098da112cSIngo Weinhold attributeString = kMiniIconAttribute; 83198da112cSIngo Weinhold bounds.Set(0, 0, 15, 15); 83298da112cSIngo Weinhold attrType = B_MINI_ICON_TYPE; 83398da112cSIngo Weinhold attrSize = 16 * 16; 83498da112cSIngo Weinhold break; 83598da112cSIngo Weinhold case B_LARGE_ICON: 83698da112cSIngo Weinhold attributeString = kLargeIconAttribute; 83798da112cSIngo Weinhold bounds.Set(0, 0, 31, 31); 83898da112cSIngo Weinhold attrType = B_LARGE_ICON_TYPE; 83998da112cSIngo Weinhold attrSize = 32 * 32; 84098da112cSIngo Weinhold break; 84198da112cSIngo Weinhold default: 842*9ecf9d1cSIngo Weinhold return B_BAD_VALUE; 84398da112cSIngo Weinhold } 84498da112cSIngo Weinhold // check type param 84598da112cSIngo Weinhold if (type) { 84617819be3SIngo Weinhold if (BMimeType::IsValid(type)) 84717819be3SIngo Weinhold attributeString += type; 84817819be3SIngo Weinhold else 849*9ecf9d1cSIngo Weinhold return B_BAD_VALUE; 85098da112cSIngo Weinhold } else 85117819be3SIngo Weinhold attributeString += kStandardIconType; 852*9ecf9d1cSIngo Weinhold 853*9ecf9d1cSIngo Weinhold attribute = attributeString.String(); 85417819be3SIngo Weinhold 85598da112cSIngo Weinhold // check parameter and initialization 856*9ecf9d1cSIngo Weinhold if (icon->Bounds() != bounds) 857*9ecf9d1cSIngo Weinhold return B_BAD_VALUE; 858*9ecf9d1cSIngo Weinhold 85998da112cSIngo Weinhold // read the data 86098da112cSIngo Weinhold if (error == B_OK) { 86198da112cSIngo Weinhold bool otherColorSpace = (icon->ColorSpace() != B_CMAP8); 86298da112cSIngo Weinhold char *buffer = NULL; 86398da112cSIngo Weinhold size_t read; 86498da112cSIngo Weinhold if (otherColorSpace) { 86598da112cSIngo Weinhold // other color space than stored in attribute 86698da112cSIngo Weinhold buffer = new(nothrow) char[attrSize]; 86798da112cSIngo Weinhold if (!buffer) 86898da112cSIngo Weinhold error = B_NO_MEMORY; 86998da112cSIngo Weinhold if (error == B_OK) { 87098da112cSIngo Weinhold error = _ReadData(attribute, -1, attrType, buffer, attrSize, 87198da112cSIngo Weinhold read); 87298da112cSIngo Weinhold } 87398da112cSIngo Weinhold } else { 87498da112cSIngo Weinhold error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize, 87598da112cSIngo Weinhold read); 87698da112cSIngo Weinhold } 87798da112cSIngo Weinhold if (error == B_OK && read != attrSize) 87898da112cSIngo Weinhold error = B_ERROR; 87998da112cSIngo Weinhold if (otherColorSpace) { 88098da112cSIngo Weinhold // other color space than stored in attribute 88176ba3434SIngo Weinhold if (error == B_OK) { 88276ba3434SIngo Weinhold error = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW, 88376ba3434SIngo Weinhold 0, B_CMAP8); 88476ba3434SIngo Weinhold } 88598da112cSIngo Weinhold delete[] buffer; 88698da112cSIngo Weinhold } 88798da112cSIngo Weinhold } 88898da112cSIngo Weinhold return error; 889d6b205f3SIngo Weinhold } 890d6b205f3SIngo Weinhold 891d6b205f3SIngo Weinhold // SetIconForType 892d6b205f3SIngo Weinhold /*! \brief Sets the icon the application provides for a given MIME type. 893d6b205f3SIngo Weinhold 89498da112cSIngo Weinhold If \a type is \c NULL, the application's icon is set. 895d6b205f3SIngo Weinhold If \a icon is \c NULL the icon is unset. 896d6b205f3SIngo Weinhold 89798da112cSIngo Weinhold If the file has a signature, then the icon is also set on the MIME type. 89898da112cSIngo Weinhold If the type for the signature has not been installed yet, it is installed 89998da112cSIngo Weinhold before. 90098da112cSIngo Weinhold 90198da112cSIngo Weinhold \param type The MIME type in question. May be \c NULL. 902d6b205f3SIngo Weinhold \param icon A pointer to the BBitmap containing the icon to be set. 903d6b205f3SIngo Weinhold May be \c NULL. 904d6b205f3SIngo Weinhold \param which Specifies the size of the icon to be set: \c B_MINI_ICON 905d6b205f3SIngo Weinhold for the mini and \c B_LARGE_ICON for the large icon. 906d6b205f3SIngo Weinhold \return 907d6b205f3SIngo Weinhold - \c B_OK: Everything went fine. 908d6b205f3SIngo Weinhold - \c B_NO_INIT: The object is not properly initialized. 909d6b205f3SIngo Weinhold - \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon) 910d6b205f3SIngo Weinhold and icon size (\a which) do not match. 911d6b205f3SIngo Weinhold - other error codes 912d6b205f3SIngo Weinhold */ 913d6b205f3SIngo Weinhold status_t 914d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon, 915d6b205f3SIngo Weinhold icon_size which) 916d6b205f3SIngo Weinhold { 91798da112cSIngo Weinhold status_t error = B_OK; 91898da112cSIngo Weinhold // set some icon size related variables 91998da112cSIngo Weinhold BString attributeString; 92098da112cSIngo Weinhold BRect bounds; 921a04efc92SIngo Weinhold uint32 attrType = 0; 922a04efc92SIngo Weinhold size_t attrSize = 0; 923a04efc92SIngo Weinhold int32 resourceID = 0; 92498da112cSIngo Weinhold switch (which) { 92598da112cSIngo Weinhold case B_MINI_ICON: 92698da112cSIngo Weinhold attributeString = kMiniIconAttribute; 92798da112cSIngo Weinhold bounds.Set(0, 0, 15, 15); 92898da112cSIngo Weinhold attrType = B_MINI_ICON_TYPE; 92998da112cSIngo Weinhold attrSize = 16 * 16; 93098da112cSIngo Weinhold resourceID = (type ? kMiniIconForTypeResourceID 93198da112cSIngo Weinhold : kMiniIconResourceID); 93298da112cSIngo Weinhold break; 93398da112cSIngo Weinhold case B_LARGE_ICON: 93498da112cSIngo Weinhold attributeString = kLargeIconAttribute; 93598da112cSIngo Weinhold bounds.Set(0, 0, 31, 31); 93698da112cSIngo Weinhold attrType = B_LARGE_ICON_TYPE; 93798da112cSIngo Weinhold attrSize = 32 * 32; 93898da112cSIngo Weinhold resourceID = (type ? kLargeIconForTypeResourceID 93998da112cSIngo Weinhold : kLargeIconResourceID); 94098da112cSIngo Weinhold break; 94198da112cSIngo Weinhold default: 94298da112cSIngo Weinhold error = B_BAD_VALUE; 94398da112cSIngo Weinhold break; 94498da112cSIngo Weinhold } 94598da112cSIngo Weinhold // check type param 94698da112cSIngo Weinhold if (error == B_OK) { 94798da112cSIngo Weinhold if (type) { 94817819be3SIngo Weinhold if (BMimeType::IsValid(type)) 94998da112cSIngo Weinhold attributeString += type; 95017819be3SIngo Weinhold else 95117819be3SIngo Weinhold error = B_BAD_VALUE; 95298da112cSIngo Weinhold } else 95398da112cSIngo Weinhold attributeString += kStandardIconType; 95498da112cSIngo Weinhold } 95598da112cSIngo Weinhold const char *attribute = attributeString.String(); 95698da112cSIngo Weinhold // check parameter and initialization 95798da112cSIngo Weinhold if (error == B_OK && icon 95898da112cSIngo Weinhold && (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) { 95998da112cSIngo Weinhold error = B_BAD_VALUE; 96098da112cSIngo Weinhold } 96198da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 96298da112cSIngo Weinhold error = B_NO_INIT; 96398da112cSIngo Weinhold // write/remove the attribute 96498da112cSIngo Weinhold if (error == B_OK) { 96598da112cSIngo Weinhold if (icon) { 96698da112cSIngo Weinhold bool otherColorSpace = (icon->ColorSpace() != B_CMAP8); 96798da112cSIngo Weinhold if (otherColorSpace) { 968290bc091SIngo Weinhold BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8); 96998da112cSIngo Weinhold error = bitmap.InitCheck(); 97076ba3434SIngo Weinhold if (error == B_OK) 97176ba3434SIngo Weinhold error = bitmap.ImportBits(icon); 97298da112cSIngo Weinhold if (error == B_OK) { 97398da112cSIngo Weinhold error = _WriteData(attribute, resourceID, attrType, 97498da112cSIngo Weinhold bitmap.Bits(), attrSize, true); 97598da112cSIngo Weinhold } 97698da112cSIngo Weinhold } else { 97798da112cSIngo Weinhold error = _WriteData(attribute, resourceID, attrType, 97898da112cSIngo Weinhold icon->Bits(), attrSize, true); 97998da112cSIngo Weinhold } 98098da112cSIngo Weinhold } else // no icon given => remove 98198da112cSIngo Weinhold error = _RemoveData(attribute, attrType); 98298da112cSIngo Weinhold } 98398da112cSIngo Weinhold // set the attribute on the MIME type, if the file has a signature 98498da112cSIngo Weinhold BMimeType mimeType; 98598da112cSIngo Weinhold if (error == B_OK && GetMetaMime(&mimeType) == B_OK) { 98698da112cSIngo Weinhold if (!mimeType.IsInstalled()) 98798da112cSIngo Weinhold error = mimeType.Install(); 98898da112cSIngo Weinhold if (error == B_OK) 98998da112cSIngo Weinhold error = mimeType.SetIconForType(type, icon, which); 99098da112cSIngo Weinhold } 99198da112cSIngo Weinhold return error; 992d6b205f3SIngo Weinhold } 993d6b205f3SIngo Weinhold 994d6b205f3SIngo Weinhold // SetInfoLocation 995d6b205f3SIngo Weinhold /*! \brief Specifies the location where the meta data shall be stored. 996d6b205f3SIngo Weinhold 997d6b205f3SIngo Weinhold The options for \a location are: 998d6b205f3SIngo Weinhold - \c B_USE_ATTRIBUTES: Store the data in the attributes. 999d6b205f3SIngo Weinhold - \c B_USE_RESOURCES: Store the data in the resources. 1000d6b205f3SIngo Weinhold - \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources. 1001d6b205f3SIngo Weinhold 1002d6b205f3SIngo Weinhold \param location The location where the meta data shall be stored. 1003d6b205f3SIngo Weinhold */ 1004d6b205f3SIngo Weinhold void 1005d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location) 1006d6b205f3SIngo Weinhold { 100798da112cSIngo Weinhold fWhere = location; 1008d6b205f3SIngo Weinhold } 1009d6b205f3SIngo Weinhold 1010d6b205f3SIngo Weinhold // IsUsingAttributes 1011d6b205f3SIngo Weinhold /*! \brief Returns whether the object stores the meta data (also) in the 1012d6b205f3SIngo Weinhold file's attributes. 1013d6b205f3SIngo Weinhold \return \c true, if the meta data are (also) stored in the file's 1014d6b205f3SIngo Weinhold attributes, \c false otherwise. 1015d6b205f3SIngo Weinhold */ 1016d6b205f3SIngo Weinhold bool 1017d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const 1018d6b205f3SIngo Weinhold { 101998da112cSIngo Weinhold return (fWhere & B_USE_ATTRIBUTES); 1020d6b205f3SIngo Weinhold } 1021d6b205f3SIngo Weinhold 1022d6b205f3SIngo Weinhold // IsUsingResources 1023d6b205f3SIngo Weinhold /*! \brief Returns whether the object stores the meta data (also) in the 1024d6b205f3SIngo Weinhold file's resources. 1025d6b205f3SIngo Weinhold \return \c true, if the meta data are (also) stored in the file's 1026d6b205f3SIngo Weinhold resources, \c false otherwise. 1027d6b205f3SIngo Weinhold */ 1028d6b205f3SIngo Weinhold bool 1029d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const 1030d6b205f3SIngo Weinhold { 103198da112cSIngo Weinhold return (fWhere & B_USE_RESOURCES); 1032d6b205f3SIngo Weinhold } 1033d6b205f3SIngo Weinhold 1034d6b205f3SIngo Weinhold // FBC 1035d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {} 1036d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {} 1037d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {} 1038d6b205f3SIngo Weinhold 1039d6b205f3SIngo Weinhold // = 1040d6b205f3SIngo Weinhold /*! \brief Privatized assignment operator to prevent usage. 1041d6b205f3SIngo Weinhold */ 1042d6b205f3SIngo Weinhold BAppFileInfo & 1043d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &) 1044d6b205f3SIngo Weinhold { 1045d6b205f3SIngo Weinhold return *this; 1046d6b205f3SIngo Weinhold } 1047d6b205f3SIngo Weinhold 1048d6b205f3SIngo Weinhold // copy constructor 1049d6b205f3SIngo Weinhold /*! \brief Privatized copy constructor to prevent usage. 1050d6b205f3SIngo Weinhold */ 1051d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &) 1052d6b205f3SIngo Weinhold { 1053d6b205f3SIngo Weinhold } 1054d6b205f3SIngo Weinhold 105598da112cSIngo Weinhold // GetMetaMime 105698da112cSIngo Weinhold /*! \brief Initializes a BMimeType to the file's signature. 105798da112cSIngo Weinhold 105898da112cSIngo Weinhold The parameter \a meta is not checked. 105998da112cSIngo Weinhold 106098da112cSIngo Weinhold \param meta A pointer to a pre-allocated BMimeType that shall be 106198da112cSIngo Weinhold initialized to the file's signature. 106298da112cSIngo Weinhold \return 106398da112cSIngo Weinhold - \c B_OK: Everything went fine. 106498da112cSIngo Weinhold - \c B_BAD_VALUE: \c NULL \a meta 106598da112cSIngo Weinhold - \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is 106698da112cSIngo Weinhold ( not installed in the MIME database.) 106798da112cSIngo Weinhold no valid MIME string. 106898da112cSIngo Weinhold - other error codes 106998da112cSIngo Weinhold */ 107098da112cSIngo Weinhold status_t 107198da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType *meta) const 107298da112cSIngo Weinhold { 107398da112cSIngo Weinhold char signature[B_MIME_TYPE_LENGTH]; 107498da112cSIngo Weinhold status_t error = GetSignature(signature); 107598da112cSIngo Weinhold if (error == B_OK) 107698da112cSIngo Weinhold error = meta->SetTo(signature); 10777f20062dSJérôme Duval else if (error == B_BAD_VALUE) 10787f20062dSJérôme Duval error = B_ENTRY_NOT_FOUND; 107998da112cSIngo Weinhold if (error == B_OK && !meta->IsValid()) 108098da112cSIngo Weinhold error = B_BAD_VALUE; 108198da112cSIngo Weinhold return error; 108298da112cSIngo Weinhold } 108398da112cSIngo Weinhold 108498da112cSIngo Weinhold // _ReadData 108598da112cSIngo Weinhold /*! \brief Reads data from an attribute or resource. 108698da112cSIngo Weinhold 108798da112cSIngo Weinhold The data are read from the location specified by \a fWhere. 108898da112cSIngo Weinhold 108998da112cSIngo Weinhold The object must be properly initialized. The parameters are NOT checked. 109098da112cSIngo Weinhold 109198da112cSIngo Weinhold \param name The name of the attribute/resource to be read. 109298da112cSIngo Weinhold \param id The resource ID of the resource to be read. Is ignored, when 109398da112cSIngo Weinhold < 0. 109498da112cSIngo Weinhold \param type The type of the attribute/resource to be read. 109598da112cSIngo Weinhold \param buffer A pre-allocated buffer for the data to be read. 109698da112cSIngo Weinhold \param bufferSize The size of the supplied buffer. 109798da112cSIngo Weinhold \param bytesRead A reference parameter, set to the number of bytes 109898da112cSIngo Weinhold actually read. 109998da112cSIngo Weinhold \param allocatedBuffer If not \c NULL, the method allocates a buffer 110098da112cSIngo Weinhold large enough too store the whole data and writes a pointer to it 110198da112cSIngo Weinhold into this variable. If \c NULL, the supplied buffer is used. 110298da112cSIngo Weinhold \return 110398da112cSIngo Weinhold - \c B_OK: Everything went fine. 110498da112cSIngo Weinhold - error code 110598da112cSIngo Weinhold */ 110698da112cSIngo Weinhold status_t 110798da112cSIngo Weinhold BAppFileInfo::_ReadData(const char *name, int32 id, type_code type, 110898da112cSIngo Weinhold void *buffer, size_t bufferSize, 110998da112cSIngo Weinhold size_t &bytesRead, void **allocatedBuffer) const 111098da112cSIngo Weinhold { 111198da112cSIngo Weinhold status_t error = B_OK; 1112338b8dc3SIngo Weinhold 111398da112cSIngo Weinhold if (allocatedBuffer) 111498da112cSIngo Weinhold buffer = NULL; 1115338b8dc3SIngo Weinhold 1116338b8dc3SIngo Weinhold bool foundData = false; 1117338b8dc3SIngo Weinhold 111898da112cSIngo Weinhold if (IsUsingAttributes()) { 111998da112cSIngo Weinhold // get an attribute info 112098da112cSIngo Weinhold attr_info info; 112198da112cSIngo Weinhold if (error == B_OK) 112298da112cSIngo Weinhold error = fNode->GetAttrInfo(name, &info); 1123338b8dc3SIngo Weinhold 112498da112cSIngo Weinhold // check type and size, allocate a buffer, if required 112598da112cSIngo Weinhold if (error == B_OK && info.type != type) 112698da112cSIngo Weinhold error = B_BAD_VALUE; 1127b4598d95SIngo Weinhold if (error == B_OK && allocatedBuffer) { 112898da112cSIngo Weinhold buffer = malloc(info.size); 112998da112cSIngo Weinhold if (!buffer) 113098da112cSIngo Weinhold error = B_NO_MEMORY; 113198da112cSIngo Weinhold bufferSize = info.size; 113298da112cSIngo Weinhold } 113398da112cSIngo Weinhold if (error == B_OK && bufferSize < info.size) 113498da112cSIngo Weinhold error = B_BAD_VALUE; 1135338b8dc3SIngo Weinhold 113698da112cSIngo Weinhold // read the data 113798da112cSIngo Weinhold if (error == B_OK) { 113898da112cSIngo Weinhold ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size); 113998da112cSIngo Weinhold if (read < 0) 114098da112cSIngo Weinhold error = read; 114198da112cSIngo Weinhold else if (read != info.size) 114298da112cSIngo Weinhold error = B_ERROR; 114398da112cSIngo Weinhold else 114498da112cSIngo Weinhold bytesRead = read; 114598da112cSIngo Weinhold } 1146338b8dc3SIngo Weinhold 1147338b8dc3SIngo Weinhold foundData = (error == B_OK); 1148b4598d95SIngo Weinhold 1149b4598d95SIngo Weinhold // free the allocated buffer on error 1150b4598d95SIngo Weinhold if (!foundData && allocatedBuffer && buffer) { 1151b4598d95SIngo Weinhold free(buffer); 1152b4598d95SIngo Weinhold buffer = NULL; 1153b4598d95SIngo Weinhold } 1154338b8dc3SIngo Weinhold } 1155338b8dc3SIngo Weinhold 1156338b8dc3SIngo Weinhold if (!foundData && IsUsingResources()) { 115798da112cSIngo Weinhold // get a resource info 1158338b8dc3SIngo Weinhold error = B_OK; 115998da112cSIngo Weinhold int32 idFound; 116098da112cSIngo Weinhold size_t sizeFound; 116198da112cSIngo Weinhold if (error == B_OK) { 116298da112cSIngo Weinhold if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 116398da112cSIngo Weinhold error = B_ENTRY_NOT_FOUND; 116498da112cSIngo Weinhold } 1165338b8dc3SIngo Weinhold 116698da112cSIngo Weinhold // check id and size, allocate a buffer, if required 116798da112cSIngo Weinhold if (error == B_OK && id >= 0 && idFound != id) 116898da112cSIngo Weinhold error = B_ENTRY_NOT_FOUND; 1169b4598d95SIngo Weinhold if (error == B_OK && allocatedBuffer) { 117098da112cSIngo Weinhold buffer = malloc(sizeFound); 117198da112cSIngo Weinhold if (!buffer) 117298da112cSIngo Weinhold error = B_NO_MEMORY; 117398da112cSIngo Weinhold bufferSize = sizeFound; 117498da112cSIngo Weinhold } 117598da112cSIngo Weinhold if (error == B_OK && bufferSize < sizeFound) 117698da112cSIngo Weinhold error = B_BAD_VALUE; 1177338b8dc3SIngo Weinhold 117898da112cSIngo Weinhold // load resource 117998da112cSIngo Weinhold const void *resourceData = NULL; 118098da112cSIngo Weinhold if (error == B_OK) { 118198da112cSIngo Weinhold resourceData = fResources->LoadResource(type, name, &bytesRead); 118298da112cSIngo Weinhold if (resourceData && sizeFound == bytesRead) 118398da112cSIngo Weinhold memcpy(buffer, resourceData, bytesRead); 118498da112cSIngo Weinhold else 118598da112cSIngo Weinhold error = B_ERROR; 118698da112cSIngo Weinhold } 1187773be699SAxel Dörfler } else if (!foundData) 118898da112cSIngo Weinhold error = B_BAD_VALUE; 1189338b8dc3SIngo Weinhold 119098da112cSIngo Weinhold // return the allocated buffer, or free it on error 119198da112cSIngo Weinhold if (allocatedBuffer) { 119298da112cSIngo Weinhold if (error == B_OK) 119398da112cSIngo Weinhold *allocatedBuffer = buffer; 119498da112cSIngo Weinhold else 119598da112cSIngo Weinhold free(buffer); 119698da112cSIngo Weinhold } 1197338b8dc3SIngo Weinhold 119898da112cSIngo Weinhold return error; 119998da112cSIngo Weinhold } 120098da112cSIngo Weinhold 120198da112cSIngo Weinhold // _WriteData 120298da112cSIngo Weinhold /*! \brief Writes data to an attribute or resource. 120398da112cSIngo Weinhold 120498da112cSIngo Weinhold The data are written to the location(s) specified by \a fWhere. 120598da112cSIngo Weinhold 120698da112cSIngo Weinhold The object must be properly initialized. The parameters are NOT checked. 120798da112cSIngo Weinhold 120898da112cSIngo Weinhold \param name The name of the attribute/resource to be written. 120998da112cSIngo Weinhold \param id The resource ID of the resource to be written. 121098da112cSIngo Weinhold \param type The type of the attribute/resource to be written. 121198da112cSIngo Weinhold \param buffer A buffer containing the data to be written. 121298da112cSIngo Weinhold \param bufferSize The size of the supplied buffer. 121398da112cSIngo Weinhold \param findID If set to \c true use the ID that is already assigned to the 121498da112cSIngo Weinhold \a name / \a type pair or take the first unused ID >= \a id. 121598da112cSIngo Weinhold If \c false, \a id is used. 121698da112cSIngo Weinhold If \a id is already in use and . 121798da112cSIngo Weinhold \return 121898da112cSIngo Weinhold - \c B_OK: Everything went fine. 121998da112cSIngo Weinhold - error code 122098da112cSIngo Weinhold */ 122198da112cSIngo Weinhold status_t 122298da112cSIngo Weinhold BAppFileInfo::_WriteData(const char *name, int32 id, type_code type, 122398da112cSIngo Weinhold const void *buffer, size_t bufferSize, bool findID) 122498da112cSIngo Weinhold { 122598da112cSIngo Weinhold status_t error = B_OK; 122698da112cSIngo Weinhold // write to attribute 122798da112cSIngo Weinhold if (IsUsingAttributes() && error == B_OK) { 122898da112cSIngo Weinhold ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize); 122998da112cSIngo Weinhold if (written < 0) 123098da112cSIngo Weinhold error = written; 123198da112cSIngo Weinhold else if (written != (ssize_t)bufferSize) 123298da112cSIngo Weinhold error = B_ERROR; 123398da112cSIngo Weinhold } 123498da112cSIngo Weinhold // write to resource 123598da112cSIngo Weinhold if (IsUsingResources() && error == B_OK) { 123698da112cSIngo Weinhold if (findID) { 123798da112cSIngo Weinhold // get the resource info 123898da112cSIngo Weinhold int32 idFound; 123998da112cSIngo Weinhold size_t sizeFound; 124098da112cSIngo Weinhold if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 124198da112cSIngo Weinhold id = idFound; 124298da112cSIngo Weinhold else { 124398da112cSIngo Weinhold // type-name pair doesn't exist yet -- find unused ID 124498da112cSIngo Weinhold while (fResources->HasResource(type, id)) 124598da112cSIngo Weinhold id++; 124698da112cSIngo Weinhold } 124798da112cSIngo Weinhold } 124898da112cSIngo Weinhold error = fResources->AddResource(type, id, buffer, bufferSize, name); 124998da112cSIngo Weinhold } 125098da112cSIngo Weinhold return error; 125198da112cSIngo Weinhold } 125298da112cSIngo Weinhold 125398da112cSIngo Weinhold // _RemoveData 125498da112cSIngo Weinhold /*! \brief Removes an attribute or resource. 125598da112cSIngo Weinhold 125698da112cSIngo Weinhold The removal location is specified by \a fWhere. 125798da112cSIngo Weinhold 125898da112cSIngo Weinhold The object must be properly initialized. The parameters are NOT checked. 125998da112cSIngo Weinhold 126098da112cSIngo Weinhold \param name The name of the attribute/resource to be remove. 126198da112cSIngo Weinhold \param type The type of the attribute/resource to be removed. 126298da112cSIngo Weinhold \return 126398da112cSIngo Weinhold - \c B_OK: Everything went fine. 126498da112cSIngo Weinhold - error code 126598da112cSIngo Weinhold */ 126698da112cSIngo Weinhold status_t 126798da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char *name, type_code type) 126898da112cSIngo Weinhold { 126998da112cSIngo Weinhold status_t error = B_OK; 127098da112cSIngo Weinhold // remove the attribute 127198da112cSIngo Weinhold if (IsUsingAttributes() && error == B_OK) { 127298da112cSIngo Weinhold error = fNode->RemoveAttr(name); 127398da112cSIngo Weinhold // It's no error, if there has been no attribute. 127498da112cSIngo Weinhold if (error == B_ENTRY_NOT_FOUND) 127598da112cSIngo Weinhold error = B_OK; 127698da112cSIngo Weinhold } 127798da112cSIngo Weinhold // remove the resource 127898da112cSIngo Weinhold if (IsUsingResources() && error == B_OK) { 127998da112cSIngo Weinhold // get a resource info 128098da112cSIngo Weinhold int32 idFound; 128198da112cSIngo Weinhold size_t sizeFound; 128298da112cSIngo Weinhold if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 128398da112cSIngo Weinhold error = fResources->RemoveResource(type, idFound); 128498da112cSIngo Weinhold } 128598da112cSIngo Weinhold return error; 128698da112cSIngo Weinhold } 128798da112cSIngo Weinhold 1288