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 16 using 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 */ 21 Rule::Rule() 22 : fPriority(0.0) 23 , fConjList(NULL) 24 { 25 } 26 27 Rule::~Rule() { 28 Unset(); 29 } 30 31 status_t 32 Rule::InitCheck() const { 33 return fConjList ? B_OK : B_NO_INIT; 34 } 35 36 //! Returns the priority of the rule. 0.0 <= priority <= 1.0. 37 double 38 Rule::Priority() const { 39 return fPriority; 40 } 41 42 //! Sniffs the given data stream. Returns true if the rule matches, false if not. 43 bool 44 Rule::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 */ 61 ssize_t 62 Rule::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 87 void 88 Rule::Unset() { 89 if (fConjList){ 90 delete fConjList; 91 fConjList = NULL; 92 } 93 } 94 95 //! Called by Parser::Parse() after successfully parsing a sniffer rule. 96 void 97 Rule::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