VirtualBox

source: vbox/trunk/src/VBox/Main/Matching.cpp@ 4753

Last change on this file since 4753 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.7 KB
Line 
1/** @file
2 *
3 * Definition of template classes that provide simple API to
4 * do matching between values and value filters constructed from strings.
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "Matching.h"
20
21#include "Logging.h"
22
23#include <stdlib.h>
24#include <errno.h>
25
26#include <iprt/err.h>
27
28namespace matching
29{
30
31// static
32void ParsedIntervalFilter_base::parse (const char *aFilter,
33 ParsedIntervalFilter_base *that)
34{
35 // initially null and valid
36 that->mNull = true;
37 that->mValid = true;
38 that->mErrorPosition = 0;
39
40 if (!aFilter || strncmp (aFilter, "int:", 4) != 0)
41 return;
42
43 that->mNull = false;
44
45 size_t len = strlen (aFilter);
46
47 Mode mode = Single; // what's expected next
48 size_t start = 4, end = 4;
49 size_t err = 0; // less than 4 indicates success
50
51 do
52 {
53 end = strcspn (aFilter + start, ",-");
54 end += start;
55
56 char delim = aFilter [end];
57
58 if (delim == '-')
59 {
60 if (mode == End)
61 {
62 err = end;
63 break;
64 }
65 else
66 mode = Start;
67 }
68
69 // skip spaces around numbers
70 size_t s = start;
71 while (s < end && aFilter [s] == ' ') ++ s;
72 size_t e = end - 1;
73 while (e > s && aFilter [e] == ' ') -- e;
74 ++ e;
75
76 that->parseValue (aFilter, s, e, mode);
77 if (!that->mValid)
78 return;
79
80 if (mode == Start)
81 mode = End;
82 else if (mode == End)
83 mode = Single;
84
85 start = end + 1;
86 }
87 while (start <= len);
88
89 if (err >= 4)
90 {
91 that->mValid = false;
92 that->mErrorPosition = err;
93 }
94}
95
96// static
97size_t ParsedIntervalFilter_base::parseValue (
98 const char *aFilter, size_t aStart, size_t aEnd,
99 bool aIsSigned, const Limits &aLimits,
100 Widest &val)
101{
102 char *endptr = NULL;
103
104 int vrc = 0;
105 if (aIsSigned)
106 vrc = RTStrToInt64Ex(aFilter + aStart, &endptr, 0, &val.ll);
107 else
108 vrc = RTStrToUInt64Ex(aFilter + aStart, &endptr, 0, &val.ull);
109
110 AssertReturn (endptr, 0);
111
112 size_t parsed = endptr - aFilter;
113
114 // return parsed if not able to parse to the end
115 if (parsed != aEnd)
116 return parsed;
117
118 // return aStart if out if range
119 if (vrc == VWRN_NUMBER_TOO_BIG ||
120 (aIsSigned &&
121 (val.ll < aLimits.min.ll ||
122 val.ll > aLimits.max.ll)) ||
123 (!aIsSigned &&
124 (val.ull < aLimits.min.ull ||
125 val.ull > aLimits.max.ull)))
126 return aStart;
127
128 return parsed;
129}
130
131void ParsedBoolFilter::parse (const Bstr &aFilter)
132{
133 mNull = false;
134 mValid = true;
135 mErrorPosition = 0;
136
137 if (aFilter.isEmpty())
138 {
139 mValueAny = true;
140 mValue = false;
141 }
142 else
143 {
144 mValueAny = false;
145 if (aFilter == L"true" || aFilter == L"yes" || aFilter == L"1")
146 mValue = true;
147 else
148 if (aFilter == L"false" || aFilter == L"no" || aFilter == L"0")
149 mValue = false;
150 else
151 mValid = false;
152 }
153}
154
155void ParsedRegexpFilter_base::parse (const Bstr &aFilter)
156{
157 /// @todo (dmik) parse "rx:<regexp>" string
158 // note, that min/max checks must not be done, when the string
159 // begins with "rx:". These limits are for exact matching only!
160
161 // empty or null string means any match (see #isMatch() below),
162 // so we don't apply Min/Max restrictions in this case
163
164 if (!aFilter.isEmpty())
165 {
166 size_t len = aFilter.length();
167
168 if (mMinLen > 0 && len < mMinLen)
169 {
170 mNull = mValid = false;
171 mErrorPosition = len;
172 return;
173 }
174
175 if (mMaxLen > 0 && len > mMaxLen)
176 {
177 mNull = mValid = false;
178 mErrorPosition = mMaxLen;
179 return;
180 }
181 }
182
183 mSimple = aFilter;
184 mNull = false;
185 mValid = true;
186 mErrorPosition = 0;
187}
188
189bool ParsedRegexpFilter_base::isMatch (const Bstr &aValue) const
190{
191 /// @todo (dmik) do regexp matching
192
193 // empty or null mSimple matches any match
194 return
195 mSimple.isEmpty() ||
196 (mIgnoreCase && mSimple.compareIgnoreCase (aValue) == 0) ||
197 (!mIgnoreCase && mSimple.compare (aValue) == 0);
198}
199
200}
201
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette