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

OpenLightingProject / ola / 23758994672

30 Mar 2026 05:43PM UTC coverage: 45.174% (-0.7%) from 45.909%
23758994672

push

github

web-flow
Merge pull request #2033 from peternewman/0.10-fix-sid

Fix Sid dependencies and autopkgtest

8051 of 18455 branches covered (43.63%)

20598 of 45597 relevant lines covered (45.17%)

50.22 hits per line

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

84.97
/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 uint16_t PidStoreLoader::ESTA_MANUFACTURER_ID = 0;
54
const uint16_t PidStoreLoader::MANUFACTURER_PID_MIN = 0x8000;
55
const uint16_t PidStoreLoader::MANUFACTURER_PID_MAX = 0xffe0;
56

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

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

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

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

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

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

108
    google::protobuf::io::IstreamInputStream input_stream(&proto_file);
5✔
109
    bool ok = google::protobuf::TextFormat::Merge(&input_stream,
5✔
110
                                                  &pid_store_pb);
111
    proto_file.close();
5✔
112

113
    if (!ok) {
5✔
114
      OLA_WARN << "Failed to load " << *iter;
×
115
      return NULL;
×
116
    }
117
  }
5✔
118

119
  ola::rdm::pid::PidStore override_pb;
2✔
120
  if (!override_file.empty()) {
2✔
121
    if (!ReadFile(override_file, &override_pb)) {
1✔
122
      return NULL;
123
    }
124
  }
125

126
  return BuildStore(pid_store_pb, override_pb, validate);
2✔
127
}
3✔
128

129
const RootPidStore *PidStoreLoader::LoadFromStream(std::istream *data,
12✔
130
                                                   bool validate) {
131
  ola::rdm::pid::PidStore pid_store_pb;
12✔
132
  google::protobuf::io::IstreamInputStream input_stream(data);
12✔
133
  bool ok = google::protobuf::TextFormat::Parse(&input_stream, &pid_store_pb);
12✔
134

135
  if (!ok)
12✔
136
    return NULL;
137

138
  ola::rdm::pid::PidStore override_pb;
11✔
139
  return BuildStore(pid_store_pb, override_pb, validate);
11✔
140
}
12✔
141

142
bool PidStoreLoader::ReadFile(const std::string &file_path,
1✔
143
                              ola::rdm::pid::PidStore *proto) {
144
  std::ifstream proto_file(file_path.c_str());
1✔
145
  if (!proto_file.is_open()) {
1✔
146
    OLA_WARN << "Failed to open " << file_path << ": " << strerror(errno);
×
147
    return false;
×
148
  }
149

150
  google::protobuf::io::IstreamInputStream input_stream(&proto_file);
1✔
151
  bool ok = google::protobuf::TextFormat::Merge(&input_stream, proto);
1✔
152
  proto_file.close();
1✔
153

154
  if (!ok) {
1✔
155
    OLA_WARN << "Failed to load " << file_path;
×
156
  }
157
  return ok;
1✔
158
}
1✔
159

160
/*
161
 * Build the RootPidStore from a protocol buffer.
162
 */
163
const RootPidStore *PidStoreLoader::BuildStore(
13✔
164
    const ola::rdm::pid::PidStore &store_pb,
165
    const ola::rdm::pid::PidStore &override_pb,
166
    bool validate) {
167
  ManufacturerMap pid_data;
13✔
168
  // Load the overrides first so they get first dibs on each PID.
169
  if (!LoadFromProto(&pid_data, override_pb, validate)) {
13✔
170
    FreeManufacturerMap(&pid_data);
×
171
    return NULL;
×
172
  }
173

174
  // Load the main data
175
  if (!LoadFromProto(&pid_data, store_pb, validate)) {
13✔
176
    FreeManufacturerMap(&pid_data);
5✔
177
    return NULL;
×
178
  }
179

180
  // Now we need to convert the data structure into a format that the PidStore
181
  // understands.
182
  auto_ptr<const PidStore> esta_store;
8✔
183
  RootPidStore::ManufacturerMap manufacturer_map;
8✔
184

185
  ManufacturerMap::iterator iter = pid_data.begin();
8✔
186
  for (; iter != pid_data.end(); ++iter) {
70✔
187
    // Ownership of the Descriptors is transferred to the vector
188
    vector<const PidDescriptor*> pids;
62✔
189
    STLValues(*iter->second, &pids);
62✔
190
    delete iter->second;
124✔
191

192
    if (iter->first == ESTA_MANUFACTURER_ID) {
62✔
193
      esta_store.reset(new PidStore(pids));
8✔
194
    } else {
195
      STLReplaceAndDelete(&manufacturer_map, iter->first,
54✔
196
                          new PidStore(pids));
54✔
197
    }
198
  }
62✔
199
  pid_data.clear();
8✔
200

201
  OLA_DEBUG << "Load Complete";
8✔
202
  return new RootPidStore(esta_store.release(),
8✔
203
                          manufacturer_map,
204
                          store_pb.version());
8✔
205
}
21✔
206

