+ Updated all the parsing code to use std::strings everywhere
instead of const char*'s to allow for rules with NULL characters embedded in them. + Updated Rule::Sniff() to actually return a useful value git-svn-id: file:///srv/svn/repos/haiku/trunk/current@662 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -43,23 +43,24 @@ status_t parse(const char *rule, Rule *result, BString *parseError = NULL);
|
|||||||
*/
|
*/
|
||||||
class CharStream {
|
class CharStream {
|
||||||
public:
|
public:
|
||||||
CharStream(const char *string = NULL);
|
CharStream(const std::string &string);
|
||||||
|
CharStream();
|
||||||
~CharStream();
|
~CharStream();
|
||||||
|
|
||||||
status_t SetTo(const char *string);
|
status_t SetTo(const std::string &string);
|
||||||
void Unset();
|
void Unset();
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
ssize_t Pos() const;
|
ssize_t Pos() const;
|
||||||
const char *String() const;
|
const std::string& String() const;
|
||||||
|
|
||||||
char Get();
|
char Get();
|
||||||
void Unget();
|
void Unget();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *fString;
|
std::string fString;
|
||||||
ssize_t fPos;
|
ssize_t fPos;
|
||||||
ssize_t fLen;
|
// ssize_t fLen;
|
||||||
status_t fCStatus;
|
status_t fCStatus;
|
||||||
|
|
||||||
CharStream(const CharStream &ref);
|
CharStream(const CharStream &ref);
|
||||||
@@ -95,9 +96,8 @@ const char* tokenTypeToString(TokenType type);
|
|||||||
class Token {
|
class Token {
|
||||||
public:
|
public:
|
||||||
Token(TokenType type = EmptyToken, const ssize_t pos = -1);
|
Token(TokenType type = EmptyToken, const ssize_t pos = -1);
|
||||||
virtual ~Token();
|
|
||||||
TokenType Type() const;
|
TokenType Type() const;
|
||||||
virtual const char* String() const;
|
virtual const std::string& String() const;
|
||||||
virtual int32 Int() const;
|
virtual int32 Int() const;
|
||||||
virtual double Float() const;
|
virtual double Float() const;
|
||||||
ssize_t Pos() const;
|
ssize_t Pos() const;
|
||||||
@@ -114,11 +114,10 @@ protected:
|
|||||||
*/
|
*/
|
||||||
class StringToken : public Token {
|
class StringToken : public Token {
|
||||||
public:
|
public:
|
||||||
StringToken(const char *string, const ssize_t pos);
|
StringToken(const std::string &str, const ssize_t pos);
|
||||||
virtual ~StringToken();
|
virtual const std::string& String() const;
|
||||||
virtual const char* String() const;
|
|
||||||
protected:
|
protected:
|
||||||
char *fString;
|
std::string fString;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Integer token class
|
//! Integer token class
|
||||||
@@ -157,10 +156,11 @@ protected:
|
|||||||
*/
|
*/
|
||||||
class TokenStream {
|
class TokenStream {
|
||||||
public:
|
public:
|
||||||
TokenStream(const char *string = NULL);
|
TokenStream(const std::string &string);
|
||||||
|
TokenStream();
|
||||||
~TokenStream();
|
~TokenStream();
|
||||||
|
|
||||||
status_t SetTo(const char *string);
|
status_t SetTo(const std::string &string);
|
||||||
void Unset();
|
void Unset();
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void AddToken(TokenType type, ssize_t pos);
|
void AddToken(TokenType type, ssize_t pos);
|
||||||
void AddString(const char *str, ssize_t pos);
|
void AddString(const std::string &str, ssize_t pos);
|
||||||
void AddInt(const char *str, ssize_t pos);
|
void AddInt(const char *str, ssize_t pos);
|
||||||
void AddFloat(const char *str, ssize_t pos);
|
void AddFloat(const char *str, ssize_t pos);
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ class Err;
|
|||||||
/*! The byte string and mask (if supplied) must be of the same length. */
|
/*! The byte string and mask (if supplied) must be of the same length. */
|
||||||
class Pattern {
|
class Pattern {
|
||||||
public:
|
public:
|
||||||
Pattern(const char *string, const char *mask = NULL);
|
Pattern(const std::string &string, const std::string &mask);
|
||||||
|
Pattern(const std::string &string);
|
||||||
~Pattern();
|
~Pattern();
|
||||||
|
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
@@ -31,7 +32,7 @@ public:
|
|||||||
|
|
||||||
bool Sniff(Range range, BPositionIO *data) const;
|
bool Sniff(Range range, BPositionIO *data) const;
|
||||||
|
|
||||||
status_t SetTo(const char *string, const char *mask = NULL);
|
status_t SetTo(const std::string &string, const std::string &mask);
|
||||||
private:
|
private:
|
||||||
bool Sniff(off_t start, off_t size, BPositionIO *data) const;
|
bool Sniff(off_t start, off_t size, BPositionIO *data) const;
|
||||||
|
|
||||||
|
|||||||
+426
-433
@@ -65,13 +65,19 @@ Sniffer::parse(const char *rule, Rule *result, BString *parseError) {
|
|||||||
// CharStream
|
// CharStream
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
CharStream::CharStream(const char *string)
|
CharStream::CharStream(const std::string &string)
|
||||||
: fString(NULL)
|
: fString(string)
|
||||||
|
, fPos(0)
|
||||||
|
// , fLen(-1)
|
||||||
|
, fCStatus(B_OK)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CharStream::CharStream()
|
||||||
|
: fString("")
|
||||||
, fPos(0)
|
, fPos(0)
|
||||||
, fLen(-1)
|
|
||||||
, fCStatus(B_NO_INIT)
|
, fCStatus(B_NO_INIT)
|
||||||
{
|
{
|
||||||
SetTo(string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CharStream::~CharStream() {
|
CharStream::~CharStream() {
|
||||||
@@ -79,27 +85,18 @@ CharStream::~CharStream() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
CharStream::SetTo(const char *string) {
|
CharStream::SetTo(const std::string &string) {
|
||||||
Unset();
|
fString = string;
|
||||||
if (string) {
|
fPos = 0;
|
||||||
fString = new(nothrow) char[strlen(string)+1];
|
fCStatus = B_OK;
|
||||||
if (!fString)
|
|
||||||
fCStatus = B_NO_MEMORY;
|
|
||||||
else {
|
|
||||||
strcpy(fString, string);
|
|
||||||
fLen = strlen(fString);
|
|
||||||
fCStatus = B_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fCStatus;
|
return fCStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CharStream::Unset() {
|
CharStream::Unset() {
|
||||||
delete fString;
|
fString = "";
|
||||||
fCStatus = B_NO_INIT;
|
|
||||||
fPos = 0;
|
fPos = 0;
|
||||||
fLen = -1;
|
fCStatus = B_NO_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
@@ -109,7 +106,7 @@ CharStream::InitCheck() const {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
CharStream::IsEmpty() const {
|
CharStream::IsEmpty() const {
|
||||||
return fPos >= fLen;
|
return fPos >= fString.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
@@ -117,7 +114,7 @@ CharStream::Pos() const {
|
|||||||
return fPos;
|
return fPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const std::string&
|
||||||
CharStream::String() const {
|
CharStream::String() const {
|
||||||
return fString;
|
return fString;
|
||||||
}
|
}
|
||||||
@@ -126,7 +123,7 @@ char
|
|||||||
CharStream::Get() {
|
CharStream::Get() {
|
||||||
if (fCStatus != B_OK)
|
if (fCStatus != B_OK)
|
||||||
throw new Err("Sniffer parser error: CharStream::Get() called on uninitialized CharStream object", -1);
|
throw new Err("Sniffer parser error: CharStream::Get() called on uninitialized CharStream object", -1);
|
||||||
if (fPos < fLen)
|
if (fPos < fString.length())
|
||||||
return fString[fPos++];
|
return fString[fPos++];
|
||||||
else {
|
else {
|
||||||
fPos++; // Increment fPos to keep Unget()s consistent
|
fPos++; // Increment fPos to keep Unget()s consistent
|
||||||
@@ -156,15 +153,12 @@ Token::Token(TokenType type, const ssize_t pos)
|
|||||||
// cout << "New Token, fType == " << tokenTypeToString(fType) << endl;
|
// cout << "New Token, fType == " << tokenTypeToString(fType) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::~Token() {
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenType
|
TokenType
|
||||||
Token::Type() const {
|
Token::Type() const {
|
||||||
return fType;
|
return fType;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const std::string&
|
||||||
Token::String() const {
|
Token::String() const {
|
||||||
throw new Err("Sniffer scanner error: Token::String() called on non-string token", fPos);
|
throw new Err("Sniffer scanner error: Token::String() called on non-string token", fPos);
|
||||||
}
|
}
|
||||||
@@ -194,6 +188,9 @@ Token::operator==(Token &ref) const {
|
|||||||
// printf(" str2 == '%s'\n", ref.String());
|
// printf(" str2 == '%s'\n", ref.String());
|
||||||
// printf(" strcmp() == %d\n", strcmp(String(), ref.String()));
|
// printf(" strcmp() == %d\n", strcmp(String(), ref.String()));
|
||||||
{
|
{
|
||||||
|
return String() == ref.String();
|
||||||
|
|
||||||
|
/*
|
||||||
// strcmp() seems to choke on certain, non-normal ASCII chars
|
// strcmp() seems to choke on certain, non-normal ASCII chars
|
||||||
// (i.e. chars outside the usual alphabets, but still valid
|
// (i.e. chars outside the usual alphabets, but still valid
|
||||||
// as far as ASCII is concerned), so we'll just compare the
|
// as far as ASCII is concerned), so we'll just compare the
|
||||||
@@ -212,6 +209,7 @@ Token::operator==(Token &ref) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
// return strcmp(String(), ref.String()) == 0;
|
// return strcmp(String(), ref.String()) == 0;
|
||||||
|
|
||||||
@@ -232,22 +230,13 @@ Token::operator==(Token &ref) const {
|
|||||||
// StringToken
|
// StringToken
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
StringToken::StringToken(const char *string, const ssize_t pos)
|
StringToken::StringToken(const std::string &str, const ssize_t pos)
|
||||||
: Token(CharacterString, pos)
|
: Token(CharacterString, pos)
|
||||||
, fString(NULL)
|
, fString(str)
|
||||||
{
|
{
|
||||||
if (string) {
|
|
||||||
fString = new(nothrow) char[strlen(string)+1];
|
|
||||||
if (fString)
|
|
||||||
strcpy(fString, string);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringToken::~StringToken() {
|
const std::string&
|
||||||
delete fString;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
|
||||||
StringToken::String() const {
|
StringToken::String() const {
|
||||||
return fString;
|
return fString;
|
||||||
}
|
}
|
||||||
@@ -291,7 +280,7 @@ FloatToken::Float() const {
|
|||||||
// TokenStream
|
// TokenStream
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
TokenStream::TokenStream(const char *string = NULL)
|
TokenStream::TokenStream(const std::string &string)
|
||||||
: fCStatus(B_NO_INIT)
|
: fCStatus(B_NO_INIT)
|
||||||
, fPos(-1)
|
, fPos(-1)
|
||||||
, fStrLen(-1)
|
, fStrLen(-1)
|
||||||
@@ -299,435 +288,439 @@ TokenStream::TokenStream(const char *string = NULL)
|
|||||||
SetTo(string);
|
SetTo(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TokenStream::TokenStream()
|
||||||
|
: fCStatus(B_NO_INIT)
|
||||||
|
, fPos(-1)
|
||||||
|
, fStrLen(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
TokenStream::~TokenStream() {
|
TokenStream::~TokenStream() {
|
||||||
Unset();
|
Unset();
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TokenStream::SetTo(const char *string) {
|
TokenStream::SetTo(const std::string &string) {
|
||||||
int q = 0;
|
|
||||||
Unset();
|
Unset();
|
||||||
if (string) {
|
fStrLen = string.length();
|
||||||
fStrLen = strlen(string);
|
CharStream stream(string);
|
||||||
CharStream stream(string);
|
if (stream.InitCheck() != B_OK)
|
||||||
if (stream.InitCheck() != B_OK)
|
throw new Err("Sniffer scanner error: Unable to intialize character stream", -1);
|
||||||
throw new Err("Sniffer scanner error: Unable to intialize character stream", -1);
|
|
||||||
|
|
||||||
typedef enum TokenStreamScannerState {
|
typedef enum TokenStreamScannerState {
|
||||||
tsssStart,
|
tsssStart,
|
||||||
tsssOneSingle,
|
tsssOneSingle,
|
||||||
tsssOneDouble,
|
tsssOneDouble,
|
||||||
tsssOneZero,
|
tsssOneZero,
|
||||||
tsssZeroX,
|
tsssZeroX,
|
||||||
tsssOneHex,
|
tsssOneHex,
|
||||||
tsssTwoHex,
|
tsssTwoHex,
|
||||||
tsssHexStringEnd,
|
tsssHexStringEnd,
|
||||||
tsssIntOrFloat,
|
tsssIntOrFloat,
|
||||||
tsssFloat,
|
tsssFloat,
|
||||||
tsssLonelyDecimalPoint,
|
tsssLonelyDecimalPoint,
|
||||||
tsssLonelyMinusOrPlus,
|
tsssLonelyMinusOrPlus,
|
||||||
tsssLonelyFloatExtension,
|
tsssLonelyFloatExtension,
|
||||||
tsssLonelyFloatExtensionWithSign,
|
tsssLonelyFloatExtensionWithSign,
|
||||||
tsssExtendedFloat,
|
tsssExtendedFloat,
|
||||||
tsssUnquoted,
|
tsssUnquoted,
|
||||||
tsssEscape,
|
tsssEscape,
|
||||||
tsssEscapeX,
|
tsssEscapeX,
|
||||||
tsssEscapeOneOctal,
|
tsssEscapeOneOctal,
|
||||||
tsssEscapeTwoOctal,
|
tsssEscapeTwoOctal,
|
||||||
tsssEscapeOneHex,
|
tsssEscapeOneHex,
|
||||||
tsssEscapeTwoHex
|
tsssEscapeTwoHex
|
||||||
};
|
};
|
||||||
|
|
||||||
TokenStreamScannerState state = tsssStart;
|
TokenStreamScannerState state = tsssStart;
|
||||||
TokenStreamScannerState escapedState;
|
TokenStreamScannerState escapedState;
|
||||||
// Used to remember which state to return to from an escape sequence
|
// Used to remember which state to return to from an escape sequence
|
||||||
|
|
||||||
std::string charStr; // Used to build up character strings
|
std::string charStr; // Used to build up character strings
|
||||||
char lastChar; // For two char lookahead
|
char lastChar; // For two char lookahead
|
||||||
char lastLastChar; // For three char lookahead
|
char lastLastChar; // For three char lookahead (have I mentioned I hate octal?)
|
||||||
bool keepLooping = true;
|
bool keepLooping = true;
|
||||||
ssize_t startPos;
|
ssize_t startPos;
|
||||||
while (keepLooping) {
|
while (keepLooping) {
|
||||||
ssize_t pos = stream.Pos();
|
ssize_t pos = stream.Pos();
|
||||||
char ch = stream.Get();
|
char ch = stream.Get();
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case tsssStart:
|
case tsssStart:
|
||||||
startPos = pos;
|
startPos = pos;
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 0x3: // End-Of-Text
|
case 0x3: // End-Of-Text
|
||||||
if (stream.IsEmpty())
|
if (stream.IsEmpty())
|
||||||
keepLooping = false;
|
keepLooping = false;
|
||||||
else
|
else
|
||||||
throw new Err(std::string("Sniffer pattern error: invalid character '") + ch + "'", pos);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\t':
|
|
||||||
case '\n':
|
|
||||||
case ' ':
|
|
||||||
// Whitespace, so ignore it.
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '"':
|
|
||||||
charStr = "";
|
|
||||||
state = tsssOneDouble;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\'':
|
|
||||||
charStr = "";
|
|
||||||
state = tsssOneSingle;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '+':
|
|
||||||
case '-':
|
|
||||||
charStr = ch;
|
|
||||||
state = tsssLonelyMinusOrPlus;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '.':
|
|
||||||
charStr = ch;
|
|
||||||
state = tsssLonelyDecimalPoint;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '0':
|
|
||||||
charStr = ch;
|
|
||||||
state = tsssOneZero;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
charStr = ch;
|
|
||||||
state = tsssIntOrFloat;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '&': AddToken(Ampersand, pos); break;
|
|
||||||
case '(': AddToken(LeftParen, pos); break;
|
|
||||||
case ')': AddToken(RightParen, pos); break;
|
|
||||||
case ':': AddToken(Colon, pos); break;
|
|
||||||
case '[': AddToken(LeftBracket, pos); break;
|
|
||||||
|
|
||||||
case '\\':
|
|
||||||
charStr = ""; // Clear our string
|
|
||||||
state = tsssEscape;
|
|
||||||
escapedState = tsssUnquoted; // Unquoted strings begin with an escaped character
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ']': AddToken(RightBracket, pos); break;
|
|
||||||
case '|': AddToken(Divider, pos); break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Err(std::string("Sniffer pattern error: invalid character '") + ch + "'", pos);
|
throw new Err(std::string("Sniffer pattern error: invalid character '") + ch + "'", pos);
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssOneSingle:
|
case '\t':
|
||||||
switch (ch) {
|
case '\n':
|
||||||
case '\\':
|
case ' ':
|
||||||
escapedState = state; // Save our state
|
// Whitespace, so ignore it.
|
||||||
state = tsssEscape; // Handle the escape sequence
|
break;
|
||||||
break;
|
|
||||||
case '\'':
|
|
||||||
AddString(charStr.c_str(), startPos);
|
|
||||||
state = tsssStart;
|
|
||||||
break;
|
|
||||||
case 0x3:
|
|
||||||
if (stream.IsEmpty())
|
|
||||||
throw new Err(std::string("Sniffer pattern error: unterminated single-quoted string"), pos);
|
|
||||||
else
|
|
||||||
charStr += ch;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
charStr += ch;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssOneDouble:
|
case '"':
|
||||||
switch (ch) {
|
charStr = "";
|
||||||
case '\\':
|
state = tsssOneDouble;
|
||||||
escapedState = state; // Save our state
|
break;
|
||||||
state = tsssEscape; // Handle the escape sequence
|
|
||||||
break;
|
|
||||||
case '"':
|
|
||||||
AddString(charStr.c_str(), startPos);
|
|
||||||
state = tsssStart;
|
|
||||||
break;
|
|
||||||
case 0x3:
|
|
||||||
if (stream.IsEmpty())
|
|
||||||
throw new Err(std::string("Sniffer pattern error: unterminated double-quoted string"), pos);
|
|
||||||
else
|
|
||||||
charStr += ch;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
charStr += ch;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssOneZero:
|
case '\'':
|
||||||
if (ch == 'x') {
|
charStr = "";
|
||||||
charStr = ""; // Reinit, since we actually have a hex string
|
state = tsssOneSingle;
|
||||||
state = tsssZeroX;
|
break;
|
||||||
} else if ('0' <= ch && ch <= '9') {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssIntOrFloat;
|
|
||||||
} else if (ch == '.') {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssFloat;
|
|
||||||
} else if (ch == 'e' || ch == 'E') {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssLonelyFloatExtension;
|
|
||||||
} else {
|
|
||||||
// Terminate the number
|
|
||||||
AddInt(charStr.c_str(), startPos);
|
|
||||||
|
|
||||||
// Push the last char back on and try again
|
case '+':
|
||||||
stream.Unget();
|
case '-':
|
||||||
state = tsssStart;
|
charStr = ch;
|
||||||
}
|
state = tsssLonelyMinusOrPlus;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tsssZeroX:
|
case '.':
|
||||||
if (isHexChar(ch)) {
|
charStr = ch;
|
||||||
lastChar = ch;
|
|
||||||
state = tsssOneHex;
|
|
||||||
} else
|
|
||||||
throw new Err(std::string("Sniffer pattern error: incomplete hex code"), pos);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssOneHex:
|
|
||||||
if (isHexChar(ch)) {
|
|
||||||
try {
|
|
||||||
charStr += hexToChar(lastChar, ch);
|
|
||||||
} catch (Err *err) {
|
|
||||||
if (err)
|
|
||||||
err->SetPos(pos);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
state = tsssTwoHex;
|
|
||||||
} else
|
|
||||||
throw new Err(std::string("Sniffer pattern error: bad hex literal"), pos); // Same as R5
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssTwoHex:
|
|
||||||
if (isHexChar(ch)) {
|
|
||||||
lastChar = ch;
|
|
||||||
state = tsssOneHex;
|
|
||||||
} else {
|
|
||||||
AddString(charStr.c_str(), startPos);
|
|
||||||
stream.Unget(); // So punctuation gets handled properly
|
|
||||||
state = tsssStart;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssIntOrFloat:
|
|
||||||
if (isDecimalChar(ch))
|
|
||||||
charStr += ch;
|
|
||||||
else if (ch == '.') {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssFloat;
|
|
||||||
} else if (ch == 'e' || ch == 'E') {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssLonelyFloatExtension;
|
|
||||||
} else {
|
|
||||||
// Terminate the number
|
|
||||||
AddInt(charStr.c_str(), startPos);
|
|
||||||
|
|
||||||
// Push the last char back on and try again
|
|
||||||
stream.Unget();
|
|
||||||
state = tsssStart;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssFloat:
|
|
||||||
if (isDecimalChar(ch))
|
|
||||||
charStr += ch;
|
|
||||||
else if (ch == 'e' || ch == 'E') {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssLonelyFloatExtension;
|
|
||||||
} else {
|
|
||||||
// Terminate the number
|
|
||||||
AddFloat(charStr.c_str(), startPos);
|
|
||||||
|
|
||||||
// Push the last char back on and try again
|
|
||||||
stream.Unget();
|
|
||||||
state = tsssStart;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssLonelyDecimalPoint:
|
|
||||||
if (isDecimalChar(ch)) {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssFloat;
|
|
||||||
} else
|
|
||||||
throw new Err(std::string("Sniffer pattern error: incomplete floating point number"), pos);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssLonelyMinusOrPlus:
|
|
||||||
if (isDecimalChar(ch)) {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssIntOrFloat;
|
|
||||||
} else if (ch == '.') {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssLonelyDecimalPoint;
|
state = tsssLonelyDecimalPoint;
|
||||||
} else
|
break;
|
||||||
throw new Err(std::string("Sniffer pattern error: incomplete signed number"), pos);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssLonelyFloatExtension:
|
case '0':
|
||||||
if (ch == '+' || ch == '-') {
|
charStr = ch;
|
||||||
charStr += ch;
|
state = tsssOneZero;
|
||||||
state = tsssLonelyFloatExtensionWithSign;
|
break;
|
||||||
} else if (isDecimalChar(ch)) {
|
|
||||||
charStr += ch;
|
|
||||||
state = tsssExtendedFloat;
|
|
||||||
} else
|
|
||||||
throw new Err(std::string("Sniffer pattern error: incomplete extended-notation floating point number"), pos);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssLonelyFloatExtensionWithSign:
|
case '1':
|
||||||
if (isDecimalChar(ch)) {
|
case '2':
|
||||||
charStr += ch;
|
case '3':
|
||||||
state = tsssExtendedFloat;
|
case '4':
|
||||||
} else
|
case '5':
|
||||||
throw new Err(std::string("Sniffer pattern error: incomplete extended-notation floating point number"), pos);
|
case '6':
|
||||||
break;
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
charStr = ch;
|
||||||
|
state = tsssIntOrFloat;
|
||||||
|
break;
|
||||||
|
|
||||||
case tsssExtendedFloat:
|
case '&': AddToken(Ampersand, pos); break;
|
||||||
if (isDecimalChar(ch)) {
|
case '(': AddToken(LeftParen, pos); break;
|
||||||
charStr += ch;
|
case ')': AddToken(RightParen, pos); break;
|
||||||
state = tsssExtendedFloat;
|
case ':': AddToken(Colon, pos); break;
|
||||||
} else {
|
case '[': AddToken(LeftBracket, pos); break;
|
||||||
// Terminate the number
|
|
||||||
AddFloat(charStr.c_str(), startPos);
|
|
||||||
|
|
||||||
// Push the last char back on and try again
|
case '\\':
|
||||||
stream.Unget();
|
charStr = ""; // Clear our string
|
||||||
state = tsssStart;
|
state = tsssEscape;
|
||||||
}
|
escapedState = tsssUnquoted; // Unquoted strings begin with an escaped character
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tsssUnquoted:
|
case ']': AddToken(RightBracket, pos); break;
|
||||||
if (ch == '\\') {
|
case '|': AddToken(Divider, pos); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Err(std::string("Sniffer pattern error: invalid character '") + ch + "'", pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssOneSingle:
|
||||||
|
switch (ch) {
|
||||||
|
case '\\':
|
||||||
escapedState = state; // Save our state
|
escapedState = state; // Save our state
|
||||||
state = tsssEscape; // Handle the escape sequence
|
state = tsssEscape; // Handle the escape sequence
|
||||||
} else if (isWhiteSpace(ch) || isPunctuation(ch)) {
|
break;
|
||||||
AddString(charStr.c_str(), startPos);
|
case '\'':
|
||||||
stream.Unget(); // In case it's punctuation, let tsssStart handle it
|
AddString(charStr, startPos);
|
||||||
state = tsssStart;
|
state = tsssStart;
|
||||||
} else if (ch == '\'' || ch == '"') {
|
break;
|
||||||
throw new Err(std::string("Sniffer pattern error: illegal unquoted character '") + ch + "'", pos);
|
case 0x3:
|
||||||
} else if (ch == 0x3 && stream.IsEmpty()) {
|
if (stream.IsEmpty())
|
||||||
AddString(charStr.c_str(), startPos);
|
throw new Err(std::string("Sniffer pattern error: unterminated single-quoted string"), pos);
|
||||||
keepLooping = false;
|
else
|
||||||
} else {
|
charStr += ch;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
charStr += ch;
|
charStr += ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssOneDouble:
|
||||||
|
switch (ch) {
|
||||||
|
case '\\':
|
||||||
|
escapedState = state; // Save our state
|
||||||
|
state = tsssEscape; // Handle the escape sequence
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
AddString(charStr, startPos);
|
||||||
|
state = tsssStart;
|
||||||
|
break;
|
||||||
|
case 0x3:
|
||||||
|
if (stream.IsEmpty())
|
||||||
|
throw new Err(std::string("Sniffer pattern error: unterminated double-quoted string"), pos);
|
||||||
|
else
|
||||||
|
charStr += ch;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
charStr += ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssOneZero:
|
||||||
|
if (ch == 'x') {
|
||||||
|
charStr = ""; // Reinit, since we actually have a hex string
|
||||||
|
state = tsssZeroX;
|
||||||
|
} else if ('0' <= ch && ch <= '9') {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssIntOrFloat;
|
||||||
|
} else if (ch == '.') {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssFloat;
|
||||||
|
} else if (ch == 'e' || ch == 'E') {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssLonelyFloatExtension;
|
||||||
|
} else {
|
||||||
|
// Terminate the number
|
||||||
|
AddInt(charStr.c_str(), startPos);
|
||||||
|
|
||||||
|
// Push the last char back on and try again
|
||||||
|
stream.Unget();
|
||||||
|
state = tsssStart;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssZeroX:
|
||||||
|
if (isHexChar(ch)) {
|
||||||
|
lastChar = ch;
|
||||||
|
state = tsssOneHex;
|
||||||
|
} else
|
||||||
|
throw new Err(std::string("Sniffer pattern error: incomplete hex code"), pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssOneHex:
|
||||||
|
if (isHexChar(ch)) {
|
||||||
|
try {
|
||||||
|
charStr += hexToChar(lastChar, ch);
|
||||||
|
} catch (Err *err) {
|
||||||
|
if (err)
|
||||||
|
err->SetPos(pos);
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
break;
|
state = tsssTwoHex;
|
||||||
|
} else
|
||||||
|
throw new Err(std::string("Sniffer pattern error: bad hex literal"), pos); // Same as R5
|
||||||
|
break;
|
||||||
|
|
||||||
case tsssEscape:
|
case tsssTwoHex:
|
||||||
if (isOctalChar(ch)) {
|
if (isHexChar(ch)) {
|
||||||
lastChar = ch;
|
lastChar = ch;
|
||||||
state = tsssEscapeOneOctal;
|
state = tsssOneHex;
|
||||||
} else if (ch == 'x') {
|
} else {
|
||||||
state = tsssEscapeX;
|
AddString(charStr, startPos);
|
||||||
} else {
|
stream.Unget(); // So punctuation gets handled properly
|
||||||
// Check for a true end-of-text marker
|
state = tsssStart;
|
||||||
if (ch == 0x3 && stream.IsEmpty())
|
}
|
||||||
throw new Err(std::string("Sniffer pattern error: incomplete escape sequence"), pos);
|
break;
|
||||||
else {
|
|
||||||
charStr += escapeChar(ch);
|
case tsssIntOrFloat:
|
||||||
state = escapedState; // Return to the state we were in before the escape
|
if (isDecimalChar(ch))
|
||||||
}
|
charStr += ch;
|
||||||
|
else if (ch == '.') {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssFloat;
|
||||||
|
} else if (ch == 'e' || ch == 'E') {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssLonelyFloatExtension;
|
||||||
|
} else {
|
||||||
|
// Terminate the number
|
||||||
|
AddInt(charStr.c_str(), startPos);
|
||||||
|
|
||||||
|
// Push the last char back on and try again
|
||||||
|
stream.Unget();
|
||||||
|
state = tsssStart;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssFloat:
|
||||||
|
if (isDecimalChar(ch))
|
||||||
|
charStr += ch;
|
||||||
|
else if (ch == 'e' || ch == 'E') {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssLonelyFloatExtension;
|
||||||
|
} else {
|
||||||
|
// Terminate the number
|
||||||
|
AddFloat(charStr.c_str(), startPos);
|
||||||
|
|
||||||
|
// Push the last char back on and try again
|
||||||
|
stream.Unget();
|
||||||
|
state = tsssStart;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssLonelyDecimalPoint:
|
||||||
|
if (isDecimalChar(ch)) {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssFloat;
|
||||||
|
} else
|
||||||
|
throw new Err(std::string("Sniffer pattern error: incomplete floating point number"), pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssLonelyMinusOrPlus:
|
||||||
|
if (isDecimalChar(ch)) {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssIntOrFloat;
|
||||||
|
} else if (ch == '.') {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssLonelyDecimalPoint;
|
||||||
|
} else
|
||||||
|
throw new Err(std::string("Sniffer pattern error: incomplete signed number"), pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssLonelyFloatExtension:
|
||||||
|
if (ch == '+' || ch == '-') {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssLonelyFloatExtensionWithSign;
|
||||||
|
} else if (isDecimalChar(ch)) {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssExtendedFloat;
|
||||||
|
} else
|
||||||
|
throw new Err(std::string("Sniffer pattern error: incomplete extended-notation floating point number"), pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssLonelyFloatExtensionWithSign:
|
||||||
|
if (isDecimalChar(ch)) {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssExtendedFloat;
|
||||||
|
} else
|
||||||
|
throw new Err(std::string("Sniffer pattern error: incomplete extended-notation floating point number"), pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssExtendedFloat:
|
||||||
|
if (isDecimalChar(ch)) {
|
||||||
|
charStr += ch;
|
||||||
|
state = tsssExtendedFloat;
|
||||||
|
} else {
|
||||||
|
// Terminate the number
|
||||||
|
AddFloat(charStr.c_str(), startPos);
|
||||||
|
|
||||||
|
// Push the last char back on and try again
|
||||||
|
stream.Unget();
|
||||||
|
state = tsssStart;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssUnquoted:
|
||||||
|
if (ch == '\\') {
|
||||||
|
escapedState = state; // Save our state
|
||||||
|
state = tsssEscape; // Handle the escape sequence
|
||||||
|
} else if (isWhiteSpace(ch) || isPunctuation(ch)) {
|
||||||
|
AddString(charStr, startPos);
|
||||||
|
stream.Unget(); // In case it's punctuation, let tsssStart handle it
|
||||||
|
state = tsssStart;
|
||||||
|
} else if (ch == '\'' || ch == '"') {
|
||||||
|
throw new Err(std::string("Sniffer pattern error: illegal unquoted character '") + ch + "'", pos);
|
||||||
|
} else if (ch == 0x3 && stream.IsEmpty()) {
|
||||||
|
AddString(charStr, startPos);
|
||||||
|
keepLooping = false;
|
||||||
|
} else {
|
||||||
|
charStr += ch;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tsssEscape:
|
||||||
|
if (isOctalChar(ch)) {
|
||||||
|
lastChar = ch;
|
||||||
|
state = tsssEscapeOneOctal;
|
||||||
|
} else if (ch == 'x') {
|
||||||
|
state = tsssEscapeX;
|
||||||
|
} else {
|
||||||
|
// Check for a true end-of-text marker
|
||||||
|
if (ch == 0x3 && stream.IsEmpty())
|
||||||
|
throw new Err(std::string("Sniffer pattern error: incomplete escape sequence"), pos);
|
||||||
|
else {
|
||||||
|
charStr += escapeChar(ch);
|
||||||
|
state = escapedState; // Return to the state we were in before the escape
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case tsssEscapeX:
|
case tsssEscapeX:
|
||||||
if (isHexChar(ch)) {
|
if (isHexChar(ch)) {
|
||||||
lastChar = ch;
|
lastChar = ch;
|
||||||
state = tsssEscapeOneHex;
|
state = tsssEscapeOneHex;
|
||||||
} else
|
} else
|
||||||
throw new Err(std::string("Sniffer pattern error: incomplete escaped hex code"), pos);
|
throw new Err(std::string("Sniffer pattern error: incomplete escaped hex code"), pos);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tsssEscapeOneOctal:
|
case tsssEscapeOneOctal:
|
||||||
if (isOctalChar(ch)) {
|
if (isOctalChar(ch)) {
|
||||||
lastLastChar = lastChar;
|
lastLastChar = lastChar;
|
||||||
lastChar = ch;
|
lastChar = ch;
|
||||||
state = tsssEscapeTwoOctal;
|
state = tsssEscapeTwoOctal;
|
||||||
} else {
|
} else {
|
||||||
// First handle the octal
|
// First handle the octal
|
||||||
try {
|
try {
|
||||||
charStr += octalToChar(lastChar);
|
charStr += octalToChar(lastChar);
|
||||||
} catch (Err *err) {
|
} catch (Err *err) {
|
||||||
if (err)
|
if (err)
|
||||||
err->SetPos(startPos);
|
err->SetPos(startPos);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
|
||||||
|
|
||||||
// Push the new char back on and let the state we
|
|
||||||
// were in when the escape sequence was hit handle it.
|
|
||||||
stream.Unget();
|
|
||||||
state = escapedState;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssEscapeTwoOctal:
|
// Push the new char back on and let the state we
|
||||||
if (isOctalChar(ch)) {
|
// were in when the escape sequence was hit handle it.
|
||||||
try {
|
stream.Unget();
|
||||||
charStr += octalToChar(lastLastChar, lastChar, ch);
|
state = escapedState;
|
||||||
} catch (Err *err) {
|
}
|
||||||
if (err)
|
break;
|
||||||
err->SetPos(startPos);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
state = escapedState;
|
|
||||||
} else {
|
|
||||||
// First handle the octal
|
|
||||||
try {
|
|
||||||
charStr += octalToChar(lastLastChar, lastChar);
|
|
||||||
} catch (Err *err) {
|
|
||||||
if (err)
|
|
||||||
err->SetPos(startPos);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push the new char back on and let the state we
|
case tsssEscapeTwoOctal:
|
||||||
// were in when the escape sequence was hit handle it.
|
if (isOctalChar(ch)) {
|
||||||
stream.Unget();
|
try {
|
||||||
state = escapedState;
|
charStr += octalToChar(lastLastChar, lastChar, ch);
|
||||||
|
} catch (Err *err) {
|
||||||
|
if (err)
|
||||||
|
err->SetPos(startPos);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
state = escapedState;
|
||||||
|
} else {
|
||||||
|
// First handle the octal
|
||||||
|
try {
|
||||||
|
charStr += octalToChar(lastLastChar, lastChar);
|
||||||
|
} catch (Err *err) {
|
||||||
|
if (err)
|
||||||
|
err->SetPos(startPos);
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case tsssEscapeOneHex:
|
// Push the new char back on and let the state we
|
||||||
if (isHexChar(ch)) {
|
// were in when the escape sequence was hit handle it.
|
||||||
try {
|
stream.Unget();
|
||||||
charStr += hexToChar(lastChar, ch);
|
state = escapedState;
|
||||||
} catch (Err *err) {
|
}
|
||||||
if (err)
|
break;
|
||||||
err->SetPos(pos);
|
|
||||||
throw err;
|
case tsssEscapeOneHex:
|
||||||
}
|
if (isHexChar(ch)) {
|
||||||
state = escapedState;
|
try {
|
||||||
} else
|
charStr += hexToChar(lastChar, ch);
|
||||||
throw new Err(std::string("Sniffer pattern error: incomplete escaped hex code"), pos);
|
} catch (Err *err) {
|
||||||
break;
|
if (err)
|
||||||
|
err->SetPos(pos);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
state = escapedState;
|
||||||
|
} else
|
||||||
|
throw new Err(std::string("Sniffer pattern error: incomplete escaped hex code"), pos);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (state == tsssStart) {
|
|
||||||
fCStatus = B_OK;
|
|
||||||
fPos = 0;
|
|
||||||
} else {
|
|
||||||
throw new Err("Sniffer pattern error: unterminated rule", stream.Pos());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (state == tsssStart) {
|
||||||
|
fCStatus = B_OK;
|
||||||
|
fPos = 0;
|
||||||
|
} else {
|
||||||
|
throw new Err("Sniffer pattern error: unterminated rule", stream.Pos());
|
||||||
|
}
|
||||||
|
|
||||||
return fCStatus;
|
return fCStatus;
|
||||||
}
|
}
|
||||||
@@ -828,7 +821,7 @@ TokenStream::AddToken(TokenType type, ssize_t pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TokenStream::AddString(const char *str, ssize_t pos) {
|
TokenStream::AddString(const std::string &str, ssize_t pos) {
|
||||||
Token *token = new StringToken(str, pos);
|
Token *token = new StringToken(str, pos);
|
||||||
fTokenList.push_back(token);
|
fTokenList.push_back(token);
|
||||||
}
|
}
|
||||||
@@ -1274,7 +1267,7 @@ Parser::ParsePattern() {
|
|||||||
// String (i.e. Mask)
|
// String (i.e. Mask)
|
||||||
const Token *t = stream.Get();
|
const Token *t = stream.Get();
|
||||||
if (t->Type() == CharacterString) {
|
if (t->Type() == CharacterString) {
|
||||||
Pattern *result = new(nothrow) Pattern(str.c_str(), t->String());
|
Pattern *result = new(nothrow) Pattern(str, t->String());
|
||||||
if (!result)
|
if (!result)
|
||||||
ThrowOutOfMemError(t->Pos());
|
ThrowOutOfMemError(t->Pos());
|
||||||
if (result->InitCheck() == B_OK) {
|
if (result->InitCheck() == B_OK) {
|
||||||
@@ -1291,7 +1284,7 @@ Parser::ParsePattern() {
|
|||||||
ThrowUnexpectedTokenError(CharacterString, t);
|
ThrowUnexpectedTokenError(CharacterString, t);
|
||||||
} else {
|
} else {
|
||||||
// No mask specified.
|
// No mask specified.
|
||||||
Pattern *result = new(nothrow) Pattern(str.c_str());
|
Pattern *result = new(nothrow) Pattern(str);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (result->InitCheck() == B_OK)
|
if (result->InitCheck() == B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -14,13 +14,25 @@
|
|||||||
|
|
||||||
using namespace Sniffer;
|
using namespace Sniffer;
|
||||||
|
|
||||||
Pattern::Pattern(const char *string, const char *mask = NULL)
|
Pattern::Pattern(const std::string &string, const std::string &mask)
|
||||||
: fCStatus(B_NO_INIT)
|
: fCStatus(B_NO_INIT)
|
||||||
, fErrorMessage(NULL)
|
, fErrorMessage(NULL)
|
||||||
{
|
{
|
||||||
SetTo(string, mask);
|
SetTo(string, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pattern::Pattern(const std::string &string)
|
||||||
|
: fCStatus(B_NO_INIT)
|
||||||
|
, fErrorMessage(NULL)
|
||||||
|
{
|
||||||
|
// Build a mask with all bits turned on of the
|
||||||
|
// appropriate length
|
||||||
|
std::string mask = "";
|
||||||
|
for (int i = 0; i < string.length(); i++)
|
||||||
|
mask += (char)0xFF;
|
||||||
|
SetTo(string, mask);
|
||||||
|
}
|
||||||
|
|
||||||
Pattern::~Pattern() {
|
Pattern::~Pattern() {
|
||||||
delete fErrorMessage;
|
delete fErrorMessage;
|
||||||
}
|
}
|
||||||
@@ -38,29 +50,28 @@ Pattern::GetErr() const {
|
|||||||
return new(nothrow) Err(*fErrorMessage);
|
return new(nothrow) Err(*fErrorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dumpStr(const std::string &string, const char *label = NULL) {
|
||||||
|
if (label)
|
||||||
|
printf("%s: ", label);
|
||||||
|
for (int i = 0; i < string.length(); i++)
|
||||||
|
printf("%x ", string[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Pattern::SetTo(const char *string, const char *mask) {
|
Pattern::SetTo(const std::string &string, const std::string &mask) {
|
||||||
if (string) {
|
fString = string;
|
||||||
fString = string;
|
if (fString.length() == 0) {
|
||||||
if (fString.length() == 0) {
|
SetStatus(B_BAD_VALUE, "Sniffer pattern error: illegal empty pattern");
|
||||||
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 {
|
} else {
|
||||||
SetStatus(B_BAD_VALUE, "Sniffer parser error: NULL string parameter passed to Pattern::SetTo()");
|
fMask = mask;
|
||||||
|
// dumpStr(string, "data");
|
||||||
|
// dumpStr(mask, "mask");
|
||||||
|
if (fString.length() != fMask.length()) {
|
||||||
|
SetStatus(B_BAD_VALUE, "Sniffer pattern error: pattern and mask lengths do not match");
|
||||||
|
} else {
|
||||||
|
SetStatus(B_OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +93,7 @@ Pattern::Sniff(Range range, BPositionIO *data) const {
|
|||||||
if (Sniff(i, size, data))
|
if (Sniff(i, size, data))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assumes the BPositionIO object is in the correct
|
// Assumes the BPositionIO object is in the correct
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ Rule::Sniff(BPositionIO *data) const {
|
|||||||
if (*i)
|
if (*i)
|
||||||
result &= (*i)->Sniff(data);
|
result &= (*i)->Sniff(data);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user