VirtualBox

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

Last change on this file since 73768 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.8 KB
Line 
1/* $Id: Matching.cpp 69500 2017-10-28 15:14:05Z vboxsync $ */
2/** @file
3 *
4 * Definition of template classes that provide simple API to
5 * do matching between values and value filters constructed from strings.
6 */
7
8/*
9 * Copyright (C) 2006-2017 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20#include "Matching.h"
21
22#include "Logging.h"
23
24#include <stdlib.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, RT_STR_TUPLE("int:")) != 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 mSimple.isEmpty()
195 || (mIgnoreCase && mSimple.compare(aValue, Bstr::CaseInsensitive) == 0)
196 || (!mIgnoreCase && mSimple.compare(aValue) == 0);
197}
198
199} /* namespace matching */
200/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use