207
/*
208
 * @brief Load the data from the PidStore proto into the ManufacturerMap.
209
 * @param[out] pid_data the ManufacturerMap to populate.
210
 * @param proto the Protobuf data.
211
 * @param validate Enables strict validation mode.
212
 *
213
 * If a collision occurs, the data in the map is not replaced.
214
 */
215
bool PidStoreLoader::LoadFromProto(ManufacturerMap *pid_data,
26✔
216
                                   const ola::rdm::pid::PidStore &proto,
217
                                   bool validate) {
218
  set<uint16_t> seen_manufacturer_ids;
26✔
219

220
  ManufacturerMap::iterator iter = STLLookupOrInsertNew(
26✔
221
      pid_data, ESTA_MANUFACTURER_ID);
222
  if (!GetPidList(iter->second, proto, validate, true)) {
26✔
223
    return false;
224
  }
225

226
  for (int i = 0; i < proto.manufacturer_size(); ++i) {
78✔
227
    const ola::rdm::pid::Manufacturer &manufacturer = proto.manufacturer(i);
57✔
228

229
    if (STLContains(seen_manufacturer_ids, manufacturer.manufacturer_id())) {
57✔
230
      OLA_WARN << "Manufacturer id " << manufacturer.manufacturer_id() <<
2✔
231
          "(" << manufacturer.manufacturer_name() <<
1✔
232
          ") listed more than once in the PIDs file";
1✔
233
      return false;
1✔
234
    }
235
    seen_manufacturer_ids.insert(manufacturer.manufacturer_id());
56✔
236

237
    ManufacturerMap::iterator iter = STLLookupOrInsertNew(
56✔
238
        pid_data, manufacturer.manufacturer_id());
56✔
239
    if (!GetPidList(iter->second, manufacturer, validate, false)) {
56✔
240
      return false;
241
    }
242
  }
243

244
  return true;
245
}
26✔
246

247
/*
248
 * @brief Populate a PidMap from a protobuf object that has a set of repeated
249
 * PIDs.
250
 */
251
template <typename pb_object>
252
bool PidStoreLoader::GetPidList(PidMap *pid_map,
26✔
253
                                const pb_object &store,
254
                                bool validate,
255
                                bool limit_pid_values) {
256
  set<uint16_t> seen_pids;
26✔
257
  set<string> seen_names;
26✔
258

259
  for (int i = 0; i < store.pid_size(); ++i) {
490✔
260
    const ola::rdm::pid::Pid &pid = store.pid(i);
468✔
261

262
    OLA_DEBUG << "Loading " << pid.name();
468✔
263
    if (validate) {
468✔
264
      if (STLContains(seen_pids, pid.value())) {
468✔
265
        OLA_WARN << "PID " << pid.value()
2!
266
                 << " exists multiple times in the pid file";
1!
267
        return false;
27✔
268
      }
269
      seen_pids.insert(pid.value());
467✔
270

271
      if (STLContains(seen_names, pid.name())) {
467✔
272
        OLA_WARN << "PID " << pid.name()
2!
273
                 << " exists multiple times in the pid file";
1!
274
        return false;
1✔
275
      }
276
      seen_names.insert(pid.name());
466✔
277

278
      if (limit_pid_values && pid.value() > MANUFACTURER_PID_MIN &&
466✔
279
          pid.value() < MANUFACTURER_PID_MAX) {
1!
280
        OLA_WARN << "ESTA PID " << pid.name() << " (" << pid.value() << ")"
2!
281
                 << " is outside acceptable range";
1!
282
        return false;
1✔
283
      }
284
    }
285

286
    PidMap::iterator iter = STLLookupOrInsertNull(pid_map, pid.value());
465✔
287
    if (iter->second) {
465✔
288
      OLA_INFO << "Using " << OVERRIDE_FILE_NAME << " for " << pid.name()
×
289
               << "( " << strings::ToHex(pid.value()) << ")";
×
290
      continue;
×
291
    }
292

293
    const PidDescriptor *descriptor = PidToDescriptor(pid, validate);
465✔
294
    if (!descriptor) {
465✔
295
      return false;
296
    }
297
    iter->second = descriptor;
464✔
298
  }
299
  return true;
300
}
26✔
301

