VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/Matching.cpp@ 50403

Last change on this file since 50403 was 48012, checked in by vboxsync, 11 years ago

RT_STR_TUPLE

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