Coverage Report

Created: 2025-06-09 07:38

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