Unexpected BW Response Fix
[rtmpdump.git] / librtmp / log.c
blob0012985c8d743608003a4a1628971048cbed3f65
1 /*
2 * Copyright (C) 2008-2009 Andrej Stepanchuk
3 * Copyright (C) 2009-2010 Howard Chu
5 * This file is part of librtmp.
7 * librtmp is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1,
10 * or (at your option) any later version.
12 * librtmp is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with librtmp see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 * http://www.gnu.org/copyleft/lgpl.html
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <ctype.h>
30 #include "rtmp_sys.h"
31 #include "log.h"
33 #define MAX_PRINT_LEN 2048
35 RTMP_LogLevel RTMP_debuglevel = RTMP_LOGERROR;
37 static int neednl;
39 static FILE *fmsg;
41 static RTMP_LogCallback rtmp_log_default, *cb = rtmp_log_default;
43 static const char *levels[] = {
44 "CRIT", "ERROR", "WARNING", "INFO",
45 "DEBUG", "DEBUG2"
48 static void rtmp_log_default(int level, const char *format, va_list vl)
50 char str[MAX_PRINT_LEN]="";
52 vsnprintf(str, MAX_PRINT_LEN-1, format, vl);
54 /* Filter out 'no-name' */
55 if ( RTMP_debuglevel<RTMP_LOGALL && strstr(str, "no-name" ) != NULL )
56 return;
58 if ( !fmsg ) fmsg = stderr;
60 if ( level <= RTMP_debuglevel ) {
61 if (neednl) {
62 putc('\n', fmsg);
63 neednl = 0;
65 fprintf(fmsg, "%s: %s\n", levels[level], str);
66 #ifdef _DEBUG
67 fflush(fmsg);
68 #endif
72 void RTMP_LogSetOutput(FILE *file)
74 fmsg = file;
77 void RTMP_LogSetLevel(RTMP_LogLevel level)
79 RTMP_debuglevel = level;
82 void RTMP_LogSetCallback(RTMP_LogCallback *cbp)
84 cb = cbp;
87 RTMP_LogLevel RTMP_LogGetLevel()
89 return RTMP_debuglevel;
92 void RTMP_Log(int level, const char *format, ...)
94 va_list args;
95 va_start(args, format);
96 cb(level, format, args);
97 va_end(args);
100 static const char hexdig[] = "0123456789abcdef";
102 void RTMP_LogHex(int level, const uint8_t *data, unsigned long len)
104 unsigned long i;
105 char line[50], *ptr;
107 if ( level > RTMP_debuglevel )
108 return;
110 ptr = line;
112 for(i=0; i<len; i++) {
113 *ptr++ = hexdig[0x0f & (data[i] >> 4)];
114 *ptr++ = hexdig[0x0f & data[i]];
115 if ((i & 0x0f) == 0x0f) {
116 *ptr = '\0';
117 ptr = line;
118 RTMP_Log(level, "%s", line);
119 } else {
120 *ptr++ = ' ';
123 if (i & 0x0f) {
124 *ptr = '\0';
125 RTMP_Log(level, "%s", line);
129 void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len)
131 #define BP_OFFSET 9
132 #define BP_GRAPH 60
133 #define BP_LEN 80
134 char line[BP_LEN];
135 unsigned long i;
137 if ( !data || level > RTMP_debuglevel )
138 return;
140 /* in case len is zero */
141 line[0] = '\0';
143 for ( i = 0 ; i < len ; i++ ) {
144 int n = i % 16;
145 unsigned off;
147 if( !n ) {
148 if( i ) RTMP_Log( level, "%s", line );
149 memset( line, ' ', sizeof(line)-2 );
150 line[sizeof(line)-2] = '\0';
152 off = i % 0x0ffffU;
154 line[2] = hexdig[0x0f & (off >> 12)];
155 line[3] = hexdig[0x0f & (off >> 8)];
156 line[4] = hexdig[0x0f & (off >> 4)];
157 line[5] = hexdig[0x0f & off];
158 line[6] = ':';
161 off = BP_OFFSET + n*3 + ((n >= 8)?1:0);
162 line[off] = hexdig[0x0f & ( data[i] >> 4 )];
163 line[off+1] = hexdig[0x0f & data[i]];
165 off = BP_GRAPH + n + ((n >= 8)?1:0);
167 if ( isprint( data[i] )) {
168 line[BP_GRAPH + n] = data[i];
169 } else {
170 line[BP_GRAPH + n] = '.';
174 RTMP_Log( level, "%s", line );
177 /* These should only be used by apps, never by the library itself */
178 void RTMP_LogPrintf(const char *format, ...)
180 char str[MAX_PRINT_LEN]="";
181 int len;
182 va_list args;
183 va_start(args, format);
184 len = vsnprintf(str, MAX_PRINT_LEN-1, format, args);
185 va_end(args);
187 if ( RTMP_debuglevel==RTMP_LOGCRIT )
188 return;
190 if ( !fmsg ) fmsg = stderr;
192 if (neednl) {
193 putc('\n', fmsg);
194 neednl = 0;
197 if (len > MAX_PRINT_LEN-1)
198 len = MAX_PRINT_LEN-1;
199 fprintf(fmsg, "%s", str);
200 if (str[len-1] == '\n')
201 fflush(fmsg);
204 void RTMP_LogStatus(const char *format, ...)
206 char str[MAX_PRINT_LEN]="";
207 va_list args;
208 va_start(args, format);
209 vsnprintf(str, MAX_PRINT_LEN-1, format, args);
210 va_end(args);
212 if ( RTMP_debuglevel==RTMP_LOGCRIT )
213 return;
215 if ( !fmsg ) fmsg = stderr;
217 fprintf(fmsg, "%s", str);
218 fflush(fmsg);
219 neednl = 1;