• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OpenLightingProject / ola / 16900099157

12 Aug 2025 05:43AM UTC coverage: 45.72% (-0.02%) from 45.742%
16900099157

Pull #2016

github

web-flow
Merge c368ef6ae into eaf937e80
Pull Request #2016: Bump actions/checkout from 4 to 5

7586 of 17462 branches covered (43.44%)

22424 of 49046 relevant lines covered (45.72%)

51.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.31
/common/rdm/GroupSizeCalculator.cpp
1
/*
2
 * This library is free software; you can redistribute it and/or
3
 * modify it under the terms of the GNU Lesser General Public
4
 * License as published by the Free Software Foundation; either
5
 * version 2.1 of the License, or (at your option) any later version.
6
 *
7
 * This library is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10
 * Lesser General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU Lesser General Public
13
 * License along with this library; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
 *
16
 * GroupSizeCalculator.cpp
17
 * Copyright (C) 2011 Simon Newton
18
 */
19

20

21
#include <ola/Logging.h>
22
#include <ola/base/Macro.h>
23
#include <ola/messaging/Descriptor.h>
24
#include <vector>
25
#include "common/rdm/GroupSizeCalculator.h"
26

27
namespace ola {
28
namespace rdm {
29

30
using ola::messaging::FieldDescriptor;
31
using ola::messaging::FieldDescriptorGroup;
32
using std::vector;
33

34

35
/**
36
 * Figure out the number of group repetitions required.
37
 *
38
 * This method is *not* re-entrant.
39
 * @param token_count the number of tokens supplied
40
 * @param descriptor the descriptor to use to build the Message
41
 * @param[out] group_repeat_count the number of repeated groups
42
 * @returns the state of the calculator as a calculator_state.
43
 */
44
GroupSizeCalculator::calculator_state GroupSizeCalculator::CalculateGroupSize(
81✔
45
    unsigned int token_count,
46
    const ola::messaging::Descriptor *descriptor,
47
    unsigned int *group_repeat_count) {
48

49
  m_groups.clear();
81✔
50
  m_non_groups.clear();
81✔
51

52
  // split out the fields into singular fields and groups
53
  for (unsigned int i = 0; i < descriptor->FieldCount(); ++i)
298✔
54
    descriptor->GetField(i)->Accept(this);
434✔
55

56
  unsigned int required_tokens = m_non_groups.size();
81✔
57

58
  if (required_tokens > token_count)
81✔
59
    return INSUFFICIENT_TOKENS;
60

61
  // this takes care of the easy case where there are no groups
62
  if (m_groups.empty()) {
76✔
63
    if (required_tokens == token_count) {
57✔
64
      return NO_VARIABLE_GROUPS;
65
    } else {
66
      OLA_WARN << "Got an incorrect number of tokens, expecting "
2✔
67
               << required_tokens << " tokens, got " << token_count;
1✔
68
      return EXTRA_TOKENS;
1✔
69
    }
70
  }
71

72
  // check all groups, looking for multiple non-fixed sized groups
73
  unsigned int variable_group_counter = 0;
74
  unsigned int variable_group_token_count = 0;
75
  const FieldDescriptorGroup *variable_group = NULL;
76
  vector<const FieldDescriptorGroup*>::const_iterator iter = m_groups.begin();
77
  for (; iter != m_groups.end(); ++iter) {
42✔
78
    unsigned int group_size;
25✔
79
    if (!m_simple_calculator.CalculateTokensRequired(*iter, &group_size))
25✔
80
      return NESTED_VARIABLE_GROUPS;
2✔
81

82
    if ((*iter)->FixedSize()) {
24✔
83
      required_tokens += (*iter)->MinBlocks() * group_size;
10✔
84
    } else {
85
      // variable sized group
86
      variable_group_token_count = group_size;
14✔
87
      variable_group = *iter;
14✔
88
      if (++variable_group_counter > 1)
14✔
89
        return MULTIPLE_VARIABLE_GROUPS;
90
    }
91
  }
92

93
  if (required_tokens > token_count)
17✔
94
    return INSUFFICIENT_TOKENS;
95

96
  if (!variable_group_counter) {
14✔
97
    if (required_tokens == token_count) {
2✔
98
      return NO_VARIABLE_GROUPS;
99
    } else {
100
      OLA_WARN << "Got an incorrect number of tokens, expecting "
2✔
101
               << required_tokens << " tokens, got " << token_count;
1✔
102
      return EXTRA_TOKENS;
1✔
103
    }
104
  }
105

106
  // now we have a single variable sized group and a 0 or more tokens remaining
107
  unsigned int remaining_tokens = token_count - required_tokens;
12✔
108
  // some groups limit the number of blocks, check for that here
109
  if (variable_group->MaxBlocks() != FieldDescriptorGroup::UNLIMITED_BLOCKS &&
12✔
110
      variable_group->MaxBlocks() * variable_group_token_count <
11✔
111
          remaining_tokens)
112
    return EXTRA_TOKENS;
113

114
  if (remaining_tokens % variable_group_token_count)
10✔
115
    return MISMATCHED_TOKENS;
116

117
  *group_repeat_count = remaining_tokens / variable_group_token_count;
10✔
118
  return SINGLE_VARIABLE_GROUP;
10✔
119
}
120

121

122
void GroupSizeCalculator::Visit(
13✔
123
    const ola::messaging::BoolFieldDescriptor *descriptor) {
124
  m_non_groups.push_back(descriptor);
13✔
125
}
13✔
126

127

128
void GroupSizeCalculator::Visit(
6✔
129
    const ola::messaging::IPV4FieldDescriptor *descriptor) {
130
  m_non_groups.push_back(descriptor);
6✔
131
}
6✔
132

133

134
void GroupSizeCalculator::Visit(
6✔
135
    const ola::messaging::IPV6FieldDescriptor *descriptor) {
136
  m_non_groups.push_back(descriptor);
6✔
137
}
6✔
138

139

140
void GroupSizeCalculator::Visit(
6✔
141
    const ola::messaging::MACFieldDescriptor *descriptor) {
142
  m_non_groups.push_back(descriptor);
6✔
143
}
6✔
144

145

146
void GroupSizeCalculator::Visit(
5✔
147
    const ola::messaging::UIDFieldDescriptor *descriptor) {
148
  m_non_groups.push_back(descriptor);
5✔
149
}
5✔
150

151

152
void GroupSizeCalculator::Visit(
11✔
153
    const ola::messaging::StringFieldDescriptor *descriptor) {
154
  m_non_groups.push_back(descriptor);
11✔
155
}
11✔
156

157

158
void GroupSizeCalculator::Visit(
65✔
159
    const ola::messaging::UInt8FieldDescriptor *descriptor) {
160
  m_non_groups.push_back(descriptor);
65✔
161
}
65✔
162

163

164
void GroupSizeCalculator::Visit(
20✔
165
    const ola::messaging::UInt16FieldDescriptor *descriptor) {
166
  m_non_groups.push_back(descriptor);
20✔
167
}
20✔
168

169

170
void GroupSizeCalculator::Visit(
17✔
171
    const ola::messaging::UInt32FieldDescriptor *descriptor) {
172
  m_non_groups.push_back(descriptor);
17✔
173
}
17✔
174

175

176
void GroupSizeCalculator::Visit(
7✔
177
    const ola::messaging::UInt64FieldDescriptor *descriptor) {
178
  m_non_groups.push_back(descriptor);
7✔
179
}
7✔
180

181

182
void GroupSizeCalculator::Visit(
10✔
183
    const ola::messaging::Int8FieldDescriptor *descriptor) {
184
  m_non_groups.push_back(descriptor);
10✔
185
}
10✔
186

187

188
void GroupSizeCalculator::Visit(
9✔
189
    const ola::messaging::Int16FieldDescriptor *descriptor) {
190
  m_non_groups.push_back(descriptor);
9✔
191
}
9✔
192

193

194
void GroupSizeCalculator::Visit(
7✔
195
    const ola::messaging::Int32FieldDescriptor *descriptor) {
196
  m_non_groups.push_back(descriptor);
7✔
197
}
7✔
198

199

200
void GroupSizeCalculator::Visit(
7✔
201
    const ola::messaging::Int64FieldDescriptor *descriptor) {
202
  m_non_groups.push_back(descriptor);
7✔
203
}
7✔
204

205

206
void GroupSizeCalculator::Visit(
28✔
207
    const ola::messaging::FieldDescriptorGroup *descriptor) {
208
  m_groups.push_back(descriptor);
28✔
209
}
28✔
210

211

212
void GroupSizeCalculator::PostVisit(
28✔
213
    const ola::messaging::FieldDescriptorGroup *descriptor) {
214
  (void) descriptor;
28✔
215
}
28✔
216

217

218
// StaticGroupTokenCalculator
219
//-----------------------------------------------------------------------------
220

221
/**
222
 * For a group of fields, figure out the number of inputs required to build a
223
 * single instance of the group. This assumes that the group does not contain
224
 * any variable-sized groups but it may contain fixed sized nested groups.
225
 * @param descriptor the group descriptor
226
 * @param token_count the number of inputs required to build a single instance
227
 * of this group.
228
 * @return true if we could calculate the inputs required, false if this group
229
 * was of a variable size.
230
 */
231
bool StaticGroupTokenCalculator::CalculateTokensRequired(
31✔
232
    const class ola::messaging::FieldDescriptorGroup *descriptor,
233
    unsigned int *token_count) {
234
  // reset the stack
235
  while (!m_token_count.empty()) {
31✔
236
    m_token_count.pop();
×
237
  }
238

239
  m_token_count.push(0);
31✔
240
  m_variable_sized_group_encountered = false;
31✔
241

242
  for (unsigned int i = 0; i < descriptor->FieldCount(); ++i) {
113✔
243
    descriptor->GetField(i)->Accept(this);
164✔
244
  }
245

246
  if (m_variable_sized_group_encountered) {
31✔
247
    return false;
248
  }
249

250
  *token_count = m_token_count.top();
29✔
251
  m_token_count.pop();
29✔
252
  return true;
29✔
253
}
254

255
void StaticGroupTokenCalculator::Visit(
30✔
256
    OLA_UNUSED const ola::messaging::BoolFieldDescriptor *descriptor) {
257
  m_token_count.top()++;
30✔
258
}
30✔
259

260

261
void StaticGroupTokenCalculator::Visit(
1✔
262
    OLA_UNUSED const ola::messaging::IPV4FieldDescriptor *descriptor) {
263
  m_token_count.top()++;
1✔
264
}
1✔
265

266

267
void StaticGroupTokenCalculator::Visit(
1✔
268
    OLA_UNUSED const ola::messaging::IPV6FieldDescriptor *descriptor) {
269
  m_token_count.top()++;
1✔
270
}
1✔
271

272

273
void StaticGroupTokenCalculator::Visit(
1✔
274
    OLA_UNUSED const ola::messaging::MACFieldDescriptor *descriptor) {
275
  m_token_count.top()++;
1✔
276
}
1✔
277

278

279
void StaticGroupTokenCalculator::Visit(
1✔
280
    OLA_UNUSED const ola::messaging::UIDFieldDescriptor *descriptor) {
281
  m_token_count.top()++;
1✔
282
}
1✔
283

284

285
void StaticGroupTokenCalculator::Visit(
1✔
286
    OLA_UNUSED const ola::messaging::StringFieldDescriptor *descriptor) {
287
  m_token_count.top()++;
1✔
288
}
1✔
289

290

291
void StaticGroupTokenCalculator::Visit(
20✔
292
    OLA_UNUSED const ola::messaging::UInt8FieldDescriptor *descriptor) {
293
  m_token_count.top()++;
20✔
294
}
20✔
295

296

297
void StaticGroupTokenCalculator::Visit(
10✔
298
    OLA_UNUSED const ola::messaging::UInt16FieldDescriptor *descriptor) {
299
  m_token_count.top()++;
10✔
300
}
10✔
301

302

303
void StaticGroupTokenCalculator::Visit(
2✔
304
    OLA_UNUSED const ola::messaging::UInt32FieldDescriptor *descriptor) {
305
  m_token_count.top()++;
2✔
306
}
2✔
307

308

309
void StaticGroupTokenCalculator::Visit(
1✔
310
    OLA_UNUSED const ola::messaging::UInt64FieldDescriptor *descriptor) {
311
  m_token_count.top()++;
1✔
312
}
1✔
313

314

315
void StaticGroupTokenCalculator::Visit(
1✔
316
    OLA_UNUSED const ola::messaging::Int8FieldDescriptor *descriptor) {
317
  m_token_count.top()++;
1✔
318
}
1✔
319

320

321
void StaticGroupTokenCalculator::Visit(
13✔
322
    OLA_UNUSED const ola::messaging::Int16FieldDescriptor *descriptor) {
323
  m_token_count.top()++;
13✔
324
}
13✔
325

326

327
void StaticGroupTokenCalculator::Visit(
1✔
328
    OLA_UNUSED const ola::messaging::Int32FieldDescriptor *descriptor) {
329
  m_token_count.top()++;
1✔
330
}
1✔
331

332

333
void StaticGroupTokenCalculator::Visit(
1✔
334
    OLA_UNUSED const ola::messaging::Int64FieldDescriptor *descriptor) {
335
  m_token_count.top()++;
1✔
336
}
1✔
337

338

339
void StaticGroupTokenCalculator::Visit(
4✔
340
    const ola::messaging::FieldDescriptorGroup *descriptor) {
341
  m_token_count.push(0);
4✔
342
  if (!descriptor->FixedSize()) {
4✔
343
    m_variable_sized_group_encountered = true;
2✔
344
  }
345
}
4✔
346

347

348
void StaticGroupTokenCalculator::PostVisit(
4✔
349
    const ola::messaging::FieldDescriptorGroup *descriptor) {
350
  unsigned int group_length = m_token_count.top();
4✔
351
  m_token_count.pop();
4✔
352
  m_token_count.top() += group_length * descriptor->MinBlocks();
4✔
353
}
4✔
354
}  // namespace rdm
355
}  // namespace ola
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc