1/*
2Open Tracker License
3
4Terms and Conditions
5
6Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a copy of
9this software and associated documentation files (the "Software"), to deal in
10the Software without restriction, including without limitation the rights to
11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12of the Software, and to permit persons to whom the Software is furnished to do
13so, subject to the following conditions:
14
15The above copyright notice and this permission notice applies to all licensees
16and shall be included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25Except as contained in this notice, the name of Be Incorporated shall not be
26used in advertising or otherwise to promote the sale, use or other dealings in
27this Software without prior written authorization from Be Incorporated.
28
29Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30of Be Incorporated in the United States and other countries. Other brand product
31names are registered trademarks or trademarks of their respective holders.
32All rights reserved.
33*/
34
35#include <Mime.h>
36
37#include <strings.h>
38
39#include "AutoLock.h"
40#include "MimeTypeList.h"
41#include "Thread.h"
42
43
44ShortMimeInfo::ShortMimeInfo(const BMimeType& mimeType)
45	:
46	fCommonMimeType(true)
47{
48	fPrivateName = mimeType.Type();
49
50	char buffer[B_MIME_TYPE_LENGTH];
51
52	// weed out apps - their preferred handler is themselves
53	if (mimeType.GetPreferredApp(buffer) == B_OK
54		&& fPrivateName.ICompare(buffer) == 0) {
55		fCommonMimeType = false;
56	}
57
58	// weed out metamimes without a short description
59	if (mimeType.GetShortDescription(buffer) != B_OK || buffer[0] == 0)
60		fCommonMimeType = false;
61	else
62		fShortDescription = buffer;
63}
64
65
66ShortMimeInfo::ShortMimeInfo(const char* shortDescription)
67	:
68	fShortDescription(shortDescription),
69	fCommonMimeType(true)
70{
71}
72
73
74const char*
75ShortMimeInfo::InternalName() const
76{
77	return fPrivateName.String();
78}
79
80
81const char*
82ShortMimeInfo::ShortDescription() const
83{
84	return fShortDescription.String();
85}
86
87
88int
89ShortMimeInfo::CompareShortDescription(const ShortMimeInfo* a,
90	const ShortMimeInfo* b)
91{
92	return a->fShortDescription.ICompare(b->fShortDescription);
93}
94
95
96bool
97ShortMimeInfo::IsCommonMimeType() const
98{
99	return fCommonMimeType;
100}
101
102
103//	#pragma mark - MimeTypeList
104
105
106MimeTypeList::MimeTypeList()
107	:
108	fMimeList(100, true),
109	fCommonMimeList(30, false),
110	fLock("mimeListLock")
111{
112	fLock.Lock();
113	Thread::Launch(NewMemberFunctionObject(&MimeTypeList::Build, this),
114		B_NORMAL_PRIORITY);
115}
116
117
118static int
119MatchOneShortDescription(const ShortMimeInfo* a, const ShortMimeInfo* b)
120{
121	return strcasecmp(a->ShortDescription(), b->ShortDescription());
122}
123
124
125const ShortMimeInfo*
126MimeTypeList::FindMimeType(const char* shortDescription) const
127{
128	ShortMimeInfo tmp(shortDescription);
129	const ShortMimeInfo* result = fCommonMimeList.BinarySearch(tmp,
130		&MatchOneShortDescription);
131
132	return result;
133}
134
135
136const ShortMimeInfo*
137MimeTypeList::EachCommonType(bool (*func)(const ShortMimeInfo*, void*),
138	void* state) const
139{
140	AutoLock<Benaphore> locker(fLock);
141	int32 count = fCommonMimeList.CountItems();
142	for (int32 index = 0; index < count; index++) {
143		if ((func)(fCommonMimeList.ItemAt(index), state))
144			return fCommonMimeList.ItemAt(index);
145	}
146
147	return NULL;
148}
149
150
151void
152MimeTypeList::Build()
153{
154	ASSERT(fLock.IsLocked());
155
156	BMessage message;
157	BMimeType::GetInstalledTypes(&message);
158
159	int32 count;
160	uint32 type;
161	message.GetInfo("types", &type, &count);
162
163	for (int32 index = 0; index < count; index++) {
164		const char* str;
165		if (message.FindString("types", index, &str) != B_OK)
166			continue;
167
168		BMimeType mimetype(str);
169		if (mimetype.InitCheck() != B_OK)
170			continue;
171
172		ShortMimeInfo* mimeInfo = new ShortMimeInfo(mimetype);
173		fMimeList.AddItem(mimeInfo);
174		if (mimeInfo->IsCommonMimeType())
175			fCommonMimeList.AddItem(mimeInfo);
176	}
177
178	fCommonMimeList.SortItems(&ShortMimeInfo::CompareShortDescription);
179	fLock.Unlock();
180}
181