[dali_2.3.24] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / event / common / demangler-unix.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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  */
17
18 // EXTERNAL HEADER
19 #include <string_view>
20
21 // FILE HEADER
22 #include <dali/internal/event/common/demangler.h>
23
24 namespace
25 {
26 // Extracts the number from the src view and update the view.
27 size_t ExtractNumber(std::string_view& src)
28 {
29   auto   IsDigit = [](char c) { return (c >= '0' && c <= '9'); };
30   size_t number  = 0;
31
32   for(auto i = 0u; i < src.size(); ++i)
33   {
34     char c = src[i];
35     if(!IsDigit(c))
36     {
37       //update the src view.
38       src.remove_prefix(i);
39       break;
40     }
41     else
42     {
43       number = 10 * number + (c - '0');
44     }
45   }
46
47   return number;
48 }
49
50 /**
51  * @brief Demangle a nested typeid name into its component parts and return
52  * the last component.
53  * A nested type name is one containing namespaces and class names only.
54  *   eg ExtractDemangleNestedName(typeid(Dali::Actor).name());
55  * @param[in] typeIdName The type id name string to demangle.
56  * @returns the last component "Actor" or an empty string_view
57  */
58 std::string_view ExtractDemangleNestedName(std::string_view mangledName)
59 {
60   if(mangledName.empty())
61   {
62     return {};
63   }
64
65   // classes nested inside a namespace starts with 'N' and ends with 'E'
66   // so trim those
67   if(mangledName.front() == 'N' && mangledName.back() == 'E')
68   {
69     mangledName.remove_prefix(1);
70     mangledName.remove_suffix(1);
71   }
72
73   std::string_view result;
74   while(!mangledName.empty())
75   {
76     auto length = ExtractNumber(mangledName);
77     result      = {mangledName.data(), length};
78     mangledName.remove_prefix(length);
79   }
80
81   return result;
82 }
83
84 } // namespace
85
86 namespace Dali
87 {
88 namespace Internal
89 {
90 std::string DemangleClassName(const char* typeIdName)
91 {
92   return std::string(ExtractDemangleNestedName(typeIdName));
93 }
94
95 } // namespace Internal
96
97 } // namespace Dali