xref: /haiku/src/kits/storage/sniffer/Rule.cpp (revision 268f99dd7dc4bd7474a8bd2742d3f1ec1de6752a)
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 */
Rule()21 Rule::Rule()
22 	: fPriority(0.0)
23 	, fConjList(NULL)
24 {
25 }
26 
~Rule()27 Rule::~Rule() {
28 	Unset();
29 }
30 
31 status_t
InitCheck() const32 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
Priority() const38 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
Sniff(BPositionIO * data) const44 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
BytesNeeded() const62 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
Unset()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
SetTo(double priority,std::vector<DisjList * > * list)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