Merge "Add an environment variable for long press gesture" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / common / demangler-unix.cpp
1 /*
2  * Copyright (c) 2019 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 // FILE HEADER
19 #include <dali/internal/event/common/demangler.h>
20
21 // INTERNAL HEADERS
22 #include <dali/public-api/common/vector-wrapper.h>
23
24 namespace
25 {
26
27 // true if character represent a digit
28 inline bool IsDigit(char c)
29 {
30   return (c >= '0' && c <= '9');
31 }
32
33 // Gets the number of characters (number is in string)
34 //   start The start position to look for a number
35 //   result The number as an integer
36 //   returns the number of characters used to define the number ie '12' is 2
37 size_t GetNumberOfCharacters(const std::string& s, const size_t& start, int& result)
38 {
39   size_t size = s.size();
40
41   size_t i = start;
42
43   int number = 0;
44
45   for( ; i < size; ++i )
46   {
47     char c = s.at(i);
48     if( !IsDigit( c ) )
49     {
50       break;
51     }
52     else
53     {
54       number = 10 * number + (c - '0');
55     }
56   }
57
58   if( i - start )
59   {
60     result = number;
61   }
62
63   return i - start;
64 }
65
66 /**
67  * @brief Demangle a nested typeid name into its component parts.
68  * A nested type name is one containing namespaces and class names only.
69  *   eg DemangleNestedNames(typeid(Dali::Actor).name());
70  * @param[in] typeIdName The type id name string to demangle.
71  * @returns the demangled list of names ie ["Dali","Actor"] or an empty list
72  */
73 std::vector<std::string> DemangleNestedNames(const char *typeIdName)
74 {
75   // Demangle class name mangled according to the Itanium C++ ABI
76   // Returns demangled names ie "N4Dali8Internal5ActorE" is ["Dali","Internal","Actor"]
77   std::vector<std::string> ret;
78
79   const std::string mangledName(typeIdName);
80
81
82   size_t size = mangledName.size();
83
84   if( size >= 2 )
85   {
86     int number = 0;
87     size_t start = 0;
88
89     // If the class isnt nested in a namespace then it just starts with the
90     // number of characters
91     if(mangledName[0] == 'N' && mangledName[size-1]  == 'E')
92     {
93       start = 1;
94     }
95
96     while( size_t chars = GetNumberOfCharacters(mangledName, start, number) )
97     {
98       ret.push_back( mangledName.substr( start + chars, number ) );
99
100       start += chars + number;
101     }
102   }
103
104   return ret;
105 }
106
107 } // anon namespace
108
109 namespace Dali
110 {
111
112 namespace Internal
113 {
114
115 const std::string DemangleClassName(const char *typeIdName)
116 {
117   std::string name;
118   std::vector<std::string> names = DemangleNestedNames(typeIdName);
119
120   if( names.size() )
121   {
122     name = names[ names.size() - 1 ];
123   }
124
125   return name;
126 }
127
128 } // namespace Internal
129
130 } // namespace Dali