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

OpenLightingProject / ola / 20179851591

12 Dec 2025 09:05PM UTC coverage: 45.048% (-0.7%) from 45.72%
20179851591

Pull #2027

github

web-flow
Bump actions/upload-artifact from 4 to 6

Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #2027: Bump actions/upload-artifact from 4 to 6

8554 of 19812 branches covered (43.18%)

22094 of 49046 relevant lines covered (45.05%)

50.63 hits per line

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

82.21
/common/rdm/PidStoreLoader.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
 * PidStoreLoader.cpp
17
 * The PidStoreLoader and helper code.
18
 * Copyright (C) 2011 Simon Newton
19
 */
20

21
#include <errno.h>
22
#include <google/protobuf/io/zero_copy_stream_impl.h>
23
#include <google/protobuf/text_format.h>
24
#include <fstream>
25
#include <set>
26
#include <sstream>
27
#include <string>
28
#include <vector>
29
#include "common/rdm/DescriptorConsistencyChecker.h"
30
#include "common/rdm/PidStoreLoader.h"
31
#include "common/rdm/Pids.pb.h"
32
#include "ola/Logging.h"
33
#include "ola/StringUtils.h"
34
#include "ola/file/Util.h"
35
#include "ola/rdm/PidStore.h"
36
#include "ola/rdm/RDMEnums.h"
37
#include "ola/stl/STLUtils.h"
38
#include "ola/strings/Format.h"
39

