blob: 1062cedce504e1622b2ae790fc4b45d6023c21bb [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"
Shawn McCarney91f87a52021-09-07 09:59:57 -050025#include "i2c_capture_bytes_action.hpp"
Bob Kingf09bfe02020-04-13 17:21:15 +080026#include "i2c_compare_bit_action.hpp"
27#include "i2c_compare_byte_action.hpp"
28#include "i2c_compare_bytes_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080029#include "i2c_interface.hpp"
Bob Kingf617f892020-03-30 19:03:35 +080030#include "i2c_write_bit_action.hpp"
Bob King87ff9d72020-03-31 14:02:55 +080031#include "i2c_write_byte_action.hpp"
Bob Kingbafcb862020-03-31 16:39:00 +080032#include "i2c_write_bytes_action.hpp"
Bob King93a89d72020-04-15 15:11:11 +080033#include "if_action.hpp"
Bob Kingf1b58dc2020-04-14 14:53:10 +080034#include "not_action.hpp"
Bob King0b51a9b2020-04-15 13:24:18 +080035#include "or_action.hpp"
Bob King84614882020-04-30 13:13:48 +080036#include "pmbus_read_sensor_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050037#include "pmbus_write_vout_command_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080038#include "presence_detection.hpp"
39#include "rail.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050040#include "rule.hpp"
Bob King315b0b62020-04-03 21:47:58 +080041#include "run_rule_action.hpp"
Bob Kinga2f2a0d2020-04-09 13:32:14 +080042#include "sensor_monitoring.hpp"
Shawn McCarney2f9e14f2021-04-29 02:45:18 -050043#include "sensors.hpp"
Bob King18a68502020-04-17 14:19:56 +080044#include "set_device_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050045
46#include <nlohmann/json.hpp>
47
48#include <cstdint>
49#include <filesystem>
50#include <memory>
51#include <stdexcept>
52#include <string>
53#include <tuple>
54#include <vector>
55
56namespace phosphor::power::regulators::config_file_parser
57{
58
59/**
60 * Parses the specified JSON configuration file.
61 *
62 * Returns the corresponding C++ Rule and Chassis objects.
63 *
64 * Throws a ConfigFileParserError if an error occurs.
65 *
66 * @param pathName configuration file path name
67 * @return tuple containing vectors of Rule and Chassis objects
68 */
69std::tuple<std::vector<std::unique_ptr<Rule>>,
70 std::vector<std::unique_ptr<Chassis>>>
71 parse(const std::filesystem::path& pathName);
72
73/*
74 * Internal implementation details for parse()
75 */
76namespace internal
77{
78
79/**
80 * Returns the specified property of the specified JSON element.
81 *
82 * Throws an invalid_argument exception if the property does not exist.
83 *
84 * @param element JSON element
85 * @param property property name
86 */
87inline const nlohmann::json& getRequiredProperty(const nlohmann::json& element,
88 const std::string& property)
89{
90 auto it = element.find(property);
91 if (it == element.end())
92 {
93 throw std::invalid_argument{"Required property missing: " + property};
94 }
95 return *it;
96}
97
98/**
99 * Parses a JSON element containing an action.
100 *
101 * Returns the corresponding C++ Action object.
102 *
103 * Throws an exception if parsing fails.
104 *
105 * @param element JSON element
106 * @return Action object
107 */
108std::unique_ptr<Action> parseAction(const nlohmann::json& element);
109
110/**
111 * Parses a JSON element containing an array of actions.
112 *
113 * Returns the corresponding C++ Action objects.
114 *
115 * Throws an exception if parsing fails.
116 *
117 * @param element JSON element
118 * @return vector of Action objects
119 */
120std::vector<std::unique_ptr<Action>>
121 parseActionArray(const nlohmann::json& element);
122
123/**
Bob King3a787542020-04-14 13:45:01 +0800124 * Parses a JSON element containing an and action.
125 *
126 * Returns the corresponding C++ AndAction object.
127 *
128 * Throws an exception if parsing fails.
129 *
130 * @param element JSON element
131 * @return AndAction object
132 */
133std::unique_ptr<AndAction> parseAnd(const nlohmann::json& element);
134
135/**
Bob Kingf617f892020-03-30 19:03:35 +0800136 * Parses a JSON element containing a bit position (from 0-7).
137 *
138 * Returns the corresponding C++ uint8_t value.
139 *
140 * Throws an exception if parsing fails.
141 *
142 * @param element JSON element
143 * @return uint8_t value
144 */
145inline uint8_t parseBitPosition(const nlohmann::json& element)
146{
147 // Verify element contains an integer
148 if (!element.is_number_integer())
149 {
150 throw std::invalid_argument{"Element is not an integer"};
151 }
Bob King6afbf1a2020-04-06 17:19:01 +0800152 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800153 if ((value < 0) || (value > 7))
154 {
155 throw std::invalid_argument{"Element is not a bit position"};
156 }
157 return static_cast<uint8_t>(value);
158}
159
160/**
161 * Parses a JSON element containing a bit value (0 or 1).
162 *
163 * Returns the corresponding C++ uint8_t value.
164 *
165 * Throws an exception if parsing fails.
166 *
167 * @param element JSON element
168 * @return uint8_t value
169 */
170inline uint8_t parseBitValue(const nlohmann::json& element)
171{
172 // Verify element contains an integer
173 if (!element.is_number_integer())
174 {
175 throw std::invalid_argument{"Element is not an integer"};
176 }
Bob King6afbf1a2020-04-06 17:19:01 +0800177 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800178 if ((value < 0) || (value > 1))
179 {
180 throw std::invalid_argument{"Element is not a bit value"};
181 }
182 return static_cast<uint8_t>(value);
183}
184
185/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500186 * Parses a JSON element containing a boolean.
187 *
188 * Returns the corresponding C++ boolean value.
189 *
190 * Throws an exception if parsing fails.
191 *
192 * @param element JSON element
193 * @return boolean value
194 */
195inline bool parseBoolean(const nlohmann::json& element)
196{
197 // Verify element contains a boolean
198 if (!element.is_boolean())
199 {
200 throw std::invalid_argument{"Element is not a boolean"};
201 }
202 return element.get<bool>();
203}
204
205/**
Bob King0e701132020-04-03 21:50:31 +0800206 * Parses a JSON element containing a chassis.
207 *
208 * Returns the corresponding C++ Chassis object.
209 *
210 * Throws an exception if parsing fails.
211 *
212 * @param element JSON element
213 * @return Chassis object
214 */
215std::unique_ptr<Chassis> parseChassis(const nlohmann::json& element);
216
217/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500218 * Parses a JSON element containing an array of chassis.
219 *
220 * Returns the corresponding C++ Chassis objects.
221 *
222 * Throws an exception if parsing fails.
223 *
224 * @param element JSON element
225 * @return vector of Chassis objects
226 */
227std::vector<std::unique_ptr<Chassis>>
228 parseChassisArray(const nlohmann::json& element);
229
230/**
Bob Kingb267b7e2020-04-22 14:42:39 +0800231 * Parses a JSON element containing a compare_presence action.
232 *
233 * Returns the corresponding C++ ComparePresenceAction object.
234 *
235 * Throws an exception if parsing fails.
236 *
237 * @param element JSON element
238 * @return ComparePresenceAction object
239 */
240std::unique_ptr<ComparePresenceAction>
241 parseComparePresence(const nlohmann::json& element);
242
243/**
Bob Kingf2134322020-04-27 14:14:56 +0800244 * Parses a JSON element containing a compare_vpd action.
245 *
246 * Returns the corresponding C++ CompareVPDAction object.
247 *
248 * Throws an exception if parsing fails.
249 *
250 * @param element JSON element
251 * @return CompareVPDAction object
252 */
253std::unique_ptr<CompareVPDAction>
254 parseCompareVPD(const nlohmann::json& element);
255
256/**
Bob King33e7eaa2020-04-01 18:09:34 +0800257 * Parses a JSON element containing a configuration.
258 *
259 * Returns the corresponding C++ Configuration object.
260 *
261 * Throws an exception if parsing fails.
262 *
263 * @param element JSON element
264 * @return Configuration object
265 */
266std::unique_ptr<Configuration>
267 parseConfiguration(const nlohmann::json& element);
268
269/**
Bob King9c36c5f2020-04-06 11:34:09 +0800270 * Parses a JSON element containing a device.
271 *
272 * Returns the corresponding C++ Device object.
273 *
274 * Throws an exception if parsing fails.
275 *
276 * @param element JSON element
277 * @return Device object
278 */
279std::unique_ptr<Device> parseDevice(const nlohmann::json& element);
280
281/**
Bob King0e701132020-04-03 21:50:31 +0800282 * Parses a JSON element containing an array of devices.
283 *
284 * Returns the corresponding C++ Device objects.
285 *
286 * Throws an exception if parsing fails.
287 *
288 * @param element JSON element
289 * @return vector of Device objects
290 */
291std::vector<std::unique_ptr<Device>>
292 parseDeviceArray(const nlohmann::json& element);
293
294/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500295 * Parses a JSON element containing a double (floating point number).
296 *
297 * Returns the corresponding C++ double value.
298 *
299 * Throws an exception if parsing fails.
300 *
301 * @param element JSON element
302 * @return double value
303 */
304inline double parseDouble(const nlohmann::json& element)
305{
306 // Verify element contains a number (integer or floating point)
307 if (!element.is_number())
308 {
309 throw std::invalid_argument{"Element is not a number"};
310 }
311 return element.get<double>();
312}
313
314/**
Bob Kingbafcb862020-03-31 16:39:00 +0800315 * Parses a JSON element containing a byte value expressed as a hexadecimal
316 * string.
317 *
318 * The JSON number data type does not support the hexadecimal format. For this
319 * reason, hexadecimal byte values are stored as strings in the configuration
320 * file.
321 *
322 * Returns the corresponding C++ uint8_t value.
323 *
324 * Throws an exception if parsing fails.
325 *
326 * @param element JSON element
327 * @return uint8_t value
328 */
329inline uint8_t parseHexByte(const nlohmann::json& element)
330{
331 if (!element.is_string())
332 {
333 throw std::invalid_argument{"Element is not a string"};
334 }
Bob King6afbf1a2020-04-06 17:19:01 +0800335 std::string value = element.get<std::string>();
Bob Kingbafcb862020-03-31 16:39:00 +0800336
337 bool isHex = (value.compare(0, 2, "0x") == 0) && (value.size() > 2) &&
338 (value.size() < 5) &&
339 (value.find_first_not_of("0123456789abcdefABCDEF", 2) ==
340 std::string::npos);
341 if (!isHex)
342 {
343 throw std::invalid_argument{"Element is not hexadecimal string"};
344 }
345 return static_cast<uint8_t>(std::stoul(value, 0, 0));
346}
347
348/**
349 * Parses a JSON element containing an array of byte values expressed as a
350 * hexadecimal strings.
351 *
352 * Returns the corresponding C++ uint8_t values.
353 *
354 * Throws an exception if parsing fails.
355 *
356 * @param element JSON element
357 * @return vector of uint8_t
358 */
359std::vector<uint8_t> parseHexByteArray(const nlohmann::json& element);
360
361/**
Shawn McCarney91f87a52021-09-07 09:59:57 -0500362 * Parses a JSON element containing an i2c_capture_bytes action.
363 *
364 * Returns the corresponding C++ I2CCaptureBytesAction object.
365 *
366 * Throws an exception if parsing fails.
367 *
368 * @param element JSON element
369 * @return I2CCaptureBytesAction object
370 */
371std::unique_ptr<I2CCaptureBytesAction>
372 parseI2CCaptureBytes(const nlohmann::json& element);
373
374/**
Bob Kingf09bfe02020-04-13 17:21:15 +0800375 * Parses a JSON element containing an i2c_compare_bit action.
376 *
377 * Returns the corresponding C++ I2CCompareBitAction object.
378 *
379 * Throws an exception if parsing fails.
380 *
381 * @param element JSON element
382 * @return I2CCompareBitAction object
383 */
384std::unique_ptr<I2CCompareBitAction>
385 parseI2CCompareBit(const nlohmann::json& element);
386
387/**
388 * Parses a JSON element containing an i2c_compare_byte action.
389 *
390 * Returns the corresponding C++ I2CCompareByteAction object.
391 *
392 * Throws an exception if parsing fails.
393 *
394 * @param element JSON element
395 * @return I2CCompareByteAction object
396 */
397std::unique_ptr<I2CCompareByteAction>
398 parseI2CCompareByte(const nlohmann::json& element);
399
400/**
401 * Parses a JSON element containing an i2c_compare_bytes action.
402 *
403 * Returns the corresponding C++ I2CCompareBytesAction object.
404 *
405 * Throws an exception if parsing fails.
406 *
407 * @param element JSON element
408 * @return I2CCompareBytesAction object
409 */
410std::unique_ptr<I2CCompareBytesAction>
411 parseI2CCompareBytes(const nlohmann::json& element);
412
413/**
Bob King9c36c5f2020-04-06 11:34:09 +0800414 * Parses a JSON element containing an i2c_interface.
415 *
416 * Returns the corresponding C++ i2c::I2CInterface object.
417 *
418 * Throws an exception if parsing fails.
419 *
420 * @param element JSON element
421 * @return i2c::I2CInterface object
422 */
423std::unique_ptr<i2c::I2CInterface>
424 parseI2CInterface(const nlohmann::json& element);
425
426/**
Bob Kingf617f892020-03-30 19:03:35 +0800427 * Parses a JSON element containing an i2c_write_bit action.
428 *
429 * Returns the corresponding C++ I2CWriteBitAction object.
430 *
431 * Throws an exception if parsing fails.
432 *
433 * @param element JSON element
434 * @return I2CWriteBitAction object
435 */
436std::unique_ptr<I2CWriteBitAction>
437 parseI2CWriteBit(const nlohmann::json& element);
438
439/**
Bob King87ff9d72020-03-31 14:02:55 +0800440 * Parses a JSON element containing an i2c_write_byte action.
441 *
442 * Returns the corresponding C++ I2CWriteByteAction object.
443 *
444 * Throws an exception if parsing fails.
445 *
446 * @param element JSON element
447 * @return I2CWriteByteAction object
448 */
449std::unique_ptr<I2CWriteByteAction>
450 parseI2CWriteByte(const nlohmann::json& element);
451
452/**
Bob Kingbafcb862020-03-31 16:39:00 +0800453 * Parses a JSON element containing an i2c_write_bytes action.
454 *
455 * Returns the corresponding C++ I2CWriteBytesAction object.
456 *
457 * Throws an exception if parsing fails.
458 *
459 * @param element JSON element
460 * @return I2CWriteBytesAction object
461 */
462std::unique_ptr<I2CWriteBytesAction>
463 parseI2CWriteBytes(const nlohmann::json& element);
464
465/**
Bob King93a89d72020-04-15 15:11:11 +0800466 * Parses a JSON element containing an if action.
467 *
468 * Returns the corresponding C++ IfAction object.
469 *
470 * Throws an exception if parsing fails.
471 *
472 * @param element JSON element
473 * @return IfAction object
474 */
475std::unique_ptr<IfAction> parseIf(const nlohmann::json& element);
476
477/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500478 * Parses a JSON element containing an 8-bit signed integer.
479 *
480 * Returns the corresponding C++ int8_t value.
481 *
482 * Throws an exception if parsing fails.
483 *
484 * @param element JSON element
485 * @return int8_t value
486 */
487inline int8_t parseInt8(const nlohmann::json& element)
488{
489 // Verify element contains an integer
490 if (!element.is_number_integer())
491 {
492 throw std::invalid_argument{"Element is not an integer"};
493 }
Bob King6afbf1a2020-04-06 17:19:01 +0800494 int value = element.get<int>();
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500495 if ((value < INT8_MIN) || (value > INT8_MAX))
496 {
497 throw std::invalid_argument{"Element is not an 8-bit signed integer"};
498 }
499 return static_cast<int8_t>(value);
500}
501
502/**
Bob Kinga76898f2020-10-13 15:08:33 +0800503 * Parses a JSON element containing a relative inventory path.
504 *
505 * Returns the corresponding C++ string containing the absolute inventory path.
506 *
507 * Inventory paths in the JSON configuration file are relative. Adds the
508 * necessary prefix to make the path absolute.
509 *
510 * Throws an exception if parsing fails.
511 *
512 * @param element JSON element
513 * @return absolute D-Bus inventory path
514 */
515std::string parseInventoryPath(const nlohmann::json& element);
516
517/**
Bob Kingf1b58dc2020-04-14 14:53:10 +0800518 * Parses a JSON element containing a not action.
519 *
520 * Returns the corresponding C++ NotAction object.
521 *
522 * Throws an exception if parsing fails.
523 *
524 * @param element JSON element
525 * @return NotAction object
526 */
527std::unique_ptr<NotAction> parseNot(const nlohmann::json& element);
528
529/**
Bob King0b51a9b2020-04-15 13:24:18 +0800530 * Parses a JSON element containing an or action.
531 *
532 * Returns the corresponding C++ OrAction object.
533 *
534 * Throws an exception if parsing fails.
535 *
536 * @param element JSON element
537 * @return OrAction object
538 */
539std::unique_ptr<OrAction> parseOr(const nlohmann::json& element);
540
541/**
Bob King84614882020-04-30 13:13:48 +0800542 * Parses a JSON element containing a pmbus_read_sensor action.
543 *
544 * Returns the corresponding C++ PMBusReadSensorAction object.
545 *
546 * Throws an exception if parsing fails.
547 *
548 * @param element JSON element
549 * @return PMBusReadSensorAction object
550 */
551std::unique_ptr<PMBusReadSensorAction>
552 parsePMBusReadSensor(const nlohmann::json& element);
553
554/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500555 * Parses a JSON element containing a pmbus_write_vout_command action.
556 *
557 * Returns the corresponding C++ PMBusWriteVoutCommandAction object.
558 *
559 * Throws an exception if parsing fails.
560 *
561 * @param element JSON element
562 * @return PMBusWriteVoutCommandAction object
563 */
564std::unique_ptr<PMBusWriteVoutCommandAction>
565 parsePMBusWriteVoutCommand(const nlohmann::json& element);
566
567/**
Bob King2aafb1c2020-04-16 15:24:32 +0800568 * Parses a JSON element containing a presence detection operation.
569 *
570 * Returns the corresponding C++ PresenceDetection object.
571 *
572 * Throws an exception if parsing fails.
573 *
574 * @param element JSON element
575 * @return PresenceDetection object
576 */
577std::unique_ptr<PresenceDetection>
578 parsePresenceDetection(const nlohmann::json& element);
579
580/**
Bob Kinga2f2a0d2020-04-09 13:32:14 +0800581 * Parses a JSON element containing a rail.
582 *
583 * Returns the corresponding C++ Rail object.
584 *
585 * Throws an exception if parsing fails.
586 *
587 * @param element JSON element
588 * @return Rail object
589 */
590std::unique_ptr<Rail> parseRail(const nlohmann::json& element);
591
592/**
Bob King9c36c5f2020-04-06 11:34:09 +0800593 * Parses a JSON element containing an array of rails.
594 *
595 * Returns the corresponding C++ Rail objects.
596 *
597 * Throws an exception if parsing fails.
598 *
599 * @param element JSON element
600 * @return vector of Rail objects
601 */
602std::vector<std::unique_ptr<Rail>>
603 parseRailArray(const nlohmann::json& element);
604
605/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500606 * Parses the JSON root element of the entire configuration file.
607 *
608 * Returns the corresponding C++ Rule and Chassis objects.
609 *
610 * Throws an exception if parsing fails.
611 *
612 * @param element JSON element
613 * @return tuple containing vectors of Rule and Chassis objects
614 */
615std::tuple<std::vector<std::unique_ptr<Rule>>,
616 std::vector<std::unique_ptr<Chassis>>>
617 parseRoot(const nlohmann::json& element);
618
619/**
620 * Parses a JSON element containing a rule.
621 *
622 * Returns the corresponding C++ Rule object.
623 *
624 * Throws an exception if parsing fails.
625 *
626 * @param element JSON element
627 * @return Rule object
628 */
629std::unique_ptr<Rule> parseRule(const nlohmann::json& element);
630
631/**
632 * Parses a JSON element containing an array of rules.
633 *
634 * Returns the corresponding C++ Rule objects.
635 *
636 * Throws an exception if parsing fails.
637 *
638 * @param element JSON element
639 * @return vector of Rule objects
640 */
641std::vector<std::unique_ptr<Rule>>
642 parseRuleArray(const nlohmann::json& element);
643
644/**
Bob King33e7eaa2020-04-01 18:09:34 +0800645 * Parses the "rule_id" or "actions" property in a JSON element.
646 *
647 * The element must contain one property or the other but not both.
648 *
649 * If the element contains a "rule_id" property, the corresponding C++
650 * RunRuleAction object is returned.
651 *
652 * If the element contains an "actions" property, the corresponding C++ Action
653 * objects are returned.
654 *
655 * Throws an exception if parsing fails.
656 *
657 * @param element JSON element
658 * @return vector of Action objects
659 */
660std::vector<std::unique_ptr<Action>>
661 parseRuleIDOrActionsProperty(const nlohmann::json& element);
662
663/**
Bob King315b0b62020-04-03 21:47:58 +0800664 * Parses a JSON element containing a run_rule action.
665 *
666 * Returns the corresponding C++ RunRuleAction object.
667 *
668 * Throws an exception if parsing fails.
669 *
670 * @param element JSON element
671 * @return RunRuleAction object
672 */
673std::unique_ptr<RunRuleAction> parseRunRule(const nlohmann::json& element);
674
675/**
Bob King84614882020-04-30 13:13:48 +0800676 * Parses a JSON element containing a SensorDataFormat expressed as a string.
677 *
678 * Returns the corresponding SensorDataFormat enum value.
679 *
680 * Throws an exception if parsing fails.
681 *
682 * @param element JSON element
683 * @return SensorDataFormat enum value
684 */
685pmbus_utils::SensorDataFormat
686 parseSensorDataFormat(const nlohmann::json& element);
687
688/**
Bob Kinga2f2a0d2020-04-09 13:32:14 +0800689 * Parses a JSON element containing a sensor monitoring operation.
690 *
691 * Returns the corresponding C++ SensorMonitoring object.
692 *
693 * Throws an exception if parsing fails.
694 *
695 * @param element JSON element
696 * @return SensorMonitoring object
697 */
698std::unique_ptr<SensorMonitoring>
699 parseSensorMonitoring(const nlohmann::json& element);
700
701/**
Shawn McCarney2f9e14f2021-04-29 02:45:18 -0500702 * Parses a JSON element containing a SensorType expressed as a string.
Bob King84614882020-04-30 13:13:48 +0800703 *
Shawn McCarney2f9e14f2021-04-29 02:45:18 -0500704 * Returns the corresponding SensorType enum value.
Bob King84614882020-04-30 13:13:48 +0800705 *
706 * Throws an exception if parsing fails.
707 *
708 * @param element JSON element
Shawn McCarney2f9e14f2021-04-29 02:45:18 -0500709 * @return SensorType enum value
Bob King84614882020-04-30 13:13:48 +0800710 */
Shawn McCarney2f9e14f2021-04-29 02:45:18 -0500711SensorType parseSensorType(const nlohmann::json& element);
Bob King84614882020-04-30 13:13:48 +0800712
713/**
Bob King18a68502020-04-17 14:19:56 +0800714 * Parses a JSON element containing a set_device action.
715 *
716 * Returns the corresponding C++ SetDeviceAction object.
717 *
718 * Throws an exception if parsing fails.
719 *
720 * @param element JSON element
721 * @return SetDeviceAction object
722 */
723std::unique_ptr<SetDeviceAction> parseSetDevice(const nlohmann::json& element);
724
725/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500726 * Parses a JSON element containing a string.
727 *
728 * Returns the corresponding C++ string.
729 *
730 * Throws an exception if parsing fails.
731 *
732 * @param element JSON element
733 * @param isEmptyValid indicates whether an empty string value is valid
734 * @return string value
735 */
736inline std::string parseString(const nlohmann::json& element,
737 bool isEmptyValid = false)
738{
739 if (!element.is_string())
740 {
741 throw std::invalid_argument{"Element is not a string"};
742 }
Bob King6afbf1a2020-04-06 17:19:01 +0800743 std::string value = element.get<std::string>();
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500744 if (value.empty() && !isEmptyValid)
745 {
746 throw std::invalid_argument{"Element contains an empty string"};
747 }
748 return value;
749}
750
751/**
Bob Kingf617f892020-03-30 19:03:35 +0800752 * Parses a JSON element containing an 8-bit unsigned integer.
753 *
754 * Returns the corresponding C++ uint8_t value.
755 *
756 * Throws an exception if parsing fails.
757 *
758 * @param element JSON element
759 * @return uint8_t value
760 */
761inline uint8_t parseUint8(const nlohmann::json& element)
762{
763 // Verify element contains an integer
764 if (!element.is_number_integer())
765 {
766 throw std::invalid_argument{"Element is not an integer"};
767 }
Bob King6afbf1a2020-04-06 17:19:01 +0800768 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800769 if ((value < 0) || (value > UINT8_MAX))
770 {
771 throw std::invalid_argument{"Element is not an 8-bit unsigned integer"};
772 }
773 return static_cast<uint8_t>(value);
774}
775
776/**
Bob King0e701132020-04-03 21:50:31 +0800777 * Parses a JSON element containing an unsigned integer.
778 *
779 * Returns the corresponding C++ unsigned int value.
780 *
781 * Throws an exception if parsing fails.
782 *
783 * @param element JSON element
784 * @return unsigned int value
785 */
786inline unsigned int parseUnsignedInteger(const nlohmann::json& element)
787{
788 // Verify element contains an unsigned integer
789 if (!element.is_number_unsigned())
790 {
791 throw std::invalid_argument{"Element is not an unsigned integer"};
792 }
793 return element.get<unsigned int>();
794}
795
796/**
Bob King84614882020-04-30 13:13:48 +0800797 * Parses a JSON element containing a VoutDataFormat expressed as a string.
798 *
799 * Returns the corresponding VoutDataFormat enum value.
800 *
801 * Throws an exception if parsing fails.
802 *
803 * @param element JSON element
804 * @return VoutDataFormat enum value
805 */
806pmbus_utils::VoutDataFormat parseVoutDataFormat(const nlohmann::json& element);
807
808/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500809 * Verifies that the specified JSON element is a JSON array.
810 *
811 * Throws an invalid_argument exception if the element is not an array.
812 *
813 * @param element JSON element
814 */
815inline void verifyIsArray(const nlohmann::json& element)
816{
817 if (!element.is_array())
818 {
819 throw std::invalid_argument{"Element is not an array"};
820 }
821}
822
823/**
824 * Verifies that the specified JSON element is a JSON object.
825 *
826 * Throws an invalid_argument exception if the element is not an object.
827 *
828 * @param element JSON element
829 */
830inline void verifyIsObject(const nlohmann::json& element)
831{
832 if (!element.is_object())
833 {
834 throw std::invalid_argument{"Element is not an object"};
835 }
836}
837
838/**
839 * Verifies that the specified JSON element contains the expected number of
840 * properties.
841 *
842 * Throws an invalid_argument exception if the element contains a different
843 * number of properties. This indicates the element contains an invalid
844 * property.
845 *
846 * @param element JSON element
847 * @param expectedCount expected number of properties in element
848 */
849inline void verifyPropertyCount(const nlohmann::json& element,
850 unsigned int expectedCount)
851{
852 if (element.size() != expectedCount)
853 {
854 throw std::invalid_argument{"Element contains an invalid property"};
855 }
856}
857
858} // namespace internal
859
860} // namespace phosphor::power::regulators::config_file_parser