1 /**
2 * Copyright © 2020 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #pragma once
17
18 #include "action.hpp"
19 #include "and_action.hpp"
20 #include "chassis.hpp"
21 #include "compare_presence_action.hpp"
22 #include "compare_vpd_action.hpp"
23 #include "configuration.hpp"
24 #include "device.hpp"
25 #include "i2c_capture_bytes_action.hpp"
26 #include "i2c_compare_bit_action.hpp"
27 #include "i2c_compare_byte_action.hpp"
28 #include "i2c_compare_bytes_action.hpp"
29 #include "i2c_interface.hpp"
30 #include "i2c_write_bit_action.hpp"
31 #include "i2c_write_byte_action.hpp"
32 #include "i2c_write_bytes_action.hpp"
33 #include "if_action.hpp"
34 #include "log_phase_fault_action.hpp"
35 #include "not_action.hpp"
36 #include "or_action.hpp"
37 #include "phase_fault.hpp"
38 #include "phase_fault_detection.hpp"
39 #include "pmbus_read_sensor_action.hpp"
40 #include "pmbus_write_vout_command_action.hpp"
41 #include "presence_detection.hpp"
42 #include "rail.hpp"
43 #include "rule.hpp"
44 #include "run_rule_action.hpp"
45 #include "sensor_monitoring.hpp"
46 #include "sensors.hpp"
47 #include "set_device_action.hpp"
48
49 #include <nlohmann/json.hpp>
50
51 #include <cstdint>
52 #include <filesystem>
53 #include <memory>
54 #include <stdexcept>
55 #include <string>
56 #include <tuple>
57 #include <vector>
58
59 namespace phosphor::power::regulators::config_file_parser
60 {
61
62 /**
63 * Parses the specified JSON configuration file.
64 *
65 * Returns the corresponding C++ Rule and Chassis objects.
66 *
67 * Throws a ConfigFileParserError if an error occurs.
68 *
69 * @param pathName configuration file path name
70 * @return tuple containing vectors of Rule and Chassis objects
71 */
72 std::tuple<std::vector<std::unique_ptr<Rule>>,
73 std::vector<std::unique_ptr<Chassis>>>
74 parse(const std::filesystem::path& pathName);
75
76 /*
77 * Internal implementation details for parse()
78 */
79 namespace internal
80 {
81
82 /**
83 * Returns the specified property of the specified JSON element.
84 *
85 * Throws an invalid_argument exception if the property does not exist.
86 *
87 * @param element JSON element
88 * @param property property name
89 */
90 #pragma GCC diagnostic push
91 #if __GNUC__ >= 13
92 #pragma GCC diagnostic ignored "-Wdangling-reference"
93 #endif
getRequiredProperty(const nlohmann::json & element,const std::string & property)94 inline const nlohmann::json& getRequiredProperty(const nlohmann::json& element,
95 const std::string& property)
96 {
97 auto it = element.find(property);
98 if (it == element.end())
99 {
100 throw std::invalid_argument{"Required property missing: " + property};
101 }
102 return *it;
103 }
104 #pragma GCC diagnostic pop
105
106 /**
107 * Parses a JSON element containing an action.
108 *
109 * Returns the corresponding C++ Action object.
110 *
111 * Throws an exception if parsing fails.
112 *
113 * @param element JSON element
114 * @return Action object
115 */
116 std::unique_ptr<Action> parseAction(const nlohmann::json& element);
117
118 /**
119 * Parses a JSON element containing an array of actions.
120 *
121 * Returns the corresponding C++ Action objects.
122 *
123 * Throws an exception if parsing fails.
124 *
125 * @param element JSON element
126 * @return vector of Action objects
127 */
128 std::vector<std::unique_ptr<Action>>
129 parseActionArray(const nlohmann::json& element);
130
131 /**
132 * Parses a JSON element containing an and action.
133 *
134 * Returns the corresponding C++ AndAction object.
135 *
136 * Throws an exception if parsing fails.
137 *
138 * @param element JSON element
139 * @return AndAction object
140 */
141 std::unique_ptr<AndAction> parseAnd(const nlohmann::json& element);
142
143 /**
144 * Parses a JSON element containing a bit position (from 0-7).
145 *
146 * Returns the corresponding C++ uint8_t value.
147 *
148 * Throws an exception if parsing fails.
149 *
150 * @param element JSON element
151 * @return uint8_t value
152 */
parseBitPosition(const nlohmann::json & element)153 inline uint8_t parseBitPosition(const nlohmann::json& element)
154 {
155 // Verify element contains an integer
156 if (!element.is_number_integer())
157 {
158 throw std::invalid_argument{"Element is not an integer"};
159 }
160 int value = element.get<int>();
161 if ((value < 0) || (value > 7))
162 {
163 throw std::invalid_argument{"Element is not a bit position"};
164 }
165 return static_cast<uint8_t>(value);
166 }
167
168 /**
169 * Parses a JSON element containing a bit value (0 or 1).
170 *
171 * Returns the corresponding C++ uint8_t value.
172 *
173 * Throws an exception if parsing fails.
174 *
175 * @param element JSON element
176 * @return uint8_t value
177 */
parseBitValue(const nlohmann::json & element)178 inline uint8_t parseBitValue(const nlohmann::json& element)
179 {
180 // Verify element contains an integer
181 if (!element.is_number_integer())
182 {
183 throw std::invalid_argument{"Element is not an integer"};
184 }
185 int value = element.get<int>();
186 if ((value < 0) || (value > 1))
187 {
188 throw std::invalid_argument{"Element is not a bit value"};
189 }
190 return static_cast<uint8_t>(value);
191 }
192
193 /**
194 * Parses a JSON element containing a boolean.
195 *
196 * Returns the corresponding C++ boolean value.
197 *
198 * Throws an exception if parsing fails.
199 *
200 * @param element JSON element
201 * @return boolean value
202 */
parseBoolean(const nlohmann::json & element)203 inline bool parseBoolean(const nlohmann::json& element)
204 {
205 // Verify element contains a boolean
206 if (!element.is_boolean())
207 {
208 throw std::invalid_argument{"Element is not a boolean"};
209 }
210 return element.get<bool>();
211 }
212
213 /**
214 * Parses a JSON element containing a chassis.
215 *
216 * Returns the corresponding C++ Chassis object.
217 *
218 * Throws an exception if parsing fails.
219 *
220 * @param element JSON element
221 * @return Chassis object
222 */
223 std::unique_ptr<Chassis> parseChassis(const nlohmann::json& element);
224
225 /**
226 * Parses a JSON element containing an array of chassis.
227 *
228 * Returns the corresponding C++ Chassis objects.
229 *
230 * Throws an exception if parsing fails.
231 *
232 * @param element JSON element
233 * @return vector of Chassis objects
234 */
235 std::vector<std::unique_ptr<Chassis>>
236 parseChassisArray(const nlohmann::json& element);
237
238 /**
239 * Parses a JSON element containing a compare_presence action.
240 *
241 * Returns the corresponding C++ ComparePresenceAction object.
242 *
243 * Throws an exception if parsing fails.
244 *
245 * @param element JSON element
246 * @return ComparePresenceAction object
247 */
248 std::unique_ptr<ComparePresenceAction>
249 parseComparePresence(const nlohmann::json& element);
250
251 /**
252 * Parses a JSON element containing a compare_vpd action.
253 *
254 * Returns the corresponding C++ CompareVPDAction object.
255 *
256 * Throws an exception if parsing fails.
257 *
258 * @param element JSON element
259 * @return CompareVPDAction object
260 */
261 std::unique_ptr<CompareVPDAction>
262 parseCompareVPD(const nlohmann::json& element);
263
264 /**
265 * Parses a JSON element containing a configuration object.
266 *
267 * Returns the corresponding C++ Configuration object.
268 *
269 * Throws an exception if parsing fails.
270 *
271 * @param element JSON element
272 * @return Configuration object
273 */
274 std::unique_ptr<Configuration>
275 parseConfiguration(const nlohmann::json& element);
276
277 /**
278 * Parses a JSON element containing a device.
279 *
280 * Returns the corresponding C++ Device object.
281 *
282 * Throws an exception if parsing fails.
283 *
284 * @param element JSON element
285 * @return Device object
286 */
287 std::unique_ptr<Device> parseDevice(const nlohmann::json& element);
288
289 /**
290 * Parses a JSON element containing an array of devices.
291 *
292 * Returns the corresponding C++ Device objects.
293 *
294 * Throws an exception if parsing fails.
295 *
296 * @param element JSON element
297 * @return vector of Device objects
298 */
299 std::vector<std::unique_ptr<Device>>
300 parseDeviceArray(const nlohmann::json& element);
301
302 /**
303 * Parses a JSON element containing a double (floating point number).
304 *
305 * Returns the corresponding C++ double value.
306 *
307 * Throws an exception if parsing fails.
308 *
309 * @param element JSON element
310 * @return double value
311 */
parseDouble(const nlohmann::json & element)312 inline double parseDouble(const nlohmann::json& element)
313 {
314 // Verify element contains a number (integer or floating point)
315 if (!element.is_number())
316 {
317 throw std::invalid_argument{"Element is not a number"};
318 }
319 return element.get<double>();
320 }
321
322 /**
323 * Parses a JSON element containing a byte value expressed as a hexadecimal
324 * string.
325 *
326 * The JSON number data type does not support the hexadecimal format. For this
327 * reason, hexadecimal byte values are stored as strings in the configuration
328 * file.
329 *
330 * Returns the corresponding C++ uint8_t value.
331 *
332 * Throws an exception if parsing fails.
333 *
334 * @param element JSON element
335 * @return uint8_t value
336 */
parseHexByte(const nlohmann::json & element)337 inline uint8_t parseHexByte(const nlohmann::json& element)
338 {
339 if (!element.is_string())
340 {
341 throw std::invalid_argument{"Element is not a string"};
342 }
343 std::string value = element.get<std::string>();
344
345 bool isHex = (value.compare(0, 2, "0x") == 0) && (value.size() > 2) &&
346 (value.size() < 5) &&
347 (value.find_first_not_of("0123456789abcdefABCDEF", 2) ==
348 std::string::npos);
349 if (!isHex)
350 {
351 throw std::invalid_argument{"Element is not hexadecimal string"};
352 }
353 return static_cast<uint8_t>(std::stoul(value, 0, 0));
354 }
355
356 /**
357 * Parses a JSON element containing an array of byte values expressed as a
358 * hexadecimal strings.
359 *
360 * Returns the corresponding C++ uint8_t values.
361 *
362 * Throws an exception if parsing fails.
363 *
364 * @param element JSON element
365 * @return vector of uint8_t
366 */
367 std::vector<uint8_t> parseHexByteArray(const nlohmann::json& element);
368
369 /**
370 * Parses a JSON element containing an i2c_capture_bytes action.
371 *
372 * Returns the corresponding C++ I2CCaptureBytesAction object.
373 *
374 * Throws an exception if parsing fails.
375 *
376 * @param element JSON element
377 * @return I2CCaptureBytesAction object
378 */
379 std::unique_ptr<I2CCaptureBytesAction>
380 parseI2CCaptureBytes(const nlohmann::json& element);
381
382 /**
383 * Parses a JSON element containing an i2c_compare_bit action.
384 *
385 * Returns the corresponding C++ I2CCompareBitAction object.
386 *
387 * Throws an exception if parsing fails.
388 *
389 * @param element JSON element
390 * @return I2CCompareBitAction object
391 */
392 std::unique_ptr<I2CCompareBitAction>
393 parseI2CCompareBit(const nlohmann::json& element);
394
395 /**
396 * Parses a JSON element containing an i2c_compare_byte action.
397 *
398 * Returns the corresponding C++ I2CCompareByteAction object.
399 *
400 * Throws an exception if parsing fails.
401 *
402 * @param element JSON element
403 * @return I2CCompareByteAction object
404 */
405 std::unique_ptr<I2CCompareByteAction>
406 parseI2CCompareByte(const nlohmann::json& element);
407
408 /**
409 * Parses a JSON element containing an i2c_compare_bytes action.
410 *
411 * Returns the corresponding C++ I2CCompareBytesAction object.
412 *
413 * Throws an exception if parsing fails.
414 *
415 * @param element JSON element
416 * @return I2CCompareBytesAction object
417 */
418 std::unique_ptr<I2CCompareBytesAction>
419 parseI2CCompareBytes(const nlohmann::json& element);
420
421 /**
422 * Parses a JSON element containing an i2c_interface.
423 *
424 * Returns the corresponding C++ i2c::I2CInterface object.
425 *
426 * Throws an exception if parsing fails.
427 *
428 * @param element JSON element
429 * @return i2c::I2CInterface object
430 */
431 std::unique_ptr<i2c::I2CInterface>
432 parseI2CInterface(const nlohmann::json& element);
433
434 /**
435 * Parses a JSON element containing an i2c_write_bit action.
436 *
437 * Returns the corresponding C++ I2CWriteBitAction object.
438 *
439 * Throws an exception if parsing fails.
440 *
441 * @param element JSON element
442 * @return I2CWriteBitAction object
443 */
444 std::unique_ptr<I2CWriteBitAction>
445 parseI2CWriteBit(const nlohmann::json& element);
446
447 /**
448 * Parses a JSON element containing an i2c_write_byte action.
449 *
450 * Returns the corresponding C++ I2CWriteByteAction object.
451 *
452 * Throws an exception if parsing fails.
453 *
454 * @param element JSON element
455 * @return I2CWriteByteAction object
456 */
457 std::unique_ptr<I2CWriteByteAction>
458 parseI2CWriteByte(const nlohmann::json& element);
459
460 /**
461 * Parses a JSON element containing an i2c_write_bytes action.
462 *
463 * Returns the corresponding C++ I2CWriteBytesAction object.
464 *
465 * Throws an exception if parsing fails.
466 *
467 * @param element JSON element
468 * @return I2CWriteBytesAction object
469 */
470 std::unique_ptr<I2CWriteBytesAction>
471 parseI2CWriteBytes(const nlohmann::json& element);
472
473 /**
474 * Parses a JSON element containing an if action.
475 *
476 * Returns the corresponding C++ IfAction object.
477 *
478 * Throws an exception if parsing fails.
479 *
480 * @param element JSON element
481 * @return IfAction object
482 */
483 std::unique_ptr<IfAction> parseIf(const nlohmann::json& element);
484
485 /**
486 * Parses a JSON element containing an 8-bit signed integer.
487 *
488 * Returns the corresponding C++ int8_t value.
489 *
490 * Throws an exception if parsing fails.
491 *
492 * @param element JSON element
493 * @return int8_t value
494 */
parseInt8(const nlohmann::json & element)495 inline int8_t parseInt8(const nlohmann::json& element)
496 {
497 // Verify element contains an integer
498 if (!element.is_number_integer())
499 {
500 throw std::invalid_argument{"Element is not an integer"};
501 }
502 int value = element.get<int>();
503 if ((value < INT8_MIN) || (value > INT8_MAX))
504 {
505 throw std::invalid_argument{"Element is not an 8-bit signed integer"};
506 }
507 return static_cast<int8_t>(value);
508 }
509
510 /**
511 * Parses a JSON element containing a relative inventory path.
512 *
513 * Returns the corresponding C++ string containing the absolute inventory path.
514 *
515 * Inventory paths in the JSON configuration file are relative. Adds the
516 * necessary prefix to make the path absolute.
517 *
518 * Throws an exception if parsing fails.
519 *
520 * @param element JSON element
521 * @return absolute D-Bus inventory path
522 */
523 std::string parseInventoryPath(const nlohmann::json& element);
524
525 /**
526 * Parses a JSON element containing a log_phase_fault action.
527 *
528 * Returns the corresponding C++ LogPhaseFaultAction object.
529 *
530 * Throws an exception if parsing fails.
531 *
532 * @param element JSON element
533 * @return LogPhaseFaultAction object
534 */
535 std::unique_ptr<LogPhaseFaultAction>
536 parseLogPhaseFault(const nlohmann::json& element);
537
538 /**
539 * Parses a JSON element containing a not action.
540 *
541 * Returns the corresponding C++ NotAction object.
542 *
543 * Throws an exception if parsing fails.
544 *
545 * @param element JSON element
546 * @return NotAction object
547 */
548 std::unique_ptr<NotAction> parseNot(const nlohmann::json& element);
549
550 /**
551 * Parses a JSON element containing an or action.
552 *
553 * Returns the corresponding C++ OrAction object.
554 *
555 * Throws an exception if parsing fails.
556 *
557 * @param element JSON element
558 * @return OrAction object
559 */
560 std::unique_ptr<OrAction> parseOr(const nlohmann::json& element);
561
562 /**
563 * Parses a JSON element containing a phase_fault_detection object.
564 *
565 * Returns the corresponding C++ PhaseFaultDetection object.
566 *
567 * Throws an exception if parsing fails.
568 *
569 * @param element JSON element
570 * @return PhaseFaultDetection object
571 */
572 std::unique_ptr<PhaseFaultDetection>
573 parsePhaseFaultDetection(const nlohmann::json& element);
574
575 /**
576 * Parses a JSON element containing a PhaseFaultType expressed as a string.
577 *
578 * Returns the corresponding PhaseFaultType enum value.
579 *
580 * Throws an exception if parsing fails.
581 *
582 * @param element JSON element
583 * @return PhaseFaultType enum value
584 */
585 PhaseFaultType parsePhaseFaultType(const nlohmann::json& element);
586
587 /**
588 * Parses a JSON element containing a pmbus_read_sensor action.
589 *
590 * Returns the corresponding C++ PMBusReadSensorAction object.
591 *
592 * Throws an exception if parsing fails.
593 *
594 * @param element JSON element
595 * @return PMBusReadSensorAction object
596 */
597 std::unique_ptr<PMBusReadSensorAction>
598 parsePMBusReadSensor(const nlohmann::json& element);
599
600 /**
601 * Parses a JSON element containing a pmbus_write_vout_command action.
602 *
603 * Returns the corresponding C++ PMBusWriteVoutCommandAction object.
604 *
605 * Throws an exception if parsing fails.
606 *
607 * @param element JSON element
608 * @return PMBusWriteVoutCommandAction object
609 */
610 std::unique_ptr<PMBusWriteVoutCommandAction>
611 parsePMBusWriteVoutCommand(const nlohmann::json& element);
612
613 /**
614 * Parses a JSON element containing a presence_detection object.
615 *
616 * Returns the corresponding C++ PresenceDetection object.
617 *
618 * Throws an exception if parsing fails.
619 *
620 * @param element JSON element
621 * @return PresenceDetection object
622 */
623 std::unique_ptr<PresenceDetection>
624 parsePresenceDetection(const nlohmann::json& element);
625
626 /**
627 * Parses a JSON element containing a rail.
628 *
629 * Returns the corresponding C++ Rail object.
630 *
631 * Throws an exception if parsing fails.
632 *
633 * @param element JSON element
634 * @return Rail object
635 */
636 std::unique_ptr<Rail> parseRail(const nlohmann::json& element);
637
638 /**
639 * Parses a JSON element containing an array of rails.
640 *
641 * Returns the corresponding C++ Rail objects.
642 *
643 * Throws an exception if parsing fails.
644 *
645 * @param element JSON element
646 * @return vector of Rail objects
647 */
648 std::vector<std::unique_ptr<Rail>>
649 parseRailArray(const nlohmann::json& element);
650
651 /**
652 * Parses the JSON root element of the entire configuration file.
653 *
654 * Returns the corresponding C++ Rule and Chassis objects.
655 *
656 * Throws an exception if parsing fails.
657 *
658 * @param element JSON element
659 * @return tuple containing vectors of Rule and Chassis objects
660 */
661 std::tuple<std::vector<std::unique_ptr<Rule>>,
662 std::vector<std::unique_ptr<Chassis>>>
663 parseRoot(const nlohmann::json& element);
664
665 /**
666 * Parses a JSON element containing a rule.
667 *
668 * Returns the corresponding C++ Rule object.
669 *
670 * Throws an exception if parsing fails.
671 *
672 * @param element JSON element
673 * @return Rule object
674 */
675 std::unique_ptr<Rule> parseRule(const nlohmann::json& element);
676
677 /**
678 * Parses a JSON element containing an array of rules.
679 *
680 * Returns the corresponding C++ Rule objects.
681 *
682 * Throws an exception if parsing fails.
683 *
684 * @param element JSON element
685 * @return vector of Rule objects
686 */
687 std::vector<std::unique_ptr<Rule>>
688 parseRuleArray(const nlohmann::json& element);
689
690 /**
691 * Parses the "rule_id" or "actions" property in a JSON element.
692 *
693 * The element must contain one property or the other but not both.
694 *
695 * If the element contains a "rule_id" property, the corresponding C++
696 * RunRuleAction object is returned.
697 *
698 * If the element contains an "actions" property, the corresponding C++ Action
699 * objects are returned.
700 *
701 * Throws an exception if parsing fails.
702 *
703 * @param element JSON element
704 * @return vector of Action objects
705 */
706 std::vector<std::unique_ptr<Action>>
707 parseRuleIDOrActionsProperty(const nlohmann::json& element);
708
709 /**
710 * Parses a JSON element containing a run_rule action.
711 *
712 * Returns the corresponding C++ RunRuleAction object.
713 *
714 * Throws an exception if parsing fails.
715 *
716 * @param element JSON element
717 * @return RunRuleAction object
718 */
719 std::unique_ptr<RunRuleAction> parseRunRule(const nlohmann::json& element);
720
721 /**
722 * Parses a JSON element containing a SensorDataFormat expressed as a string.
723 *
724 * Returns the corresponding SensorDataFormat enum value.
725 *
726 * Throws an exception if parsing fails.
727 *
728 * @param element JSON element
729 * @return SensorDataFormat enum value
730 */
731 pmbus_utils::SensorDataFormat
732 parseSensorDataFormat(const nlohmann::json& element);
733
734 /**
735 * Parses a JSON element containing a sensor_monitoring object.
736 *
737 * Returns the corresponding C++ SensorMonitoring object.
738 *
739 * Throws an exception if parsing fails.
740 *
741 * @param element JSON element
742 * @return SensorMonitoring object
743 */
744 std::unique_ptr<SensorMonitoring>
745 parseSensorMonitoring(const nlohmann::json& element);
746
747 /**
748 * Parses a JSON element containing a SensorType expressed as a string.
749 *
750 * Returns the corresponding SensorType enum value.
751 *
752 * Throws an exception if parsing fails.
753 *
754 * @param element JSON element
755 * @return SensorType enum value
756 */
757 SensorType parseSensorType(const nlohmann::json& element);
758
759 /**
760 * Parses a JSON element containing a set_device action.
761 *
762 * Returns the corresponding C++ SetDeviceAction object.
763 *
764 * Throws an exception if parsing fails.
765 *
766 * @param element JSON element
767 * @return SetDeviceAction object
768 */
769 std::unique_ptr<SetDeviceAction> parseSetDevice(const nlohmann::json& element);
770
771 /**
772 * Parses a JSON element containing a string.
773 *
774 * Returns the corresponding C++ string.
775 *
776 * Throws an exception if parsing fails.
777 *
778 * @param element JSON element
779 * @param isEmptyValid indicates whether an empty string value is valid
780 * @return string value
781 */
parseString(const nlohmann::json & element,bool isEmptyValid=false)782 inline std::string parseString(const nlohmann::json& element,
783 bool isEmptyValid = false)
784 {
785 if (!element.is_string())
786 {
787 throw std::invalid_argument{"Element is not a string"};
788 }
789 std::string value = element.get<std::string>();
790 if (value.empty() && !isEmptyValid)
791 {
792 throw std::invalid_argument{"Element contains an empty string"};
793 }
794 return value;
795 }
796
797 /**
798 * Parses a JSON element containing an 8-bit unsigned integer.
799 *
800 * Returns the corresponding C++ uint8_t value.
801 *
802 * Throws an exception if parsing fails.
803 *
804 * @param element JSON element
805 * @return uint8_t value
806 */
parseUint8(const nlohmann::json & element)807 inline uint8_t parseUint8(const nlohmann::json& element)
808 {
809 // Verify element contains an integer
810 if (!element.is_number_integer())
811 {
812 throw std::invalid_argument{"Element is not an integer"};
813 }
814 int value = element.get<int>();
815 if ((value < 0) || (value > UINT8_MAX))
816 {
817 throw std::invalid_argument{"Element is not an 8-bit unsigned integer"};
818 }
819 return static_cast<uint8_t>(value);
820 }
821
822 /**
823 * Parses a JSON element containing an unsigned integer.
824 *
825 * Returns the corresponding C++ unsigned int value.
826 *
827 * Throws an exception if parsing fails.
828 *
829 * @param element JSON element
830 * @return unsigned int value
831 */
parseUnsignedInteger(const nlohmann::json & element)832 inline unsigned int parseUnsignedInteger(const nlohmann::json& element)
833 {
834 // Verify element contains an unsigned integer
835 if (!element.is_number_unsigned())
836 {
837 throw std::invalid_argument{"Element is not an unsigned integer"};
838 }
839 return element.get<unsigned int>();
840 }
841
842 /**
843 * Parses a JSON element containing a VoutDataFormat expressed as a string.
844 *
845 * Returns the corresponding VoutDataFormat enum value.
846 *
847 * Throws an exception if parsing fails.
848 *
849 * @param element JSON element
850 * @return VoutDataFormat enum value
851 */
852 pmbus_utils::VoutDataFormat parseVoutDataFormat(const nlohmann::json& element);
853
854 /**
855 * Verifies that the specified JSON element is a JSON array.
856 *
857 * Throws an invalid_argument exception if the element is not an array.
858 *
859 * @param element JSON element
860 */
verifyIsArray(const nlohmann::json & element)861 inline void verifyIsArray(const nlohmann::json& element)
862 {
863 if (!element.is_array())
864 {
865 throw std::invalid_argument{"Element is not an array"};
866 }
867 }
868
869 /**
870 * Verifies that the specified JSON element is a JSON object.
871 *
872 * Throws an invalid_argument exception if the element is not an object.
873 *
874 * @param element JSON element
875 */
verifyIsObject(const nlohmann::json & element)876 inline void verifyIsObject(const nlohmann::json& element)
877 {
878 if (!element.is_object())
879 {
880 throw std::invalid_argument{"Element is not an object"};
881 }
882 }
883
884 /**
885 * Verifies that the specified JSON element contains the expected number of
886 * properties.
887 *
888 * Throws an invalid_argument exception if the element contains a different
889 * number of properties. This indicates the element contains an invalid
890 * property.
891 *
892 * @param element JSON element
893 * @param expectedCount expected number of properties in element
894 */
verifyPropertyCount(const nlohmann::json & element,unsigned int expectedCount)895 inline void verifyPropertyCount(const nlohmann::json& element,
896 unsigned int expectedCount)
897 {
898 if (element.size() != expectedCount)
899 {
900 throw std::invalid_argument{"Element contains an invalid property"};
901 }
902 }
903
904 } // namespace internal
905
906 } // namespace phosphor::power::regulators::config_file_parser
907