summaryrefslogtreecommitdiff
path: root/include/dlt/dlt_cpp_extension.hpp
blob: fe344e5cf9396de7e59617b6cce8c3d12e9818f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * @licence app begin@
 * SPDX license identifier: MPL-2.0
 *
 * Copyright (C) 2015  Intel Corporation
 *
 * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
 *
 * This Source Code Form is subject to the terms of the
 * Mozilla Public License (MPL), v. 2.0.
 * If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * For further information see http://www.genivi.org/.
 * @licence end@
 */

/*!
 * \author Stefan Vacek <stefan.vacek@intel.com> Intel Corporation
 *
 * \copyright Copyright © 2015 Intel Corporation. \n
 * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
 *
 * \file dlt_cpp_extension.hpp
*/

#ifndef DLT_CPP_EXTENSION_HPP
#define DLT_CPP_EXTENSION_HPP

#include <string>
#include <vector>
#include <list>
#include <map>

#include "dlt.h"

template<typename T>
int32_t logToDlt(DltContextData &log, T const &value) = delete;

template<>
inline int32_t logToDlt(DltContextData &log, int8_t const &value)
{
    return dlt_user_log_write_int8(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, int16_t const &value)
{
    return dlt_user_log_write_int16(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, int32_t const &value)
{
    return dlt_user_log_write_int32(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, int64_t const &value)
{
    return dlt_user_log_write_int64(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, uint8_t const &value)
{
    return dlt_user_log_write_uint8(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, uint16_t const &value)
{
    return dlt_user_log_write_uint16(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, uint32_t const &value)
{
    return dlt_user_log_write_uint32(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, uint64_t const &value)
{
    return dlt_user_log_write_uint64(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, float32_t const &value)
{
    return dlt_user_log_write_float32(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, double const &value)
{
    return dlt_user_log_write_float64(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, bool const &value)
{
    return dlt_user_log_write_bool(&log, value);
}

static inline int32_t logToDlt(DltContextData &log, char const * const value)
{
    return dlt_user_log_write_utf8_string(&log, value);
}

static inline int32_t logToDlt(DltContextData &log, char * const value)
{
    return dlt_user_log_write_utf8_string(&log, value);
}

template<>
inline int32_t logToDlt(DltContextData &log, std::string const &value)
{
    return dlt_user_log_write_utf8_string(&log, value.c_str());
}

/* stl types */
template<>
int32_t logToDlt(DltContextData &log, std::string const &value);

template<typename _Tp, typename _Alloc = std::allocator<_Tp>>
static inline int32_t logToDlt(DltContextData &log, std::vector<_Tp, _Alloc> const & value)
{
    int result = 0;

    for (auto elem : value)
        result += logToDlt(log, elem);

    if (result != 0)
        result = -1;

    return result;
}

template<typename _Tp, typename _Alloc = std::allocator<_Tp>>
static inline int32_t logToDlt(DltContextData &log, std::list<_Tp, _Alloc> const & value)
{
    int result = 0;

    for (auto elem : value)
        result += logToDlt(log, elem);

    if (result != 0)
        result = -1;

    return result;
}

template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
                typename _Alloc = std::allocator<std::pair<const _Key, _Tp>>>
static inline int32_t logToDlt(DltContextData &log, std::map<_Key, _Tp, _Compare, _Alloc> const & value)
{
    int result = 0;

    for (auto elem : value)
    {
        result += logToDlt(log, elem.first);
        result += logToDlt(log, elem.second);
    }

    if (result != 0)
        result = -1;

    return result;
}

//variadic functions using C11 standard
template<typename First>
static inline int32_t logToDltVariadic(DltContextData &log, First const &valueA)
{
    return logToDlt(log, valueA);
}

template<typename First, typename ... Rest>
static inline int32_t logToDltVariadic(DltContextData &log, First const &valueA, const Rest&... valueB)
{
    int result = logToDlt(log, valueA) + logToDltVariadic(log, valueB...);

    if (result != 0)
        result = -1;

    return result;
}

/**
 * @brief macro to write a log message with variable number of arguments and without the need to specify the type of log data
 *
 * The macro can be used with any type that provides a logToDlt function.
 *
 * Example:
 * DLT_LOG_CXX(dltContext, DLT_LV_X, "text", valueA, valueB, ...)
 */
#define DLT_LOG_CXX(CONTEXT, LOGLEVEL, ...)\
    do\
    {\
        DltContextData log;\
        if (dlt_user_log_write_start(&CONTEXT,&log,LOGLEVEL)>0)\
        {\
            logToDltVariadic(log, ##__VA_ARGS__);\
            dlt_user_log_write_finish(&log);\
        }\
    }\
    while(0)

/**
 * @brief macro to write a log message with variable number of arguments and without the need to specify the type of log data.
 *
 * The macro can be used with any type that provides a logToDlt function.
 * This includes all the types that are code generated.
 *
 * This macro is similar to \c DLT_LOG_CXX. However, it adds the current function name as the first log argument.
 *
 * Example:
 * DLT_LOG_FCN_CXX(dltContext, DLT_LV_X, "text", valueA, valueB, ...)
 */
#define DLT_LOG_FCN_CXX(CONTEXT, LOGLEVEL, ...) \
    do\
    {\
        DltContextData log;\
        if (dlt_user_log_write_start(&CONTEXT, &log, LOGLEVEL) > 0)\
        {\
            dlt_user_log_write_string(&log, __PRETTY_FUNCTION__);\
            logToDltVariadic(log, ##__VA_ARGS__);\
            dlt_user_log_write_finish(&log);\
        }\
  }\
  while(0)

#endif /* DLT_CPP_EXTENSION_HPP */