Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL/OGR Geography Network support (Geographic Network Model)
4 : * Purpose: GNM rule class.
5 : * Authors: Mikhail Gusev (gusevmihs at gmail dot com)
6 : * Dmitry Baryshnikov, polimax@mail.ru
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2014, Mikhail Gusev
10 : * Copyright (c) 2014-2015, NextGIS <info@nextgis.com>
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 : #include "gnm.h"
31 : #include "gnm_priv.h"
32 :
33 : /*! @cond Doxygen_Suppress */
34 : GNMRule::GNMRule() = default;
35 :
36 0 : GNMRule::GNMRule(const std::string &oRule) : m_soRuleString(oRule)
37 : {
38 0 : m_bValid = GNMRule::ParseRuleString();
39 0 : }
40 :
41 16 : GNMRule::GNMRule(const char *pszRule) : m_soRuleString(pszRule)
42 : {
43 16 : m_bValid = GNMRule::ParseRuleString();
44 16 : }
45 :
46 16 : GNMRule::GNMRule(const GNMRule &oRule)
47 16 : : m_soSrcLayerName(oRule.m_soSrcLayerName),
48 16 : m_soTgtLayerName(oRule.m_soTgtLayerName),
49 32 : m_soConnLayerName(oRule.m_soConnLayerName), m_bAllow(oRule.m_bAllow),
50 16 : m_bValid(oRule.m_bValid), m_bAny(oRule.m_bAny),
51 16 : m_soRuleString(oRule.m_soRuleString)
52 : {
53 16 : }
54 :
55 46 : GNMRule::~GNMRule()
56 : {
57 46 : }
58 :
59 16 : bool GNMRule::IsValid() const
60 : {
61 16 : return m_bValid;
62 : }
63 :
64 68 : bool GNMRule::IsAcceptAny() const
65 : {
66 68 : return m_bAny;
67 : }
68 :
69 0 : GNMRuleType GNMRule::GetType() const
70 : {
71 0 : return GRTConnection;
72 : }
73 :
74 66 : bool GNMRule::CanConnect(const CPLString &soSrcLayerName,
75 : const CPLString &soTgtLayerName,
76 : const CPLString &soConnLayerName)
77 : {
78 66 : if (IsAcceptAny())
79 66 : return m_bAllow;
80 :
81 0 : if (m_soSrcLayerName == soSrcLayerName &&
82 0 : m_soTgtLayerName == soTgtLayerName)
83 : {
84 0 : if (soConnLayerName.empty())
85 0 : return m_bAllow;
86 : else
87 0 : return m_bAllow && m_soConnLayerName == soConnLayerName;
88 : }
89 :
90 0 : return false;
91 : }
92 :
93 4 : CPLString GNMRule::GetSourceLayerName() const
94 : {
95 4 : return m_soSrcLayerName;
96 : }
97 :
98 4 : CPLString GNMRule::GetTargetLayerName() const
99 : {
100 4 : return m_soTgtLayerName;
101 : }
102 :
103 4 : CPLString GNMRule::GetConnectorLayerName() const
104 : {
105 4 : return m_soConnLayerName;
106 : }
107 :
108 3 : const char *GNMRule::c_str() const
109 : {
110 3 : return m_soRuleString.c_str();
111 : }
112 :
113 3 : GNMRule::operator const char *() const
114 : {
115 3 : return c_str();
116 : }
117 :
118 16 : bool GNMRule::ParseRuleString()
119 : {
120 : CPLStringList aTokens(
121 : CSLTokenizeString2(m_soRuleString.c_str(), " ",
122 32 : CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES));
123 :
124 : // the minimum rule consist 3 tokens
125 16 : int nTokenCount = aTokens.Count();
126 16 : if (nTokenCount < 3)
127 : {
128 0 : CPLError(CE_Failure, CPLE_IllegalArg,
129 : "Need more than %d tokens. Failed to parse rule: %s",
130 : nTokenCount, m_soRuleString.c_str());
131 0 : return false;
132 : }
133 :
134 16 : if (EQUAL(aTokens[0], GNM_RULEKW_ALLOW))
135 16 : m_bAllow = true;
136 0 : else if (EQUAL(aTokens[0], GNM_RULEKW_DENY))
137 0 : m_bAllow = false;
138 : else
139 : {
140 0 : CPLError(CE_Failure, CPLE_IllegalArg,
141 : "First token is invalid. Failed to parse rule: %s",
142 : m_soRuleString.c_str());
143 0 : return false;
144 : }
145 :
146 : // now just test if the value == connects
147 : // in future should set rule type
148 :
149 16 : if (!EQUAL(aTokens[1], GNM_RULEKW_CONNECTS))
150 : {
151 0 : CPLError(CE_Failure, CPLE_IllegalArg,
152 : "Not a CONNECTS rule. Failed to parse rule: %s",
153 : m_soRuleString.c_str());
154 0 : return false;
155 : }
156 :
157 16 : if (EQUAL(aTokens[2], GNM_RULEKW_ANY))
158 : {
159 16 : m_bAny = true;
160 16 : return true;
161 : }
162 : else
163 : {
164 0 : if (nTokenCount < 5)
165 : {
166 0 : CPLError(CE_Failure, CPLE_IllegalArg,
167 : "Not an ANY rule, but have only %d tokens. Failed to "
168 : "parse rule: %s",
169 : nTokenCount, m_soRuleString.c_str());
170 0 : return false;
171 : }
172 0 : m_soSrcLayerName = aTokens[2];
173 0 : m_soTgtLayerName = aTokens[4];
174 : }
175 :
176 0 : if (nTokenCount < 7) // skip 5 and 6 parameters
177 0 : return true;
178 : else
179 0 : m_soConnLayerName = aTokens[6];
180 :
181 0 : return true;
182 : }
183 :
184 : /*! @endcond */
|