New mime sniffer support classes
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@601 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file sniffer/Err.h
|
||||
Mime Sniffer Error class declarations
|
||||
*/
|
||||
#ifndef _sk_sniffer_err_h_
|
||||
#define _sk_sniffer_err_h_
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <string>
|
||||
|
||||
namespace Sniffer {
|
||||
|
||||
//! Exception class used by the MIME Sniffer
|
||||
class Err {
|
||||
public:
|
||||
Err(const char *msg, const ssize_t pos);
|
||||
Err(const std::string &msg, const ssize_t pos);
|
||||
Err(const Err &ref);
|
||||
virtual ~Err();
|
||||
Err& operator=(const Err &ref);
|
||||
|
||||
status_t SetTo(const char *msg, const ssize_t pos);
|
||||
status_t SetTo(const std::string &msg, const ssize_t pos);
|
||||
void Unset();
|
||||
|
||||
const char* Msg() const;
|
||||
ssize_t Pos() const;
|
||||
|
||||
private:
|
||||
friend class Parser; // So it can update the pos of its out of mem object
|
||||
void SetMsg(const char *msg);
|
||||
void SetPos(ssize_t pos);
|
||||
char *fMsg;
|
||||
ssize_t fPos;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _sk_sniffer_err_h_
|
||||
@@ -0,0 +1,49 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file sniffer/Pattern.h
|
||||
Mime Sniffer Pattern declarations
|
||||
*/
|
||||
#ifndef _sk_sniffer_pattern_h_
|
||||
#define _sk_sniffer_pattern_h_
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <string>
|
||||
#include <sniffer/Range.h>
|
||||
|
||||
class BPositionIO;
|
||||
|
||||
namespace Sniffer {
|
||||
|
||||
class Err;
|
||||
|
||||
//! Abstract class definining an interface for sniffing BPositionIO objects
|
||||
class Pattern {
|
||||
public:
|
||||
Pattern(const char *string, const char *mask = NULL);
|
||||
~Pattern();
|
||||
|
||||
status_t InitCheck() const;
|
||||
Err* GetErr() const;
|
||||
|
||||
bool Sniff(Range range, BPositionIO *data) const;
|
||||
|
||||
status_t SetTo(const char *string, const char *mask = NULL);
|
||||
private:
|
||||
bool Sniff(off_t start, off_t size, BPositionIO *data) const;
|
||||
|
||||
void SetStatus(status_t status, const char *msg = NULL);
|
||||
void SetErrorMessage(const char *msg);
|
||||
|
||||
std::string fString;
|
||||
std::string fMask;
|
||||
|
||||
status_t fCStatus;
|
||||
Err *fErrorMessage;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _sk_sniffer_pattern_h_
|
||||
@@ -0,0 +1,40 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file sniffer/PatternList.h
|
||||
MIME sniffer pattern list declarations
|
||||
*/
|
||||
#ifndef _sk_sniffer_pattern_list_h_
|
||||
#define _sk_sniffer_pattern_list_h_
|
||||
|
||||
#include <sniffer/Expr.h>
|
||||
#include <sniffer/Range.h>
|
||||
#include <vector>
|
||||
|
||||
class BPositionIO;
|
||||
|
||||
namespace Sniffer {
|
||||
|
||||
class Err;
|
||||
class Pattern;
|
||||
|
||||
class PatternList : public Expr {
|
||||
public:
|
||||
PatternList(Range range);
|
||||
virtual ~PatternList();
|
||||
|
||||
status_t InitCheck() const;
|
||||
Err* GetErr() const;
|
||||
|
||||
virtual bool Sniff(BPositionIO *data) const;
|
||||
void Add(Pattern *pattern);
|
||||
private:
|
||||
std::vector<Pattern*> fList;
|
||||
Range fRange;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _sk_sniffer_pattern_list_h_
|
||||
@@ -0,0 +1,38 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file sniffer/RPattern.h
|
||||
Mime Sniffer RPattern declarations
|
||||
*/
|
||||
#ifndef _sk_sniffer_r_pattern_h_
|
||||
#define _sk_sniffer_r_pattern_h_
|
||||
|
||||
#include <sniffer/Range.h>
|
||||
|
||||
class BPositionIO;
|
||||
|
||||
namespace Sniffer {
|
||||
|
||||
class Err;
|
||||
class Pattern;
|
||||
|
||||
//! Abstract class definining an interface for sniffing BFile objects
|
||||
class RPattern {
|
||||
public:
|
||||
RPattern(Range range, Pattern *pattern);
|
||||
~RPattern();
|
||||
|
||||
status_t InitCheck() const;
|
||||
Err* GetErr() const;
|
||||
|
||||
bool Sniff(BPositionIO *data) const;
|
||||
private:
|
||||
Range fRange;
|
||||
Pattern *fPattern;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _sk_sniffer_r_pattern_h_
|
||||
@@ -0,0 +1,38 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file sniffer/RPatternList.h
|
||||
MIME sniffer rpattern list declarations
|
||||
*/
|
||||
#ifndef _sk_sniffer_r_pattern_list_h_
|
||||
#define _sk_sniffer_r_pattern_list_h_
|
||||
|
||||
#include <sniffer/Expr.h>
|
||||
#include <vector>
|
||||
|
||||
class BPositionIO;
|
||||
|
||||
namespace Sniffer {
|
||||
|
||||
class Err;
|
||||
class RPattern;
|
||||
|
||||
class RPatternList : public Expr {
|
||||
public:
|
||||
RPatternList();
|
||||
virtual ~RPatternList();
|
||||
|
||||
status_t InitCheck() const;
|
||||
Err* GetErr() const;
|
||||
|
||||
virtual bool Sniff(BPositionIO *data) const;
|
||||
void Add(RPattern *rpattern);
|
||||
private:
|
||||
std::vector<RPattern*> fList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _sk_sniffer_r_pattern_list_h_
|
||||
@@ -0,0 +1,94 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file Err.cpp
|
||||
MIME sniffer Error class implementation
|
||||
*/
|
||||
|
||||
#include <sniffer/Err.h>
|
||||
#include <new.h>
|
||||
|
||||
using namespace Sniffer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Err
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Err::Err(const char *msg, const ssize_t pos)
|
||||
: fMsg(NULL)
|
||||
, fPos(-1)
|
||||
{
|
||||
SetTo(msg, pos);
|
||||
}
|
||||
|
||||
Err::Err(const std::string &msg, const ssize_t pos)
|
||||
: fMsg(NULL)
|
||||
, fPos(-1)
|
||||
{
|
||||
SetTo(msg, pos);
|
||||
}
|
||||
|
||||
Err::Err(const Err &ref)
|
||||
: fMsg(NULL)
|
||||
, fPos(-1)
|
||||
{
|
||||
*this = ref;
|
||||
}
|
||||
|
||||
Err::~Err() {
|
||||
Unset();
|
||||
}
|
||||
|
||||
Err&
|
||||
Err::operator=(const Err &ref) {
|
||||
SetTo(ref.Msg(), ref.Pos());
|
||||
return *this;
|
||||
}
|
||||
|
||||
status_t
|
||||
Err::SetTo(const char *msg, const ssize_t pos) {
|
||||
SetMsg(msg);
|
||||
SetPos(pos);
|
||||
}
|
||||
|
||||
status_t
|
||||
Err::SetTo(const std::string &msg, const ssize_t pos) {
|
||||
SetTo(msg.c_str(), pos);
|
||||
}
|
||||
|
||||
void
|
||||
Err::Unset() {
|
||||
delete fMsg;
|
||||
fMsg = NULL;
|
||||
fPos = -1;
|
||||
}
|
||||
|
||||
const char*
|
||||
Err::Msg() const {
|
||||
return fMsg;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
Err::Pos() const {
|
||||
return fPos;
|
||||
}
|
||||
|
||||
void
|
||||
Err::SetMsg(const char *msg) {
|
||||
if (fMsg) {
|
||||
delete fMsg;
|
||||
fMsg = NULL;
|
||||
}
|
||||
if (msg) {
|
||||
fMsg = new(nothrow) char[strlen(msg)+1];
|
||||
if (fMsg)
|
||||
strcpy(fMsg, msg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Err::SetPos(ssize_t pos) {
|
||||
fPos = pos;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file Pattern.cpp
|
||||
MIME sniffer pattern implementation
|
||||
*/
|
||||
|
||||
#include <sniffer/Err.h>
|
||||
#include <sniffer/Pattern.h>
|
||||
#include <DataIO.h>
|
||||
#include <stdio.h> // for SEEK_* defines
|
||||
|
||||
using namespace Sniffer;
|
||||
|
||||
Pattern::Pattern(const char *string, const char *mask = NULL)
|
||||
: fCStatus(B_NO_INIT)
|
||||
, fErrorMessage(NULL)
|
||||
{
|
||||
SetTo(string, mask);
|
||||
}
|
||||
|
||||
Pattern::~Pattern() {
|
||||
delete fErrorMessage;
|
||||
}
|
||||
|
||||
status_t
|
||||
Pattern::InitCheck() const {
|
||||
return fCStatus;
|
||||
}
|
||||
|
||||
Err*
|
||||
Pattern::GetErr() const {
|
||||
if (fCStatus == B_OK)
|
||||
return NULL;
|
||||
else
|
||||
return new(nothrow) Err(*fErrorMessage);
|
||||
// return fErrorMessage ? NULL : new Err(*fErrorMessage);
|
||||
// return new Err("HEY, FIX THIS CRAP!", -1);
|
||||
}
|
||||
|
||||
status_t
|
||||
Pattern::SetTo(const char *string, const char *mask) {
|
||||
if (string) {
|
||||
fString = string;
|
||||
if (fString.length() == 0) {
|
||||
SetStatus(B_BAD_VALUE, "Sniffer pattern error: illegal empty pattern");
|
||||
} else {
|
||||
if (mask) {
|
||||
fMask = mask;
|
||||
if (fString.length() != fMask.length()) {
|
||||
SetStatus(B_BAD_VALUE, "Sniffer pattern error: pattern and mask lengths do not match");
|
||||
} else {
|
||||
SetStatus(B_OK);
|
||||
}
|
||||
} else {
|
||||
fMask = "";
|
||||
for (int i = 0; i < fString.length(); i++)
|
||||
fMask += (char)0xFF;
|
||||
SetStatus(B_OK);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SetStatus(B_BAD_VALUE, "Sniffer parser error: NULL string parameter passed to Pattern::SetTo()");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Pattern::Sniff(Range range, BPositionIO *data) const {
|
||||
// If our range contains negative values relative to the end of
|
||||
// the file, convert them to positive values relative to the
|
||||
// beginning of the file.
|
||||
int32 start = range.Start();
|
||||
int32 end = range.End();
|
||||
off_t size = data->Seek(0, SEEK_END);
|
||||
if (end >= size)
|
||||
end = size-1;
|
||||
for (int i = start; i <= end; i++) {
|
||||
if (Sniff(i, size, data))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Assumes the BPositionIO object is in the correct
|
||||
// position from which to sniff
|
||||
bool
|
||||
Pattern::Sniff(off_t start, off_t size, BPositionIO *data) const {
|
||||
off_t len = fString.length();
|
||||
char *buffer = new(nothrow) char[len+1];
|
||||
if (buffer) {
|
||||
ssize_t bytesRead = data->ReadAt(start, buffer, len);
|
||||
// /todo If there are fewer bytes left in the data stream
|
||||
// from the given position than the length of our data
|
||||
// string, should we just return false (which is what we're
|
||||
// doing now), or should we compare as many bytes as we
|
||||
// can and return true if those match?
|
||||
if (bytesRead < len)
|
||||
return false;
|
||||
else {
|
||||
bool result = true;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if ((fString[i] & fMask[i]) != (buffer[i] & fMask[i])) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Pattern::SetStatus(status_t status, const char *msg) {
|
||||
fCStatus = status;
|
||||
if (status == B_OK)
|
||||
SetErrorMessage(NULL);
|
||||
else {
|
||||
if (msg)
|
||||
SetErrorMessage(msg);
|
||||
else {
|
||||
SetErrorMessage("Sniffer parser error: Pattern::SetStatus() -- NULL msg with non-B_OK status.\n"
|
||||
"(This is officially the most helpful error message you will ever receive ;-)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Pattern::SetErrorMessage(const char *msg) {
|
||||
delete fErrorMessage;
|
||||
fErrorMessage = (msg) ? (new(nothrow) Err(msg, -1)) : (NULL);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file PatternList.cpp
|
||||
MIME sniffer pattern list implementation
|
||||
*/
|
||||
|
||||
#include <sniffer/Err.h>
|
||||
#include <sniffer/Pattern.h>
|
||||
#include <sniffer/PatternList.h>
|
||||
#include <DataIO.h>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace Sniffer;
|
||||
|
||||
PatternList::PatternList(Range range)
|
||||
: fRange(range)
|
||||
{
|
||||
}
|
||||
|
||||
PatternList::~PatternList() {
|
||||
// Clean up
|
||||
std::vector<Pattern*>::iterator i;
|
||||
for (i = fList.begin(); i != fList.end(); i++)
|
||||
delete *i;
|
||||
}
|
||||
|
||||
status_t
|
||||
PatternList::InitCheck() const {
|
||||
return fRange.InitCheck();
|
||||
}
|
||||
|
||||
Err*
|
||||
PatternList::GetErr() const {
|
||||
return fRange.GetErr();
|
||||
}
|
||||
|
||||
bool
|
||||
PatternList::Sniff(BPositionIO *data) const {
|
||||
if (InitCheck() != B_OK)
|
||||
return false;
|
||||
else {
|
||||
bool result = false;
|
||||
std::vector<Pattern*>::const_iterator i;
|
||||
for (i = fList.begin(); i != fList.end(); i++) {
|
||||
if (*i)
|
||||
result |= (*i)->Sniff(fRange, data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PatternList::Add(Pattern *pattern) {
|
||||
if (pattern)
|
||||
fList.push_back(pattern);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file RPattern.cpp
|
||||
MIME sniffer rpattern implementation
|
||||
*/
|
||||
|
||||
#include <sniffer/Err.h>
|
||||
#include <sniffer/Pattern.h>
|
||||
#include <sniffer/Range.h>
|
||||
#include <sniffer/RPattern.h>
|
||||
#include <DataIO.h>
|
||||
|
||||
using namespace Sniffer;
|
||||
|
||||
RPattern::RPattern(Range range, Pattern *pattern)
|
||||
: fRange(range)
|
||||
, fPattern(pattern)
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
RPattern::InitCheck() const {
|
||||
if (fRange.InitCheck() != B_OK)
|
||||
return fRange.InitCheck();
|
||||
else if (fPattern) {
|
||||
if (fPattern->InitCheck() != B_OK)
|
||||
return fPattern->InitCheck();
|
||||
else
|
||||
return B_OK;
|
||||
} else
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
Err*
|
||||
RPattern::GetErr() const {
|
||||
if (fRange.InitCheck() != B_OK)
|
||||
return fRange.GetErr();
|
||||
else if (fPattern) {
|
||||
if (fPattern->InitCheck() != B_OK)
|
||||
return fPattern->GetErr();
|
||||
else
|
||||
return NULL;
|
||||
} else
|
||||
return new Err("Sniffer parser error: RPattern::RPattern() -- NULL pattern parameter", -1);
|
||||
}
|
||||
|
||||
RPattern::~RPattern() {
|
||||
delete fPattern;
|
||||
}
|
||||
|
||||
bool
|
||||
RPattern::Sniff(BPositionIO *data) const {
|
||||
if (!data || InitCheck() != B_OK)
|
||||
return false;
|
||||
else
|
||||
return fPattern->Sniff(fRange, data);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*!
|
||||
\file RPatternList.cpp
|
||||
MIME sniffer rpattern list implementation
|
||||
*/
|
||||
|
||||
#include <sniffer/Err.h>
|
||||
#include <sniffer/RPattern.h>
|
||||
#include <sniffer/RPatternList.h>
|
||||
#include <DataIO.h>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace Sniffer;
|
||||
|
||||
RPatternList::RPatternList()
|
||||
{
|
||||
}
|
||||
|
||||
RPatternList::~RPatternList() {
|
||||
// Clear our rpattern list
|
||||
std::vector<RPattern*>::iterator i;
|
||||
for (i = fList.begin(); i != fList.end(); i++)
|
||||
delete *i;
|
||||
}
|
||||
|
||||
status_t
|
||||
RPatternList::InitCheck() const {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
Err*
|
||||
RPatternList::GetErr() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
RPatternList::Sniff(BPositionIO *data) const {
|
||||
if (InitCheck() != B_OK)
|
||||
return false;
|
||||
else {
|
||||
bool result = false;
|
||||
std::vector<RPattern*>::const_iterator i;
|
||||
for (i = fList.begin(); i != fList.end(); i++) {
|
||||
if (*i)
|
||||
result |= (*i)->Sniff(data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RPatternList::Add(RPattern *rpattern) {
|
||||
if (rpattern)
|
||||
fList.push_back(rpattern);
|
||||
}
|
||||
Reference in New Issue
Block a user