VirtualBox

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

Last change on this file since 27166 was 26753, checked in by vboxsync, 15 years ago

Main: Bstr makeover (third attempt) -- make Bstr(NULL) and Bstr() behave the same; resulting cleanup; make some more internal methods use Utf8Str instead of Bstr; fix a lot of CheckComArgNotNull??() usage

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