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

OpenLightingProject / ola / 11783254300

11 Nov 2024 05:23PM UTC coverage: 45.767% (+0.09%) from 45.677%
11783254300

push

github

web-flow
Merge pull request #1978 from DMXControl/add_nodle_r4s

Add DMXControl Projects e.V. Nodle R4S

7798 of 17938 branches covered (43.47%)

0 of 1 new or added line in 1 file covered. (0.0%)

721 existing lines in 11 files now uncovered.

22344 of 48821 relevant lines covered (45.77%)

64.39 hits per line

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

83.94
/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) {
53✔
92
      override_file = *file_iter;
1✔
93
    } else if (ola::file::FilenameFromPath(*file_iter) ==
51✔
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
}
6✔
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;
8✔
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,494✔
247
    const ola::rdm::pid::Manufacturer &manufacturer = proto.manufacturer(i);
1,465✔
248

249
    if (STLContains(seen_manufacturer_ids, manufacturer.manufacturer_id())) {
1,465✔
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,464✔
256

257
    ManufacturerMap::iterator iter = STLLookupOrInsertNew(
1,464✔
258
        pid_data, manufacturer.manufacturer_id());
1,464✔
259
    if (!GetPidList(iter->second, manufacturer, validate, false)) {
1,464✔
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,
2,996✔
273
                                const pb_object &store,
274
                                bool validate,
275
                                bool limit_pid_values) {
276
  set<uint16_t> seen_pids;
2,996✔
277
  set<string> seen_names;
2,996✔
278

279
  for (int i = 0; i < store.pid_size(); ++i) {
4,694✔
280
    const ola::rdm::pid::Pid &pid = store.pid(i);
1,706✔
281

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

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

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

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

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

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

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

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

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

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

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

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

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

405
  if (!ok) {
2,834✔
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,668✔
415

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

426
/*
427
 * Convert a protobuf field object to a FieldDescriptor.
428
 */
429
const FieldDescriptor *PidStoreLoader::FieldToFieldDescriptor(
2,796✔
430
    const ola::rdm::pid::Field &field) {
431
  const FieldDescriptor *descriptor = NULL;
2,796✔
432
  switch (field.type()) {
2,796✔
433
    case ola::rdm::pid::BOOL:
313✔
434
      descriptor = new ola::messaging::BoolFieldDescriptor(field.name());
313✔
435
      break;
313✔
436
    case ola::rdm::pid::UINT8:
1,255✔
437
      descriptor =
1,255✔
438
        IntegerFieldToFieldDescriptor<ola::messaging::UInt8FieldDescriptor>(
1,255✔
439
            field);
440
      break;
1,255✔
441
    case ola::rdm::pid::UINT16:
738✔
442
      descriptor =
738✔
443
        IntegerFieldToFieldDescriptor<ola::messaging::UInt16FieldDescriptor>(
738✔
444
            field);
445
      break;
738✔
446
    case ola::rdm::pid::UINT32:
145✔
447
      descriptor =
145✔
448
        IntegerFieldToFieldDescriptor<ola::messaging::UInt32FieldDescriptor>(
145✔
449
            field);
450
      break;
145✔
451
    case ola::rdm::pid::UINT64:
×
452
      descriptor =
×
453
        IntegerFieldToFieldDescriptor<ola::messaging::UInt64FieldDescriptor>(
×
454
            field);
455
      break;
×
UNCOV
456
    case ola::rdm::pid::INT8:
×
UNCOV
457
      descriptor =
×
UNCOV
458
        IntegerFieldToFieldDescriptor<ola::messaging::Int8FieldDescriptor>(
×
459
            field);
UNCOV
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✔
UNCOV
471
    case ola::rdm::pid::INT64:
×
UNCOV
472
      descriptor =
×
UNCOV
473
        IntegerFieldToFieldDescriptor<ola::messaging::Int64FieldDescriptor>(
×
474
            field);
UNCOV
475
      break;
×
476
    case ola::rdm::pid::STRING:
164✔
477
      descriptor = StringFieldToFieldDescriptor(field);
164✔
478
      break;
164✔
479
    case ola::rdm::pid::GROUP:
87✔
480
      descriptor = GroupFieldToFieldDescriptor(field);
87✔
481
      break;
87✔
482
    case ola::rdm::pid::IPV4:
10✔
483
      descriptor = new ola::messaging::IPV4FieldDescriptor(field.name());
10✔
484
      break;
10✔
485
    case ola::rdm::pid::MAC:
1✔
486
      descriptor = new ola::messaging::MACFieldDescriptor(field.name());
1✔
487
      break;
1✔
488
    case ola::rdm::pid::UID:
8✔
489
      descriptor = new ola::messaging::UIDFieldDescriptor(field.name());
8✔
490
      break;
8✔
491
    case ola::rdm::pid::IPV6:
3✔
492
      descriptor = new ola::messaging::IPV6FieldDescriptor(field.name());
3✔
493
      break;
3✔
UNCOV
494
    default:
×
UNCOV
495
      OLA_WARN << "Unknown field type: " << field.type();
×
496
  }
497
  return descriptor;
2,796✔
498
}
499

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

507
  typename descriptor_class::IntervalVector intervals;
4,420✔
508
  typename descriptor_class::LabeledValues labels;
4,420✔
509

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

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

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

530
  int8_t multiplier = 0;
4,420✔
531
  if (field.has_multiplier())
4,420✔
532
    multiplier = field.multiplier();
380✔
533

534
  return new descriptor_class(
4,420✔
535
      field.name(),
536
      intervals,
537
      labels,
538
      false,
539
      multiplier);
4,420✔
540
}
5,996✔
541

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

549
  if (field.has_min_size())
164✔
550
    min = field.min_size();
15✔
551

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

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

570
  uint16_t min = 0;
87✔
571
  int16_t max = ola::messaging::FieldDescriptorGroup::UNLIMITED_BLOCKS;
87✔
572

573
  if (field.has_min_size())
87✔
574
    min = field.min_size();
2✔
575

576
  if (field.has_max_size())
87✔
577
    max = field.max_size();
8✔
578

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

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

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

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

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