VirtualBox

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

Last change on this file since 16954 was 14772, checked in by vboxsync, 16 years ago

Added vim modelines to aid following coding guidelines, like no tabs,
similar to what is already in the xidl file.

  • 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
199 mSimple.isEmpty() ||
200 (mIgnoreCase && mSimple.compareIgnoreCase (aValue) == 0) ||
201 (!mIgnoreCase && mSimple.compare (aValue) == 0);
202}
203
204} /* namespace matching */
205/* 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