mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Create MIMETypeLibrary for general MIME type detection
This commit is contained in:
parent
2919097f29
commit
142e787a9c
2 changed files with 176 additions and 0 deletions
85
libraries/shared/src/shared/MIMETypeLibrary.cpp
Normal file
85
libraries/shared/src/shared/MIMETypeLibrary.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// MIMETypeLibrary.cpp
|
||||
// libraries/shared/src/shared
|
||||
//
|
||||
// Created by Sabrina Shanman on 2018/11/29.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "MIMETypeLibrary.h"
|
||||
|
||||
MIMETypeLibrary::ID MIMETypeLibrary::registerMIMEType(const MIMEType& mimeType) {
|
||||
ID id;
|
||||
withWriteLock([&](){
|
||||
id = nextID++;
|
||||
_mimeTypes.emplace_back(id, mimeType);
|
||||
});
|
||||
return id;
|
||||
}
|
||||
|
||||
void MIMETypeLibrary::unregisterMIMEType(const MIMETypeLibrary::ID& id) {
|
||||
withWriteLock([&](){
|
||||
for (auto it = _mimeTypes.begin(); it != _mimeTypes.end(); it++) {
|
||||
if ((*it).id == id) {
|
||||
_mimeTypes.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
MIMEType MIMETypeLibrary::getMIMEType(const MIMETypeLibrary::ID& id) const {
|
||||
return resultWithReadLock<MIMEType>([&](){
|
||||
for (auto& supportedFormat : _mimeTypes) {
|
||||
if (supportedFormat.id == id) {
|
||||
return supportedFormat.mimeType;
|
||||
}
|
||||
}
|
||||
return MIMEType::NONE;
|
||||
});
|
||||
}
|
||||
|
||||
MIMETypeLibrary::ID MIMETypeLibrary::findMatchingMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const {
|
||||
return resultWithReadLock<MIMETypeLibrary::ID>([&](){
|
||||
// Check file contents
|
||||
for (auto& mimeType : _mimeTypes) {
|
||||
for (auto& fileSignature : mimeType.mimeType.fileSignatures) {
|
||||
auto testBytes = data.mid(fileSignature.byteOffset, (int)fileSignature.bytes.size()).toStdString();
|
||||
if (testBytes == fileSignature.bytes) {
|
||||
return mimeType.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check file extension
|
||||
std::string urlString = url.path().toStdString();
|
||||
std::size_t extensionSeparator = urlString.rfind('.');
|
||||
if (extensionSeparator != std::string::npos) {
|
||||
std::string detectedExtension = urlString.substr(extensionSeparator + 1);
|
||||
for (auto& supportedFormat : _mimeTypes) {
|
||||
for (auto& extension : supportedFormat.mimeType.extensions) {
|
||||
if (extension == detectedExtension) {
|
||||
return supportedFormat.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check web media type
|
||||
if (webMediaType != "") {
|
||||
for (auto& supportedFormat : _mimeTypes) {
|
||||
for (auto& candidateWebMediaType : supportedFormat.mimeType.webMediaTypes) {
|
||||
if (candidateWebMediaType == webMediaType) {
|
||||
return supportedFormat.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Supported file type not found.
|
||||
return INVALID_ID;
|
||||
});
|
||||
}
|
91
libraries/shared/src/shared/MIMETypeLibrary.h
Normal file
91
libraries/shared/src/shared/MIMETypeLibrary.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
//
|
||||
// MIMETypeLibrary.h
|
||||
// libraries/shared/src/shared
|
||||
//
|
||||
// Created by Sabrina Shanman on 2018/11/28.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_MIMETypeLibrary_h
|
||||
#define hifi_MIMETypeLibrary_h
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
#include "HifiTypes.h"
|
||||
|
||||
#include "ReadWriteLockable.h"
|
||||
|
||||
// A short sequence of bytes, typically at the beginning of the file, which identifies the file format
|
||||
class FileSignature {
|
||||
public:
|
||||
FileSignature(const std::string& bytes, int byteOffset) :
|
||||
bytes(bytes),
|
||||
byteOffset(byteOffset) {
|
||||
}
|
||||
FileSignature(const FileSignature& fileSignature) :
|
||||
bytes(fileSignature.bytes),
|
||||
byteOffset(fileSignature.byteOffset) {
|
||||
}
|
||||
|
||||
std::string bytes;
|
||||
int byteOffset;
|
||||
};
|
||||
|
||||
// A named file extension with a list of known ways to positively identify the file type
|
||||
class MIMEType {
|
||||
public:
|
||||
MIMEType(const std::string& name) :
|
||||
name(name) {
|
||||
}
|
||||
MIMEType() {};
|
||||
MIMEType(const MIMEType& mimeType) :
|
||||
name(mimeType.name),
|
||||
extensions(mimeType.extensions),
|
||||
webMediaTypes(mimeType.webMediaTypes),
|
||||
fileSignatures(mimeType.fileSignatures) {
|
||||
}
|
||||
|
||||
static MIMEType NONE;
|
||||
|
||||
std::string name;
|
||||
std::vector<std::string> extensions;
|
||||
std::vector<std::string> webMediaTypes;
|
||||
std::vector<FileSignature> fileSignatures;
|
||||
};
|
||||
|
||||
MIMEType MIMEType::NONE = MIMEType("");
|
||||
|
||||
class MIMETypeLibrary : ReadWriteLockable {
|
||||
public:
|
||||
using ID = unsigned int;
|
||||
static const ID INVALID_ID { 0 };
|
||||
|
||||
ID registerMIMEType(const MIMEType& mimeType);
|
||||
void unregisterMIMEType(const ID& id);
|
||||
|
||||
MIMEType getMIMEType(const ID& id) const;
|
||||
ID findMatchingMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const;
|
||||
|
||||
protected:
|
||||
ID nextID { 1 };
|
||||
|
||||
class Entry {
|
||||
public:
|
||||
Entry(const ID& id, const MIMEType& mimeType) :
|
||||
id(id),
|
||||
mimeType(mimeType) {
|
||||
}
|
||||
ID id;
|
||||
MIMEType mimeType;
|
||||
};
|
||||
|
||||
std::vector<Entry> _mimeTypes;
|
||||
};
|
||||
|
||||
#endif // hifi_MIMETypeLibrary_h
|
Loading…
Reference in a new issue