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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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