1/*
2 * Copyright (c) 2015, Intel Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30#pragma once
31
32#include "log/ILogger.h"
33#include "Utility.h"
34#include <string>
35#include <sstream>
36#include <iterator>
37#include <list>
38
39namespace core
40{
41namespace log
42{
43namespace details
44{
45
46/**
47 * Template log wrapper
48 * Simulate a stream which can be used instead of basic ILogger API.
49 *
50 * @tparam isWarning indicates which log canal to use
51 */
52template <bool isWarning>
53class LogWrapper
54{
55public:
56    /** @param logger the ILogger to wrap */
57    LogWrapper(ILogger &logger, const std::string &prolog = "") : mLogger(logger), mProlog(prolog)
58    {
59    }
60
61    /**
62     * Class copy constructor
63     *
64     * @param[in] logWrapper the instance to copy
65     */
66    LogWrapper(const LogWrapper &logWrapper)
67        : mLogger(logWrapper.mLogger), mProlog(logWrapper.mProlog)
68    {
69    }
70
71    /** Class destructor */
72    ~LogWrapper()
73    {
74        if (!mLog.str().empty()) {
75            if (isWarning) {
76                mLogger.warning(mProlog + mLog.str());
77            } else {
78                mLogger.info(mProlog + mLog.str());
79            }
80        }
81    }
82
83    /**
84     * Simulate stream behaviour
85     *
86     * @tparam T the type of the information to log
87     * @param[in] log the information to log
88     */
89    template <class T>
90    LogWrapper &operator<<(const T &log)
91    {
92        mLog << log;
93        return *this;
94    }
95
96    /**
97     * Simulate stream behaviour for string list
98     *
99     * @param[in] logs list of information to log
100     */
101    LogWrapper &operator<<(const std::list<std::string> &logs)
102    {
103        std::string separator = "\n" + mProlog;
104        std::string formatedLogs = utility::asString(logs, separator);
105
106        // Check if there is something in the log to know if we have to add a prefix
107        if (!mLog.str().empty() && mLog.str()[mLog.str().length() - 1] == separator[0]) {
108            *this << mProlog;
109        }
110
111        *this << formatedLogs;
112        return *this;
113    }
114
115private:
116    LogWrapper &operator=(const LogWrapper &);
117
118    /** Log stream holder */
119    std::ostringstream mLog;
120
121    /** Wrapped logger */
122    ILogger &mLogger;
123
124    /** Log Prefix */
125    const std::string &mProlog;
126};
127
128/** Default information logger type */
129typedef details::LogWrapper<false> Info;
130
131/** Default warning logger type */
132typedef details::LogWrapper<true> Warning;
133
134} /** details namespace */
135} /** log namespace */
136} /** core namespace */
137