#include <Mime.h>
#include <strings.h>
#include "AutoLock.h"
#include "MimeTypeList.h"
#include "Thread.h"
ShortMimeInfo::ShortMimeInfo(const BMimeType& mimeType)
:
fCommonMimeType(true)
{
fPrivateName = mimeType.Type();
char buffer[B_MIME_TYPE_LENGTH];
if (mimeType.GetPreferredApp(buffer) == B_OK
&& fPrivateName.ICompare(buffer) == 0) {
fCommonMimeType = false;
}
if (mimeType.GetShortDescription(buffer) != B_OK || buffer[0] == 0)
fCommonMimeType = false;
else
fShortDescription = buffer;
}
ShortMimeInfo::ShortMimeInfo(const char* shortDescription)
:
fShortDescription(shortDescription),
fCommonMimeType(true)
{
}
const char*
ShortMimeInfo::InternalName() const
{
return fPrivateName.String();
}
const char*
ShortMimeInfo::ShortDescription() const
{
return fShortDescription.String();
}
int
ShortMimeInfo::CompareShortDescription(const ShortMimeInfo* a,
const ShortMimeInfo* b)
{
return a->fShortDescription.ICompare(b->fShortDescription);
}
bool
ShortMimeInfo::IsCommonMimeType() const
{
return fCommonMimeType;
}
MimeTypeList::MimeTypeList()
:
fMimeList(100),
fCommonMimeList(30),
fLock("mimeListLock")
{
fLock.Lock();
Thread::Launch(NewMemberFunctionObject(&MimeTypeList::Build, this),
B_NORMAL_PRIORITY);
}
static int
MatchOneShortDescription(const ShortMimeInfo* a, const ShortMimeInfo* b)
{
return strcasecmp(a->ShortDescription(), b->ShortDescription());
}
const ShortMimeInfo*
MimeTypeList::FindMimeType(const char* shortDescription) const
{
ShortMimeInfo tmp(shortDescription);
const ShortMimeInfo* result = fCommonMimeList.BinarySearch(tmp,
&MatchOneShortDescription);
return result;
}
const ShortMimeInfo*
MimeTypeList::EachCommonType(bool (*func)(const ShortMimeInfo*, void*),
void* state) const
{
AutoLock<Benaphore> locker(fLock);
int32 count = fCommonMimeList.CountItems();
for (int32 index = 0; index < count; index++) {
if ((func)(fCommonMimeList.ItemAt(index), state))
return fCommonMimeList.ItemAt(index);
}
return NULL;
}
void
MimeTypeList::Build()
{
ASSERT(fLock.IsLocked());
BMessage message;
BMimeType::GetInstalledTypes(&message);
int32 count;
uint32 type;
message.GetInfo("types", &type, &count);
for (int32 index = 0; index < count; index++) {
const char* str;
if (message.FindString("types", index, &str) != B_OK)
continue;
BMimeType mimetype(str);
if (mimetype.InitCheck() != B_OK)
continue;
ShortMimeInfo* mimeInfo = new ShortMimeInfo(mimetype);
fMimeList.AddItem(mimeInfo);
if (mimeInfo->IsCommonMimeType())
fCommonMimeList.AddItem(mimeInfo);
}
fCommonMimeList.SortItems(&ShortMimeInfo::CompareShortDescription);
fLock.Unlock();
}