1/*=--------------------------------------------------------------------------=*
2 * NetDebug.cpp -- Implementation of the BNetDebug class.
3 *
4 * Written by S.T. Mansfield (thephantom@mac.com)
5 *
6 * Remarks:
7 *   * Although this would more properly be implemented as a namespace...
8 *   * Do not burn the candle at both ends as it leads to the life of a
9 *     hairdresser.
10 *=--------------------------------------------------------------------------=*
11 * Copyright (c) 2002, The Haiku project.
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a
14 * copy of this software and associated documentation files (the "Software"),
15 * to deal in the Software without restriction, including without limitation
16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 * and/or sell copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 * DEALINGS IN THE SOFTWARE.
30 *=--------------------------------------------------------------------------=*
31 */
32
33
34#include <ctype.h>
35#include <stdio.h>
36#include <string.h>
37
38#include <NetDebug.h>
39#include <SupportDefs.h>
40
41
42// Off by default cuz the BeBook sez so.
43static bool g_NetDebugEnabled = false;
44
45
46/* Enable
47 *=--------------------------------------------------------------------------=*
48 * Purpose:
49 *     Enable/disable debug message capability for your app.
50 *
51 * Input parameter:
52 *     Enable       : True/False to enable/disable debug message output.
53 *
54 * Remarks:
55 *     This flag/setting is a per application basis, and not a per-instance
56 *     occurrence as one would expect when instantiating an instance of
57 *     this class.  This is by design as /everything/ is static.  Caveat
58 *     Emptor.  Needs to be dealt with in G.E.
59 */
60void BNetDebug::Enable( bool Enable )
61{
62    g_NetDebugEnabled = Enable;
63}
64
65
66/* IsEnabled
67 *=--------------------------------------------------------------------------=*
68 * Purpose:
69 *     Quiz the enable/disable status.
70 *
71 * Returns:
72 *     True/false if enabled/disabled.
73 */
74bool BNetDebug::IsEnabled( void )
75{
76    return g_NetDebugEnabled;
77}
78
79
80/* Print
81 *=--------------------------------------------------------------------------=*
82 * Purpose:
83 *     If enabled, spew forth a debug message.
84 *
85 * Input parameter:
86 *     msg          : The message to print.
87 *
88 * Remarks:
89 *     * Basically a no-op if not enabled.
90 *     * We're inheriting R5 (and Nettle's) behavior, so...
91 *       * The output is always "debug: msg\n"  Yes, kids, you read it right;
92 *         you get a newline whether you want it or not!
93 *       * If msg is empty, you get "debug: \n"
94 *       * Message is always printed on stderr.  Redirect accordingly.
95 */
96void BNetDebug::Print( const char* msg )
97{
98	if ( !g_NetDebugEnabled )
99    	return;
100
101	if (msg == NULL)
102		msg = "(null)";
103
104	fprintf( stderr, "debug: %s\n", msg );
105}
106
107
108/* Dump
109 *=--------------------------------------------------------------------------=*
110 * Purpose:
111 *     If enabled, spew forth a combination hex/ASCII dump of raw data.
112 *
113 * Input parameters:
114 *     data         : Data to dump.
115 *     size         : How many bytes of data to dump.
116 *     title        : Title to display in message header.
117 *
118 * Remarks:
119 *     * Basically a no-op if not enabled.
120 *     * We're inheriting R5 (and Nettle's) behavior, so...
121 *       * The output is always "debug: msg\n"  Yes, kids, you read it right;
122 *         you get a newline whether you want it or not!
123 *       * If msg is empty, you get "debug: \n"
124 *       * Behavior is undefined if data or title is NULL.  This is a
125 *         possible design flaw in Nettle/R5.
126 *       * Do not expect an output like this:
127 *          00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF | abcdefghijklmnop
128 *          00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF | abcdefghijklmnop
129 *          00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF | abcdefghijklmnop
130 *          00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF | abcdefghijklmnop
131 *         because you ain't gettin' it.  You will get a complete hex dump,
132 *         /followed/ by an ASCII dump.  More Glass Elevator stuff.
133 *     * Nettle dumps to stdOUT, the BeBook says all output goes to stdERR, so
134 *       the author chose to...
135 *     * always print to stdERR.  Redirect accordingly.
136 *     * stderr is flushed after the dump is complete to keep things
137 *       reasonably cohesive in appearance.  This might be an expensive
138 *       operation so use judiciously.
139 */
140void BNetDebug::Dump(const char* data, size_t size, const char* title)
141{
142
143    if ( ! g_NetDebugEnabled)
144        return;
145
146    fprintf( stderr, "----------\n%s\n(dumping %ld bytes)\n",
147    	title ? title : "(untitled)", size );
148
149    if (! data)
150    	fprintf(stderr, "NULL data!\n");
151    else {
152		uint32	i,j;
153	  	char text[96];	// only 3*16 + 3 + 16 max by line needed
154		uint8 *byte = (uint8 *) data;
155		char *ptr;
156
157		for ( i = 0; i < size; i += 16 )	{
158			ptr = text;
159
160	      	for ( j = i; j < i + 16 ; j++ ) {
161				if ( j < size )
162					sprintf(ptr, "%02x ", byte[j]);
163				else
164					sprintf(ptr, "   ");
165				ptr += 3;
166			};
167
168			strcat(ptr, "| ");
169			ptr += 2;
170
171			for (j = i; j < size && j < i + 16;j++) {
172				if ( byte[j] >= 0x20 && byte[j] < 0x7e )
173					*ptr = byte[j];
174				else
175					*ptr = '.';
176				ptr++;
177			};
178
179			ptr[0] = '\n';
180			ptr[1] = '\0';
181			fputs(text, stderr);
182		};
183	};
184    fputs("----------\n", stderr);
185    fflush( stderr );
186}
187
188
189/*=------------------------------------------------------------------- End -=*/
190