1//---------------------------------------------------------------------- 2// This software is part of the Haiku distribution and is covered 3// by the MIT License. 4//--------------------------------------------------------------------- 5/*! 6 \file Supertype.cpp 7 Supertype class implementation 8*/ 9 10#include <mime/Supertype.h> 11 12#include <Message.h> 13#include <mime/database_support.h> 14 15#include <new> 16#include <stdio.h> 17 18#define DBG(x) x 19//#define DBG(x) 20#define OUT printf 21 22namespace BPrivate { 23namespace Storage { 24namespace Mime { 25 26/*! 27 \class Supertype 28 \brief Installed types information for a single supertype 29*/ 30 31// Constructor 32//! Constructs a new Supertype object 33Supertype::Supertype(const char *super) 34 : fCachedMessage(NULL) 35 , fName(super ? super : "") 36{ 37} 38 39// Destructor 40//! Destroys the Supertype object 41Supertype::~Supertype() 42{ 43 delete fCachedMessage; 44} 45 46// GetInstalledSubtypes 47/*! \brief Returns a list of the installeds subtypes for this supertype 48 in the pre-allocated \c BMessage pointed to by \c types. 49*/ 50status_t 51Supertype::GetInstalledSubtypes(BMessage *types) 52{ 53 status_t err = types ? B_OK : B_BAD_VALUE; 54 // See if we need to fill up a new message 55 if (!err && !fCachedMessage) { 56 err = CreateMessageWithTypes(&fCachedMessage); 57 } 58 // If we get this far, there's a cached message waiting 59 if (!err) { 60 *types = *fCachedMessage; 61 } 62 return err; 63} 64 65// AddSubtype 66/*! \brief Adds the given subtype to the subtype list and the cached message, 67 if one exists. 68 \param sub The subtype to add (do not include the supertype) 69 \return 70 - B_OK: success 71 - B_NAME_IN_USE: The subtype already exists in the subtype list 72 - "error code": failure 73*/ 74status_t 75Supertype::AddSubtype(const char *sub) 76{ 77 status_t err = sub ? B_OK : B_BAD_VALUE; 78 if (!err) 79 err = fSubtypes.insert(sub).second ? B_OK : B_NAME_IN_USE; 80 if (!err && fCachedMessage) { 81 char type[B_PATH_NAME_LENGTH]; 82 sprintf(type, "%s/%s", fName.c_str(), sub); 83 err = fCachedMessage->AddString("types", type); 84 } 85 return err; 86} 87 88// RemoveSubtype 89/*! \brief Removes the given subtype from the subtype list and invalidates the 90 cached message, if one exists. 91 \param sub The subtype to remove (do not include the supertype) 92*/ 93status_t 94Supertype::RemoveSubtype(const char *sub) 95{ 96 status_t err = sub ? B_OK : B_BAD_VALUE; 97 if (!err) 98 err = fSubtypes.erase(sub) == 1 ? B_OK : B_NAME_NOT_FOUND; 99 if (!err && fCachedMessage) { 100 delete fCachedMessage; 101 fCachedMessage = NULL; 102 } 103 return err; 104} 105 106// SetName 107//! Sets the supertype's name 108void 109Supertype::SetName(const char *super) 110{ 111 if (super) 112 fName = super; 113} 114 115// GetName 116//! Returns the supertype's name 117const char* 118Supertype::GetName() 119{ 120 return fName.c_str(); 121} 122 123// FillMessageWithTypes 124//! Adds the supertype's subtypes to the given message 125/*! Each subtype is added as another item in the message's \c Mime::kTypesField 126 field. The complete type ("supertype/subtype") is added. The supertype itself 127 is not added to the message. 128*/ 129status_t 130Supertype::FillMessageWithTypes(BMessage &msg) const 131{ 132 status_t err = B_OK; 133 std::set<std::string>::const_iterator i; 134 for (i = fSubtypes.begin(); i != fSubtypes.end() && !err; i++) { 135 char type[B_PATH_NAME_LENGTH]; 136 sprintf(type, "%s/%s", fName.c_str(), (*i).c_str()); 137 err = msg.AddString(kTypesField, type); 138 } 139 return err; 140} 141 142// CreateMessageWithTypes 143/*! \brief Allocates a new BMessage into the BMessage pointer pointed to by \c result 144 and fills it with the supertype's subtypes. 145 146 See \c Supertype::FillMessageWithTypes() for more information. 147*/ 148status_t 149Supertype::CreateMessageWithTypes(BMessage **result) const 150{ 151 status_t err = result ? B_OK : B_BAD_VALUE; 152 // Alloc the message 153 if (!err) { 154 try { 155 *result = new BMessage(); 156 } catch (std::bad_alloc&) { 157 err = B_NO_MEMORY; 158 } 159 } 160 // Fill with types 161 if (!err) 162 err = FillMessageWithTypes(**result); 163 return err; 164} 165 166} // namespace Mime 167} // namespace Storage 168} // namespace BPrivate 169 170