Attempt to fix the IPv4/IPv6 problems once and for all
[deb_shairplay.git] / src / lib / logger.c
CommitLineData
23e7e3ae
JVH
1/**
2 * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 */
14
2340bcd3
JVH
15#include <stdlib.h>
16#include <stdio.h>
17#include <stdarg.h>
18#include <assert.h>
19
20#include "logger.h"
979533c3 21#include "compat.h"
2340bcd3 22
fda63ad4
JVH
23struct logger_s {
24 mutex_handle_t lvl_mutex;
25 mutex_handle_t cb_mutex;
26
27 int level;
28 logger_callback_t callback;
29};
30
31logger_t *
32logger_init()
2340bcd3 33{
fda63ad4 34 logger_t *logger = calloc(1, sizeof(logger_t));
2340bcd3
JVH
35 assert(logger);
36
fda63ad4
JVH
37 MUTEX_CREATE(logger->lvl_mutex);
38 MUTEX_CREATE(logger->cb_mutex);
39
46212791 40 logger->level = LOGGER_DEBUG;
2340bcd3 41 logger->callback = NULL;
fda63ad4
JVH
42 return logger;
43}
44
45void
46logger_destroy(logger_t *logger)
47{
48 MUTEX_DESTROY(logger->lvl_mutex);
49 MUTEX_DESTROY(logger->cb_mutex);
50 free(logger);
2340bcd3
JVH
51}
52
53void
54logger_set_level(logger_t *logger, int level)
55{
56 assert(logger);
57
fda63ad4 58 MUTEX_LOCK(logger->lvl_mutex);
2340bcd3 59 logger->level = level;
fda63ad4 60 MUTEX_UNLOCK(logger->lvl_mutex);
2340bcd3
JVH
61}
62
63void
64logger_set_callback(logger_t *logger, logger_callback_t callback)
65{
66 assert(logger);
67
fda63ad4 68 MUTEX_LOCK(logger->cb_mutex);
2340bcd3 69 logger->callback = callback;
fda63ad4 70 MUTEX_UNLOCK(logger->cb_mutex);
2340bcd3
JVH
71}
72
73static char *
74logger_utf8_to_local(const char *str)
75{
76 char *ret = NULL;
77
78/* FIXME: This is only implemented on Windows for now */
79#if defined(_WIN32) || defined(_WIN64)
80 int wclen, mblen;
81 WCHAR *wcstr;
82 BOOL failed;
83
84 wclen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
85 wcstr = malloc(sizeof(WCHAR) * wclen);
86 MultiByteToWideChar(CP_UTF8, 0, str, -1, wcstr, wclen);
87
88 mblen = WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, NULL, 0, NULL, &failed);
89 if (failed) {
90 /* Invalid characters in input, conversion failed */
91 free(wcstr);
92 return NULL;
93 }
94
95 ret = malloc(sizeof(CHAR) * mblen);
96 WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, ret, mblen, NULL, NULL);
97 free(wcstr);
98#endif
99
100 return ret;
101}
102
103void
104logger_log(logger_t *logger, int level, const char *fmt, ...)
105{
106 char buffer[4096];
107 va_list ap;
108
fda63ad4
JVH
109 MUTEX_LOCK(logger->lvl_mutex);
110 if (level > logger->level) {
111 MUTEX_UNLOCK(logger->lvl_mutex);
2340bcd3 112 return;
fda63ad4
JVH
113 }
114 MUTEX_UNLOCK(logger->lvl_mutex);
2340bcd3
JVH
115
116 buffer[sizeof(buffer)-1] = '\0';
117 va_start(ap, fmt);
118 vsnprintf(buffer, sizeof(buffer)-1, fmt, ap);
119 va_end(ap);
120
fda63ad4 121 MUTEX_LOCK(logger->cb_mutex);
2340bcd3
JVH
122 if (logger->callback) {
123 logger->callback(level, buffer);
fda63ad4 124 MUTEX_UNLOCK(logger->cb_mutex);
2340bcd3 125 } else {
fda63ad4
JVH
126 char *local;
127 MUTEX_UNLOCK(logger->cb_mutex);
128 local = logger_utf8_to_local(buffer);
2340bcd3 129 if (local) {
46212791 130 fprintf(stderr, "%s\n", local);
2340bcd3
JVH
131 free(local);
132 } else {
46212791 133 fprintf(stderr, "%s\n", buffer);
2340bcd3
JVH
134 }
135 }
136}
137