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 : GNMRule::~GNMRule() = default;
47 :
48 16 : bool GNMRule::IsValid() const
49 : {
50 16 : return m_bValid;
51 : }
52 :
53 68 : bool GNMRule::IsAcceptAny() const
54 : {
55 68 : return m_bAny;
56 : }
57 :
58 0 : GNMRuleType GNMRule::GetType() const
59 : {
60 0 : return GRTConnection;
61 : }
62 :
63 66 : bool GNMRule::CanConnect(const CPLString &soSrcLayerName,
64 : const CPLString &soTgtLayerName,
65 : const CPLString &soConnLayerName)
66 : {
67 66 : if (IsAcceptAny())
68 66 : return m_bAllow;
69 :
70 0 : if (m_soSrcLayerName == soSrcLayerName &&
71 0 : m_soTgtLayerName == soTgtLayerName)
72 : {
73 0 : if (soConnLayerName.empty())
74 0 : return m_bAllow;
75 : else
76 0 : return m_bAllow && m_soConnLayerName == soConnLayerName;
77 : }
78 :
79 0 : return false;
80 : }
81 :
82 4 : CPLString GNMRule::GetSourceLayerName() const
83 : {
84 4 : return m_soSrcLayerName;
85 : }
86 :
87 4 : CPLString GNMRule::GetTargetLayerName() const
88 : {
89 4 : return m_soTgtLayerName;
90 : }
91 :
92 4 : CPLString GNMRule::GetConnectorLayerName() const
93 : {
94 4 : return m_soConnLayerName;
95 : }
96 :
97 3 : const char *GNMRule::c_str() const
98 : {
99 3 : return m_soRuleString.c_str();
100 : }
101 :
102 3 : GNMRule::operator const char *() const
103 : {
104 3 : return c_str();
105 : }
106 :
107 16 : bool GNMRule::ParseRuleString()
108 : {
109 : CPLStringList aTokens(
110 : CSLTokenizeString2(m_soRuleString.c_str(), " ",
111 32 : CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES));
112 :
113 : // the minimum rule consist 3 tokens
114 16 : int nTokenCount = aTokens.Count();
115 16 : if (nTokenCount < 3)
116 : {
117 0 : CPLError(CE_Failure, CPLE_IllegalArg,
118 : "Need more than %d tokens. Failed to parse rule: %s",
119 : nTokenCount, m_soRuleString.c_str());
120 0 : return false;
121 : }
122 :
123 16 : if (EQUAL(aTokens[0], GNM_RULEKW_ALLOW))
124 16 : m_bAllow = true;
125 0 : else if (EQUAL(aTokens[0], GNM_RULEKW_DENY))
126 0 : m_bAllow = false;
127 : else
128 : {
129 0 : CPLError(CE_Failure, CPLE_IllegalArg,
130 : "First token is invalid. Failed to parse rule: %s",
131 : m_soRuleString.c_str());
132 0 : return false;
133 : }
134 :
135 : // now just test if the value == connects
136 : // in future should set rule type
137 :
138 16 : if (!EQUAL(aTokens[1], GNM_RULEKW_CONNECTS))
139 : {
140 0 : CPLError(CE_Failure, CPLE_IllegalArg,
141 : "Not a CONNECTS rule. Failed to parse rule: %s",
142 : m_soRuleString.c_str());
143 0 : return false;
144 : }
145 :
146 16 : if (EQUAL(aTokens[2], GNM_RULEKW_ANY))
147 : {
148 16 : m_bAny = true;
149 16 : return true;
150 : }
151 : else
152 : {
153 0 : if (nTokenCount < 5)
154 : {
155 0 : CPLError(CE_Failure, CPLE_IllegalArg,
156 : "Not an ANY rule, but have only %d tokens. Failed to "
157 : "parse rule: %s",
158 : nTokenCount, m_soRuleString.c_str());
159 0 : return false;
160 : }
161 0 : m_soSrcLayerName = aTokens[2];
162 0 : m_soTgtLayerName = aTokens[4];
163 : }
164 :
165 0 : if (nTokenCount < 7) // skip 5 and 6 parameters
166 0 : return true;
167 : else
168 0 : m_soConnLayerName = aTokens[6];
169 :
170 0 : return true;
171 : }
172 :
173 : /*! @endcond */
|