302
/*
303
 * Build a PidDescriptor from a Pid protobuf object
304
 */
305
PidDescriptor *PidStoreLoader::PidToDescriptor(const ola::rdm::pid::Pid &pid,
847✔
306
                                               bool validate) {
307
  // populate sub device validators
308
  PidDescriptor::sub_device_validator get_validator =
847✔
309
    PidDescriptor::ANY_SUB_DEVICE;
310
  if (pid.has_get_sub_device_range())
847✔
311
    get_validator = ConvertSubDeviceValidator(pid.get_sub_device_range());
782✔
312
  PidDescriptor::sub_device_validator set_validator =
847✔
313
    PidDescriptor::ANY_SUB_DEVICE;
314
  if (pid.has_set_sub_device_range())
847✔
315
    set_validator = ConvertSubDeviceValidator(pid.set_sub_device_range());
631✔
316

317
  // yuck, code smell. This should use protobuf reflections instead.
318
  const Descriptor *get_request = NULL;
847✔
319
  if (pid.has_get_request()) {
847✔
320
    get_request = FrameFormatToDescriptor(pid.get_request(), validate);
783✔
321
    if (!get_request)
783✔
322
      return NULL;
323
  }
324

325
  const Descriptor *get_response = NULL;
847✔
326
  if (pid.has_get_response()) {
847✔
327
    get_response = FrameFormatToDescriptor(pid.get_response(), validate);
783✔
328
    if (!get_response) {
783✔
329
      delete get_request;
1✔
330
      return NULL;
1✔
331
    }
332
  }
333

334
  const Descriptor *set_request = NULL;
846✔
335
  if (pid.has_set_request()) {
846✔
336
    set_request = FrameFormatToDescriptor(pid.set_request(), validate);
630✔
337
    if (!set_request) {
630✔
338
      delete get_request;
×
339
      delete get_response;
×
340
      return NULL;
×
341
    }
342
  }
343

344
  const Descriptor *set_response = NULL;
846✔
345
  if (pid.has_set_response()) {
846✔
346
    set_response = FrameFormatToDescriptor(pid.set_response(), validate);
630✔
347
    if (!set_response) {
630✔
348
      delete get_request;
×
349
      delete get_response;
×
350
      delete set_request;
×
351
      return NULL;
×
352
    }
353
  }
354

355
  PidDescriptor *descriptor = new PidDescriptor(
846✔
356
      pid.name(),
357
      pid.value(),
846✔
358
      get_request,
359
      get_response,
360
      set_request,
361
      set_response,
362
      get_validator,
363
      set_validator);
846✔
364
  return descriptor;
846✔
365
}
366

367
/*
368
 * Convert a protobuf frame format to a Descriptor object
369
 */
370
const Descriptor* PidStoreLoader::FrameFormatToDescriptor(
2,826✔
371
    const ola::rdm::pid::FrameFormat &format,
372
    bool validate) {
373
  bool ok = true;
2,826✔
374
  vector<const FieldDescriptor*> fields;
2,826✔
375

376
  for (int i = 0; i < format.field_size(); ++i) {
5,461✔
377
    const FieldDescriptor *field = FieldToFieldDescriptor(format.field(i));
2,635✔
378
    if (!field) {
2,635✔
379
      ok = false;
×
380
      break;
×
381
    }
382
    fields.push_back(field);
2,635✔
383
  }
384

385
  if (!ok) {
2,826✔
386
    vector<const FieldDescriptor*>::iterator iter = fields.begin();
×
387
    for (; iter != fields.end(); ++iter) {
×
388
      delete *iter;
×
389
    }
390
    return NULL;
391
  }
392

393
  // we don't give these descriptors names
394
  const Descriptor *descriptor = new Descriptor("", fields);
5,652✔
395

396
  if (validate) {
2,826✔
397
    if (!m_checker.CheckConsistency(descriptor)) {
2,826✔
398
      OLA_WARN << "Invalid frame format";
1✔
399
      delete descriptor;
1✔
400
      return NULL;
1✔
401
    }
402
  }
403
  return descriptor;
404
}
2,826✔
405

