1//---------------------------------------------------------------------- 2// This software is part of the Haiku distribution and is covered 3// by the MIT License. 4//--------------------------------------------------------------------- 5/*! 6 \file Rule.cpp 7 MIME sniffer rule implementation 8*/ 9 10#include <sniffer/Err.h> 11#include <sniffer/DisjList.h> 12#include <sniffer/Rule.h> 13#include <DataIO.h> 14#include <stdio.h> 15 16using namespace BPrivate::Storage::Sniffer; 17 18/*! \brief Creates an unitialized Sniffer::Rule object. To initialize it, you 19 must pass a pointer to the object to Sniffer::parse(). 20*/ 21Rule::Rule() 22 : fPriority(0.0) 23 , fConjList(NULL) 24{ 25} 26 27Rule::~Rule() { 28 Unset(); 29} 30 31status_t 32Rule::InitCheck() const { 33 return fConjList ? B_OK : B_NO_INIT; 34} 35 36//! Returns the priority of the rule. 0.0 <= priority <= 1.0. 37double 38Rule::Priority() const { 39 return fPriority; 40} 41 42//! Sniffs the given data stream. Returns true if the rule matches, false if not. 43bool 44Rule::Sniff(BPositionIO *data) const { 45 if (InitCheck() != B_OK) 46 return false; 47 else { 48 bool result = true; 49 std::vector<DisjList*>::const_iterator i; 50 for (i = fConjList->begin(); i != fConjList->end(); i++) { 51 if (*i) 52 result &= (*i)->Sniff(data); 53 } 54 return result; 55 } 56} 57 58/*! \brief Returns the number of bytes needed for this rule to perform a complete sniff, 59 or an error code if something goes wrong. 60*/ 61ssize_t 62Rule::BytesNeeded() const 63{ 64 ssize_t result = InitCheck(); 65 66 // Tally up the BytesNeeded() values for all the DisjLists and return the largest. 67 if (result == B_OK) { 68 result = 0; // Just to be safe... 69 std::vector<DisjList*>::const_iterator i; 70 for (i = fConjList->begin(); i != fConjList->end(); i++) { 71 if (*i) { 72 ssize_t bytes = (*i)->BytesNeeded(); 73 if (bytes >= 0) { 74 if (bytes > result) 75 result = bytes; 76 } else { 77 result = bytes; 78 break; 79 } 80 } 81 } 82 } 83 return result; 84} 85 86 87void 88Rule::Unset() { 89 if (fConjList){ 90 delete fConjList; 91 fConjList = NULL; 92 } 93} 94 95//! Called by Parser::Parse() after successfully parsing a sniffer rule. 96void 97Rule::SetTo(double priority, std::vector<DisjList*>* list) { 98 Unset(); 99 if (0.0 <= priority && priority <= 1.0) 100 fPriority = priority; 101 else 102 throw new Err("Sniffer pattern error: invalid priority", -1); 103 fConjList = list; 104} 105 106 107 108 109 110 111