repository_infos: Enable automatic updates on the main Haiku repostiory.
[haiku.git] / src / kits / storage / MimeType.cpp
blobd03b4d06b2add6de5d82584e5db60418e5a7ad55
1 /*
2 * Copyright 2002-2006 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 * Tyler Dauwalder
8 * Ingo Weinhold, bonefish@users.sf.net
9 */
12 #include "MimeType.h"
14 #include <Bitmap.h>
15 #include <mime/database_support.h>
16 #include <mime/DatabaseLocation.h>
17 #include <sniffer/Rule.h>
18 #include <sniffer/Parser.h>
20 #include <RegistrarDefs.h>
21 #include <RosterPrivate.h>
23 #include <ctype.h>
24 #include <new>
25 #include <stdio.h>
26 #include <strings.h>
29 using namespace BPrivate;
31 // Private helper functions
32 static bool isValidMimeChar(const char ch);
34 using namespace BPrivate::Storage::Mime;
35 using namespace std;
37 const char* B_PEF_APP_MIME_TYPE = "application/x-be-executable";
38 const char* B_PE_APP_MIME_TYPE = "application/x-vnd.Be-peexecutable";
39 const char* B_ELF_APP_MIME_TYPE = "application/x-vnd.Be-elfexecutable";
40 const char* B_RESOURCE_MIME_TYPE = "application/x-be-resource";
41 const char* B_FILE_MIME_TYPE = "application/octet-stream";
42 // Might be defined platform depended, but ELF will certainly be the common
43 // format for all platforms anyway.
44 const char* B_APP_MIME_TYPE = B_ELF_APP_MIME_TYPE;
47 static bool
48 isValidMimeChar(const char ch)
50 // Handles white space and most CTLs
51 return ch > 32
52 && ch != '/'
53 && ch != '<'
54 && ch != '>'
55 && ch != '@'
56 && ch != ','
57 && ch != ';'
58 && ch != ':'
59 && ch != '"'
60 && ch != '('
61 && ch != ')'
62 && ch != '['
63 && ch != ']'
64 && ch != '?'
65 && ch != '='
66 && ch != '\\'
67 && ch != 127; // DEL
71 // #pragma mark -
74 // Creates an uninitialized BMimeType object.
75 BMimeType::BMimeType()
77 fType(NULL),
78 fCStatus(B_NO_INIT)
83 // Creates a BMimeType object and initializes it to the supplied
84 // MIME type.
85 BMimeType::BMimeType(const char* mimeType)
87 fType(NULL),
88 fCStatus(B_NO_INIT)
90 SetTo(mimeType);
94 // Frees all resources associated with this object.
95 BMimeType::~BMimeType()
97 Unset();
101 // Initializes this object to the supplied MIME type.
102 status_t
103 BMimeType::SetTo(const char* mimeType)
105 if (mimeType == NULL) {
106 Unset();
107 } else if (!BMimeType::IsValid(mimeType)) {
108 fCStatus = B_BAD_VALUE;
109 } else {
110 Unset();
111 fType = new(std::nothrow) char[strlen(mimeType) + 1];
112 if (fType) {
113 strlcpy(fType, mimeType, B_MIME_TYPE_LENGTH);
114 fCStatus = B_OK;
115 } else {
116 fCStatus = B_NO_MEMORY;
119 return fCStatus;
123 // Returns the object to an uninitialized state
124 void
125 BMimeType::Unset()
127 delete [] fType;
128 fType = NULL;
129 fCStatus = B_NO_INIT;
133 // Returns the result of the most recent constructor or SetTo() call
134 status_t
135 BMimeType::InitCheck() const
137 return fCStatus;
141 // Returns the MIME string represented by this object
142 const char*
143 BMimeType::Type() const
145 return fType;
149 // Returns whether the object represents a valid MIME type
150 bool
151 BMimeType::IsValid() const
153 return InitCheck() == B_OK && BMimeType::IsValid(Type());
157 // Returns whether this objects represents a supertype
158 bool
159 BMimeType::IsSupertypeOnly() const
161 if (fCStatus == B_OK) {
162 // We assume here fCStatus will be B_OK *only* if
163 // the MIME string is valid
164 size_t len = strlen(fType);
165 for (size_t i = 0; i < len; i++) {
166 if (fType[i] == '/')
167 return false;
169 return true;
170 } else
171 return false;
175 // Returns whether or not this type is currently installed in the
176 // MIME database
177 bool
178 BMimeType::IsInstalled() const
180 return InitCheck() == B_OK
181 && default_database_location()->IsInstalled(Type());
185 // Gets the supertype of the MIME type represented by this object
186 status_t
187 BMimeType::GetSupertype(BMimeType* supertype) const
189 if (supertype == NULL)
190 return B_BAD_VALUE;
192 supertype->Unset();
193 status_t status = fCStatus == B_OK ? B_OK : B_BAD_VALUE;
194 if (status == B_OK) {
195 size_t len = strlen(fType);
196 size_t i = 0;
197 for (; i < len; i++) {
198 if (fType[i] == '/')
199 break;
201 if (i == len) {
202 // object is a supertype only
203 status = B_BAD_VALUE;
204 } else {
205 char superMime[B_MIME_TYPE_LENGTH];
206 strncpy(superMime, fType, i);
207 superMime[i] = 0;
208 status = supertype->SetTo(superMime) == B_OK ? B_OK : B_BAD_VALUE;
212 return status;
216 // Returns whether this and the supplied MIME type are equal
217 bool
218 BMimeType::operator==(const BMimeType &type) const
220 if (InitCheck() == B_NO_INIT && type.InitCheck() == B_NO_INIT)
221 return true;
222 else if (InitCheck() == B_OK && type.InitCheck() == B_OK)
223 return strcasecmp(Type(), type.Type()) == 0;
225 return false;
229 // Returns whether this and the supplied MIME type are equal
230 bool
231 BMimeType::operator==(const char* type) const
233 BMimeType mime;
234 if (type)
235 mime.SetTo(type);
237 return (*this) == mime;
241 // Returns whether this MIME type is a supertype of or equals the
242 // supplied one
243 bool
244 BMimeType::Contains(const BMimeType* type) const
246 if (type == NULL)
247 return false;
249 if (*this == *type)
250 return true;
252 BMimeType super;
253 if (type->GetSupertype(&super) == B_OK && *this == super)
254 return true;
255 return false;
259 // Adds the MIME type to the MIME database
260 status_t
261 BMimeType::Install()
263 status_t err = InitCheck();
265 BMessage message(B_REG_MIME_INSTALL);
266 BMessage reply;
267 status_t result;
269 // Build and send the message, read the reply
270 if (err == B_OK)
271 err = message.AddString("type", Type());
273 if (err == B_OK)
274 err = BRoster::Private().SendTo(&message, &reply, true);
276 if (err == B_OK)
277 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
279 if (err == B_OK)
280 err = reply.FindInt32("result", &result);
282 if (err == B_OK)
283 err = result;
285 return err;
289 // Removes the MIME type from the MIME database
290 status_t
291 BMimeType::Delete()
293 status_t err = InitCheck();
295 BMessage message(B_REG_MIME_DELETE);
296 BMessage reply;
297 status_t result;
299 // Build and send the message, read the reply
300 if (err == B_OK)
301 err = message.AddString("type", Type());
303 if (err == B_OK)
304 err = BRoster::Private().SendTo(&message, &reply, true);
306 if (err == B_OK)
307 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
309 if (err == B_OK)
310 err = reply.FindInt32("result", &result);
312 if (err == B_OK)
313 err = result;
315 return err;
319 // Fetches the large or mini icon associated with the MIME type
320 status_t
321 BMimeType::GetIcon(BBitmap* icon, icon_size size) const
323 if (icon == NULL)
324 return B_BAD_VALUE;
326 status_t err = InitCheck();
327 if (err == B_OK)
328 err = default_database_location()->GetIcon(Type(), *icon, size);
330 return err;
334 // Fetches the vector icon associated with the MIME type
335 status_t
336 BMimeType::GetIcon(uint8** data, size_t* size) const
338 if (data == NULL || size == NULL)
339 return B_BAD_VALUE;
341 status_t err = InitCheck();
342 if (err == B_OK)
343 err = default_database_location()->GetIcon(Type(), *data, *size);
345 return err;
349 // Fetches the signature of the MIME type's preferred application from the
350 // MIME database
351 status_t
352 BMimeType::GetPreferredApp(char* signature, app_verb verb) const
354 status_t err = InitCheck();
355 if (err == B_OK) {
356 err = default_database_location()->GetPreferredApp(Type(), signature,
357 verb);
360 return err;
364 // Fetches from the MIME database a BMessage describing the attributes
365 // typically associated with files of the given MIME type
366 status_t
367 BMimeType::GetAttrInfo(BMessage* info) const
369 if (info == NULL)
370 return B_BAD_VALUE;
372 status_t err = InitCheck();
373 if (err == B_OK)
374 err = default_database_location()->GetAttributesInfo(Type(), *info);
376 return err;
380 // Fetches the MIME type's associated filename extensions from the MIME
381 // database
382 status_t
383 BMimeType::GetFileExtensions(BMessage* extensions) const
385 if (extensions == NULL)
386 return B_BAD_VALUE;
388 status_t err = InitCheck();
389 if (err == B_OK) {
390 err = default_database_location()->GetFileExtensions(Type(),
391 *extensions);
394 return err;
398 // Fetches the MIME type's short description from the MIME database
399 status_t
400 BMimeType::GetShortDescription(char* description) const
402 status_t err = InitCheck();
403 if (err == B_OK) {
404 err = default_database_location()->GetShortDescription(Type(),
405 description);
408 return err;
412 // Fetches the MIME type's long description from the MIME database
413 status_t
414 BMimeType::GetLongDescription(char* description) const
416 status_t err = InitCheck();
417 if (err == B_OK) {
418 err = default_database_location()->GetLongDescription(Type(),
419 description);
422 return err;
426 // Fetches a \c BMessage containing a list of MIME signatures of
427 // applications that are able to handle files of this MIME type.
428 status_t
429 BMimeType::GetSupportingApps(BMessage* signatures) const
431 if (signatures == NULL)
432 return B_BAD_VALUE;
434 BMessage message(B_REG_MIME_GET_SUPPORTING_APPS);
435 status_t result;
437 status_t err = InitCheck();
438 if (err == B_OK)
439 err = message.AddString("type", Type());
440 if (err == B_OK)
441 err = BRoster::Private().SendTo(&message, signatures, true);
442 if (err == B_OK) {
443 err = (status_t)(signatures->what == B_REG_RESULT ? B_OK
444 : B_BAD_REPLY);
446 if (err == B_OK)
447 err = signatures->FindInt32("result", &result);
448 if (err == B_OK)
449 err = result;
451 return err;
455 // Sets the large or mini icon for the MIME type
456 status_t
457 BMimeType::SetIcon(const BBitmap* icon, icon_size which)
459 return SetIconForType(NULL, icon, which);
463 // Sets the vector icon for the MIME type
464 status_t
465 BMimeType::SetIcon(const uint8* data, size_t size)
467 return SetIconForType(NULL, data, size);
471 // Sets the preferred application for the MIME type
472 status_t
473 BMimeType::SetPreferredApp(const char* signature, app_verb verb)
475 status_t err = InitCheck();
477 BMessage message(signature && signature[0]
478 ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
479 BMessage reply;
480 status_t result;
482 // Build and send the message, read the reply
483 if (err == B_OK)
484 err = message.AddString("type", Type());
486 if (err == B_OK)
487 err = message.AddInt32("which", B_REG_MIME_PREFERRED_APP);
489 if (err == B_OK && signature != NULL)
490 err = message.AddString("signature", signature);
492 if (err == B_OK)
493 err = message.AddInt32("app verb", verb);
495 if (err == B_OK)
496 err = BRoster::Private().SendTo(&message, &reply, true);
498 if (err == B_OK)
499 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
501 if (err == B_OK)
502 err = reply.FindInt32("result", &result);
504 if (err == B_OK)
505 err = result;
507 return err;
511 // Sets the description of the attributes typically associated with files
512 // of the given MIME type
513 status_t
514 BMimeType::SetAttrInfo(const BMessage* info)
516 status_t err = InitCheck();
518 BMessage message(info ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
519 BMessage reply;
520 status_t result;
522 // Build and send the message, read the reply
523 if (err == B_OK)
524 err = message.AddString("type", Type());
525 if (err == B_OK)
526 err = message.AddInt32("which", B_REG_MIME_ATTR_INFO);
527 if (err == B_OK && info != NULL)
528 err = message.AddMessage("attr info", info);
529 if (err == B_OK)
530 err = BRoster::Private().SendTo(&message, &reply, true);
531 if (err == B_OK)
532 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
533 if (err == B_OK)
534 err = reply.FindInt32("result", &result);
535 if (err == B_OK)
536 err = result;
538 return err;
542 // Sets the list of filename extensions associated with the MIME type
543 status_t
544 BMimeType::SetFileExtensions(const BMessage* extensions)
546 status_t err = InitCheck();
548 BMessage message(extensions ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
549 BMessage reply;
550 status_t result;
552 // Build and send the message, read the reply
553 if (err == B_OK)
554 err = message.AddString("type", Type());
556 if (err == B_OK)
557 err = message.AddInt32("which", B_REG_MIME_FILE_EXTENSIONS);
559 if (err == B_OK && extensions != NULL)
560 err = message.AddMessage("extensions", extensions);
562 if (err == B_OK)
563 err = BRoster::Private().SendTo(&message, &reply, true);
565 if (err == B_OK)
566 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
568 if (err == B_OK)
569 err = reply.FindInt32("result", &result);
571 if (err == B_OK)
572 err = result;
574 return err;
578 // Sets the short description field for the MIME type
579 status_t
580 BMimeType::SetShortDescription(const char* description)
582 status_t err = InitCheck();
584 BMessage message(description && description [0]
585 ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
586 BMessage reply;
587 status_t result;
589 // Build and send the message, read the reply
590 if (err == B_OK)
591 err = message.AddString("type", Type());
593 if (err == B_OK)
594 err = message.AddInt32("which", B_REG_MIME_DESCRIPTION);
596 if (err == B_OK && description)
597 err = message.AddString("description", description);
599 if (err == B_OK)
600 err = message.AddBool("long", false);
602 if (err == B_OK)
603 err = BRoster::Private().SendTo(&message, &reply, true);
605 if (err == B_OK)
606 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
608 if (err == B_OK)
609 err = reply.FindInt32("result", &result);
611 if (err == B_OK)
612 err = result;
614 return err;
618 // Sets the long description field for the MIME type
619 status_t
620 BMimeType::SetLongDescription(const char* description)
622 status_t err = InitCheck();
624 BMessage message(description && description[0]
625 ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
626 BMessage reply;
627 status_t result;
629 // Build and send the message, read the reply
630 if (err == B_OK)
631 err = message.AddString("type", Type());
633 if (err == B_OK)
634 err = message.AddInt32("which", B_REG_MIME_DESCRIPTION);
636 if (err == B_OK && description)
637 err = message.AddString("description", description);
639 if (err == B_OK)
640 err = message.AddBool("long", true);
642 if (err == B_OK)
643 err = BRoster::Private().SendTo(&message, &reply, true);
645 if (err == B_OK)
646 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
648 if (err == B_OK)
649 err = reply.FindInt32("result", &result);
651 if (err == B_OK)
652 err = result;
654 return err;
658 // Fetches a BMessage listing all the MIME supertypes currently
659 // installed in the MIME database.
660 /*static*/ status_t
661 BMimeType::GetInstalledSupertypes(BMessage* supertypes)
663 if (supertypes == NULL)
664 return B_BAD_VALUE;
666 BMessage message(B_REG_MIME_GET_INSTALLED_SUPERTYPES);
667 status_t result;
669 status_t err = BRoster::Private().SendTo(&message, supertypes, true);
670 if (err == B_OK) {
671 err = (status_t)(supertypes->what == B_REG_RESULT ? B_OK
672 : B_BAD_REPLY);
674 if (err == B_OK)
675 err = supertypes->FindInt32("result", &result);
676 if (err == B_OK)
677 err = result;
679 return err;
683 // Fetches a BMessage listing all the MIME types currently installed
684 // in the MIME database.
685 status_t
686 BMimeType::GetInstalledTypes(BMessage* types)
688 return GetInstalledTypes(NULL, types);
692 // Fetches a BMessage listing all the MIME subtypes of the given
693 // supertype currently installed in the MIME database.
694 /*static*/ status_t
695 BMimeType::GetInstalledTypes(const char* supertype, BMessage* types)
697 if (types == NULL)
698 return B_BAD_VALUE;
700 status_t result;
702 // Build and send the message, read the reply
703 BMessage message(B_REG_MIME_GET_INSTALLED_TYPES);
704 status_t err = B_OK;
706 if (supertype != NULL)
707 err = message.AddString("supertype", supertype);
708 if (err == B_OK)
709 err = BRoster::Private().SendTo(&message, types, true);
710 if (err == B_OK)
711 err = (status_t)(types->what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
712 if (err == B_OK)
713 err = types->FindInt32("result", &result);
714 if (err == B_OK)
715 err = result;
717 return err;
721 // Fetches a \c BMessage containing a list of MIME signatures of
722 // applications that are able to handle files of any type.
723 status_t
724 BMimeType::GetWildcardApps(BMessage* wild_ones)
726 BMimeType mime;
727 status_t err = mime.SetTo("application/octet-stream");
728 if (err == B_OK)
729 err = mime.GetSupportingApps(wild_ones);
730 return err;
734 // Returns whether the given string represents a valid MIME type.
735 bool
736 BMimeType::IsValid(const char* string)
738 if (string == NULL)
739 return false;
741 bool foundSlash = false;
742 size_t len = strlen(string);
743 if (len >= B_MIME_TYPE_LENGTH || len == 0)
744 return false;
746 for (size_t i = 0; i < len; i++) {
747 char ch = string[i];
748 if (ch == '/') {
749 if (foundSlash || i == 0 || i == len - 1)
750 return false;
751 else
752 foundSlash = true;
753 } else if (!isValidMimeChar(ch)) {
754 return false;
757 return true;
761 // Fetches an \c entry_ref that serves as a hint as to where the MIME type's
762 // preferred application might live
763 status_t
764 BMimeType::GetAppHint(entry_ref* ref) const
766 if (ref == NULL)
767 return B_BAD_VALUE;
769 status_t err = InitCheck();
770 if (err == B_OK)
771 err = default_database_location()->GetAppHint(Type(), *ref);
772 return err;
776 // Sets the app hint field for the MIME type
777 status_t
778 BMimeType::SetAppHint(const entry_ref* ref)
780 status_t err = InitCheck();
782 BMessage message(ref ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
783 BMessage reply;
784 status_t result;
786 // Build and send the message, read the reply
787 if (err == B_OK)
788 err = message.AddString("type", Type());
790 if (err == B_OK)
791 err = message.AddInt32("which", B_REG_MIME_APP_HINT);
793 if (err == B_OK && ref != NULL)
794 err = message.AddRef("app hint", ref);
796 if (err == B_OK)
797 err = BRoster::Private().SendTo(&message, &reply, true);
799 if (err == B_OK)
800 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
802 if (err == B_OK)
803 err = reply.FindInt32("result", &result);
805 if (err == B_OK)
806 err = result;
808 return err;
812 // Fetches the large or mini icon used by an application of this type for
813 // files of the given type.
814 status_t
815 BMimeType::GetIconForType(const char* type, BBitmap* icon, icon_size which) const
817 if (icon == NULL)
818 return B_BAD_VALUE;
820 // If type is NULL, this function works just like GetIcon(), othewise,
821 // we need to make sure the give type is valid.
822 status_t err;
823 if (type) {
824 err = BMimeType::IsValid(type) ? B_OK : B_BAD_VALUE;
825 if (err == B_OK) {
826 err = default_database_location()->GetIconForType(Type(), type,
827 *icon, which);
829 } else
830 err = GetIcon(icon, which);
832 return err;
836 // Fetches the vector icon used by an application of this type for files of
837 // the given type.
838 status_t
839 BMimeType::GetIconForType(const char* type, uint8** _data, size_t* _size) const
841 if (_data == NULL || _size == NULL)
842 return B_BAD_VALUE;
844 // If type is NULL, this function works just like GetIcon(), otherwise,
845 // we need to make sure the give type is valid.
846 if (type == NULL)
847 return GetIcon(_data, _size);
849 if (!BMimeType::IsValid(type))
850 return B_BAD_VALUE;
852 return default_database_location()->GetIconForType(Type(), type, *_data,
853 *_size);
857 // Sets the large or mini icon used by an application of this type for
858 // files of the given type.
859 status_t
860 BMimeType::SetIconForType(const char* type, const BBitmap* icon, icon_size which)
862 status_t err = InitCheck();
864 BMessage message(icon ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
865 BMessage reply;
866 status_t result;
868 void* data = NULL;
869 int32 dataSize;
871 // Build and send the message, read the reply
872 if (err == B_OK)
873 err = message.AddString("type", Type());
875 if (err == B_OK) {
876 err = message.AddInt32("which",
877 type ? B_REG_MIME_ICON_FOR_TYPE : B_REG_MIME_ICON);
880 if (icon != NULL) {
881 if (err == B_OK)
882 err = get_icon_data(icon, which, &data, &dataSize);
884 if (err == B_OK)
885 err = message.AddData("icon data", B_RAW_TYPE, data, dataSize);
888 if (err == B_OK)
889 err = message.AddInt32("icon size", which);
891 if (type != NULL) {
892 if (err == B_OK)
893 err = BMimeType::IsValid(type) ? B_OK : B_BAD_VALUE;
895 if (err == B_OK)
896 err = message.AddString("file type", type);
899 if (err == B_OK)
900 err = BRoster::Private().SendTo(&message, &reply, true);
902 if (err == B_OK)
903 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
905 if (err == B_OK)
906 err = reply.FindInt32("result", &result);
908 if (err == B_OK)
909 err = result;
911 delete[] (int8*)data;
913 return err;
917 // Sets the large or mini icon used by an application of this type for
918 // files of the given type.
919 status_t
920 BMimeType::SetIconForType(const char* type, const uint8* data, size_t dataSize)
922 status_t err = InitCheck();
924 BMessage message(data ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
925 BMessage reply;
926 status_t result;
928 // Build and send the message, read the reply
929 if (err == B_OK)
930 err = message.AddString("type", Type());
931 if (err == B_OK)
932 err = message.AddInt32("which", (type ? B_REG_MIME_ICON_FOR_TYPE : B_REG_MIME_ICON));
933 if (data) {
934 if (err == B_OK)
935 err = message.AddData("icon data", B_RAW_TYPE, data, dataSize);
937 if (err == B_OK)
938 err = message.AddInt32("icon size", -1);
939 // -1 indicates size should be ignored (vector icon data)
940 if (type) {
941 if (err == B_OK)
942 err = BMimeType::IsValid(type) ? B_OK : B_BAD_VALUE;
943 if (err == B_OK)
944 err = message.AddString("file type", type);
946 if (err == B_OK)
947 err = BRoster::Private().SendTo(&message, &reply, true);
948 if (err == B_OK)
949 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
950 if (err == B_OK)
951 err = reply.FindInt32("result", &result);
952 if (err == B_OK)
953 err = result;
955 return err;
959 // Retrieves the MIME type's sniffer rule
960 status_t
961 BMimeType::GetSnifferRule(BString* result) const
963 if (result == NULL)
964 return B_BAD_VALUE;
966 status_t err = InitCheck();
967 if (err == B_OK)
968 err = default_database_location()->GetSnifferRule(Type(), *result);
970 return err;
974 // Sets the MIME type's sniffer rule
975 status_t
976 BMimeType::SetSnifferRule(const char* rule)
978 status_t err = InitCheck();
979 if (err == B_OK && rule != NULL && rule[0] != '\0')
980 err = CheckSnifferRule(rule, NULL);
982 if (err != B_OK)
983 return err;
985 BMessage message(rule && rule[0] ? B_REG_MIME_SET_PARAM
986 : B_REG_MIME_DELETE_PARAM);
987 BMessage reply;
988 status_t result;
990 // Build and send the message, read the reply
991 err = message.AddString("type", Type());
992 if (err == B_OK)
993 err = message.AddInt32("which", B_REG_MIME_SNIFFER_RULE);
995 if (err == B_OK && rule)
996 err = message.AddString("sniffer rule", rule);
998 if (err == B_OK)
999 err = BRoster::Private().SendTo(&message, &reply, true);
1001 if (err == B_OK)
1002 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
1004 if (err == B_OK)
1005 err = reply.FindInt32("result", &result);
1007 if (err == B_OK)
1008 err = result;
1010 return err;
1014 // Checks whether a MIME sniffer rule is valid or not.
1015 status_t
1016 BMimeType::CheckSnifferRule(const char* rule, BString* parseError)
1018 BPrivate::Storage::Sniffer::Rule snifferRule;
1020 return BPrivate::Storage::Sniffer::parse(rule, &snifferRule, parseError);
1024 // Guesses a MIME type for the entry referred to by the given
1025 // entry_ref.
1026 status_t
1027 BMimeType::GuessMimeType(const entry_ref* file, BMimeType* type)
1029 status_t err = file && type ? B_OK : B_BAD_VALUE;
1031 BMessage message(B_REG_MIME_SNIFF);
1032 BMessage reply;
1033 status_t result;
1034 const char* str;
1036 // Build and send the message, read the reply
1037 if (err == B_OK)
1038 err = message.AddRef("file ref", file);
1040 if (err == B_OK)
1041 err = BRoster::Private().SendTo(&message, &reply, true);
1043 if (err == B_OK)
1044 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
1046 if (err == B_OK)
1047 err = reply.FindInt32("result", &result);
1049 if (err == B_OK)
1050 err = result;
1052 if (err == B_OK)
1053 err = reply.FindString("mime type", &str);
1055 if (err == B_OK)
1056 err = type->SetTo(str);
1058 return err;
1062 // Guesses a MIME type for the supplied chunk of data.
1063 status_t
1064 BMimeType::GuessMimeType(const void* buffer, int32 length, BMimeType* type)
1066 status_t err = buffer && type ? B_OK : B_BAD_VALUE;
1068 BMessage message(B_REG_MIME_SNIFF);
1069 BMessage reply;
1070 status_t result;
1071 const char* str;
1073 // Build and send the message, read the reply
1074 if (err == B_OK)
1075 err = message.AddData("data", B_RAW_TYPE, buffer, length);
1077 if (err == B_OK)
1078 err = BRoster::Private().SendTo(&message, &reply, true);
1080 if (err == B_OK)
1081 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
1083 if (err == B_OK)
1084 err = reply.FindInt32("result", &result);
1086 if (err == B_OK)
1087 err = result;
1089 if (err == B_OK)
1090 err = reply.FindString("mime type", &str);
1092 if (err == B_OK)
1093 err = type->SetTo(str);
1095 return err;
1099 // Guesses a MIME type for the given filename.
1100 status_t
1101 BMimeType::GuessMimeType(const char* filename, BMimeType* type)
1103 status_t err = filename && type ? B_OK : B_BAD_VALUE;
1105 BMessage message(B_REG_MIME_SNIFF);
1106 BMessage reply;
1107 status_t result;
1108 const char* str;
1110 // Build and send the message, read the reply
1111 if (err == B_OK)
1112 err = message.AddString("filename", filename);
1114 if (err == B_OK)
1115 err = BRoster::Private().SendTo(&message, &reply, true);
1117 if (err == B_OK)
1118 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
1120 if (err == B_OK)
1121 err = reply.FindInt32("result", &result);
1123 if (err == B_OK)
1124 err = result;
1126 if (err == B_OK)
1127 err = reply.FindString("mime type", &str);
1129 if (err == B_OK)
1130 err = type->SetTo(str);
1132 return err;
1136 // Starts monitoring the MIME database for a given target.
1137 status_t
1138 BMimeType::StartWatching(BMessenger target)
1140 BMessage message(B_REG_MIME_START_WATCHING);
1141 BMessage reply;
1142 status_t result;
1143 status_t err;
1145 // Build and send the message, read the reply
1146 err = message.AddMessenger("target", target);
1147 if (err == B_OK)
1148 err = BRoster::Private().SendTo(&message, &reply, true);
1150 if (err == B_OK)
1151 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
1153 if (err == B_OK)
1154 err = reply.FindInt32("result", &result);
1156 if (err == B_OK)
1157 err = result;
1159 return err;
1163 // Stops monitoring the MIME database for a given target
1164 status_t
1165 BMimeType::StopWatching(BMessenger target)
1167 BMessage message(B_REG_MIME_STOP_WATCHING);
1168 BMessage reply;
1169 status_t result;
1170 status_t err;
1172 // Build and send the message, read the reply
1173 err = message.AddMessenger("target", target);
1174 if (err == B_OK)
1175 err = BRoster::Private().SendTo(&message, &reply, true);
1177 if (err == B_OK)
1178 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
1180 if (err == B_OK)
1181 err = reply.FindInt32("result", &result);
1183 if (err == B_OK)
1184 err = result;
1186 return err;
1190 // Initializes this object to the supplied MIME type
1191 status_t
1192 BMimeType::SetType(const char* mimeType)
1194 return SetTo(mimeType);
1198 void BMimeType::_ReservedMimeType1() {}
1199 void BMimeType::_ReservedMimeType2() {}
1200 void BMimeType::_ReservedMimeType3() {}
1203 // assignment operator.
1204 // Unimplemented
1205 BMimeType&
1206 BMimeType::operator=(const BMimeType &)
1208 return *this;
1209 // not implemented
1213 // copy constructor
1214 // Unimplemented
1215 BMimeType::BMimeType(const BMimeType &)
1220 status_t
1221 BMimeType::GetSupportedTypes(BMessage* types)
1223 if (types == NULL)
1224 return B_BAD_VALUE;
1226 status_t err = InitCheck();
1227 if (err == B_OK)
1228 err = default_database_location()->GetSupportedTypes(Type(), *types);
1230 return err;
1234 /*! Sets the list of MIME types supported by the MIME type (which is
1235 assumed to be an application signature).
1237 If \a types is \c NULL the application's supported types are unset.
1239 The supported MIME types must be stored in a field "types" of type
1240 \c B_STRING_TYPE in \a types.
1242 For each supported type the result of BMimeType::GetSupportingApps() will
1243 afterwards include the signature of this application.
1245 \a fullSync specifies whether or not any types that are no longer
1246 listed as supported types as of this call to SetSupportedTypes() shall be
1247 updated as well, i.e. whether this application shall be removed from their
1248 lists of supporting applications.
1250 If \a fullSync is \c false, this application will not be removed from the
1251 previously supported types' supporting apps lists until the next call
1252 to BMimeType::SetSupportedTypes() or BMimeType::DeleteSupportedTypes()
1253 with a \c true \a fullSync parameter, the next call to BMimeType::Delete(),
1254 or the next reboot.
1256 \param types The supported types to be assigned to the file.
1257 May be \c NULL.
1258 \param fullSync \c true to also synchronize the previously supported
1259 types, \c false otherwise.
1261 \returns \c B_OK on success or another error code on failure.
1263 status_t
1264 BMimeType::SetSupportedTypes(const BMessage* types, bool fullSync)
1266 status_t err = InitCheck();
1268 // Build and send the message, read the reply
1269 BMessage message(types ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM);
1270 BMessage reply;
1271 status_t result;
1273 if (err == B_OK)
1274 err = message.AddString("type", Type());
1276 if (err == B_OK)
1277 err = message.AddInt32("which", B_REG_MIME_SUPPORTED_TYPES);
1279 if (err != B_OK && types != NULL)
1280 err = message.AddMessage("types", types);
1282 if (err == B_OK)
1283 err = message.AddBool("full sync", fullSync);
1285 if (err == B_OK)
1286 err = BRoster::Private().SendTo(&message, &reply, true);
1288 if (err == B_OK)
1289 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
1291 if (err == B_OK)
1292 err = reply.FindInt32("result", &result);
1294 if (err == B_OK)
1295 err = result;
1297 return err;
1301 /*! Returns a list of mime types associated with the given file extension
1303 The list of types is returned in the pre-allocated \c BMessage pointed to
1304 by \a types. The types are stored in the message's "types" field, which
1305 is an array of \c B_STRING_TYPE values.
1307 \param extension The file extension of interest
1308 \param types Pointer to a pre-allocated BMessage into which the result will
1309 be stored.
1311 \returns \c B_OK on success or another error code on failure.
1313 status_t
1314 BMimeType::GetAssociatedTypes(const char* extension, BMessage* types)
1316 status_t err = extension && types ? B_OK : B_BAD_VALUE;
1318 BMessage message(B_REG_MIME_GET_ASSOCIATED_TYPES);
1319 BMessage &reply = *types;
1320 status_t result;
1322 // Build and send the message, read the reply
1323 if (err == B_OK)
1324 err = message.AddString("extension", extension);
1326 if (err == B_OK)
1327 err = BRoster::Private().SendTo(&message, &reply, true);
1329 if (err == B_OK)
1330 err = (status_t)(reply.what == B_REG_RESULT ? B_OK : B_BAD_REPLY);
1332 if (err == B_OK)
1333 err = reply.FindInt32("result", &result);
1335 if (err == B_OK)
1336 err = result;
1338 return err;