406
/*
407
 * Convert a protobuf field object to a FieldDescriptor.
408
 */
409
const FieldDescriptor *PidStoreLoader::FieldToFieldDescriptor(
2,776✔
410
    const ola::rdm::pid::Field &field) {
411
  const FieldDescriptor *descriptor = NULL;
2,776✔
412
  switch (field.type()) {
2,776✔
413
    case ola::rdm::pid::BOOL:
313✔
414
      descriptor = new ola::messaging::BoolFieldDescriptor(field.name());
313✔
415
      break;
416
    case ola::rdm::pid::UINT8:
1,253✔
417
      descriptor =
1,253✔
418
        IntegerFieldToFieldDescriptor<ola::messaging::UInt8FieldDescriptor>(
1,253✔
419
            field);
420
      break;
1,253✔
421
    case ola::rdm::pid::UINT16:
731✔
422
      descriptor =
731✔
423
        IntegerFieldToFieldDescriptor<ola::messaging::UInt16FieldDescriptor>(
731✔
424
            field);
425
      break;
731✔
426
    case ola::rdm::pid::UINT32:
145✔
427
      descriptor =
145✔
428
        IntegerFieldToFieldDescriptor<ola::messaging::UInt32FieldDescriptor>(
145✔
429
            field);
430
      break;
145✔
431
    case ola::rdm::pid::INT8:
×
432
      descriptor =
×
433
        IntegerFieldToFieldDescriptor<ola::messaging::Int8FieldDescriptor>(
×
434
            field);
435
      break;
×
436
    case ola::rdm::pid::INT16:
68✔
437
      descriptor =
68✔
438
        IntegerFieldToFieldDescriptor<ola::messaging::Int16FieldDescriptor>(
68✔
439
            field);
440
      break;
68✔
441
    case ola::rdm::pid::INT32:
4✔
442
      descriptor =
4✔
443
        IntegerFieldToFieldDescriptor<ola::messaging::Int32FieldDescriptor>(
4✔
444
            field);
445
      break;
4✔
446
    case ola::rdm::pid::STRING:
160✔
447
      descriptor = StringFieldToFieldDescriptor(field);
160✔
448
      break;
160✔
449
    case ola::rdm::pid::GROUP:
86✔
450
      descriptor = GroupFieldToFieldDescriptor(field);
86✔
451
      break;
86✔
452
    case ola::rdm::pid::IPV4:
7✔
453
      descriptor = new ola::messaging::IPV4FieldDescriptor(field.name());
7✔
454
      break;
455
    case ola::rdm::pid::MAC:
1✔
456
      descriptor = new ola::messaging::MACFieldDescriptor(field.name());
1✔
457
      break;
458
    case ola::rdm::pid::UID:
8✔
459
      descriptor = new ola::messaging::UIDFieldDescriptor(field.name());
8✔
460
      break;
461
    default:
×
462
      OLA_WARN << "Unknown field type: " << field.type();
×
463
  }
464
  return descriptor;
2,776✔
465
}
466

467
/*
468
 * Convert a integer protobuf field to a FieldDescriptor.
469
 */
470
template <typename descriptor_class>
471
const FieldDescriptor *PidStoreLoader::IntegerFieldToFieldDescriptor(
731✔
472
    const ola::rdm::pid::Field &field) {
473

474
  typename descriptor_class::IntervalVector intervals;
731✔
475
  typename descriptor_class::LabeledValues labels;
731✔
476

477
  for (int i = 0; i < field.range_size(); ++i) {
973!
478
    const ola::rdm::pid::Range &range_value = field.range(i);
242!
479
    typename descriptor_class::Interval interval(range_value.min(),
242!
480
                                                 range_value.max());
242!
481
    intervals.push_back(interval);
242!
482
  }
483

484
  // if not intervals were specified, we automatically add all the labels
485
  bool intervals_empty = intervals.empty();
731✔
486

487
  for (int i = 0; i < field.label_size(); ++i) {
1,044!
488
    const ola::rdm::pid::LabeledValue &labeled_value = field.label(i);
313!
489
    labels[labeled_value.label()] = labeled_value.value();
313!
490
    if (intervals_empty) {
313!
491
      typename descriptor_class::Interval interval(labeled_value.value(),
33✔
492
                                                   labeled_value.value());
33!
493
      intervals.push_back(interval);
33!
494
    }
495
  }
496

497
  int8_t multiplier = 0;
731!
498
  if (field.has_multiplier())
731!
499
    multiplier = field.multiplier();
186✔
500

501
  return new descriptor_class(
731!
502
      field.name(),
503
      intervals,
504
      labels,
505
      false,
506
      multiplier);
731✔
507
}
939!
508

