Coverage Report

Created: 2025-11-11 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opendnp3/cpp/lib/src/app/parsing/CountParser.cpp
Line
Count
Source
1
/*
2
 * Copyright 2013-2022 Step Function I/O, LLC
3
 *
4
 * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O
5
 * LLC (https://stepfunc.io) under one or more contributor license agreements.
6
 * See the NOTICE file distributed with this work for additional information
7
 * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license
8
 * this file to you under the Apache License, Version 2.0 (the "License"); you
9
 * may not use this file except in compliance with the License. You may obtain
10
 * a copy of the License at:
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
#include "CountParser.h"
21
22
#include "logging/LogMacros.h"
23
24
#include "opendnp3/logging/LogLevels.h"
25
26
namespace opendnp3
27
{
28
29
CountParser::CountParser(uint16_t count, size_t required_size, HandleFun handler)
30
14.7k
    : count(count), required_size(required_size), handler(handler)
31
14.7k
{
32
14.7k
}
33
34
ParseResult CountParser::Process(const HeaderRecord& record,
35
                                 ser4cpp::rseq_t& buffer,
36
                                 IAPDUHandler* pHandler,
37
                                 Logger* pLogger) const
38
14.7k
{
39
14.7k
    if (buffer.length() < required_size)
40
1.29k
    {
41
1.29k
        SIMPLE_LOGGER_BLOCK(pLogger, flags::WARN, "Not enough data for specified objects");
42
1.29k
        return ParseResult::NOT_ENOUGH_DATA_FOR_OBJECTS;
43
1.29k
    }
44
45
13.4k
    if (pHandler)
46
6.95k
    {
47
6.95k
        handler(record, count, buffer, *pHandler);
48
6.95k
    }
49
13.4k
    buffer.advance(required_size);
50
13.4k
    return ParseResult::OK;
51
14.7k
}
52
53
ParseResult CountParser::ParseHeader(ser4cpp::rseq_t& buffer,
54
                                     const NumParser& numParser,
55
                                     const ParserSettings& settings,
56
                                     const HeaderRecord& record,
57
                                     Logger* pLogger,
58
                                     IAPDUHandler* pHandler)
59
19.0k
{
60
19.0k
    uint16_t count;
61
19.0k
    auto result = numParser.ParseCount(buffer, count, pLogger);
62
19.0k
    if (result == ParseResult::OK)
63
18.5k
    {
64
18.5k
        FORMAT_LOGGER_BLOCK(pLogger, settings.LoggingLevel(), "%03u,%03u %s, %s [%u]", record.group, record.variation,
65
18.5k
                            GroupVariationSpec::to_human_string(record.enumeration),
66
18.5k
                            QualifierCodeSpec::to_human_string(record.GetQualifierCode()), count);
67
68
18.5k
        if (settings.ExpectsContents())
69
14.9k
        {
70
14.9k
            return ParseCountOfObjects(buffer, record, count, pLogger, pHandler);
71
14.9k
        }
72
73
3.61k
        if (pHandler)
74
2.20k
        {
75
2.20k
            pHandler->OnHeader(CountHeader(record, count));
76
2.20k
        }
77
78
3.61k
        return ParseResult::OK;
79
18.5k
    }
80
450
    else
81
450
    {
82
450
        return result;
83
450
    }
84
19.0k
}
85
86
ParseResult CountParser::ParseCountOfObjects(
87
    ser4cpp::rseq_t& buffer, const HeaderRecord& record, uint16_t count, Logger* pLogger, IAPDUHandler* pHandler)
88
14.9k
{
89
14.9k
    switch (record.enumeration)
90
14.9k
    {
91
3.34k
    case (GroupVariation::Group50Var1):
92
3.34k
        return CountParser::From<Group50Var1>(count).Process(record, buffer, pHandler, pLogger);
93
94
2.55k
    case (GroupVariation::Group50Var3):
95
2.55k
        return CountParser::From<Group50Var3>(count).Process(record, buffer, pHandler, pLogger);
96
97
2.89k
    case (GroupVariation::Group51Var1):
98
2.89k
        return CountParser::From<Group51Var1>(count).Process(record, buffer, pHandler, pLogger);
99
100
2.42k
    case (GroupVariation::Group51Var2):
101
2.42k
        return CountParser::From<Group51Var2>(count).Process(record, buffer, pHandler, pLogger);
102
103
1.69k
    case (GroupVariation::Group52Var1):
104
1.69k
        return CountParser::From<Group52Var1>(count).Process(record, buffer, pHandler, pLogger);
105
106
1.78k
    case (GroupVariation::Group52Var2):
107
1.78k
        return CountParser::From<Group52Var2>(count).Process(record, buffer, pHandler, pLogger);
108
109
272
    default:
110
272
        FORMAT_LOGGER_BLOCK(pLogger, flags::WARN, "Unsupported qualifier/object - %s - %i / %i",
111
272
                            QualifierCodeSpec::to_human_string(record.GetQualifierCode()), record.group,
112
272
                            record.variation);
113
114
272
        return ParseResult::INVALID_OBJECT_QUALIFIER;
115
14.9k
    }
116
14.9k
}
117
118
} // namespace opendnp3