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