509
/*
510
 * Convert a string protobuf field to a FieldDescriptor.
511
 */
512
const FieldDescriptor *PidStoreLoader::StringFieldToFieldDescriptor(
160✔
513
    const ola::rdm::pid::Field &field) {
514
  uint8_t min = 0;
160✔
515

516
  if (field.has_min_size())
160✔
517
    min = field.min_size();
11✔
518

519
  if (!field.has_max_size()) {
160✔
520
    OLA_WARN << "String field failed to specify max size";
×
521
    return NULL;
×
522
  }
523
  return new ola::messaging::StringFieldDescriptor(
160✔
524
      field.name(),
525
      min,
526
      field.max_size());
160✔
527
}
528

529
/*
530
 * Convert a group protobuf field to a FieldDescriptor.
531
 */
532
const FieldDescriptor *PidStoreLoader::GroupFieldToFieldDescriptor(
86✔
533
    const ola::rdm::pid::Field &field) {
534
  vector<const class FieldDescriptor*> fields;
86✔
535
  bool ok = true;
86✔
536

537
  uint16_t min = 0;
86✔
538
  int16_t max = ola::messaging::FieldDescriptorGroup::UNLIMITED_BLOCKS;
86✔
539

540
  if (field.has_min_size())
86✔
541
    min = field.min_size();
2✔
542

543
  if (field.has_max_size())
86✔
544
    max = field.max_size();
8✔
545

546
  for (int i = 0; i < field.field_size(); ++i) {
227✔
547
    const FieldDescriptor *descriptor = FieldToFieldDescriptor(field.field(i));
141✔
548
    if (!descriptor) {
141✔
549
      ok = false;
×
550
      break;
×
551
    }
552
    fields.push_back(descriptor);
141✔
553
  }
554

555
  if (!ok) {
86✔
556
    vector<const class FieldDescriptor*>::iterator iter = fields.begin();
×
557
    for (; iter != fields.end(); ++iter) {
×
558
      delete *iter;
×
559
    }
560
    return NULL;
561
  }
562

563
  return new ola::messaging::FieldDescriptorGroup(
86✔
564
      field.name(),
565
      fields,
566
      min,
567
      max);
86✔
568
}
86✔
569

570
/*
571
 * Convert a protobuf sub device enum to a PidDescriptor one.
572
 */
573
PidDescriptor::sub_device_validator PidStoreLoader::ConvertSubDeviceValidator(
1,413✔
574
    const ola::rdm::pid::SubDeviceRange &sub_device_range) {
575
  switch (sub_device_range) {
1,413✔
576
    case ola::rdm::pid::ROOT_DEVICE:
577
      return PidDescriptor::ROOT_DEVICE;
578
    case ola::rdm::pid::ROOT_OR_ALL_SUBDEVICE:
579
      return PidDescriptor::ANY_SUB_DEVICE;
580
    case ola::rdm::pid::ROOT_OR_SUBDEVICE:
511✔
581
      return PidDescriptor::NON_BROADCAST_SUB_DEVICE;
511✔
582
    case ola::rdm::pid::ONLY_SUBDEVICES:
10✔
583
      return PidDescriptor::SPECIFIC_SUB_DEVICE;
10✔
584
    default:
×
585
      OLA_WARN << "Unknown sub device validator: " << sub_device_range <<
×
586
          ", defaulting to all";
×
587
      return PidDescriptor::ANY_SUB_DEVICE;
×
588
  }
589
}
590

591
void PidStoreLoader::FreeManufacturerMap(ManufacturerMap *data) {
5✔
592
  ManufacturerMap::iterator iter = data->begin();
5✔
593
  for (; iter != data->end(); ++iter) {
11✔
594
    STLDeleteValues(iter->second);
6✔
595
    delete iter->second;
12✔
596
  }
597
  data->clear();
5✔
598
}
5✔
599
}  // namespace rdm
600
}  // 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