Added commentary to the public API referring to new functionality of
[platform/upstream/iotivity.git] / oc_logger / cpp / oc_ostream_logger.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "oc_logger.hpp"
22 #include "targets/oc_ostream_logger.h"
23
24 #include <cstdio>
25 #include <cstdlib>
26
27 #include <mutex>
28 #include <memory>
29 #include <sstream>
30 #include <iostream>
31
32 namespace {
33
34 struct oc_ostream_logger_ctx
35 {
36  std::ostream*  os_ptr;
37  std::ostream&  os;
38
39  std::mutex     mutex;
40
41  oc_ostream_logger_ctx(std::ostream *here)
42   : os_ptr(here),
43     os(*os_ptr)
44  {}
45 };
46
47 } // namespace
48
49 /* Courtesy-function: */
50 oc_log_ctx_t *oc_make_ostream_logger()
51 {
52  return oc_log_make_ctx(
53             nullptr,
54             OC_LOG_ALL,
55             oc_ostream_log_init,
56             oc_ostream_log_destroy,
57             oc_ostream_log_flush,
58             oc_ostream_log_set_level,
59             oc_ostream_log_write,
60             oc_ostream_log_set_module
61         );
62 }
63
64 int oc_ostream_log_init(oc_log_ctx_t *ctx, void *world)
65 try
66 {
67  auto *target = reinterpret_cast<std::ostream *>(world);
68
69  if(nullptr == world)
70   target = &std::cout;
71
72  oc_ostream_logger_ctx *my_ctx = new oc_ostream_logger_ctx(target);
73
74  ctx->ctx = static_cast<void *>(my_ctx);
75
76  return 1;
77 }
78 catch(...)
79 {
80  return 0;
81 }
82
83 void oc_ostream_log_destroy(oc_log_ctx_t *ctx)
84 try
85 {
86  static std::mutex dtor_mtx;
87
88  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
89
90  {
91  std::unique_lock<std::mutex> ul(dtor_mtx);
92
93  lctx->os << std::flush;
94
95  delete lctx;
96  }
97 }
98 catch(...)
99 {
100 }
101
102 void oc_ostream_log_flush(oc_log_ctx_t *ctx)
103 try
104 {
105  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
106
107  std::lock_guard<std::mutex> lg(lctx->mutex);
108
109  lctx->os << std::flush;
110 }
111 catch(...)
112 {
113 }
114
115 void oc_ostream_log_set_level(oc_log_ctx_t *ctx, const int level)
116 try
117 {
118  /* We don't have any special thing we need to do when a log level changes. */
119  return;
120 }
121 catch(...)
122 {
123 }
124
125 size_t oc_ostream_log_write(oc_log_ctx_t *ctx, const int level, const char *msg)
126 try
127 {
128  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
129
130  std::lock_guard<std::mutex> lg(lctx->mutex);
131
132  std::ostringstream os;
133
134  os << level << ": ";
135
136  if(nullptr != ctx->module_name)
137   os << '[' << ctx->module_name << "] ";
138
139  os << msg << '\n';
140
141  lctx->os << os.str().c_str();
142
143  return 1 + os.str().length();
144 }
145 catch(...)
146 {
147  return 0;
148 }
149
150 int oc_ostream_log_set_module(oc_log_ctx_t *ctx, const char *module_name)
151 try
152 {
153  // Nothing special needs to happen for a module name change:
154  return 1;
155 }
156 catch(...)
157 {
158  return 0;
159 }
160
161 int oc_ostream_log_lock(oc_log_ctx_t *ctx)
162 try
163 {
164  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
165
166  lctx->mutex.lock();
167
168  return 1;
169 }
170 catch(...)
171 {
172  return 0;
173 }
174
175 int oc_ostream_log_unlock(oc_log_ctx_t *ctx)
176 try
177 {
178  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
179
180  lctx->mutex.unlock();
181
182  return 1;
183 }
184 catch(...)
185 {
186  return 0;
187 }
188
189 int oc_ostream_log_try_lock(oc_log_ctx_t *ctx)
190 try
191 {
192  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
193
194  return lctx->mutex.try_lock();
195 }
196 catch(...)
197 {
198  return 0;
199 }