40
namespace ola {
41
namespace rdm {
42

43
using ola::messaging::Descriptor;
44
using ola::messaging::FieldDescriptor;
45
using std::auto_ptr;
46
using std::map;
47
using std::ostringstream;
48
using std::set;
49
using std::string;
50
using std::vector;
51

52
const char PidStoreLoader::OVERRIDE_FILE_NAME[] = "overrides.proto";
53
const char PidStoreLoader::MANUFACTURER_NAMES_FILE_NAME[] =
54
    "manufacturer_names.proto";
55
const uint16_t PidStoreLoader::ESTA_MANUFACTURER_ID = 0;
56
const uint16_t PidStoreLoader::MANUFACTURER_PID_MIN = 0x8000;
57
const uint16_t PidStoreLoader::MANUFACTURER_PID_MAX = 0xffe0;
58

59
const RootPidStore *PidStoreLoader::LoadFromFile(const string &file,
11✔
60
                                                 bool validate) {
61
  std::ifstream proto_file(file.data());
11✔
62

63
  if (!proto_file.is_open()) {
11✔
64
    OLA_WARN << "Missing " << file << ": " << strerror(errno);
1✔
65
    return NULL;
1✔
66
  }
67

68
  const RootPidStore *store = LoadFromStream(&proto_file, validate);
10✔
69
  proto_file.close();
10✔
70
  return store;
71
}
11✔
72

73
const RootPidStore *PidStoreLoader::LoadFromDirectory(
3✔
74
    const string &directory,
75
    bool validate) {
76
  vector<string> files;
3✔
77

78
  string override_file;
3✔
79
  string manufacturer_names_file;
3✔
80
  vector<string> all_files;
3✔
81
  if (!ola::file::ListDirectory(directory, &all_files)) {
3✔
82
    OLA_WARN << "Failed to list files in " << directory;
1✔
83
    return NULL;
1✔
84
  }
85
  if (all_files.empty()) {
2✔
86
    OLA_WARN << "Didn't find any files in " << directory;
×
87
    return NULL;
×
88
  }
89
  vector<string>::const_iterator file_iter = all_files.begin();
90
  for (; file_iter != all_files.end(); ++file_iter) {
25✔
91
    if (ola::file::FilenameFromPath(*file_iter) == OVERRIDE_FILE_NAME) {
23✔
92
      override_file = *file_iter;
1✔
93
    } else if (ola::file::FilenameFromPath(*file_iter) ==
22✔
94
               MANUFACTURER_NAMES_FILE_NAME) {
95
      manufacturer_names_file = *file_iter;
25✔
96
    } else if (StringEndsWith(*file_iter, ".proto")) {
20✔
97
      files.push_back(*file_iter);
5✔
98
    }
99
  }
100
  if (files.empty() && override_file.empty()) {
2✔
101
    OLA_WARN << "Didn't find any files to load in " << directory;
×
102
    return NULL;
×
103
  }
104

105
  ola::rdm::pid::PidStore pid_store_pb;
2✔
106
  vector<string>::const_iterator iter = files.begin();
107
  for (; iter != files.end(); ++iter) {
7✔
108
    std::ifstream proto_file(iter->data());
5✔
109
    if (!proto_file.is_open()) {
5✔
110
      OLA_WARN << "Failed to open " << *iter << ": " << strerror(errno);
×
111
      return NULL;
×
112
    }
113

114
    google::protobuf::io::IstreamInputStream input_stream(&proto_file);
5✔
115
    bool ok = google::protobuf::TextFormat::Merge(&input_stream,
5✔
116
                                                  &pid_store_pb);
117
    proto_file.close();
5✔
118

119
    if (!ok) {
5✔
120
      OLA_WARN << "Failed to load " << *iter;
×
121
      return NULL;
×
122
    }
123
  }
5✔
124

125
  ola::rdm::pid::PidStore override_pb;
2✔
126
  if (!override_file.empty()) {
2✔
127
    if (!ReadFile(override_file, &override_pb)) {
1✔
128
      return NULL;
129
    }
130
  }
131

132
  ola::rdm::pid::PidStore manufacturer_names_pb;
2✔
133
  if (!manufacturer_names_file.empty()) {
2✔
134
    if (!ReadFile(manufacturer_names_file, &manufacturer_names_pb)) {
2✔
135
      return NULL;
136
    }
137
  }
138

139
  return BuildStore(pid_store_pb, override_pb, manufacturer_names_pb, validate);
2✔
140
}
3✔
141

142
const RootPidStore *PidStoreLoader::LoadFromStream(std::istream *data,
12✔
143
                                                   bool validate) {
144
  ola::rdm::pid::PidStore pid_store_pb;
12✔
145
  google::protobuf::io::IstreamInputStream input_stream(data);
12✔
146
  bool ok = google::protobuf::TextFormat::Parse(&input_stream, &pid_store_pb);
12✔
147

148
  if (!ok)
12✔
149
    return NULL;
150

151
  ola::rdm::pid::PidStore override_pb;
11✔
152
  return BuildStore(pid_store_pb, override_pb, validate);
11✔
153
}
12✔
154

155
bool PidStoreLoader::ReadFile(const std::string &file_path,
3✔
156
                              ola::rdm::pid::PidStore *proto) {
157
  std::ifstream proto_file(file_path.c_str());
3✔
158
  if (!proto_file.is_open()) {
3✔
159
    OLA_WARN << "Failed to open " << file_path << ": " << strerror(errno);
×
160
    return false;
×
161
  }
162

163
  google::protobuf::io::IstreamInputStream input_stream(&proto_file);
3✔
164
  bool ok = google::protobuf::TextFormat::Merge(&input_stream, proto);
3✔
165
  proto_file.close();
3✔
166

167
  if (!ok) {
3✔
168
    OLA_WARN << "Failed to load " << file_path;
×
169
  }
170
  return ok;
3✔
171
}
3✔
172

173
/*
174
 * Build the RootPidStore from a protocol buffer.
175
 */
176
const RootPidStore *PidStoreLoader::BuildStore(
13✔
177
    const ola::rdm::pid::PidStore &store_pb,
178
    const ola::rdm::pid::PidStore &override_pb,
179
    const ola::rdm::pid::PidStore &manufacturer_names_pb,
180
    bool validate) {
181
  ManufacturerMap pid_data;
13✔
182
  // Load the overrides first so they get first dibs on each PID.
183
  if (!LoadFromProto(&pid_data, override_pb, validate)) {
13✔
184
    FreeManufacturerMap(&pid_data);
×
185
    return NULL;
×
186
  }
187

188
  // Load the main data
189
  if (!LoadFromProto(&pid_data, store_pb, validate)) {
13✔
190
    FreeManufacturerMap(&pid_data);
5✔
191
    return NULL;
×
192
  }
193

194
  // Now we need to convert the data structure into a format that the PidStore
195
  // understands.
196
  auto_ptr<const PidStore> esta_store;
8✔
197
  RootPidStore::ManufacturerMap manufacturer_map;
16✔
198

199
  ManufacturerMap::iterator iter = pid_data.begin();
8✔
200
  for (; iter != pid_data.end(); ++iter) {
70✔
201
    // Ownership of the Descriptors is transferred to the vector
202
    vector<const PidDescriptor*> pids;
62✔
203
    STLValues(*iter->second, &pids);
62✔
204
    delete iter->second;
124✔
205

206
    if (iter->first == ESTA_MANUFACTURER_ID) {
62✔
207
      esta_store.reset(new PidStore(pids));
8✔
208
    } else {
209
      STLReplaceAndDelete(&manufacturer_map, iter->first,
54✔
210
                          new PidStore(pids));
54✔
211
    }
212
  }
62✔
213
  pid_data.clear();
8✔
214

215
  // Load the manufacturer names last so they update the names on the PIDs.
216
  if (!LoadFromProto(&pid_data, manufacturer_names_pb, validate)) {
8✔
217
    FreeManufacturerMap(&pid_data);
×
218
    return NULL;
×
219
  }
220

221
  OLA_DEBUG << "Load Complete";
8✔
222
  return new RootPidStore(esta_store.release(),
8✔
223
                          manufacturer_map,
224
                          store_pb.version());
8✔
225
}
21✔
226

227
/*
228
 * @brief Load the data from the PidStore proto into the ManufacturerMap.
229
 * @param[out] pid_data the ManufacturerMap to populate.
230
 * @param proto the Protobuf data.
231
 * @param validate Enables strict validation mode.
232
 *
233
 * If a collision occurs, the data in the map is not replaced.
234
 */
235
bool PidStoreLoader::LoadFromProto(ManufacturerMap *pid_data,
34✔
236
                                   const ola::rdm::pid::PidStore &proto,
237
                                   bool validate) {
238
  set<uint16_t> seen_manufacturer_ids;
34✔
239

240
  ManufacturerMap::iterator iter = STLLookupOrInsertNew(
34✔
241
      pid_data, ESTA_MANUFACTURER_ID);
242
  if (!GetPidList(iter->second, proto, validate, true)) {
34✔
243
    return false;
244
  }
245

246
  for (int i = 0; i < proto.manufacturer_size(); ++i) {
1,670✔
247
    const ola::rdm::pid::Manufacturer &manufacturer = proto.manufacturer(i);
1,641✔
248

249
    if (STLContains(seen_manufacturer_ids, manufacturer.manufacturer_id())) {
1,641✔
250
      OLA_WARN << "Manufacturer id " << manufacturer.manufacturer_id() <<
2✔
251
          "(" << manufacturer.manufacturer_name() <<
1✔
252
          ") listed more than once in the PIDs file";
1✔
253
      return false;
1✔
254
    }
255
    seen_manufacturer_ids.insert(manufacturer.manufacturer_id());
1,640✔
256

257
    ManufacturerMap::iterator iter = STLLookupOrInsertNew(
1,640✔
258
        pid_data, manufacturer.manufacturer_id());
1,640✔
259
    if (!GetPidList(iter->second, manufacturer, validate, false)) {
1,640✔
260
      return false;
261
    }
262
  }
263

264
  return true;
265
}
34✔
266

267
/*
268
 * @brief Populate a PidMap from a protobuf object that has a set of repeated
269
 * PIDs.
270
 */
271
template <typename pb_object>
272
bool PidStoreLoader::GetPidList(PidMap *pid_map,
34✔
273
                                const pb_object &store,
274
                                bool validate,
275
                                bool limit_pid_values) {
276
  set<uint16_t> seen_pids;
34✔
277
  set<string> seen_names;
34✔
278

279
  for (int i = 0; i < store.pid_size(); ++i) {
522✔
280
    const ola::rdm::pid::Pid &pid = store.pid(i);
492✔
281

282
    OLA_DEBUG << "Loading " << pid.name();
492✔
283
    if (validate) {
492✔
284
      if (STLContains(seen_pids, pid.value())) {
492✔
285
        OLA_WARN << "PID " << pid.value()
2!
286
                 << " exists multiple times in the pid file";
1!
287
        return false;
35✔
288
      }
289
      seen_pids.insert(pid.value());
491✔
290

291
      if (STLContains(seen_names, pid.name())) {
491✔
292
        OLA_WARN << "PID " << pid.name()
2!
293
                 << " exists multiple times in the pid file";
1!
294
        return false;
1✔
295
      }
296
      seen_names.insert(pid.name());
490✔
297

298
      if (limit_pid_values && pid.value() > MANUFACTURER_PID_MIN &&
490✔
299
          pid.value() < MANUFACTURER_PID_MAX) {
1!
300
        OLA_WARN << "ESTA PID " << pid.name() << " (" << pid.value() << ")"
2!
301
                 << " is outside acceptable range";
1!
302
        return false;
1✔
303
      }
304
    }
305

306
    PidMap::iterator iter = STLLookupOrInsertNull(pid_map, pid.value());
489✔
307
    if (iter->second) {
489✔
308
      OLA_INFO << "Using " << OVERRIDE_FILE_NAME << " for " << pid.name()
×
309
               << "( " << strings::ToHex(pid.value()) << ")";
×
310
      continue;
×
311
    }
312

313
    const PidDescriptor *descriptor = PidToDescriptor(pid, validate);
489✔
314
    if (!descriptor) {
489✔
315
      return false;
316
    }
317
    iter->second = descriptor;
488✔
318
  }
319
  return true;
320
}
34✔
321

322
/*
323
 * Build a PidDescriptor from a Pid protobuf object
324
 */
325
PidDescriptor *PidStoreLoader::PidToDescriptor(const ola::rdm::pid::Pid &pid,
871✔
326
                                               bool validate) {
327
  // populate sub device validators
328
  PidDescriptor::sub_device_validator get_validator =
871✔
329
    PidDescriptor::ANY_SUB_DEVICE;
330
  if (pid.has_get_sub_device_range())
871✔
331
    get_validator = ConvertSubDeviceValidator(pid.get_sub_device_range());
803✔
332
  PidDescriptor::sub_device_validator set_validator =
871✔
333
    PidDescriptor::ANY_SUB_DEVICE;
334
  if (pid.has_set_sub_device_range())
871✔
335
    set_validator = ConvertSubDeviceValidator(pid.set_sub_device_range());
641✔
336

337
  // yuck, code smell. This should use protobuf reflections instead.
338
  const Descriptor *get_request = NULL;
871✔
339
  if (pid.has_get_request()) {
871✔
340
    get_request = FrameFormatToDescriptor(pid.get_request(), validate);
804✔
341
    if (!get_request)
804✔
342
      return NULL;
343
  }
344

345
  const Descriptor *get_response = NULL;
871✔
346
  if (pid.has_get_response()) {
871✔
347
    get_response = FrameFormatToDescriptor(pid.get_response(), validate);
804✔
348
    if (!get_response) {
804✔
349
      delete get_request;
1✔
350
      return NULL;
1✔
351
    }
352
  }
353

354
  const Descriptor *set_request = NULL;
870✔
355
  if (pid.has_set_request()) {
870✔
356
    set_request = FrameFormatToDescriptor(pid.set_request(), validate);
640✔
357
    if (!set_request) {
640✔
358
      delete get_request;
×
359
      delete get_response;
×
360
      return NULL;
×
361
    }
362
  }
363

364
  const Descriptor *set_response = NULL;
870✔
365
  if (pid.has_set_response()) {
870✔
366
    set_response = FrameFormatToDescriptor(pid.set_response(), validate);
640✔
367
    if (!set_response) {
640✔
368
      delete get_request;
×
369
      delete get_response;
×
370
      delete set_request;
×
371
      return NULL;
×
372
    }
373
  }
374

375
  PidDescriptor *descriptor = new PidDescriptor(
870✔
376
      pid.name(),
377
      pid.value(),
870✔
378
      get_request,
379
      get_response,
380
      set_request,
381
      set_response,
382
      get_validator,
383
      set_validator);
870✔
384
  return descriptor;
870✔
385
}
386

387
/*
388
 * Convert a protobuf frame format to a Descriptor object
389
 */
390
const Descriptor* PidStoreLoader::FrameFormatToDescriptor(
2,888✔
391
    const ola::rdm::pid::FrameFormat &format,
392
    bool validate) {
393
  bool ok = true;
2,888✔
394
  vector<const FieldDescriptor*> fields;
2,888✔
395

396
  for (int i = 0; i < format.field_size(); ++i) {
5,599✔
397
    const FieldDescriptor *field = FieldToFieldDescriptor(format.field(i));
2,711✔
398
    if (!field) {
2,711✔
399
      ok = false;
×
400
      break;
×
401
    }
402
    fields.push_back(field);
2,711✔
403
  }
404

405
  if (!ok) {
2,888✔
406
    vector<const FieldDescriptor*>::iterator iter = fields.begin();
×
407
    for (; iter != fields.end(); ++iter) {
×
408
      delete *iter;
×
409
    }
410
    return NULL;
411
  }
412

413
  // we don't give these descriptors names
414
  const Descriptor *descriptor = new Descriptor("", fields);
5,776✔
415

416
  if (validate) {
2,888✔
417
    if (!m_checker.CheckConsistency(descriptor)) {
2,888✔
418
      OLA_WARN << "Invalid frame format";
1✔
419
      delete descriptor;
1✔
420
      return NULL;
1✔
421
    }
422
  }
423
  return descriptor;
424
}
2,888✔
425

426
/*
427
 * Convert a protobuf field object to a FieldDescriptor.
428
 */
429
const FieldDescriptor *PidStoreLoader::FieldToFieldDescriptor(
2,860✔
430
    const ola::rdm::pid::Field &field) {
431
  const FieldDescriptor *descriptor = NULL;
2,860✔
432
  switch (field.type()) {
2,860✔
433
    case ola::rdm::pid::BOOL:
315✔
434
      descriptor = new ola::messaging::BoolFieldDescriptor(field.name());
315✔
435
      break;
436
    case ola::rdm::pid::UINT8:
1,276✔
437
      descriptor =
1,276✔
438
        IntegerFieldToFieldDescriptor<ola::messaging::UInt8FieldDescriptor>(
1,276✔
439
            field);
440
      break;
1,276✔
441
    case ola::rdm::pid::UINT16:
758✔
442
      descriptor =
758✔
443
        IntegerFieldToFieldDescriptor<ola::messaging::UInt16FieldDescriptor>(
758✔
444
            field);
445
      break;
758✔
446
    case ola::rdm::pid::UINT32:
151✔
447
      descriptor =
151✔
448
        IntegerFieldToFieldDescriptor<ola::messaging::UInt32FieldDescriptor>(
151✔
449
            field);
450
      break;
151✔
451
    case ola::rdm::pid::UINT64:
×
452
      descriptor =
×
453
        IntegerFieldToFieldDescriptor<ola::messaging::UInt64FieldDescriptor>(
×
454
            field);
455
      break;
×
456
    case ola::rdm::pid::INT8:
×
457
      descriptor =
×
458
        IntegerFieldToFieldDescriptor<ola::messaging::Int8FieldDescriptor>(
×
459
            field);
460
      break;
×
461
    case ola::rdm::pid::INT16:
68✔
462
      descriptor =
68✔
463
        IntegerFieldToFieldDescriptor<ola::messaging::Int16FieldDescriptor>(
68✔
464
            field);
465
      break;
68✔
466
    case ola::rdm::pid::INT32:
4✔
467
      descriptor =
4✔
468
        IntegerFieldToFieldDescriptor<ola::messaging::Int32FieldDescriptor>(
4✔
469
            field);
470
      break;
4✔
471
    case ola::rdm::pid::INT64:
×
472
      descriptor =
×
473
        IntegerFieldToFieldDescriptor<ola::messaging::Int64FieldDescriptor>(
×
474
            field);
475
      break;
×
476
    case ola::rdm::pid::STRING:
176✔
477
      descriptor = StringFieldToFieldDescriptor(field);
176✔
478
      break;
176✔
479
    case ola::rdm::pid::GROUP:
90✔
480
      descriptor = GroupFieldToFieldDescriptor(field);
90✔
481
      break;
90✔
482
    case ola::rdm::pid::IPV4:
10✔
483
      descriptor = new ola::messaging::IPV4FieldDescriptor(field.name());
10✔
484
      break;
485
    case ola::rdm::pid::MAC:
1✔
486
      descriptor = new ola::messaging::MACFieldDescriptor(field.name());
1✔
487
      break;
488
    case ola::rdm::pid::UID:
8✔
489
      descriptor = new ola::messaging::UIDFieldDescriptor(field.name());
8✔
490
      break;
491
    case ola::rdm::pid::IPV6:
3✔
492
      descriptor = new ola::messaging::IPV6FieldDescriptor(field.name());
3✔
493
      break;
494
    default:
×
495
      OLA_WARN << "Unknown field type: " << field.type();
×
496
  }
497
  return descriptor;
2,860✔
498
}
499

500
/*
501
 * Convert a integer protobuf field to a FieldDescriptor.
502
 */
503
template <typename descriptor_class>
504
const FieldDescriptor *PidStoreLoader::IntegerFieldToFieldDescriptor(
1,276✔
505
    const ola::rdm::pid::Field &field) {
506

507
  typename descriptor_class::IntervalVector intervals;
1,276✔
508
  typename descriptor_class::LabeledValues labels;
1,276✔
509

510
  for (int i = 0; i < field.range_size(); ++i) {
1,574!
511
    const ola::rdm::pid::Range &range_value = field.range(i);
298!
512
    typename descriptor_class::Interval interval(range_value.min(),
298!
513
                                                 range_value.max());
298!
514
    intervals.push_back(interval);
298!
515
  }
516

517
  // if no intervals were specified, we automatically add all the labels
518
  bool intervals_empty = intervals.empty();
1,276✔
519

520
  for (int i = 0; i < field.label_size(); ++i) {
2,743!
521
    const ola::rdm::pid::LabeledValue &labeled_value = field.label(i);
1,467!
522
    labels[labeled_value.label()] = labeled_value.value();
1,467!
523
    if (intervals_empty) {
1,467!
524
      typename descriptor_class::Interval interval(labeled_value.value(),
1,158✔
525
                                                   labeled_value.value());
1,158!
526
      intervals.push_back(interval);
1,158!
527
    }
528
  }
529

530
  int8_t multiplier = 0;
1,276!
531
  if (field.has_multiplier())
1,276!
532
    multiplier = field.multiplier();
×
533

534
  return new descriptor_class(
1,276!
535
      field.name(),
536
      intervals,
537
      labels,
538
      false,
539
      multiplier);
1,276✔
540
}
1,811!
541

542
/*
543
 * Convert a string protobuf field to a FieldDescriptor.
544
 */
545
const FieldDescriptor *PidStoreLoader::StringFieldToFieldDescriptor(
176✔
546
    const ola::rdm::pid::Field &field) {
547
  uint8_t min = 0;
176✔
548

549
  if (field.has_min_size())
176✔
550
    min = field.min_size();
19✔
551

552
  if (!field.has_max_size()) {
176✔
553
    OLA_WARN << "String field " << field.name()
×
554
             << " failed to specify max size";
×
555
    return NULL;
×
556
  }
557
  return new ola::messaging::StringFieldDescriptor(
176✔
558
      field.name(),
559
      min,
560
      field.max_size());
176✔
561
}
562

563
/*
564
 * Convert a group protobuf field to a FieldDescriptor.
565
 */
566
const FieldDescriptor *PidStoreLoader::GroupFieldToFieldDescriptor(
90✔
567
    const ola::rdm::pid::Field &field) {
568
  vector<const class FieldDescriptor*> fields;
90✔
569
  bool ok = true;
90✔
570

571
  uint16_t min = 0;
90✔
572
  int16_t max = ola::messaging::FieldDescriptorGroup::UNLIMITED_BLOCKS;
90✔
573

574
  if (field.has_min_size())
90✔
575
    min = field.min_size();
3✔
576

577
  if (field.has_max_size())
90✔
578
    max = field.max_size();
9✔
579

580
  for (int i = 0; i < field.field_size(); ++i) {
239✔
581
    const FieldDescriptor *descriptor = FieldToFieldDescriptor(field.field(i));
149✔
582
    if (!descriptor) {
149✔
583
      ok = false;
×
584
      break;
×
585
    }
586
    fields.push_back(descriptor);
149✔
587
  }
588

589
  if (!ok) {
90✔
590
    vector<const class FieldDescriptor*>::iterator iter = fields.begin();
×
591
    for (; iter != fields.end(); ++iter) {
×
592
      delete *iter;
×
593
    }
594
    return NULL;
595
  }
596

597
  return new ola::messaging::FieldDescriptorGroup(
90✔
598
      field.name(),
599
      fields,
600
      min,
601
      max);
90✔
602
}
90✔
603

604
/*
605
 * Convert a protobuf sub device enum to a PidDescriptor one.
606
 */
607
PidDescriptor::sub_device_validator PidStoreLoader::ConvertSubDeviceValidator(
1,444✔
608
    const ola::rdm::pid::SubDeviceRange &sub_device_range) {
609
  switch (sub_device_range) {
1,444✔
610
    case ola::rdm::pid::ROOT_DEVICE:
611
      return PidDescriptor::ROOT_DEVICE;
612
    case ola::rdm::pid::ROOT_OR_ALL_SUBDEVICE:
613
      return PidDescriptor::ANY_SUB_DEVICE;
614
    case ola::rdm::pid::ROOT_OR_SUBDEVICE:
528✔
615
      return PidDescriptor::NON_BROADCAST_SUB_DEVICE;
528✔
616
    case ola::rdm::pid::ONLY_SUBDEVICES:
11✔
617
      return PidDescriptor::SPECIFIC_SUB_DEVICE;
11✔
618
    default:
×
619
      OLA_WARN << "Unknown sub device validator: " << sub_device_range <<
×
620
          ", defaulting to all";
×
621
      return PidDescriptor::ANY_SUB_DEVICE;
×
622
  }
623
}
624

625
void PidStoreLoader::FreeManufacturerMap(ManufacturerMap *data) {
5✔
626
  ManufacturerMap::iterator iter = data->begin();
5✔
627
  for (; iter != data->end(); ++iter) {
11✔
628
    STLDeleteValues(iter->second);
6✔
629
    delete iter->second;
12✔
630
  }
631
  data->clear();
5✔
632
}
5✔
633
}  // namespace rdm
634
}  // 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

© 2025 Coveralls, Inc