xref: /haiku/src/kits/storage/sniffer/PatternList.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 //----------------------------------------------------------------------
2 //  This software is part of the Haiku distribution and is covered
3 //  by the MIT License.
4 //---------------------------------------------------------------------
5 /*!
6 	\file PatternList.cpp
7 	MIME sniffer pattern list implementation
8 */
9 
10 #include <sniffer/Err.h>
11 #include <sniffer/Pattern.h>
12 #include <sniffer/PatternList.h>
13 #include <DataIO.h>
14 #include <stdio.h>
15 
16 using namespace BPrivate::Storage::Sniffer;
17 
18 PatternList::PatternList(Range range)
19 	: DisjList()
20 	, fRange(range)
21 {
22 }
23 
24 PatternList::~PatternList() {
25 	// Clean up
26 	std::vector<Pattern*>::iterator i;
27 	for (i = fList.begin(); i != fList.end(); i++)
28 		delete *i;
29 }
30 
31 status_t
32 PatternList::InitCheck() const {
33 	return fRange.InitCheck();
34 }
35 
36 Err*
37 PatternList::GetErr() const {
38 	return fRange.GetErr();
39 }
40 
41 /*! \brief Sniffs the given data stream, searching for a match with
42 	any of the list's patterns.
43 */
44 bool
45 PatternList::Sniff(BPositionIO *data) const {
46 	if (InitCheck() != B_OK)
47 		return false;
48 	else {
49 		bool result = false;
50 		std::vector<Pattern*>::const_iterator i;
51 		for (i = fList.begin(); i != fList.end(); i++) {
52 			if (*i)
53 				result |= (*i)->Sniff(fRange, data, fCaseInsensitive);
54 		}
55 		return result;
56 	}
57 }
58 
59 /*! \brief Returns the number of bytes needed to perform a complete sniff, or an error
60 	code if something goes wrong.
61 */
62 ssize_t
63 PatternList::BytesNeeded() const
64 {
65 	ssize_t result = InitCheck();
66 
67 	// Find the number of bytes needed to sniff any of our
68 	// patterns from a single location in a data stream
69 	if (result == B_OK) {
70 		result = 0;	// I realize it already *is* zero if it == B_OK, but just in case that changes...
71 		std::vector<Pattern*>::const_iterator i;
72 		for (i = fList.begin(); i != fList.end(); i++) {
73 			if (*i) {
74 				ssize_t bytes = (*i)->BytesNeeded();
75 				if (bytes >= 0) {
76 					if (bytes > result)
77 						result = bytes;
78 				} else {
79 					result = bytes;
80 					break;
81 				}
82 			}
83 		}
84 	}
85 
86 	// Now add on the number of bytes needed to get to the
87 	// furthest allowed starting point
88 	if (result >= 0)
89 		result += fRange.End();
90 
91 	return result;
92 }
93 
94 void
95 PatternList::Add(Pattern *pattern) {
96 	if (pattern)
97 		fList.push_back(pattern);
98 }
99 
100 
101 
102