1 /************************************************************************
2 * file name         : common_functions.cpp
3 * ----------------- :
4 * creation time     : 2017/12/06
5 * author            : Victor Zarubkin
6 * email             : v.s.zarubkin@gmail.com
7 * ----------------- :
8 * description       : The file contains implementaion of common functions used by different UI widgets.
9 * ----------------- :
10 * change log        : * 2017/12/06 Victor Zarubkin: Initial commit. Moved sources from common_types.h
11 *                   :
12 *                   : *
13 * ----------------- :
14 * license           : Lightweight profiler library for c++
15 *                   : Copyright(C) 2016-2017  Sergey Yagovtsev, Victor Zarubkin
16 *                   :
17 *                   : Licensed under either of
18 *                   :     * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
19 *                   :     * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0)
20 *                   : at your option.
21 *                   :
22 *                   : The MIT License
23 *                   :
24 *                   : Permission is hereby granted, free of charge, to any person obtaining a copy
25 *                   : of this software and associated documentation files (the "Software"), to deal
26 *                   : in the Software without restriction, including without limitation the rights
27 *                   : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
28 *                   : of the Software, and to permit persons to whom the Software is furnished
29 *                   : to do so, subject to the following conditions:
30 *                   :
31 *                   : The above copyright notice and this permission notice shall be included in all
32 *                   : copies or substantial portions of the Software.
33 *                   :
34 *                   : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
35 *                   : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36 *                   : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
37 *                   : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
38 *                   : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
39 *                   : USE OR OTHER DEALINGS IN THE SOFTWARE.
40 *                   :
41 *                   : The Apache License, Version 2.0 (the "License")
42 *                   :
43 *                   : You may not use this file except in compliance with the License.
44 *                   : You may obtain a copy of the License at
45 *                   :
46 *                   : http://www.apache.org/licenses/LICENSE-2.0
47 *                   :
48 *                   : Unless required by applicable law or agreed to in writing, software
49 *                   : distributed under the License is distributed on an "AS IS" BASIS,
50 *                   : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51 *                   : See the License for the specific language governing permissions and
52 *                   : limitations under the License.
53 ************************************************************************/
54 
55 #include "common_functions.h"
56 
57 namespace profiler_gui {
58 
59     //////////////////////////////////////////////////////////////////////////
60 
timeFactor(qreal _interval)61     qreal timeFactor(qreal _interval)
62     {
63         if (_interval < 1) // interval in nanoseconds
64             return 1e3;
65 
66         if (_interval < 1e3) // interval in microseconds
67             return 1;
68 
69         if (_interval < 1e6) // interval in milliseconds
70             return 1e-3;
71 
72         // interval in seconds
73         return 1e-6;
74     }
75 
76     //////////////////////////////////////////////////////////////////////////
77 
autoTimeStringReal(qreal _interval,int _precision)78     QString autoTimeStringReal(qreal _interval, int _precision)
79     {
80         if (_interval < 1) // interval in nanoseconds
81             return QString("%1 ns").arg(static_cast<quint64>(_interval * 1e3));
82 
83         if (_interval < 1e3) // interval in microseconds
84             return QString("%1 us").arg(_interval, 0, 'f', _precision);
85 
86         if (_interval < 1e6) // interval in milliseconds
87             return QString("%1 ms").arg(_interval * 1e-3, 0, 'f', _precision);
88 
89         // interval in seconds
90         return QString("%1 s").arg(_interval * 1e-6, 0, 'f', _precision);
91     }
92 
autoTimeStringInt(qreal _interval)93     QString autoTimeStringInt(qreal _interval)
94     {
95         if (_interval < 1) // interval in nanoseconds
96             return QString("%1 ns").arg(static_cast<quint64>(_interval * 1e3 + 0.5));
97 
98         if (_interval < 1e3) // interval in microseconds
99             return QString("%1 us").arg(static_cast<quint32>(_interval + 0.5));
100 
101         if (_interval < 1e6) // interval in milliseconds
102             return QString("%1 ms").arg(static_cast<quint32>(_interval * 1e-3 + 0.5));
103 
104         // interval in seconds
105         return QString("%1 s").arg(static_cast<quint32>(_interval * 1e-6 + 0.5));
106     }
107 
autoTimeStringRealNs(::profiler::timestamp_t _interval,int _precision)108     QString autoTimeStringRealNs(::profiler::timestamp_t _interval, int _precision)
109     {
110         if (_interval < 1000) // interval in nanoseconds
111             return QString("%1 ns").arg(_interval);
112 
113         if (_interval < 1000000) // interval in microseconds
114             return QString("%1 us").arg(_interval * 1e-3, 0, 'f', _precision);
115 
116         if (_interval < 1000000000U) // interval in milliseconds
117             return QString("%1 ms").arg(_interval * 1e-6, 0, 'f', _precision);
118 
119         // interval in seconds
120         return QString("%1 s").arg(_interval * 1e-9, 0, 'f', _precision);
121     }
122 
autoTimeStringIntNs(::profiler::timestamp_t _interval)123     QString autoTimeStringIntNs(::profiler::timestamp_t _interval)
124     {
125         if (_interval < 1000) // interval in nanoseconds
126             return QString("%1 ns").arg(_interval);
127 
128         if (_interval < 1000000) // interval in microseconds
129             return QString("%1 us").arg(static_cast<quint32>(_interval * 1e-3 + 0.5));
130 
131         if (_interval < 1000000000U) // interval in milliseconds
132             return QString("%1 ms").arg(static_cast<quint32>(_interval * 1e-6 + 0.5));
133 
134         // interval in seconds
135         return QString("%1 s").arg(static_cast<quint32>(_interval * 1e-9 + 0.5));
136     }
137 
138     //////////////////////////////////////////////////////////////////////////
139 
timeStringReal(TimeUnits _units,qreal _interval,int _precision)140     QString timeStringReal(TimeUnits _units, qreal _interval, int _precision)
141     {
142         switch (_units)
143         {
144             case TimeUnits_ms:{
145                 const char fmt = _interval <= 1 ? 'g' : 'f';
146                 return QString("%1 ms").arg(_interval * 1e-3, 0, fmt, _precision);
147             }
148 
149             case TimeUnits_us:
150                 return QString("%1 us").arg(_interval, 0, 'f', _precision);
151 
152             case TimeUnits_ns:
153                 return QString("%1 ns").arg(static_cast<quint64>(_interval * 1e3 + 0.5));
154 
155             case TimeUnits_auto:
156             default:
157                 return autoTimeStringReal(_interval, _precision);
158         }
159     }
160 
timeStringRealNs(TimeUnits _units,::profiler::timestamp_t _interval,int _precision)161     QString timeStringRealNs(TimeUnits _units, ::profiler::timestamp_t _interval, int _precision)
162     {
163         switch (_units)
164         {
165             case TimeUnits_ms:{
166                 const char fmt = _interval <= 1000 ? 'g' : 'f';
167                 return QString("%1 ms").arg(_interval * 1e-6, 0, fmt, _precision);
168             }
169 
170             case TimeUnits_us:
171                 return QString("%1 us").arg(_interval * 1e-3, 0, 'f', _precision);
172 
173             case TimeUnits_ns:
174                 return QString("%1 ns").arg(_interval);
175 
176             case TimeUnits_auto:
177             default:
178                 return autoTimeStringRealNs(_interval, _precision);
179         }
180     }
181 
timeStringInt(TimeUnits _units,qreal _interval)182     QString timeStringInt(TimeUnits _units, qreal _interval)
183     {
184         switch (_units)
185         {
186             case TimeUnits_ms:
187                 return QString("%1 ms").arg(static_cast<quint32>(_interval * 1e-3 + 0.5));
188 
189             case TimeUnits_us:
190                 return QString("%1 us").arg(static_cast<quint32>(_interval + 0.5));
191 
192             case TimeUnits_ns:
193                 return QString("%1 ns").arg(static_cast<quint64>(_interval * 1e3 + 0.5));
194 
195             case TimeUnits_auto:
196             default:
197                 return autoTimeStringInt(_interval);
198         }
199     }
200 
timeStringIntNs(TimeUnits _units,::profiler::timestamp_t _interval)201     QString timeStringIntNs(TimeUnits _units, ::profiler::timestamp_t _interval)
202     {
203         switch (_units)
204         {
205             case TimeUnits_ms:
206                 return QString("%1 ms").arg(static_cast<quint32>(_interval * 1e-6 + 0.5));
207 
208             case TimeUnits_us:
209                 return QString("%1 us").arg(static_cast<quint32>(_interval * 1e-3 + 0.5));
210 
211             case TimeUnits_ns:
212                 return QString("%1 ns").arg(_interval);
213 
214             case TimeUnits_auto:
215             default:
216                 return autoTimeStringIntNs(_interval);
217         }
218     }
219 
220     //////////////////////////////////////////////////////////////////////////
221 
EFont(QFont::StyleHint _hint,const char * _family,int _size,int _weight)222     QFont EFont(QFont::StyleHint _hint, const char* _family, int _size, int _weight)
223     {
224         QFont f;
225         f.setStyleHint(_hint, QFont::PreferMatch);
226         f.setFamily(_family);
227         f.setPointSize(_size);
228         f.setWeight(_weight);
229         return f;
230     }
231 
232     //////////////////////////////////////////////////////////////////////////
233 
valueTypeString(::profiler::DataType _dataType)234     QString valueTypeString(::profiler::DataType _dataType)
235     {
236         switch (_dataType)
237         {
238             case ::profiler::DataType::Bool:   return QStringLiteral("bool");
239             case ::profiler::DataType::Char:   return QStringLiteral("char");
240             case ::profiler::DataType::Int8:   return QStringLiteral("int8");
241             case ::profiler::DataType::Uint8:  return QStringLiteral("unsigned int8");
242             case ::profiler::DataType::Int16:  return QStringLiteral("int16");
243             case ::profiler::DataType::Uint16: return QStringLiteral("unsigned int16");
244             case ::profiler::DataType::Int32:  return QStringLiteral("int32");
245             case ::profiler::DataType::Uint32: return QStringLiteral("unsigned int32");
246             case ::profiler::DataType::Int64:  return QStringLiteral("int64");
247             case ::profiler::DataType::Uint64: return QStringLiteral("unsigned int64");
248             case ::profiler::DataType::Float:  return QStringLiteral("float");
249             case ::profiler::DataType::Double: return QStringLiteral("double");
250             case ::profiler::DataType::String: return QStringLiteral("string");
251             default: return QStringLiteral("unknown");
252         }
253     }
254 
valueTypeString(const::profiler::ArbitraryValue & _serializedValue)255     QString valueTypeString(const ::profiler::ArbitraryValue& _serializedValue)
256     {
257         const auto type = _serializedValue.type();
258         if (_serializedValue.isArray() && type != ::profiler::DataType::String)
259             return valueTypeString(type) + QStringLiteral("[]");
260         return valueTypeString(type);
261     }
262 
valueString(const::profiler::ArbitraryValue & _serializedValue)263     QString valueString(const ::profiler::ArbitraryValue& _serializedValue)
264     {
265         if (_serializedValue.isArray())
266         {
267             if (_serializedValue.type() == ::profiler::DataType::String)
268                 return _serializedValue.data();
269             return QStringLiteral("[...] array");
270         }
271 
272         switch (_serializedValue.type())
273         {
274             case ::profiler::DataType::Bool:   return _serializedValue.toValue<bool>()->value() ? QStringLiteral("true") : QStringLiteral("false");
275             case ::profiler::DataType::Char:   return QChar(_serializedValue.toValue<char>()->value());
276             case ::profiler::DataType::Int8:   return QChar(_serializedValue.toValue<int8_t>()->value());
277             case ::profiler::DataType::Uint8:  return QString::number(_serializedValue.toValue<uint8_t>()->value());
278             case ::profiler::DataType::Int16:  return QString::number(_serializedValue.toValue<int16_t>()->value());
279             case ::profiler::DataType::Uint16: return QString::number(_serializedValue.toValue<uint16_t>()->value());
280             case ::profiler::DataType::Int32:  return QString::number(_serializedValue.toValue<int32_t>()->value());
281             case ::profiler::DataType::Uint32: return QString::number(_serializedValue.toValue<uint32_t>()->value());
282             case ::profiler::DataType::Int64:  return QString::number(_serializedValue.toValue<int64_t>()->value());
283             case ::profiler::DataType::Uint64: return QString::number(_serializedValue.toValue<uint64_t>()->value());
284             case ::profiler::DataType::Float:  return QString::number(_serializedValue.toValue<float>()->value());
285             case ::profiler::DataType::Double: return QString::number(_serializedValue.toValue<double>()->value());
286             case ::profiler::DataType::String: return _serializedValue.data();
287             default: return QStringLiteral("Unknown");
288         }
289     }
290 
value2real(const::profiler::ArbitraryValue & _serializedValue,int _index)291     double value2real(const ::profiler::ArbitraryValue& _serializedValue, int _index)
292     {
293         if (_serializedValue.isArray())
294         {
295             switch (_serializedValue.type())
296             {
297                 case ::profiler::DataType::Bool:
298                 {
299                     const auto value = _serializedValue.toArray<bool>()->at(_index);
300                     return value ? 1 : 0;
301                 }
302 
303                 case ::profiler::DataType::Char:   return static_cast<double>(_serializedValue.toArray<char>()->at(_index));
304                 case ::profiler::DataType::Int8:   return static_cast<double>(_serializedValue.toArray<int8_t>()->at(_index));
305                 case ::profiler::DataType::Uint8:  return static_cast<double>(_serializedValue.toArray<uint8_t>()->at(_index));
306                 case ::profiler::DataType::Int16:  return static_cast<double>(_serializedValue.toArray<int16_t>()->at(_index));
307                 case ::profiler::DataType::Uint16: return static_cast<double>(_serializedValue.toArray<uint16_t>()->at(_index));
308                 case ::profiler::DataType::Int32:  return static_cast<double>(_serializedValue.toArray<int32_t>()->at(_index));
309                 case ::profiler::DataType::Uint32: return static_cast<double>(_serializedValue.toArray<uint32_t>()->at(_index));
310                 case ::profiler::DataType::Int64:  return static_cast<double>(_serializedValue.toArray<int64_t>()->at(_index));
311                 case ::profiler::DataType::Uint64: return static_cast<double>(_serializedValue.toArray<uint64_t>()->at(_index));
312                 case ::profiler::DataType::Float:  return static_cast<double>(_serializedValue.toArray<float>()->at(_index));
313                 case ::profiler::DataType::Double: return _serializedValue.toArray<double>()->at(_index);
314                 case ::profiler::DataType::String: return static_cast<double>(_serializedValue.data()[_index]);
315                 default: return 0;
316             }
317         }
318 
319         switch (_serializedValue.type())
320         {
321             case ::profiler::DataType::Bool:
322             {
323                 const auto value = _serializedValue.toValue<bool>()->value();
324                 return value ? 1 : 0;
325             }
326 
327             case ::profiler::DataType::Char:   return static_cast<double>(_serializedValue.toValue<char>()->value());
328             case ::profiler::DataType::Int8:   return static_cast<double>(_serializedValue.toValue<int8_t>()->value());
329             case ::profiler::DataType::Uint8:  return static_cast<double>(_serializedValue.toValue<uint8_t>()->value());
330             case ::profiler::DataType::Int16:  return static_cast<double>(_serializedValue.toValue<int16_t>()->value());
331             case ::profiler::DataType::Uint16: return static_cast<double>(_serializedValue.toValue<uint16_t>()->value());
332             case ::profiler::DataType::Int32:  return static_cast<double>(_serializedValue.toValue<int32_t>()->value());
333             case ::profiler::DataType::Uint32: return static_cast<double>(_serializedValue.toValue<uint32_t>()->value());
334             case ::profiler::DataType::Int64:  return static_cast<double>(_serializedValue.toValue<int64_t>()->value());
335             case ::profiler::DataType::Uint64: return static_cast<double>(_serializedValue.toValue<uint64_t>()->value());
336             case ::profiler::DataType::Float:  return static_cast<double>(_serializedValue.toValue<float>()->value());
337             case ::profiler::DataType::Double: return _serializedValue.toValue<double>()->value();
338             case ::profiler::DataType::String: return static_cast<double>(_serializedValue.data()[_index]);
339             default: return 0;
340         }
341     }
342 
343     //////////////////////////////////////////////////////////////////////////
344 
345 } // end of namespace profiler_gui.
346