Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
235 lines (191 sloc) 5.04 KB
/*
* Copyright (C) 2008-2009 Andrej Stepanchuk
* Copyright (C) 2009-2010 Howard Chu
*
* This file is part of librtmp.
*
* librtmp is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1,
* or (at your option) any later version.
*
* librtmp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with librtmp see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/lgpl.html
*/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include "log.h"
#define MAX_PRINT_LEN 65535
RTMP_LogLevel RTMP_debuglevel = RTMP_LOGERROR;
static int neednl;
static FILE *fmsg;
static RTMP_LogCallback rtmp_log_default, *cb = rtmp_log_default;
static const char *levels[] = {
"CRIT", "ERROR", "WARNING", "INFO",
"DEBUG", "DEBUG2"
};
static void rtmp_log_default(int level, const char *format, va_list vl)
{
char str[MAX_PRINT_LEN]="";
vsnprintf(str, MAX_PRINT_LEN-1, format, vl);
/* Filter out 'no-name' */
if ( RTMP_debuglevel<RTMP_LOGALL && strstr(str, "no-name" ) != NULL ) {
return;
}
if ( !fmsg ) {
fmsg = stderr;
}
if ( level <= RTMP_debuglevel ) {
if (neednl) {
putc('\n', fmsg);
neednl = 0;
}
fprintf(fmsg, "%s: %s\n", levels[level], str);
#ifdef _DEBUG
fflush(fmsg);
#endif
}
}
void RTMP_LogSetOutput(FILE *file)
{
fmsg = file;
}
void RTMP_LogSetLevel(RTMP_LogLevel level)
{
RTMP_debuglevel = level;
}
void RTMP_LogSetCallback(RTMP_LogCallback *cbp)
{
cb = cbp;
}
RTMP_LogLevel RTMP_LogGetLevel()
{
return RTMP_debuglevel;
}
void RTMP_Log(int level, const char *format, ...)
{
va_list args;
va_start(args, format);
cb(level, format, args);
va_end(args);
}
static const char hexdig[] = "0123456789abcdef";
void RTMP_LogHex(int level, const uint8_t *data, unsigned long len)
{
unsigned long i;
char line[50], *ptr;
if ( level > RTMP_debuglevel ) {
return;
}
ptr = line;
for(i=0; i<len; i++) {
*ptr++ = hexdig[0x0f & (data[i] >> 4)];
*ptr++ = hexdig[0x0f & data[i]];
if ((i & 0x0f) == 0x0f) {
*ptr = '\0';
ptr = line;
RTMP_Log(level, "%s", line);
} else {
*ptr++ = ' ';
}
}
if (i & 0x0f) {
*ptr = '\0';
RTMP_Log(level, "%s", line);
}
}
void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len)
{
#define BP_OFFSET 9
#define BP_GRAPH 60
#define BP_LEN 80
char line[BP_LEN];
unsigned long i;
if ( !data || level > RTMP_debuglevel ) {
return;
}
/* in case len is zero */
line[0] = '\0';
for ( i = 0 ; i < len ; i++ ) {
int n = i % 16;
unsigned off;
if( !n ) {
if( i ) {
RTMP_Log( level, "%s", line );
}
memset( line, ' ', sizeof(line)-2 );
line[sizeof(line)-2] = '\0';
off = i % 0x0ffffU;
line[2] = hexdig[0x0f & (off >> 12)];
line[3] = hexdig[0x0f & (off >> 8)];
line[4] = hexdig[0x0f & (off >> 4)];
line[5] = hexdig[0x0f & off];
line[6] = ':';
}
off = BP_OFFSET + n*3 + ((n >= 8)?1:0);
line[off] = hexdig[0x0f & ( data[i] >> 4 )];
line[off+1] = hexdig[0x0f & data[i]];
off = BP_GRAPH + n + ((n >= 8)?1:0);
if ( isprint( data[i] )) {
line[BP_GRAPH + n] = data[i];
} else {
line[BP_GRAPH + n] = '.';
}
}
RTMP_Log( level, "%s", line );
}
/* These should only be used by apps, never by the library itself */
void RTMP_LogPrintf(const char *format, ...)
{
char str[MAX_PRINT_LEN]="";
int len;
va_list args;
va_start(args, format);
len = vsnprintf(str, MAX_PRINT_LEN-1, format, args);
va_end(args);
if ( RTMP_debuglevel==RTMP_LOGCRIT ) {
return;
}
if ( !fmsg ) {
fmsg = stderr;
}
if (neednl) {
putc('\n', fmsg);
neednl = 0;
}
if (len > MAX_PRINT_LEN-1) {
len = MAX_PRINT_LEN-1;
}
fprintf(fmsg, "%s", str);
if (str[len-1] == '\n') {
fflush(fmsg);
}
}
void RTMP_LogStatus(const char *format, ...)
{
char str[MAX_PRINT_LEN]="";
va_list args;
va_start(args, format);
vsnprintf(str, MAX_PRINT_LEN-1, format, args);
va_end(args);
if ( RTMP_debuglevel==RTMP_LOGCRIT ) {
return;
}
if ( !fmsg ) {
fmsg = stderr;
}
fprintf(fmsg, "%s", str);
fflush(fmsg);
neednl = 1;
}