From 7f6cbc91758bfe963abe05130e66f697a0358436 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Thu, 21 Aug 2025 15:44:30 +0800 Subject: [PATCH] ApViewer Issue: 1 Signed-off-by: yp9522 --- .../ap_file/pgo_method_type_set.cpp | 18 +- .../ap_file/pgo_method_type_set.h | 12 +- .../pgo_profiler/ap_file/pool_template.h | 12 +- ecmascript/pgo_profiler/pgo_profiler_info.cpp | 20 +- ecmascript/pgo_profiler/pgo_profiler_info.h | 6 +- .../pgo_profiler/types/pgo_profile_type.h | 19 +- .../pgo_profiler/types/pgo_profiler_type.h | 35 ++-- tools/ap_file_viewer/native/BUILD.gn | 6 +- .../native/include/cjson_converter.h | 35 ++++ .../native/include/prof_convert_json.h | 172 ------------------ .../native/include/prof_json_value.h | 135 ++++++++++++++ .../native/src/cjson_converter.cpp | 77 ++++++++ .../native/src/prof_dump_json.cpp | 23 ++- 13 files changed, 321 insertions(+), 249 deletions(-) create mode 100644 tools/ap_file_viewer/native/include/cjson_converter.h delete mode 100644 tools/ap_file_viewer/native/include/prof_convert_json.h create mode 100644 tools/ap_file_viewer/native/include/prof_json_value.h create mode 100644 tools/ap_file_viewer/native/src/cjson_converter.cpp diff --git a/ecmascript/pgo_profiler/ap_file/pgo_method_type_set.cpp b/ecmascript/pgo_profiler/ap_file/pgo_method_type_set.cpp index 0c2de2645a..87dc1ec862 100644 --- a/ecmascript/pgo_profiler/ap_file/pgo_method_type_set.cpp +++ b/ecmascript/pgo_profiler/ap_file/pgo_method_type_set.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -224,29 +224,29 @@ void PGOMethodTypeSet::ProcessToText(std::string &text) const } } -void PGOMethodTypeSet::ProcessToJson(ProfileType::VariantVector &typeArray) const +void PGOMethodTypeSet::ProcessToJson(prof_json::JsonArrayPtr &typeArray) const { for (auto typeInfoIter : scalarOpTypeInfos_) { if (typeInfoIter.GetType().IsNone()) { continue; } - ProfileType::StringMap type; - type.insert(std::make_pair(DumpJsonUtils::TYPE_OFFSET, std::to_string(typeInfoIter.GetOffset()))); + auto type = prof_json::JsonObject::Create(); + type->Add(DumpJsonUtils::TYPE_OFFSET, std::to_string(typeInfoIter.GetOffset())); typeInfoIter.GetType().GetTypeJson(type); - typeArray.push_back(type); + typeArray->Add(std::move(type)); } for (auto rwScalarOpTypeInfoIter : rwScalarOpTypeInfos_) { if (rwScalarOpTypeInfoIter.GetCount() == 0) { continue; } - ProfileType::MapVector sameOffsetTypeArray; + auto sameOffsetTypeArray = prof_json::JsonArray::Create(); rwScalarOpTypeInfoIter.ProcessToJson(sameOffsetTypeArray); - typeArray.push_back(sameOffsetTypeArray); + typeArray->Add(std::move(sameOffsetTypeArray)); } for (const auto &defTypeInfoIter : objDefOpTypeInfos_) { - std::vector sameOffsetTypeArray; + auto sameOffsetTypeArray = prof_json::JsonArray::Create(); defTypeInfoIter.ProcessToJson(sameOffsetTypeArray); - typeArray.push_back(sameOffsetTypeArray); + typeArray->Add(std::move(sameOffsetTypeArray)); } } } // namespace panda::ecmascript::pgo diff --git a/ecmascript/pgo_profiler/ap_file/pgo_method_type_set.h b/ecmascript/pgo_profiler/ap_file/pgo_method_type_set.h index e3a9700f94..8deeecdd80 100644 --- a/ecmascript/pgo_profiler/ap_file/pgo_method_type_set.h +++ b/ecmascript/pgo_profiler/ap_file/pgo_method_type_set.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -112,7 +112,7 @@ public: bool ParseFromText(const std::string &typeString); void ProcessToText(std::string &text) const; - void ProcessToJson(ProfileType::VariantVector &typeArray) const; + void ProcessToJson(prof_json::JsonArrayPtr &typeArray) const; NO_COPY_SEMANTIC(PGOMethodTypeSet); NO_MOVE_SEMANTIC(PGOMethodTypeSet); @@ -210,12 +210,12 @@ private: text += DumpUtils::NEW_LINE + DumpUtils::ALIGN + DumpUtils::ALIGN + DumpUtils::ARRAY_END; } - void ProcessToJson(ProfileType::MapVector &typeArray) const + void ProcessToJson(prof_json::JsonArrayPtr &typeArray) const { for (uint32_t i = 0; i < type_.GetCount(); i++) { - std::vector sameOffsetTypeArray; + auto sameOffsetTypeArray = prof_json::JsonArray::Create(); type_.GetObjectInfo(i).GetInfoJson(sameOffsetTypeArray, std::to_string(GetOffset())); - typeArray.push_back(sameOffsetTypeArray); + typeArray->Add(std::move(sameOffsetTypeArray)); } } @@ -292,7 +292,7 @@ private: text += DumpUtils::NEW_LINE + DumpUtils::ALIGN + DumpUtils::ALIGN + DumpUtils::ARRAY_END; } - void ProcessToJson(std::vector &sameOffsetTypeArray) const + void ProcessToJson(prof_json::JsonArrayPtr &sameOffsetTypeArray) const { this->GetType().GetTypeJson(sameOffsetTypeArray, std::to_string(this->GetOffset())); } diff --git a/ecmascript/pgo_profiler/ap_file/pool_template.h b/ecmascript/pgo_profiler/ap_file/pool_template.h index 73d56b00d1..f26eb94e5a 100644 --- a/ecmascript/pgo_profiler/ap_file/pool_template.h +++ b/ecmascript/pgo_profiler/ap_file/pool_template.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -162,13 +162,13 @@ public: return true; } - void ProcessToJson(std::vector &abcPoolArray) + void ProcessToJson(prof_json::JsonArrayPtr &abcPoolArray) { for (auto &entry : pool_) { - ProfileType::StringMap abcPool; - abcPool.insert(std::make_pair(DumpJsonUtils::ABC_ID, std::to_string(entry.first))); - abcPool.insert(std::make_pair(DumpJsonUtils::ABC_FILE, entry.second.GetData())); - abcPoolArray.push_back(abcPool); + auto abcPool = prof_json::JsonObject::Create(); + abcPool->Add(DumpJsonUtils::ABC_ID, std::to_string(entry.first)); + abcPool->Add(DumpJsonUtils::ABC_FILE, std::string(entry.second.GetData())); + abcPoolArray->Add(std::move(abcPool)); } } uint32_t ParseFromBinary([[maybe_unused]] PGOContext &context, void **buffer, diff --git a/ecmascript/pgo_profiler/pgo_profiler_info.cpp b/ecmascript/pgo_profiler/pgo_profiler_info.cpp index bca2240159..f3b31d5ad4 100644 --- a/ecmascript/pgo_profiler/pgo_profiler_info.cpp +++ b/ecmascript/pgo_profiler/pgo_profiler_info.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -150,11 +150,11 @@ void PGOMethodInfo::ProcessToText(std::string &text) const text += GetMethodName(); } -void PGOMethodInfo::ProcessToJson(ProfileType::VariantMap &function) const +void PGOMethodInfo::ProcessToJson(prof_json::JsonObjectPtr &function) const { std::string methodName = GetMethodName(); std::string functionName = methodName + "(" + std::to_string(GetMethodId().GetOffset()) + ")"; - function.insert(std::make_pair(DumpJsonUtils::FUNCTION_NAME, functionName)); + function->Add(DumpJsonUtils::FUNCTION_NAME, functionName); } std::vector PGOMethodInfo::ParseFromText(const std::string &infoString) @@ -529,25 +529,25 @@ void PGOMethodInfoMap::ProcessToText(uint32_t threshold, const CString &recordNa } } -void PGOMethodInfoMap::ProcessToJson(uint32_t threshold, ProfileType::jModuleType &jModule) const +void PGOMethodInfoMap::ProcessToJson(uint32_t threshold, prof_json::JsonObjectPtr &jModule) const { - std::vector functionArray; + auto functionArray = prof_json::JsonArray::Create(); for (auto methodInfoIter : methodInfos_) { auto methodInfo = methodInfoIter.second; if (methodInfo->IsFilter(threshold)) { continue; } - ProfileType::VariantMap function; + auto function = prof_json::JsonObject::Create(); methodInfo->ProcessToJson(function); auto iter = methodTypeInfos_.find(methodInfo->GetMethodId()); if (iter != methodTypeInfos_.end()) { - ProfileType::VariantVector typeArray; + auto typeArray = prof_json::JsonArray::Create(); iter->second->ProcessToJson(typeArray); - function.insert(std::make_pair(DumpJsonUtils::TYPE, typeArray)); + function->Add(DumpJsonUtils::TYPE, std::move(typeArray)); } - functionArray.push_back(function); + functionArray->Add(std::move(function)); } - jModule.insert(std::make_pair(DumpJsonUtils::FUNCTION, functionArray)); + jModule->Add(DumpJsonUtils::FUNCTION, std::move(functionArray)); } bool PGOMethodIdSet::ParseFromBinary(PGOContext &context, void **buffer) diff --git a/ecmascript/pgo_profiler/pgo_profiler_info.h b/ecmascript/pgo_profiler/pgo_profiler_info.h index 8365496610..50723aa804 100644 --- a/ecmascript/pgo_profiler/pgo_profiler_info.h +++ b/ecmascript/pgo_profiler/pgo_profiler_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -262,7 +262,7 @@ public: static std::vector ParseFromText(const std::string &infoString); void ProcessToText(std::string &text) const; - void ProcessToJson(ProfileType::VariantMap &function) const; + void ProcessToJson(prof_json::JsonObjectPtr &function) const; NO_COPY_SEMANTIC(PGOMethodInfo); NO_MOVE_SEMANTIC(PGOMethodInfo); @@ -326,7 +326,7 @@ public: bool ParseFromText(Chunk *chunk, uint32_t threshold, const std::vector &content); void ProcessToText(uint32_t threshold, const CString &recordName, std::ofstream &stream) const; - void ProcessToJson(uint32_t threshold, ProfileType::jModuleType &jModule) const; + void ProcessToJson(uint32_t threshold, prof_json::JsonObjectPtr &jModule) const; const CMap &GetMethodInfos() const { diff --git a/ecmascript/pgo_profiler/types/pgo_profile_type.h b/ecmascript/pgo_profiler/types/pgo_profile_type.h index fa5c27cd97..54a86e6525 100644 --- a/ecmascript/pgo_profiler/types/pgo_profile_type.h +++ b/ecmascript/pgo_profiler/types/pgo_profile_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -32,6 +32,7 @@ #include "ecmascript/on_heap.h" #include "libpandabase/utils/bit_field.h" #include "libpandabase/macros.h" +#include "tools/ap_file_viewer/native/include/prof_json_value.h" namespace panda::ecmascript::pgo { class ProfileTypeRef; @@ -76,12 +77,6 @@ public: using IsRootBits = KindBits::NextFlag; // 50 using EverOutOfBoundsBits = IsRootBits::NextFlag; // 51 - using StringMap = std::multimap; - using MapVector = std::vector>; - using VariantVector = std::vector>>; - using VariantMap = std::multimap>; - using jModuleType = std::multimap>>; - class BuiltinsId { public: static constexpr uint32_t BUILTINS_ID_NUM = 16; @@ -422,11 +417,11 @@ public: return stream.str(); } - void GetTypeJson(StringMap &type) const + void GetTypeJson(prof_json::JsonObjectPtr &type) const { - type.insert(std::make_pair(DumpJsonUtils::IS_ROOT, IsRootType() ? "true" : "false")); - type.insert(std::make_pair(DumpJsonUtils::KIND, std::to_string(static_cast(GetKind())))); - type.insert(std::make_pair(DumpJsonUtils::ABC_ID, std::to_string(GetAbcId()))); + type->Add(DumpJsonUtils::IS_ROOT, IsRootType() ? "true" : "false"); + type->Add(DumpJsonUtils::KIND, std::to_string(static_cast(GetKind()))); + type->Add(DumpJsonUtils::ABC_ID, std::to_string(GetAbcId())); std::string strId; if (IsBuiltinsArray()) { auto arrayId = BuiltinsArrayId(GetId()); @@ -438,7 +433,7 @@ public: auto builtinsId = BuiltinsId(GetId()); strId = builtinsId.GetIdToString(); } - type.insert(std::make_pair(DumpJsonUtils::ID, strId)); + type->Add(DumpJsonUtils::ID, strId); } friend std::ostream& operator<<(std::ostream& os, const ProfileType& type) diff --git a/ecmascript/pgo_profiler/types/pgo_profiler_type.h b/ecmascript/pgo_profiler/types/pgo_profiler_type.h index 0db8eeaa1b..1f9d19e92b 100644 --- a/ecmascript/pgo_profiler/types/pgo_profiler_type.h +++ b/ecmascript/pgo_profiler/types/pgo_profiler_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -256,18 +256,17 @@ public: } } - void GetTypeJson(ProfileType::StringMap &type) const + void GetTypeJson(prof_json::JsonObjectPtr &type) const { if (IsPrimitiveType()) { - type.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, - std::to_string(static_cast(std::get(type_))))); + type->Add(DumpJsonUtils::TYPE_NAME, std::to_string(static_cast(std::get(type_)))); } else { - type.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, "Type")); + type->Add(DumpJsonUtils::TYPE_NAME, "Type"); std::get(type_).GetTypeJson(type); } if (IsScalarOpType()) { if (!ToString().empty()) { - type.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, ToString())); + type->Add(DumpJsonUtils::TYPE_NAME, ToString()); } } } @@ -623,16 +622,16 @@ public: template void AddTypeJson(const char *typeName, const T& type, std::string typeOffset, - std::vector &typeArray) const + prof_json::JsonArrayPtr &typeArray) const { - ProfileType::StringMap typeJson; - typeJson.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, typeName)); - typeJson.insert(std::make_pair(DumpJsonUtils::TYPE_OFFSET, typeOffset)); + auto typeJson = prof_json::JsonObject::Create(); + typeJson->Add(DumpJsonUtils::TYPE_NAME, typeName); + typeJson->Add(DumpJsonUtils::TYPE_OFFSET, typeOffset); type.GetTypeJson(typeJson); - typeArray.push_back(typeJson); + typeArray->Add(std::move(typeJson)); } - void GetInfoJson(std::vector &typeArray, std::string typeoffset) const + void GetInfoJson(prof_json::JsonArrayPtr &typeArray, std::string typeoffset) const { AddTypeJson("receiverRootType", receiverRootType_, typeoffset, typeArray); AddTypeJson("receiverType", receiverType_, typeoffset, typeArray); @@ -912,16 +911,16 @@ public: template void AddTypeJson(const char *typeName, const T& type, std::string typeOffset, - std::vector &sameOffsetTypeArray) const + prof_json::JsonArrayPtr &sameOffsetTypeArray) const { - ProfileType::StringMap typeJson; - typeJson.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, typeName)); - typeJson.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, typeOffset)); + auto typeJson = prof_json::JsonObject::Create(); + typeJson->Add(DumpJsonUtils::TYPE_NAME, typeName); + typeJson->Add(DumpJsonUtils::TYPE_NAME, typeOffset); type.GetTypeJson(typeJson); - sameOffsetTypeArray.push_back(typeJson); + sameOffsetTypeArray->Add(std::move(typeJson)); } - void GetTypeJson(std::vector &sameOffsetTypeArray, + void GetTypeJson(prof_json::JsonArrayPtr &sameOffsetTypeArray, std::string typeOffset) const { AddTypeJson("localType", type_, typeOffset, sameOffsetTypeArray); diff --git a/tools/ap_file_viewer/native/BUILD.gn b/tools/ap_file_viewer/native/BUILD.gn index c70ae4da4e..3a772af95c 100644 --- a/tools/ap_file_viewer/native/BUILD.gn +++ b/tools/ap_file_viewer/native/BUILD.gn @@ -25,7 +25,10 @@ ohos_static_library("profDumpJsonStatic") { ubsan = true } } - sources = [ "src/prof_dump_json.cpp" ] + sources = [ + "src/prof_dump_json.cpp", + "src/cjson_converter.cpp" + ] include_dirs = [ "include" ] cflags = [ "-g" ] if (is_mingw) { @@ -35,6 +38,7 @@ ohos_static_library("profDumpJsonStatic") { "$js_root:libark_js_intl_set", "$js_root:libark_jsruntime_set", "$js_root/ecmascript/compiler:libark_mock_stub_set", + "$js_root:libcommon_components_set", ] external_deps = [ "cJSON:cjson_static", diff --git a/tools/ap_file_viewer/native/include/cjson_converter.h b/tools/ap_file_viewer/native/include/cjson_converter.h new file mode 100644 index 0000000000..b1b361c169 --- /dev/null +++ b/tools/ap_file_viewer/native/include/cjson_converter.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CJSON_CONVERTER_H +#define CJSON_CONVERTER_H + +#include "prof_json_value.h" +#include "third_party/cJSON/cJSON.h" + +namespace prof_json { + +class CJsonConverter { +public: + static cJSON *Convert(const JsonValue *value); + +private: + static cJSON *ConvertObject(const JsonObject *object); + static cJSON *ConvertArray(const JsonArray *array); +}; + +} // namespace prof_json + +#endif // CJSON_CONVERTER_H diff --git a/tools/ap_file_viewer/native/include/prof_convert_json.h b/tools/ap_file_viewer/native/include/prof_convert_json.h deleted file mode 100644 index 1e6d0499e9..0000000000 --- a/tools/ap_file_viewer/native/include/prof_convert_json.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NATIVE_CONVERT_JSON_H -#define NATIVE_CONVERT_JSON_H - -#include "ecmascript/log_wrapper.h" -#include "ecmascript/pgo_profiler/pgo_profiler_manager.h" -#include "third_party/cJSON/cJSON.h" - -namespace native { -using namespace panda::ecmascript::pgo; -class JsonConverter { -public: - cJSON* ConvertStr(const std::vector& data) const - { - return HandleMapVector(data); - } - - cJSON* Convert(const std::vector& data) const - { - cJSON* jsonArray = cJSON_CreateArray(); - if (jsonArray == nullptr) { - return nullptr; - } - for (const auto& complexMap : data) { - cJSON* jsonObject = cJSON_CreateObject(); - if (jsonObject == nullptr) { - return nullptr; - } - for (const auto& [key, value] : complexMap) { - cJSON* jsonValue = HandleVariant(value); - if (jsonValue == nullptr) { - return nullptr; - } - cJSON_AddItemToObject(jsonObject, key.c_str(), jsonValue); - } - cJSON_AddItemToArray(jsonArray, jsonObject); - } - return jsonArray; - } - -private: - cJSON* HandleVariant(const std::variant>& value) const - { - if (std::holds_alternative(value)) { - return cJSON_CreateString(std::get(value).c_str()); - } else if (std::holds_alternative>(value)) { - return HandleVariantMap(std::get>(value)); - } - return nullptr; - } - - cJSON* HandleVariantMap(const std::vector& vaMap) const - { - cJSON* jsonArray = cJSON_CreateArray(); - if (jsonArray == nullptr) { - return nullptr; - } - for (const auto& nestedItem : vaMap) { - cJSON* mapObject = cJSON_CreateObject(); - if (mapObject == nullptr) { - return nullptr; - } - for (const auto& [key, value] : nestedItem) { - cJSON* jsonValue = HandleVariantNext(value); - if (jsonValue == nullptr) { - return nullptr; - } - cJSON_AddItemToObject(mapObject, key.c_str(), jsonValue); - } - cJSON_AddItemToArray(jsonArray, mapObject); - } - return jsonArray; - } - - cJSON* HandleVariantNext(const std::variant& value) const - { - if (std::holds_alternative(value)) { - return cJSON_CreateString(std::get(value).c_str()); - } else if (std::holds_alternative(value)) { - return HandleVariantVector(std::get(value)); - } - return nullptr; - } - - cJSON* HandleVariantVector(const ProfileType::VariantVector& vec) const - { - cJSON* jsonArray = cJSON_CreateArray(); - if (jsonArray == nullptr) { - return nullptr; - } - for (const auto& nestedItem : vec) { - if (std::holds_alternative(nestedItem)) { - cJSON* mapObject = HandleStringMap(std::get(nestedItem)); - cJSON_AddItemToArray(jsonArray, mapObject); - } else if (std::holds_alternative(nestedItem)) { - cJSON* innerInnerArray = HandleNestedMapVector(std::get(nestedItem)); - cJSON_AddItemToArray(jsonArray, innerInnerArray); - } else if (std::holds_alternative>(nestedItem)) { - cJSON* arrayOfMaps = HandleMapVector(std::get>(nestedItem)); - cJSON_AddItemToArray(jsonArray, arrayOfMaps); - } - } - return jsonArray; - } - - cJSON* HandleStringMap(const ProfileType::StringMap& stringMap) const - { - cJSON* mapObject = cJSON_CreateObject(); - if (mapObject == nullptr) { - return nullptr; - } - for (const auto& [mapKey, mapValue] : stringMap) { - cJSON_AddStringToObject(mapObject, mapKey.c_str(), mapValue.c_str()); - } - return mapObject; - } - - cJSON* HandleMapVector(const std::vector& vecMap) const - { - cJSON* arrayOfMaps = cJSON_CreateArray(); - if (arrayOfMaps == nullptr) { - return nullptr; - } - for (const auto& stringMap : vecMap) { - cJSON* mapObject = HandleStringMap(stringMap); - if (mapObject == nullptr) { - return nullptr; - } - cJSON_AddItemToArray(arrayOfMaps, mapObject); - } - return arrayOfMaps; - } - - cJSON* HandleNestedMapVector(const ProfileType::MapVector& vecVec) const - { - cJSON* innerInnerArray = cJSON_CreateArray(); - if (innerInnerArray == nullptr) { - return nullptr; - } - for (const auto& vec1 : vecVec) { - cJSON* innerArray = cJSON_CreateArray(); - if (innerArray == nullptr) { - return nullptr; - } - for (const auto& stringMap : vec1) { - cJSON* mapObject = HandleStringMap(stringMap); - if (mapObject == nullptr) { - return nullptr; - } - cJSON_AddItemToArray(innerArray, mapObject); - } - cJSON_AddItemToArray(innerInnerArray, innerArray); - } - return innerInnerArray; - } -}; -} // namespace native -#endif // NATIVE_CONVERT_JSON_H diff --git a/tools/ap_file_viewer/native/include/prof_json_value.h b/tools/ap_file_viewer/native/include/prof_json_value.h new file mode 100644 index 0000000000..8d6fb47ca7 --- /dev/null +++ b/tools/ap_file_viewer/native/include/prof_json_value.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JSON_VALUE_H +#define JSON_VALUE_H + +#include +#include +#include +#include + +namespace prof_json { + +enum class JsonType { + STRING, + OBJECT, + ARRAY, +}; + +class JsonValue { +public: + virtual ~JsonValue() = default; + virtual JsonType GetType() const = 0; +}; + +using JsonValuePtr = std::unique_ptr; + +class JsonString : public JsonValue { +public: + JsonString(const std::string &val) : value_(val) {} + + static std::unique_ptr Create(const std::string &value) + { + return std::make_unique(value); + } + + JsonType GetType() const override + { + return JsonType::STRING; + } + + const std::string &GetValue() const + { + return value_; + } + +private: + std::string value_; +}; + +class JsonObject : public JsonValue { +public: + static std::unique_ptr Create() + { + return std::make_unique(); + } + + JsonType GetType() const override + { + return JsonType::OBJECT; + } + + const std::vector> &GetMembers() const + { + return members_; + } + + void Add(const std::string &key, JsonValuePtr val) + { + if (val) { + members_.emplace_back(key, std::move(val)); + } + } + + void Add(const std::string &key, const std::string &value) + { + Add(key, std::make_unique(value)); + } + +private: + std::vector> members_; +}; + +class JsonArray : public JsonValue { +public: + static std::unique_ptr Create() + { + return std::make_unique(); + } + + JsonType GetType() const override + { + return JsonType::ARRAY; + } + + const std::vector &GetElements() const + { + return elements_; + } + + void Add(JsonValuePtr val) + { + if (val) { + elements_.push_back(std::move(val)); + } + } + + void Add(const std::string &value) + { + Add(std::make_unique(value)); + } + +private: + std::vector elements_; +}; + +using JsonStringPtr = std::unique_ptr; +using JsonObjectPtr = std::unique_ptr; +using JsonArrayPtr = std::unique_ptr; + +} // namespace prof_json + +#endif // JSON_VALUE_H diff --git a/tools/ap_file_viewer/native/src/cjson_converter.cpp b/tools/ap_file_viewer/native/src/cjson_converter.cpp new file mode 100644 index 0000000000..a19deecff0 --- /dev/null +++ b/tools/ap_file_viewer/native/src/cjson_converter.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cjson_converter.h" +#include + +namespace prof_json { + +cJSON *CJsonConverter::Convert(const JsonValue *value) +{ + if (value == nullptr) { + return cJSON_CreateNull(); + } + + switch (value->GetType()) { + case JsonType::STRING: { + auto jsonString = static_cast(value); + return cJSON_CreateString(jsonString->GetValue().c_str()); + } + case JsonType::OBJECT: { + auto jsonObject = static_cast(value); + return ConvertObject(jsonObject); + } + case JsonType::ARRAY: { + auto jsonArray = static_cast(value); + return ConvertArray(jsonArray); + } + default: + return cJSON_CreateNull(); + } +} + +cJSON *CJsonConverter::ConvertObject(const JsonObject *object) +{ + if (object == nullptr) { + return cJSON_CreateNull(); + } + + cJSON *jsonObject = cJSON_CreateObject(); + for (const auto &pair : object->GetMembers()) { + cJSON *jsonValue = Convert(pair.second.get()); + if (jsonValue != nullptr) { + cJSON_AddItemToObject(jsonObject, pair.first.c_str(), jsonValue); + } + } + return jsonObject; +} + +cJSON *CJsonConverter::ConvertArray(const JsonArray *array) +{ + if (array == nullptr) { + return cJSON_CreateNull(); + } + + cJSON *jsonArray = cJSON_CreateArray(); + for (const auto &element : array->GetElements()) { + cJSON *jsonValue = Convert(element.get()); + if (jsonValue != nullptr) { + cJSON_AddItemToArray(jsonArray, jsonValue); + } + } + return jsonArray; +} + +} // namespace prof_json diff --git a/tools/ap_file_viewer/native/src/prof_dump_json.cpp b/tools/ap_file_viewer/native/src/prof_dump_json.cpp index c4386f6634..ac9211928f 100644 --- a/tools/ap_file_viewer/native/src/prof_dump_json.cpp +++ b/tools/ap_file_viewer/native/src/prof_dump_json.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,8 +13,9 @@ * limitations under the License. */ +#include "cjson_converter.h" #include "prof_dump_json.h" -#include "prof_convert_json.h" +#include "prof_json_value.h" #include "ecmascript/log_wrapper.h" #include "ecmascript/pgo_profiler/pgo_profiler_manager.h" #include "ecmascript/pgo_profiler/pgo_utils.h" @@ -30,8 +31,7 @@ size_t ConvertApToJson(const char *path, const size_t pathSize) if (!decoder.LoadFull()) { return 0; } - // parse recordDetailInofo - std::vector modules; + auto modules = prof_json::JsonArray::Create(); auto recordDetailInfos = decoder.GetRecordDetailInfosPtr(); auto recordInfos = recordDetailInfos->GetRecordInfos(); auto recordPool = recordDetailInfos->GetRecordPool(); @@ -40,10 +40,10 @@ size_t ConvertApToJson(const char *path, const size_t pathSize) if (moduleName.empty()) { continue; } - ProfileType::jModuleType oneModule; - oneModule.insert(std::make_pair(DumpJsonUtils::MODULE_NAME, moduleName)); + auto oneModule = prof_json::JsonObject::Create(); + oneModule->Add(DumpJsonUtils::MODULE_NAME, moduleName); iter->second->ProcessToJson(1, oneModule); - modules.push_back(oneModule); + modules->Add(std::move(oneModule)); } // parse abcFilePool cJSON *allMessage = cJSON_CreateObject(); @@ -51,13 +51,12 @@ size_t ConvertApToJson(const char *path, const size_t pathSize) return 0; } - JsonConverter convert; - cJSON* recordDetailInofo = convert.Convert(modules); - cJSON_AddItemToObject(allMessage, DumpJsonUtils::RECORD_DETAIL.c_str(), recordDetailInofo); + cJSON *recordDetailInfo = prof_json::CJsonConverter::Convert(modules.get()); + cJSON_AddItemToObject(allMessage, DumpJsonUtils::RECORD_DETAIL.c_str(), recordDetailInfo); - std::vector abcFilePoolMessage; + auto abcFilePoolMessage = prof_json::JsonArray::Create(); decoder.GetAbcFilePool()->GetPool()->ProcessToJson(abcFilePoolMessage); - cJSON* abcFilePool = convert.ConvertStr(abcFilePoolMessage); + cJSON *abcFilePool = prof_json::CJsonConverter::Convert(abcFilePoolMessage.get()); cJSON_AddItemToObject(allMessage, DumpJsonUtils::ABC_FILE_POOL.c_str(), abcFilePool); char *data = cJSON_PrintUnformatted(allMessage); -- Gitee