18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#ifndef API_UTIL_JSON_H 178bf80f4bSopenharmony_ci#define API_UTIL_JSON_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <core/json/json.h> 208bf80f4bSopenharmony_ci 218bf80f4bSopenharmony_ci#include <util/namespace.h> 228bf80f4bSopenharmony_ci 238bf80f4bSopenharmony_ciUTIL_BEGIN_NAMESPACE() 248bf80f4bSopenharmony_ci 258bf80f4bSopenharmony_ciconstexpr int JSON_DEFAULT_INDENTATION = 2; 268bf80f4bSopenharmony_ci 278bf80f4bSopenharmony_citemplate<typename T> 288bf80f4bSopenharmony_ciBASE_NS::string to_formatted_string(const CORE_NS::json::value_t<T>& value, 298bf80f4bSopenharmony_ci const size_t indentation = JSON_DEFAULT_INDENTATION, const size_t currentIndentation = 0); 308bf80f4bSopenharmony_ci 318bf80f4bSopenharmony_ci#ifdef JSON_IMPL 328bf80f4bSopenharmony_ciusing namespace CORE_NS::json; 338bf80f4bSopenharmony_ci 348bf80f4bSopenharmony_citemplate<typename T> 358bf80f4bSopenharmony_civoid append(BASE_NS::string& out, const typename value_t<T>::string& string) 368bf80f4bSopenharmony_ci{ 378bf80f4bSopenharmony_ci out += '"'; 388bf80f4bSopenharmony_ci out.append(escape(string)); 398bf80f4bSopenharmony_ci out += '"'; 408bf80f4bSopenharmony_ci} 418bf80f4bSopenharmony_ci 428bf80f4bSopenharmony_citemplate<typename T> 438bf80f4bSopenharmony_civoid append(BASE_NS::string& out, const typename value_t<T>::object& object, const size_t indentation, 448bf80f4bSopenharmony_ci size_t currentIndentation) 458bf80f4bSopenharmony_ci{ 468bf80f4bSopenharmony_ci if (object.empty()) { 478bf80f4bSopenharmony_ci // Keep empty objects on one row. 488bf80f4bSopenharmony_ci out.append("{}"); 498bf80f4bSopenharmony_ci return; 508bf80f4bSopenharmony_ci } 518bf80f4bSopenharmony_ci 528bf80f4bSopenharmony_ci out += "{\n"; 538bf80f4bSopenharmony_ci currentIndentation += indentation; 548bf80f4bSopenharmony_ci out.append(currentIndentation, ' '); 558bf80f4bSopenharmony_ci 568bf80f4bSopenharmony_ci int count = 0; 578bf80f4bSopenharmony_ci for (const auto& v : object) { 588bf80f4bSopenharmony_ci if (count++) { 598bf80f4bSopenharmony_ci out += ",\n"; 608bf80f4bSopenharmony_ci out.append(currentIndentation, ' '); 618bf80f4bSopenharmony_ci } 628bf80f4bSopenharmony_ci append<T>(out, v.key); 638bf80f4bSopenharmony_ci out += ": "; 648bf80f4bSopenharmony_ci out += to_formatted_string(v.value, indentation, currentIndentation); 658bf80f4bSopenharmony_ci } 668bf80f4bSopenharmony_ci currentIndentation -= indentation; 678bf80f4bSopenharmony_ci out += '\n'; 688bf80f4bSopenharmony_ci out.append(currentIndentation, ' '); 698bf80f4bSopenharmony_ci out += '}'; 708bf80f4bSopenharmony_ci} 718bf80f4bSopenharmony_ci 728bf80f4bSopenharmony_citemplate<typename T> 738bf80f4bSopenharmony_civoid append( 748bf80f4bSopenharmony_ci BASE_NS::string& out, const typename value_t<T>::array& array, const size_t indentation, size_t currentIndentation) 758bf80f4bSopenharmony_ci{ 768bf80f4bSopenharmony_ci if (array.empty()) { 778bf80f4bSopenharmony_ci // Keep empty arrays on one row. 788bf80f4bSopenharmony_ci out.append("[]"); 798bf80f4bSopenharmony_ci return; 808bf80f4bSopenharmony_ci } 818bf80f4bSopenharmony_ci 828bf80f4bSopenharmony_ci out += "[\n"; 838bf80f4bSopenharmony_ci currentIndentation += indentation; 848bf80f4bSopenharmony_ci out.append(currentIndentation, ' '); 858bf80f4bSopenharmony_ci int count = 0; 868bf80f4bSopenharmony_ci for (const auto& v : array) { 878bf80f4bSopenharmony_ci if (count++) { 888bf80f4bSopenharmony_ci out += ",\n"; 898bf80f4bSopenharmony_ci out.append(currentIndentation, ' '); 908bf80f4bSopenharmony_ci } 918bf80f4bSopenharmony_ci out += to_formatted_string(v, indentation, currentIndentation); 928bf80f4bSopenharmony_ci } 938bf80f4bSopenharmony_ci currentIndentation -= indentation; 948bf80f4bSopenharmony_ci out += '\n'; 958bf80f4bSopenharmony_ci out.append(currentIndentation, ' '); 968bf80f4bSopenharmony_ci out += ']'; 978bf80f4bSopenharmony_ci} 988bf80f4bSopenharmony_ci 998bf80f4bSopenharmony_citemplate<typename T> 1008bf80f4bSopenharmony_civoid append(BASE_NS::string& out, const double floatingPoint) 1018bf80f4bSopenharmony_ci{ 1028bf80f4bSopenharmony_ci constexpr const char* FLOATING_FORMAT_STR = "%.17g"; 1038bf80f4bSopenharmony_ci const int size = snprintf(nullptr, 0, FLOATING_FORMAT_STR, floatingPoint); 1048bf80f4bSopenharmony_ci const size_t oldSize = out.size(); 1058bf80f4bSopenharmony_ci out.resize(oldSize + size); 1068bf80f4bSopenharmony_ci const size_t newSize = out.size(); 1078bf80f4bSopenharmony_ci // "At most bufsz - 1 characters are written." string has size() characters + 1 for null so use size() + 1088bf80f4bSopenharmony_ci // 1 as the total size. If resize() failed string size() hasn't changed, buffer will point to the null 1098bf80f4bSopenharmony_ci // character and bufsz will be 1 i.e. only the null character will be written. 1108bf80f4bSopenharmony_ci} 1118bf80f4bSopenharmony_ci 1128bf80f4bSopenharmony_citemplate<typename T> 1138bf80f4bSopenharmony_ciBASE_NS::string to_formatted_string(const value_t<T>& value, const size_t indentation, const size_t currentIndentation) 1148bf80f4bSopenharmony_ci{ 1158bf80f4bSopenharmony_ci BASE_NS::string out; 1168bf80f4bSopenharmony_ci switch (value.type) { 1178bf80f4bSopenharmony_ci case type::uninitialized: 1188bf80f4bSopenharmony_ci out += "{}"; 1198bf80f4bSopenharmony_ci break; 1208bf80f4bSopenharmony_ci 1218bf80f4bSopenharmony_ci case type::object: 1228bf80f4bSopenharmony_ci append<T>(out, value.object_, indentation, currentIndentation); 1238bf80f4bSopenharmony_ci break; 1248bf80f4bSopenharmony_ci 1258bf80f4bSopenharmony_ci case type::array: 1268bf80f4bSopenharmony_ci append<T>(out, value.array_, indentation, currentIndentation); 1278bf80f4bSopenharmony_ci break; 1288bf80f4bSopenharmony_ci 1298bf80f4bSopenharmony_ci case type::string: 1308bf80f4bSopenharmony_ci append<T>(out, value.string_); 1318bf80f4bSopenharmony_ci break; 1328bf80f4bSopenharmony_ci 1338bf80f4bSopenharmony_ci case type::floating_point: 1348bf80f4bSopenharmony_ci append<T>(out, value.float_); 1358bf80f4bSopenharmony_ci break; 1368bf80f4bSopenharmony_ci 1378bf80f4bSopenharmony_ci case type::signed_int: 1388bf80f4bSopenharmony_ci out += BASE_NS::to_string(value.signed_); 1398bf80f4bSopenharmony_ci break; 1408bf80f4bSopenharmony_ci 1418bf80f4bSopenharmony_ci case type::unsigned_int: 1428bf80f4bSopenharmony_ci out += BASE_NS::to_string(value.unsigned_); 1438bf80f4bSopenharmony_ci break; 1448bf80f4bSopenharmony_ci 1458bf80f4bSopenharmony_ci case type::boolean: 1468bf80f4bSopenharmony_ci if (value.boolean_) { 1478bf80f4bSopenharmony_ci out += "true"; 1488bf80f4bSopenharmony_ci } else { 1498bf80f4bSopenharmony_ci out += "false"; 1508bf80f4bSopenharmony_ci } 1518bf80f4bSopenharmony_ci break; 1528bf80f4bSopenharmony_ci 1538bf80f4bSopenharmony_ci case type::null: 1548bf80f4bSopenharmony_ci out += "null"; 1558bf80f4bSopenharmony_ci break; 1568bf80f4bSopenharmony_ci 1578bf80f4bSopenharmony_ci default: 1588bf80f4bSopenharmony_ci break; 1598bf80f4bSopenharmony_ci } 1608bf80f4bSopenharmony_ci return out; 1618bf80f4bSopenharmony_ci} 1628bf80f4bSopenharmony_ci 1638bf80f4bSopenharmony_ci// Explicit template instantiation for the needed types. 1648bf80f4bSopenharmony_citemplate BASE_NS::string to_formatted_string( 1658bf80f4bSopenharmony_ci const value& value, const size_t indentation, const size_t currentIndentation); 1668bf80f4bSopenharmony_citemplate BASE_NS::string to_formatted_string( 1678bf80f4bSopenharmony_ci const standalone_value& value, const size_t indentation, const size_t currentIndentation); 1688bf80f4bSopenharmony_ci 1698bf80f4bSopenharmony_ci#endif // JSON_IMPL 1708bf80f4bSopenharmony_ci 1718bf80f4bSopenharmony_ciUTIL_END_NAMESPACE() 1728bf80f4bSopenharmony_ci 1738bf80f4bSopenharmony_ci#endif // API_UTIL_JSON_H 174