blob: 848ed95d772e30dd2290b9125b200b47998c56c7 [file] [log] [blame]
Shawn McCarney0e8c68a2020-03-27 01:44:48 -05001/**
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"
Bob King3a787542020-04-14 13:45:01 +080019#include "and_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050020#include "chassis.hpp"
Bob Kingb267b7e2020-04-22 14:42:39 +080021#include "compare_presence_action.hpp"
Bob Kingf2134322020-04-27 14:14:56 +080022#include "compare_vpd_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080023#include "configuration.hpp"
Bob King0e701132020-04-03 21:50:31 +080024#include "device.hpp"
Bob Kingf09bfe02020-04-13 17:21:15 +080025#include "i2c_compare_bit_action.hpp"
26#include "i2c_compare_byte_action.hpp"
27#include "i2c_compare_bytes_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080028#include "i2c_interface.hpp"
Bob Kingf617f892020-03-30 19:03:35 +080029#include "i2c_write_bit_action.hpp"
Bob King87ff9d72020-03-31 14:02:55 +080030#include "i2c_write_byte_action.hpp"
Bob Kingbafcb862020-03-31 16:39:00 +080031#include "i2c_write_bytes_action.hpp"
Bob King93a89d72020-04-15 15:11:11 +080032#include "if_action.hpp"
Bob Kingf1b58dc2020-04-14 14:53:10 +080033#include "not_action.hpp"
Bob King0b51a9b2020-04-15 13:24:18 +080034#include "or_action.hpp"
Bob King84614882020-04-30 13:13:48 +080035#include "pmbus_read_sensor_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050036#include "pmbus_write_vout_command_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080037#include "presence_detection.hpp"
38#include "rail.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050039#include "rule.hpp"
Bob King315b0b62020-04-03 21:47:58 +080040#include "run_rule_action.hpp"
Bob Kinga2f2a0d2020-04-09 13:32:14 +080041#include "sensor_monitoring.hpp"
Bob King18a68502020-04-17 14:19:56 +080042#include "set_device_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050043
44#include <nlohmann/json.hpp>
45
46#include <cstdint>
47#include <filesystem>
48#include <memory>
49#include <stdexcept>
50#include <string>
51#include <tuple>
52#include <vector>
53
54namespace phosphor::power::regulators::config_file_parser
55{
56
57/**
58 * Parses the specified JSON configuration file.
59 *
60 * Returns the corresponding C++ Rule and Chassis objects.
61 *
62 * Throws a ConfigFileParserError if an error occurs.
63 *
64 * @param pathName configuration file path name
65 * @return tuple containing vectors of Rule and Chassis objects
66 */
67std::tuple<std::vector<std::unique_ptr<Rule>>,
68 std::vector<std::unique_ptr<Chassis>>>
69 parse(const std::filesystem::path& pathName);
70
71/*
72 * Internal implementation details for parse()
73 */
74namespace internal
75{
76
77/**
78 * Returns the specified property of the specified JSON element.
79 *
80 * Throws an invalid_argument exception if the property does not exist.
81 *
82 * @param element JSON element
83 * @param property property name
84 */
85inline const nlohmann::json& getRequiredProperty(const nlohmann::json& element,
86 const std::string& property)
87{
88 auto it = element.find(property);
89 if (it == element.end())
90 {
91 throw std::invalid_argument{"Required property missing: " + property};
92 }
93 return *it;
94}
95
96/**
97 * Parses a JSON element containing an action.
98 *
99 * Returns the corresponding C++ Action object.
100 *
101 * Throws an exception if parsing fails.
102 *
103 * @param element JSON element
104 * @return Action object
105 */
106std::unique_ptr<Action> parseAction(const nlohmann::json& element);
107
108/**
109 * Parses a JSON element containing an array of actions.
110 *
111 * Returns the corresponding C++ Action objects.
112 *
113 * Throws an exception if parsing fails.
114 *
115 * @param element JSON element
116 * @return vector of Action objects
117 */
118std::vector<std::unique_ptr<Action>>
119 parseActionArray(const nlohmann::json& element);
120
121/**
Bob King3a787542020-04-14 13:45:01 +0800122 * Parses a JSON element containing an and action.
123 *
124 * Returns the corresponding C++ AndAction object.
125 *
126 * Throws an exception if parsing fails.
127 *
128 * @param element JSON element
129 * @return AndAction object
130 */
131std::unique_ptr<AndAction> parseAnd(const nlohmann::json& element);
132
133/**
Bob Kingf617f892020-03-30 19:03:35 +0800134 * Parses a JSON element containing a bit position (from 0-7).
135 *
136 * Returns the corresponding C++ uint8_t value.
137 *
138 * Throws an exception if parsing fails.
139 *
140 * @param element JSON element
141 * @return uint8_t value
142 */
143inline uint8_t parseBitPosition(const nlohmann::json& element)
144{
145 // Verify element contains an integer
146 if (!element.is_number_integer())
147 {
148 throw std::invalid_argument{"Element is not an integer"};
149 }
Bob King6afbf1a2020-04-06 17:19:01 +0800150 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800151 if ((value < 0) || (value > 7))
152 {
153 throw std::invalid_argument{"Element is not a bit position"};
154 }
155 return static_cast<uint8_t>(value);
156}
157
158/**
159 * Parses a JSON element containing a bit value (0 or 1).
160 *
161 * Returns the corresponding C++ uint8_t value.
162 *
163 * Throws an exception if parsing fails.
164 *
165 * @param element JSON element
166 * @return uint8_t value
167 */
168inline uint8_t parseBitValue(const nlohmann::json& element)
169{
170 // Verify element contains an integer
171 if (!element.is_number_integer())
172 {
173 throw std::invalid_argument{"Element is not an integer"};
174 }
Bob King6afbf1a2020-04-06 17:19:01 +0800175 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800176 if ((value < 0) || (value > 1))
177 {
178 throw std::invalid_argument{"Element is not a bit value"};
179 }
180 return static_cast<uint8_t>(value);
181}
182
183/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500184 * Parses a JSON element containing a boolean.
185 *
186 * Returns the corresponding C++ boolean value.
187 *
188 * Throws an exception if parsing fails.
189 *
190 * @param element JSON element
191 * @return boolean value
192 */
193inline bool parseBoolean(const nlohmann::json& element)
194{
195 // Verify element contains a boolean
196 if (!element.is_boolean())
197 {
198 throw std::invalid_argument{"Element is not a boolean"};
199 }
200 return element.get<bool>();
201}
202
203/**
Bob King0e701132020-04-03 21:50:31 +0800204 * Parses a JSON element containing a chassis.
205 *
206 * Returns the corresponding C++ Chassis object.
207 *
208 * Throws an exception if parsing fails.
209 *
210 * @param element JSON element
211 * @return Chassis object
212 */
213std::unique_ptr<Chassis> parseChassis(const nlohmann::json& element);
214
215/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500216 * Parses a JSON element containing an array of chassis.
217 *
218 * Returns the corresponding C++ Chassis objects.
219 *
220 * Throws an exception if parsing fails.
221 *
222 * @param element JSON element
223 * @return vector of Chassis objects
224 */
225std::vector<std::unique_ptr<Chassis>>
226 parseChassisArray(const nlohmann::json& element);
227
228/**
Bob Kingb267b7e2020-04-22 14:42:39 +0800229 * Parses a JSON element containing a compare_presence action.
230 *
231 * Returns the corresponding C++ ComparePresenceAction object.
232 *
233 * Throws an exception if parsing fails.
234 *
235 * @param element JSON element
236 * @return ComparePresenceAction object
237 */
238std::unique_ptr<ComparePresenceAction>
239 parseComparePresence(const nlohmann::json& element);
240
241/**
Bob Kingf2134322020-04-27 14:14:56 +0800242 * Parses a JSON element containing a compare_vpd action.
243 *
244 * Returns the corresponding C++ CompareVPDAction object.
245 *
246 * Throws an exception if parsing fails.
247 *
248 * @param element JSON element
249 * @return CompareVPDAction object
250 */
251std::unique_ptr<CompareVPDAction>
252 parseCompareVPD(const nlohmann::json& element);
253
254/**
Bob King33e7eaa2020-04-01 18:09:34 +0800255 * Parses a JSON element containing a configuration.
256 *
257 * Returns the corresponding C++ Configuration object.
258 *
259 * Throws an exception if parsing fails.
260 *
261 * @param element JSON element
262 * @return Configuration object
263 */
264std::unique_ptr<Configuration>
265 parseConfiguration(const nlohmann::json& element);
266
267/**
Bob King9c36c5f2020-04-06 11:34:09 +0800268 * Parses a JSON element containing a device.
269 *
270 * Returns the corresponding C++ Device object.
271 *
272 * Throws an exception if parsing fails.
273 *
274 * @param element JSON element
275 * @return Device object
276 */
277std::unique_ptr<Device> parseDevice(const nlohmann::json& element);
278
279/**
Bob King0e701132020-04-03 21:50:31 +0800280 * Parses a JSON element containing an array of devices.
281 *
282 * Returns the corresponding C++ Device objects.
283 *
284 * Throws an exception if parsing fails.
285 *
286 * @param element JSON element
287 * @return vector of Device objects
288 */
289std::vector<std::unique_ptr<Device>>
290 parseDeviceArray(const nlohmann::json& element);
291
292/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500293 * Parses a JSON element containing a double (floating point number).
294 *
295 * Returns the corresponding C++ double value.
296 *
297 * Throws an exception if parsing fails.
298 *
299 * @param element JSON element
300 * @return double value
301 */
302inline double parseDouble(const nlohmann::json& element)
303{
304 // Verify element contains a number (integer or floating point)
305 if (!element.is_number())
306 {
307 throw std::invalid_argument{"Element is not a number"};
308 }
309 return element.get<double>();
310}
311
312/**
Bob Kingbafcb862020-03-31 16:39:00 +0800313 * Parses a JSON element containing a byte value expressed as a hexadecimal
314 * string.
315 *
316 * The JSON number data type does not support the hexadecimal format. For this
317 * reason, hexadecimal byte values are stored as strings in the configuration
318 * file.
319 *
320 * Returns the corresponding C++ uint8_t value.
321 *
322 * Throws an exception if parsing fails.
323 *
324 * @param element JSON element
325 * @return uint8_t value
326 */
327inline uint8_t parseHexByte(const nlohmann::json& element)
328{
329 if (!element.is_string())
330 {
331 throw std::invalid_argument{"Element is not a string"};
332 }
Bob King6afbf1a2020-04-06 17:19:01 +0800333 std::string value = element.get<std::string>();
Bob Kingbafcb862020-03-31 16:39:00 +0800334
335 bool isHex = (value.compare(0, 2, "0x") == 0) && (value.size() > 2) &&
336 (value.size() < 5) &&
337 (value.find_first_not_of("0123456789abcdefABCDEF", 2) ==
338 std::string::npos);
339 if (!isHex)
340 {
341 throw std::invalid_argument{"Element is not hexadecimal string"};
342 }
343 return static_cast<uint8_t>(std::stoul(value, 0, 0));
344}
345
346/**
347 * Parses a JSON element containing an array of byte values expressed as a
348 * hexadecimal strings.
349 *
350 * Returns the corresponding C++ uint8_t values.
351 *
352 * Throws an exception if parsing fails.
353 *
354 * @param element JSON element
355 * @return vector of uint8_t
356 */
357std::vector<uint8_t> parseHexByteArray(const nlohmann::json& element);
358
359/**
Bob Kingf09bfe02020-04-13 17:21:15 +0800360 * Parses a JSON element containing an i2c_compare_bit action.
361 *
362 * Returns the corresponding C++ I2CCompareBitAction object.
363 *
364 * Throws an exception if parsing fails.
365 *
366 * @param element JSON element
367 * @return I2CCompareBitAction object
368 */
369std::unique_ptr<I2CCompareBitAction>
370 parseI2CCompareBit(const nlohmann::json& element);
371
372/**
373 * Parses a JSON element containing an i2c_compare_byte action.
374 *
375 * Returns the corresponding C++ I2CCompareByteAction object.
376 *
377 * Throws an exception if parsing fails.
378 *
379 * @param element JSON element
380 * @return I2CCompareByteAction object
381 */
382std::unique_ptr<I2CCompareByteAction>
383 parseI2CCompareByte(const nlohmann::json& element);
384
385/**
386 * Parses a JSON element containing an i2c_compare_bytes action.
387 *
388 * Returns the corresponding C++ I2CCompareBytesAction object.
389 *
390 * Throws an exception if parsing fails.
391 *
392 * @param element JSON element
393 * @return I2CCompareBytesAction object
394 */
395std::unique_ptr<I2CCompareBytesAction>
396 parseI2CCompareBytes(const nlohmann::json& element);
397
398/**
Bob King9c36c5f2020-04-06 11:34:09 +0800399 * Parses a JSON element containing an i2c_interface.
400 *
401 * Returns the corresponding C++ i2c::I2CInterface object.
402 *
403 * Throws an exception if parsing fails.
404 *
405 * @param element JSON element
406 * @return i2c::I2CInterface object
407 */
408std::unique_ptr<i2c::I2CInterface>
409 parseI2CInterface(const nlohmann::json& element);
410
411/**
Bob Kingf617f892020-03-30 19:03:35 +0800412 * Parses a JSON element containing an i2c_write_bit action.
413 *
414 * Returns the corresponding C++ I2CWriteBitAction object.
415 *
416 * Throws an exception if parsing fails.
417 *
418 * @param element JSON element
419 * @return I2CWriteBitAction object
420 */
421std::unique_ptr<I2CWriteBitAction>
422 parseI2CWriteBit(const nlohmann::json& element);
423
424/**
Bob King87ff9d72020-03-31 14:02:55 +0800425 * Parses a JSON element containing an i2c_write_byte action.
426 *
427 * Returns the corresponding C++ I2CWriteByteAction object.
428 *
429 * Throws an exception if parsing fails.
430 *
431 * @param element JSON element
432 * @return I2CWriteByteAction object
433 */
434std::unique_ptr<I2CWriteByteAction>
435 parseI2CWriteByte(const nlohmann::json& element);
436
437/**
Bob Kingbafcb862020-03-31 16:39:00 +0800438 * Parses a JSON element containing an i2c_write_bytes action.
439 *
440 * Returns the corresponding C++ I2CWriteBytesAction object.
441 *
442 * Throws an exception if parsing fails.
443 *
444 * @param element JSON element
445 * @return I2CWriteBytesAction object
446 */
447std::unique_ptr<I2CWriteBytesAction>
448 parseI2CWriteBytes(const nlohmann::json& element);
449
450/**
Bob King93a89d72020-04-15 15:11:11 +0800451 * Parses a JSON element containing an if action.
452 *
453 * Returns the corresponding C++ IfAction object.
454 *
455 * Throws an exception if parsing fails.
456 *
457 * @param element JSON element
458 * @return IfAction object
459 */
460std::unique_ptr<IfAction> parseIf(const nlohmann::json& element);
461
462/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500463 * Parses a JSON element containing an 8-bit signed integer.
464 *
465 * Returns the corresponding C++ int8_t value.
466 *
467 * Throws an exception if parsing fails.
468 *
469 * @param element JSON element
470 * @return int8_t value
471 */
472inline int8_t parseInt8(const nlohmann::json& element)
473{
474 // Verify element contains an integer
475 if (!element.is_number_integer())
476 {
477 throw std::invalid_argument{"Element is not an integer"};
478 }
Bob King6afbf1a2020-04-06 17:19:01 +0800479 int value = element.get<int>();
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500480 if ((value < INT8_MIN) || (value > INT8_MAX))
481 {
482 throw std::invalid_argument{"Element is not an 8-bit signed integer"};
483 }
484 return static_cast<int8_t>(value);
485}
486
487/**
Bob Kingf1b58dc2020-04-14 14:53:10 +0800488 * Parses a JSON element containing a not action.
489 *
490 * Returns the corresponding C++ NotAction object.
491 *
492 * Throws an exception if parsing fails.
493 *
494 * @param element JSON element
495 * @return NotAction object
496 */
497std::unique_ptr<NotAction> parseNot(const nlohmann::json& element);
498
499/**
Bob King0b51a9b2020-04-15 13:24:18 +0800500 * Parses a JSON element containing an or action.
501 *
502 * Returns the corresponding C++ OrAction object.
503 *
504 * Throws an exception if parsing fails.
505 *
506 * @param element JSON element
507 * @return OrAction object
508 */
509std::unique_ptr<OrAction> parseOr(const nlohmann::json& element);
510
511/**
Bob King84614882020-04-30 13:13:48 +0800512 * Parses a JSON element containing a pmbus_read_sensor action.
513 *
514 * Returns the corresponding C++ PMBusReadSensorAction object.
515 *
516 * Throws an exception if parsing fails.
517 *
518 * @param element JSON element
519 * @return PMBusReadSensorAction object
520 */
521std::unique_ptr<PMBusReadSensorAction>
522 parsePMBusReadSensor(const nlohmann::json& element);
523
524/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500525 * Parses a JSON element containing a pmbus_write_vout_command action.
526 *
527 * Returns the corresponding C++ PMBusWriteVoutCommandAction object.
528 *
529 * Throws an exception if parsing fails.
530 *
531 * @param element JSON element
532 * @return PMBusWriteVoutCommandAction object
533 */
534std::unique_ptr<PMBusWriteVoutCommandAction>
535 parsePMBusWriteVoutCommand(const nlohmann::json& element);
536
537/**
Bob King2aafb1c2020-04-16 15:24:32 +0800538 * Parses a JSON element containing a presence detection operation.
539 *
540 * Returns the corresponding C++ PresenceDetection object.
541 *
542 * Throws an exception if parsing fails.
543 *
544 * @param element JSON element
545 * @return PresenceDetection object
546 */
547std::unique_ptr<PresenceDetection>
548 parsePresenceDetection(const nlohmann::json& element);
549
550/**
Bob Kinga2f2a0d2020-04-09 13:32:14 +0800551 * Parses a JSON element containing a rail.
552 *
553 * Returns the corresponding C++ Rail object.
554 *
555 * Throws an exception if parsing fails.
556 *
557 * @param element JSON element
558 * @return Rail object
559 */
560std::unique_ptr<Rail> parseRail(const nlohmann::json& element);
561
562/**
Bob King9c36c5f2020-04-06 11:34:09 +0800563 * Parses a JSON element containing an array of rails.
564 *
565 * Returns the corresponding C++ Rail objects.
566 *
567 * Throws an exception if parsing fails.
568 *
569 * @param element JSON element
570 * @return vector of Rail objects
571 */
572std::vector<std::unique_ptr<Rail>>
573 parseRailArray(const nlohmann::json& element);
574
575/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500576 * Parses the JSON root element of the entire configuration file.
577 *
578 * Returns the corresponding C++ Rule and Chassis objects.
579 *
580 * Throws an exception if parsing fails.
581 *
582 * @param element JSON element
583 * @return tuple containing vectors of Rule and Chassis objects
584 */
585std::tuple<std::vector<std::unique_ptr<Rule>>,
586 std::vector<std::unique_ptr<Chassis>>>
587 parseRoot(const nlohmann::json& element);
588
589/**
590 * Parses a JSON element containing a rule.
591 *
592 * Returns the corresponding C++ Rule object.
593 *
594 * Throws an exception if parsing fails.
595 *
596 * @param element JSON element
597 * @return Rule object
598 */
599std::unique_ptr<Rule> parseRule(const nlohmann::json& element);
600
601/**
602 * Parses a JSON element containing an array of rules.
603 *
604 * Returns the corresponding C++ Rule objects.
605 *
606 * Throws an exception if parsing fails.
607 *
608 * @param element JSON element
609 * @return vector of Rule objects
610 */
611std::vector<std::unique_ptr<Rule>>
612 parseRuleArray(const nlohmann::json& element);
613
614/**
Bob King33e7eaa2020-04-01 18:09:34 +0800615 * Parses the "rule_id" or "actions" property in a JSON element.
616 *
617 * The element must contain one property or the other but not both.
618 *
619 * If the element contains a "rule_id" property, the corresponding C++
620 * RunRuleAction object is returned.
621 *
622 * If the element contains an "actions" property, the corresponding C++ Action
623 * objects are returned.
624 *
625 * Throws an exception if parsing fails.
626 *
627 * @param element JSON element
628 * @return vector of Action objects
629 */
630std::vector<std::unique_ptr<Action>>
631 parseRuleIDOrActionsProperty(const nlohmann::json& element);
632
633/**
Bob King315b0b62020-04-03 21:47:58 +0800634 * Parses a JSON element containing a run_rule action.
635 *
636 * Returns the corresponding C++ RunRuleAction object.
637 *
638 * Throws an exception if parsing fails.
639 *
640 * @param element JSON element
641 * @return RunRuleAction object
642 */
643std::unique_ptr<RunRuleAction> parseRunRule(const nlohmann::json& element);
644
645/**
Bob King84614882020-04-30 13:13:48 +0800646 * Parses a JSON element containing a SensorDataFormat expressed as a string.
647 *
648 * Returns the corresponding SensorDataFormat enum value.
649 *
650 * Throws an exception if parsing fails.
651 *
652 * @param element JSON element
653 * @return SensorDataFormat enum value
654 */
655pmbus_utils::SensorDataFormat
656 parseSensorDataFormat(const nlohmann::json& element);
657
658/**
Bob Kinga2f2a0d2020-04-09 13:32:14 +0800659 * Parses a JSON element containing a sensor monitoring operation.
660 *
661 * Returns the corresponding C++ SensorMonitoring object.
662 *
663 * Throws an exception if parsing fails.
664 *
665 * @param element JSON element
666 * @return SensorMonitoring object
667 */
668std::unique_ptr<SensorMonitoring>
669 parseSensorMonitoring(const nlohmann::json& element);
670
671/**
Bob King84614882020-04-30 13:13:48 +0800672 * Parses a JSON element containing a SensorValueType expressed as a string.
673 *
674 * Returns the corresponding SensorValueType enum value.
675 *
676 * Throws an exception if parsing fails.
677 *
678 * @param element JSON element
679 * @return SensorValueType enum value
680 */
681pmbus_utils::SensorValueType
682 parseSensorValueType(const nlohmann::json& element);
683
684/**
Bob King18a68502020-04-17 14:19:56 +0800685 * Parses a JSON element containing a set_device action.
686 *
687 * Returns the corresponding C++ SetDeviceAction object.
688 *
689 * Throws an exception if parsing fails.
690 *
691 * @param element JSON element
692 * @return SetDeviceAction object
693 */
694std::unique_ptr<SetDeviceAction> parseSetDevice(const nlohmann::json& element);
695
696/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500697 * Parses a JSON element containing a string.
698 *
699 * Returns the corresponding C++ string.
700 *
701 * Throws an exception if parsing fails.
702 *
703 * @param element JSON element
704 * @param isEmptyValid indicates whether an empty string value is valid
705 * @return string value
706 */
707inline std::string parseString(const nlohmann::json& element,
708 bool isEmptyValid = false)
709{
710 if (!element.is_string())
711 {
712 throw std::invalid_argument{"Element is not a string"};
713 }
Bob King6afbf1a2020-04-06 17:19:01 +0800714 std::string value = element.get<std::string>();
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500715 if (value.empty() && !isEmptyValid)
716 {
717 throw std::invalid_argument{"Element contains an empty string"};
718 }
719 return value;
720}
721
722/**
Bob Kingf617f892020-03-30 19:03:35 +0800723 * Parses a JSON element containing an 8-bit unsigned integer.
724 *
725 * Returns the corresponding C++ uint8_t value.
726 *
727 * Throws an exception if parsing fails.
728 *
729 * @param element JSON element
730 * @return uint8_t value
731 */
732inline uint8_t parseUint8(const nlohmann::json& element)
733{
734 // Verify element contains an integer
735 if (!element.is_number_integer())
736 {
737 throw std::invalid_argument{"Element is not an integer"};
738 }
Bob King6afbf1a2020-04-06 17:19:01 +0800739 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800740 if ((value < 0) || (value > UINT8_MAX))
741 {
742 throw std::invalid_argument{"Element is not an 8-bit unsigned integer"};
743 }
744 return static_cast<uint8_t>(value);
745}
746
747/**
Bob King0e701132020-04-03 21:50:31 +0800748 * Parses a JSON element containing an unsigned integer.
749 *
750 * Returns the corresponding C++ unsigned int value.
751 *
752 * Throws an exception if parsing fails.
753 *
754 * @param element JSON element
755 * @return unsigned int value
756 */
757inline unsigned int parseUnsignedInteger(const nlohmann::json& element)
758{
759 // Verify element contains an unsigned integer
760 if (!element.is_number_unsigned())
761 {
762 throw std::invalid_argument{"Element is not an unsigned integer"};
763 }
764 return element.get<unsigned int>();
765}
766
767/**
Bob King84614882020-04-30 13:13:48 +0800768 * Parses a JSON element containing a VoutDataFormat expressed as a string.
769 *
770 * Returns the corresponding VoutDataFormat enum value.
771 *
772 * Throws an exception if parsing fails.
773 *
774 * @param element JSON element
775 * @return VoutDataFormat enum value
776 */
777pmbus_utils::VoutDataFormat parseVoutDataFormat(const nlohmann::json& element);
778
779/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500780 * Verifies that the specified JSON element is a JSON array.
781 *
782 * Throws an invalid_argument exception if the element is not an array.
783 *
784 * @param element JSON element
785 */
786inline void verifyIsArray(const nlohmann::json& element)
787{
788 if (!element.is_array())
789 {
790 throw std::invalid_argument{"Element is not an array"};
791 }
792}
793
794/**
795 * Verifies that the specified JSON element is a JSON object.
796 *
797 * Throws an invalid_argument exception if the element is not an object.
798 *
799 * @param element JSON element
800 */
801inline void verifyIsObject(const nlohmann::json& element)
802{
803 if (!element.is_object())
804 {
805 throw std::invalid_argument{"Element is not an object"};
806 }
807}
808
809/**
810 * Verifies that the specified JSON element contains the expected number of
811 * properties.
812 *
813 * Throws an invalid_argument exception if the element contains a different
814 * number of properties. This indicates the element contains an invalid
815 * property.
816 *
817 * @param element JSON element
818 * @param expectedCount expected number of properties in element
819 */
820inline void verifyPropertyCount(const nlohmann::json& element,
821 unsigned int expectedCount)
822{
823 if (element.size() != expectedCount)
824 {
825 throw std::invalid_argument{"Element contains an invalid property"};
826 }
827}
828
829} // namespace internal
830
831} // namespace phosphor::power::regulators::config_file_parser