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:
Tyler Dauwalder
2002-08-06 08:25:41 +00:00
parent b7b28d766e
commit 74cd43ec44
10 changed files with 612 additions and 0 deletions
+43
View File
@@ -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_
+49
View File
@@ -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_
+94
View File
@@ -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;
}
+133
View File
@@ -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);
}
+59
View File
@@ -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);
}
+60
View File
@@ -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);
}
+58
View File
@@ -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);
}