1/****************************************************************************
2** libebml : parse EBML files, see http://embl.sourceforge.net/
3**
4** <file/class description>
5**
6** Copyright (C) 2002-2004 Steve Lhomme.  All rights reserved.
7**
8** This file is part of libebml.
9**
10** This library is free software; you can redistribute it and/or
11** modify it under the terms of the GNU Lesser General Public
12** License as published by the Free Software Foundation; either
13** version 2.1 of the License, or (at your option) any later version.
14**
15** This library is distributed in the hope that it will be useful,
16** but WITHOUT ANY WARRANTY; without even the implied warranty of
17** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18** Lesser General Public License for more details.
19**
20** You should have received a copy of the GNU Lesser General Public
21** License along with this library; if not, write to the Free Software
22** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23**
24** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.
25**
26** Contact license@matroska.org if any conditions of this licensing are
27** not clear to you.
28**
29**********************************************************************/
30
31/*!
32	\file
33	\version \$Id: Debug.cpp 1268 2007-01-19 10:15:08Z robux4 $
34	\author Steve Lhomme     <robux4 @ users.sf.net>
35	\author Moritz Bunkus <moritz @ bunkus.org>
36*/
37#include <stdio.h>
38
39#ifdef WIN32
40#include <windows.h> // For OutputDebugString
41#else
42#include <time.h>
43#include <sys/time.h>
44#endif // WIN32
45
46#include "ebml/Debug.h"
47
48START_LIBEBML_NAMESPACE
49
50class ADbg globalDebug;
51
52#if !defined(NDEBUG)
53
54//////////////////////////////////////////////////////////////////////
55// Construction/Destruction
56//////////////////////////////////////////////////////////////////////
57
58ADbg::ADbg(int level)
59:my_level(level)
60,my_time_included(false)
61,my_use_file(false)
62,my_debug_output(true)
63,hFile(NULL)
64{
65	prefix[0] = '\0';
66	OutPut(-1,"ADbg Creation at debug level = %d (0x%08X)",my_level,this);
67}
68
69ADbg::~ADbg()
70{
71	unsetDebugFile();
72	OutPut(-1,"ADbg Deletion (0x%08X)",this);
73}
74
75inline int ADbg::_OutPut(const char * format,va_list params) const
76{
77	int result;
78
79	char tst[1000];
80	char myformat[256];
81
82#ifdef WIN32
83	if (my_time_included) {
84		SYSTEMTIME time;
85		GetSystemTime(&time);
86		if (prefix[0] == '\0')
87			wsprintfA(myformat,"%04d/%02d/%02d %02d:%02d:%02d.%03d UTC : %s\r\n",
88							time.wYear,
89							time.wMonth,
90							time.wDay,
91							time.wHour,
92							time.wMinute,
93							time.wSecond,
94							time.wMilliseconds,
95							format);
96		else
97			wsprintfA(myformat,"%04d/%02d/%02d %02d:%02d:%02d.%03d UTC : %s - %s\r\n",
98							time.wYear,
99							time.wMonth,
100							time.wDay,
101							time.wHour,
102							time.wMinute,
103							time.wSecond,
104							time.wMilliseconds,
105							prefix,
106							format);
107	} else {
108		if (prefix[0] == '\0')
109			wsprintfA( myformat, "%s\r\n", format);
110		else
111			wsprintfA( myformat, "%s - %s\r\n", prefix, format);
112	}
113	result = vsprintf(tst,myformat,params);
114
115	if (my_debug_output)
116		OutputDebugStringA(tst);
117
118	if (my_use_file && (hFile != NULL)) {
119		SetFilePointer( hFile, 0, 0, FILE_END );
120		DWORD written;
121		WriteFile( hFile, tst, lstrlenA(tst), &written, NULL );
122	}
123#else
124	if (my_time_included) {
125		time_t nowSecs;
126		struct tm *now;
127		struct timeval tv;
128
129		nowSecs = time(NULL);
130		gettimeofday(&tv, NULL);
131		now = gmtime(&nowSecs);
132		if (prefix[0] == '\0')
133			sprintf(myformat,"%04d/%02d/%02d %02d:%02d:%02ld.%03ld UTC : %s\r\n",
134					now->tm_year, now->tm_mon, now->tm_mday,
135					now->tm_hour, now->tm_min, tv.tv_sec,
136					(long)tv.tv_usec / 1000, format);
137		else
138			sprintf(myformat,"%04d/%02d/%02d %02d:%02d:%02ld.%03ld UTC : %s - %s\r\n",
139					now->tm_year, now->tm_mon, now->tm_mday,
140					now->tm_hour, now->tm_min, tv.tv_sec,
141					(long)tv.tv_usec / 1000, prefix, format);
142
143	} else {
144		if (prefix[0] == '\0')
145			sprintf( myformat, "%s\r\n", format);
146		else
147			sprintf( myformat, "%s - %s\r\n", prefix, format);
148	}
149
150	result = vsprintf(tst,myformat,params);
151
152	if (my_debug_output)
153		fputs(tst, stderr);
154
155	if (my_use_file && (hFile != NULL))
156		fputs(tst, hFile);
157#endif
158
159	return result;
160}
161
162int ADbg::OutPut(int forLevel, const char * format,...) const
163{
164	int result=0;
165
166	if (forLevel >= my_level) {
167		va_list tstlist;
168
169		va_start(tstlist, format);
170
171		result = _OutPut(format,tstlist);
172
173	}
174
175	return result;
176}
177
178int ADbg::OutPut(const char * format,...) const
179{
180	va_list tstlist;
181
182	va_start(tstlist, format);
183
184	return _OutPut(format,tstlist);
185}
186
187bool ADbg::setDebugFile(const char * NewFilename) {
188	bool result;
189	result = unsetDebugFile();
190
191	if (result) {
192		result = false;
193
194#ifdef WIN32
195		hFile = CreateFileA(NewFilename, GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
196
197		if (hFile != INVALID_HANDLE_VALUE) {
198			SetFilePointer( hFile, 0, 0, FILE_END );
199
200			result = true;
201#else
202		hFile = fopen(NewFilename, "w+");
203		if (hFile != NULL) {
204			fseek(hFile, 0, SEEK_END);
205#endif
206			OutPut(-1,"Debug hFile Opening succeeded");
207
208		}
209		else
210			OutPut(-1,"Debug hFile %s Opening failed",NewFilename);
211	}
212
213	return result;
214}
215
216bool ADbg::unsetDebugFile() {
217	bool result = (hFile == NULL);
218
219#ifdef WIN32
220	if (hFile != NULL) {
221		result = (CloseHandle(hFile) != 0);
222#else
223	if (hFile != NULL) {
224		result = (fclose(hFile) == 0);
225#endif
226
227		if (result) {
228			OutPut(-1,"Debug hFile Closing succeeded");
229			hFile = NULL;
230		}
231	}
232	return result;
233}
234
235#endif // !defined(NDEBUG)
236
237END_LIBEBML_NAMESPACE
238