1 /* 2 * Copyright (c) 2020, Peter Thorson, Steve Wills. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution. 11 * * Neither the name of the WebSocket++ Project nor the 12 * names of its contributors may be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 */ 27 28 #ifndef CHATTERINOWEBSOCKETPPLOGGER_HPP 29 #define CHATTERINOWEBSOCKETPPLOGGER_HPP 30 31 #include <string> 32 #include <websocketpp/common/cpp11.hpp> 33 #include <websocketpp/logger/basic.hpp> 34 #include <websocketpp/logger/levels.hpp> 35 #include "common/QLogging.hpp" 36 37 namespace websocketpp { 38 namespace log { 39 40 template <typename concurrency, typename names> 41 class chatterinowebsocketpplogger : public basic<concurrency, names> 42 { 43 public: 44 typedef chatterinowebsocketpplogger<concurrency, names> base; 45 46 chatterinowebsocketpplogger<concurrency, names>( 47 channel_type_hint::value) 48 : m_static_channels(0xffffffff) 49 , m_dynamic_channels(0) 50 { 51 } 52 53 chatterinowebsocketpplogger<concurrency, names>(std::ostream *) 54 : m_static_channels(0xffffffff) 55 , m_dynamic_channels(0) 56 { 57 } 58 59 chatterinowebsocketpplogger<concurrency, names>( 60 level c, channel_type_hint::value) 61 : m_static_channels(c) 62 , m_dynamic_channels(0) 63 { 64 } 65 66 chatterinowebsocketpplogger<concurrency, names>(level c, std::ostream *) 67 : m_static_channels(c) 68 , m_dynamic_channels(0) 69 { 70 } 71 72 ~chatterinowebsocketpplogger<concurrency, names>() 73 { 74 } 75 76 chatterinowebsocketpplogger<concurrency, names>( 77 chatterinowebsocketpplogger<concurrency, names> const &other) 78 : m_static_channels(other.m_static_channels) 79 , m_dynamic_channels(other.m_dynamic_channels) 80 { 81 } 82 83 #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ 84 chatterinowebsocketpplogger<concurrency, names> &operator=( 85 chatterinowebsocketpplogger<concurrency, names> const &) = delete; 86 #endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ 87 88 #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ 89 /// Move constructor 90 chatterinowebsocketpplogger<concurrency, names>( 91 chatterinowebsocketpplogger<concurrency, names> &&other) 92 : m_static_channels(other.m_static_channels) 93 , m_dynamic_channels(other.m_dynamic_channels) 94 { 95 } 96 # ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ 97 // no move assignment operator because of const member variables 98 chatterinowebsocketpplogger<concurrency, names> &operator=( 99 chatterinowebsocketpplogger<concurrency, names> &&) = delete; 100 # endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ 101 #endif // _WEBSOCKETPP_MOVE_SEMANTICS_ 102 103 /// Explicitly do nothing, this logger doesn't support changing ostream set_ostream(std::ostream *)104 void set_ostream(std::ostream *) 105 { 106 } 107 108 /// Dynamically enable the given list of channels 109 /** 110 * @param channels The package of channels to enable 111 */ set_channels(level channels)112 void set_channels(level channels) 113 { 114 if (channels == names::none) 115 { 116 clear_channels(names::all); 117 return; 118 } 119 120 scoped_lock_type lock(m_lock); 121 m_dynamic_channels |= (channels & m_static_channels); 122 } 123 124 /// Dynamically disable the given list of channels 125 /** 126 * @param channels The package of channels to disable 127 */ clear_channels(level channels)128 void clear_channels(level channels) 129 { 130 scoped_lock_type lock(m_lock); 131 m_dynamic_channels &= ~channels; 132 } 133 134 /// Write a string message to the given channel 135 /** 136 * @param channel The channel to write to 137 * @param msg The message to write 138 */ write(level channel,std::string const & msg)139 void write(level channel, std::string const &msg) 140 { 141 scoped_lock_type lock(m_lock); 142 if (!this->dynamic_test(channel)) 143 { 144 return; 145 } 146 qCDebug(chatterinoWebsocket).nospace() 147 << names::channel_name(channel) << ": " 148 << QString::fromStdString(msg); 149 } 150 151 /// Write a cstring message to the given channel 152 /** 153 * @param channel The channel to write to 154 * @param msg The message to write 155 */ write(level channel,char const * msg)156 void write(level channel, char const *msg) 157 { 158 scoped_lock_type lock(m_lock); 159 if (!this->dynamic_test(channel)) 160 { 161 return; 162 } 163 qCDebug(chatterinoWebsocket).nospace() 164 << names::channel_name(channel) << ": " << msg; 165 } 166 167 /// Test whether a channel is statically enabled 168 /** 169 * @param channel The package of channels to test 170 */ 171 static_test(level channel) const172 _WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level channel) const 173 { 174 return ((channel & m_static_channels) != 0); 175 } 176 177 /// Test whether a channel is dynamically enabled 178 /** 179 * @param channel The package of channels to test 180 */ dynamic_test(level channel)181 bool dynamic_test(level channel) 182 { 183 return ((channel & m_dynamic_channels) != 0); 184 } 185 186 protected: 187 typedef typename concurrency::scoped_lock_type scoped_lock_type; 188 typedef typename concurrency::mutex_type mutex_type; 189 mutex_type m_lock; 190 191 private: 192 level const m_static_channels; 193 level m_dynamic_channels; 194 }; 195 196 } // namespace log 197 } // namespace websocketpp 198 199 #endif // CHATTERINOWEBSOCKETPPLOGGER_HPP 200