xref: /openbmc/phosphor-power/json_parser_utils.hpp (revision 8873f428276818761348b4091574334870ae51a7)
138f85004SShawn McCarney /**
238f85004SShawn McCarney  * Copyright © 2025 IBM Corporation
338f85004SShawn McCarney  *
438f85004SShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
538f85004SShawn McCarney  * you may not use this file except in compliance with the License.
638f85004SShawn McCarney  * You may obtain a copy of the License at
738f85004SShawn McCarney  *
838f85004SShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
938f85004SShawn McCarney  *
1038f85004SShawn McCarney  * Unless required by applicable law or agreed to in writing, software
1138f85004SShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
1238f85004SShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1338f85004SShawn McCarney  * See the License for the specific language governing permissions and
1438f85004SShawn McCarney  * limitations under the License.
1538f85004SShawn McCarney  */
1638f85004SShawn McCarney #pragma once
1738f85004SShawn McCarney 
1838f85004SShawn McCarney #include <nlohmann/json.hpp>
1938f85004SShawn McCarney 
2038f85004SShawn McCarney #include <cstdint>
21f1845c06SShawn McCarney #include <map>
2238f85004SShawn McCarney #include <stdexcept>
2338f85004SShawn McCarney #include <string>
2438f85004SShawn McCarney #include <vector>
2538f85004SShawn McCarney 
2638f85004SShawn McCarney /**
2738f85004SShawn McCarney  * @namespace json_parser_utils
2838f85004SShawn McCarney  *
2938f85004SShawn McCarney  * Contains utility functions for parsing JSON data.
30f1845c06SShawn McCarney  *
31f1845c06SShawn McCarney  * ## Variables
32f1845c06SShawn McCarney  * The parsing functions support optional usage of variables. JSON string values
33f1845c06SShawn McCarney  * can contain one or more variables. A variable is specified using the format
34f1845c06SShawn McCarney  * `${variable_name}`. A variables map is specified to parsing functions that
35f1845c06SShawn McCarney  * provides the variable values. Any variable in a JSON string value will be
36f1845c06SShawn McCarney  * replaced by the variable value.
37f1845c06SShawn McCarney  *
38f1845c06SShawn McCarney  * Variables can only appear in a JSON string value. The parsing functions for
39f1845c06SShawn McCarney  * other data types, such as integer and double, support a string value if it
40f1845c06SShawn McCarney  * contains a variable. After variable expansion, the string is converted to the
41f1845c06SShawn McCarney  * expected data type.
4238f85004SShawn McCarney  */
4338f85004SShawn McCarney namespace phosphor::power::json_parser_utils
4438f85004SShawn McCarney {
4538f85004SShawn McCarney 
4638f85004SShawn McCarney /**
47f1845c06SShawn McCarney  * Empty variables map used as a default value for parsing functions.
48f1845c06SShawn McCarney  */
49f1845c06SShawn McCarney extern const std::map<std::string, std::string> NO_VARIABLES;
50f1845c06SShawn McCarney 
51f1845c06SShawn McCarney /**
5238f85004SShawn McCarney  * Returns the specified property of the specified JSON element.
5338f85004SShawn McCarney  *
5438f85004SShawn McCarney  * Throws an invalid_argument exception if the property does not exist.
5538f85004SShawn McCarney  *
5638f85004SShawn McCarney  * @param element JSON element
5738f85004SShawn McCarney  * @param property property name
5838f85004SShawn McCarney  */
5938f85004SShawn McCarney #pragma GCC diagnostic push
6038f85004SShawn McCarney #if __GNUC__ >= 13
6138f85004SShawn McCarney #pragma GCC diagnostic ignored "-Wdangling-reference"
6238f85004SShawn McCarney #endif
getRequiredProperty(const nlohmann::json & element,const std::string & property)6338f85004SShawn McCarney inline const nlohmann::json& getRequiredProperty(const nlohmann::json& element,
6438f85004SShawn McCarney                                                  const std::string& property)
6538f85004SShawn McCarney {
6638f85004SShawn McCarney     auto it = element.find(property);
6738f85004SShawn McCarney     if (it == element.end())
6838f85004SShawn McCarney     {
6938f85004SShawn McCarney         throw std::invalid_argument{"Required property missing: " + property};
7038f85004SShawn McCarney     }
7138f85004SShawn McCarney     return *it;
7238f85004SShawn McCarney }
7338f85004SShawn McCarney #pragma GCC diagnostic pop
7438f85004SShawn McCarney 
7538f85004SShawn McCarney /**
7638f85004SShawn McCarney  * Parses a JSON element containing a bit position (from 0-7).
7738f85004SShawn McCarney  *
7838f85004SShawn McCarney  * Returns the corresponding C++ uint8_t value.
7938f85004SShawn McCarney  *
8038f85004SShawn McCarney  * Throws an exception if parsing fails.
8138f85004SShawn McCarney  *
8238f85004SShawn McCarney  * @param element JSON element
83f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
8438f85004SShawn McCarney  * @return uint8_t value
8538f85004SShawn McCarney  */
86f1845c06SShawn McCarney uint8_t parseBitPosition(
87f1845c06SShawn McCarney     const nlohmann::json& element,
88f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
8938f85004SShawn McCarney 
9038f85004SShawn McCarney /**
9138f85004SShawn McCarney  * Parses a JSON element containing a bit value (0 or 1).
9238f85004SShawn McCarney  *
9338f85004SShawn McCarney  * Returns the corresponding C++ uint8_t value.
9438f85004SShawn McCarney  *
9538f85004SShawn McCarney  * Throws an exception if parsing fails.
9638f85004SShawn McCarney  *
9738f85004SShawn McCarney  * @param element JSON element
98f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
9938f85004SShawn McCarney  * @return uint8_t value
10038f85004SShawn McCarney  */
101f1845c06SShawn McCarney uint8_t parseBitValue(
102f1845c06SShawn McCarney     const nlohmann::json& element,
103f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
10438f85004SShawn McCarney 
10538f85004SShawn McCarney /**
10638f85004SShawn McCarney  * Parses a JSON element containing a boolean.
10738f85004SShawn McCarney  *
10838f85004SShawn McCarney  * Returns the corresponding C++ boolean value.
10938f85004SShawn McCarney  *
11038f85004SShawn McCarney  * Throws an exception if parsing fails.
11138f85004SShawn McCarney  *
11238f85004SShawn McCarney  * @param element JSON element
113f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
11438f85004SShawn McCarney  * @return boolean value
11538f85004SShawn McCarney  */
116f1845c06SShawn McCarney bool parseBoolean(
117f1845c06SShawn McCarney     const nlohmann::json& element,
118f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
11938f85004SShawn McCarney 
12038f85004SShawn McCarney /**
12138f85004SShawn McCarney  * Parses a JSON element containing a double (floating point number).
12238f85004SShawn McCarney  *
12338f85004SShawn McCarney  * Returns the corresponding C++ double value.
12438f85004SShawn McCarney  *
12538f85004SShawn McCarney  * Throws an exception if parsing fails.
12638f85004SShawn McCarney  *
12738f85004SShawn McCarney  * @param element JSON element
128f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
12938f85004SShawn McCarney  * @return double value
13038f85004SShawn McCarney  */
131f1845c06SShawn McCarney double parseDouble(
132f1845c06SShawn McCarney     const nlohmann::json& element,
133f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
13438f85004SShawn McCarney 
13538f85004SShawn McCarney /**
13638f85004SShawn McCarney  * Parses a JSON element containing a byte value expressed as a hexadecimal
13738f85004SShawn McCarney  * string.
13838f85004SShawn McCarney  *
13938f85004SShawn McCarney  * The JSON number data type does not support the hexadecimal format.  For this
140f1845c06SShawn McCarney  * reason, a hexadecimal byte value is stored in a JSON string.
14138f85004SShawn McCarney  *
14238f85004SShawn McCarney  * Returns the corresponding C++ uint8_t value.
14338f85004SShawn McCarney  *
14438f85004SShawn McCarney  * Throws an exception if parsing fails.
14538f85004SShawn McCarney  *
14638f85004SShawn McCarney  * @param element JSON element
147f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
14838f85004SShawn McCarney  * @return uint8_t value
14938f85004SShawn McCarney  */
150f1845c06SShawn McCarney uint8_t parseHexByte(
151f1845c06SShawn McCarney     const nlohmann::json& element,
152f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
15338f85004SShawn McCarney 
15438f85004SShawn McCarney /**
15538f85004SShawn McCarney  * Parses a JSON element containing an array of byte values expressed as a
15638f85004SShawn McCarney  * hexadecimal strings.
15738f85004SShawn McCarney  *
15838f85004SShawn McCarney  * Returns the corresponding C++ uint8_t values.
15938f85004SShawn McCarney  *
16038f85004SShawn McCarney  * Throws an exception if parsing fails.
16138f85004SShawn McCarney  *
16238f85004SShawn McCarney  * @param element JSON element
163f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
16438f85004SShawn McCarney  * @return vector of uint8_t
16538f85004SShawn McCarney  */
166f1845c06SShawn McCarney std::vector<uint8_t> parseHexByteArray(
167f1845c06SShawn McCarney     const nlohmann::json& element,
168f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
16938f85004SShawn McCarney 
17038f85004SShawn McCarney /**
17138f85004SShawn McCarney  * Parses a JSON element containing an 8-bit signed integer.
17238f85004SShawn McCarney  *
17338f85004SShawn McCarney  * Returns the corresponding C++ int8_t value.
17438f85004SShawn McCarney  *
17538f85004SShawn McCarney  * Throws an exception if parsing fails.
17638f85004SShawn McCarney  *
17738f85004SShawn McCarney  * @param element JSON element
178f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
17938f85004SShawn McCarney  * @return int8_t value
18038f85004SShawn McCarney  */
181f1845c06SShawn McCarney int8_t parseInt8(
182f1845c06SShawn McCarney     const nlohmann::json& element,
183f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
184f1845c06SShawn McCarney 
185f1845c06SShawn McCarney /**
186f1845c06SShawn McCarney  * Parses a JSON element containing an integer.
187f1845c06SShawn McCarney  *
188f1845c06SShawn McCarney  * Returns the corresponding C++ int value.
189f1845c06SShawn McCarney  *
190f1845c06SShawn McCarney  * Throws an exception if parsing fails.
191f1845c06SShawn McCarney  *
192f1845c06SShawn McCarney  * @param element JSON element
193f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
194f1845c06SShawn McCarney  * @return integer value
195f1845c06SShawn McCarney  */
196f1845c06SShawn McCarney int parseInteger(
197f1845c06SShawn McCarney     const nlohmann::json& element,
198f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
19938f85004SShawn McCarney 
20038f85004SShawn McCarney /**
20138f85004SShawn McCarney  * Parses a JSON element containing a string.
20238f85004SShawn McCarney  *
20338f85004SShawn McCarney  * Returns the corresponding C++ string.
20438f85004SShawn McCarney  *
20538f85004SShawn McCarney  * Throws an exception if parsing fails.
20638f85004SShawn McCarney  *
20738f85004SShawn McCarney  * @param element JSON element
20838f85004SShawn McCarney  * @param isEmptyValid indicates whether an empty string value is valid
209f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
21038f85004SShawn McCarney  * @return string value
21138f85004SShawn McCarney  */
212f1845c06SShawn McCarney std::string parseString(
213f1845c06SShawn McCarney     const nlohmann::json& element, bool isEmptyValid = false,
214f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
21538f85004SShawn McCarney 
21638f85004SShawn McCarney /**
21738f85004SShawn McCarney  * Parses a JSON element containing an 8-bit unsigned integer.
21838f85004SShawn McCarney  *
21938f85004SShawn McCarney  * Returns the corresponding C++ uint8_t value.
22038f85004SShawn McCarney  *
22138f85004SShawn McCarney  * Throws an exception if parsing fails.
22238f85004SShawn McCarney  *
22338f85004SShawn McCarney  * @param element JSON element
224f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
22538f85004SShawn McCarney  * @return uint8_t value
22638f85004SShawn McCarney  */
227f1845c06SShawn McCarney uint8_t parseUint8(
228f1845c06SShawn McCarney     const nlohmann::json& element,
229f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
23038f85004SShawn McCarney 
23138f85004SShawn McCarney /**
232*8873f428SShawn McCarney  * Parses a JSON element containing a 16-bit unsigned integer.
233*8873f428SShawn McCarney  *
234*8873f428SShawn McCarney  * Returns the corresponding C++ uint16_t value.
235*8873f428SShawn McCarney  *
236*8873f428SShawn McCarney  * Throws an exception if parsing fails.
237*8873f428SShawn McCarney  *
238*8873f428SShawn McCarney  * @param element JSON element
239*8873f428SShawn McCarney  * @param variables variables map used to expand variables in element value
240*8873f428SShawn McCarney  * @return uint16_t value
241*8873f428SShawn McCarney  */
242*8873f428SShawn McCarney uint16_t parseUint16(
243*8873f428SShawn McCarney     const nlohmann::json& element,
244*8873f428SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
245*8873f428SShawn McCarney 
246*8873f428SShawn McCarney /**
24738f85004SShawn McCarney  * Parses a JSON element containing an unsigned integer.
24838f85004SShawn McCarney  *
24938f85004SShawn McCarney  * Returns the corresponding C++ unsigned int value.
25038f85004SShawn McCarney  *
25138f85004SShawn McCarney  * Throws an exception if parsing fails.
25238f85004SShawn McCarney  *
25338f85004SShawn McCarney  * @param element JSON element
254f1845c06SShawn McCarney  * @param variables variables map used to expand variables in element value
25538f85004SShawn McCarney  * @return unsigned int value
25638f85004SShawn McCarney  */
257f1845c06SShawn McCarney unsigned int parseUnsignedInteger(
258f1845c06SShawn McCarney     const nlohmann::json& element,
259f1845c06SShawn McCarney     const std::map<std::string, std::string>& variables = NO_VARIABLES);
26038f85004SShawn McCarney 
26138f85004SShawn McCarney /**
26238f85004SShawn McCarney  * Verifies that the specified JSON element is a JSON array.
26338f85004SShawn McCarney  *
26438f85004SShawn McCarney  * Throws an invalid_argument exception if the element is not an array.
26538f85004SShawn McCarney  *
26638f85004SShawn McCarney  * @param element JSON element
26738f85004SShawn McCarney  */
verifyIsArray(const nlohmann::json & element)26838f85004SShawn McCarney inline void verifyIsArray(const nlohmann::json& element)
26938f85004SShawn McCarney {
27038f85004SShawn McCarney     if (!element.is_array())
27138f85004SShawn McCarney     {
27238f85004SShawn McCarney         throw std::invalid_argument{"Element is not an array"};
27338f85004SShawn McCarney     }
27438f85004SShawn McCarney }
27538f85004SShawn McCarney 
27638f85004SShawn McCarney /**
27738f85004SShawn McCarney  * Verifies that the specified JSON element is a JSON object.
27838f85004SShawn McCarney  *
27938f85004SShawn McCarney  * Throws an invalid_argument exception if the element is not an object.
28038f85004SShawn McCarney  *
28138f85004SShawn McCarney  * @param element JSON element
28238f85004SShawn McCarney  */
verifyIsObject(const nlohmann::json & element)28338f85004SShawn McCarney inline void verifyIsObject(const nlohmann::json& element)
28438f85004SShawn McCarney {
28538f85004SShawn McCarney     if (!element.is_object())
28638f85004SShawn McCarney     {
28738f85004SShawn McCarney         throw std::invalid_argument{"Element is not an object"};
28838f85004SShawn McCarney     }
28938f85004SShawn McCarney }
29038f85004SShawn McCarney 
29138f85004SShawn McCarney /**
29238f85004SShawn McCarney  * Verifies that the specified JSON element contains the expected number of
29338f85004SShawn McCarney  * properties.
29438f85004SShawn McCarney  *
29538f85004SShawn McCarney  * Throws an invalid_argument exception if the element contains a different
29638f85004SShawn McCarney  * number of properties.  This indicates the element contains an invalid
29738f85004SShawn McCarney  * property.
29838f85004SShawn McCarney  *
29938f85004SShawn McCarney  * @param element JSON element
30038f85004SShawn McCarney  * @param expectedCount expected number of properties in element
30138f85004SShawn McCarney  */
verifyPropertyCount(const nlohmann::json & element,unsigned int expectedCount)30238f85004SShawn McCarney inline void verifyPropertyCount(const nlohmann::json& element,
30338f85004SShawn McCarney                                 unsigned int expectedCount)
30438f85004SShawn McCarney {
30538f85004SShawn McCarney     if (element.size() != expectedCount)
30638f85004SShawn McCarney     {
30738f85004SShawn McCarney         throw std::invalid_argument{"Element contains an invalid property"};
30838f85004SShawn McCarney     }
30938f85004SShawn McCarney }
31038f85004SShawn McCarney 
311f1845c06SShawn McCarney namespace internal
312f1845c06SShawn McCarney {
313f1845c06SShawn McCarney 
314f1845c06SShawn McCarney /**
315f1845c06SShawn McCarney  * Expands any variables that appear in the specified string value.
316f1845c06SShawn McCarney  *
317f1845c06SShawn McCarney  * Does nothing if the variables map is empty or the value contains no
318f1845c06SShawn McCarney  * variables.
319f1845c06SShawn McCarney  *
320f1845c06SShawn McCarney  * Throws an invalid_argument exception if a variable occurs in the value that
321f1845c06SShawn McCarney  * does not exist in the variables map.
322f1845c06SShawn McCarney  *
323f1845c06SShawn McCarney  * @param value string value in which to perform variable expansion
324f1845c06SShawn McCarney  * @param variables variables map containing variable values
325f1845c06SShawn McCarney  */
326f1845c06SShawn McCarney void expandVariables(std::string& value,
327f1845c06SShawn McCarney                      const std::map<std::string, std::string>& variables);
328f1845c06SShawn McCarney 
329f1845c06SShawn McCarney } // namespace internal
330f1845c06SShawn McCarney 
33138f85004SShawn McCarney } // namespace phosphor::power::json_parser_utils
332