1 /*
2  * Modification History
3  *
4  * 2004-January-26		Jason Rohrer
5  * Created.
6  *
7  * 2004-January-27		Jason Rohrer
8  * Changed to support externally-specified file name prefixes.
9  */
10 
11 #include "minorGems/common.h"
12 
13 
14 #ifndef LOGGING_SOCKET_STREAM_CLASS_INCLUDED
15 #define LOGGING_SOCKET_STREAM_CLASS_INCLUDED
16 
17 #include "SocketStream.h"
18 
19 #include "minorGems/util/stringUtils.h"
20 
21 
22 #include <stdio.h>
23 
24 
25 
26 /**
27  * A SocketStream that logs inbound and outbound data.
28  *
29  * @author Jason Rohrer
30  */
31 class LoggingSocketStream : public SocketStream {
32 
33     public:
34 
35 
36         /**
37          * Constructs a SocketStream.
38          *
39          * @param inSocket the newtork socket wrapped by this stream.
40          *   inSocket is NOT destroyed when the stream is destroyed.
41          * @param inEnableInboundLog set to true to enable inbound logging.
42          * @param inEnableOutboundLog set to true to enable outbound logging.
43          * @param inLogSizeLimit the size limit of each log (both inbound
44          *   and outbound), in bytes.
45          *   Logging will stop after inLogSizeLimit bytes have been
46          *   written to each log.
47          * @param inLogNamePrefix a string that will be used to name
48          *   the log files (appending .in and .out for the two logs).
49          *   Should be unique.
50          *   Must be destroyed by caller.
51          */
52         LoggingSocketStream( Socket *inSocket, char inEnableInboundLog,
53                              char inEnableOutboundLog,
54                              unsigned long inLogSizeLimit,
55                              char *inLogNamePrefix );
56 
57 
58         virtual ~LoggingSocketStream();
59 
60 
61 
62         // overrides the SocketStream implementations
63 
64         long read( unsigned char *inBuffer, long inNumBytes );
65 
66         long write( unsigned char *inBuffer, long inNumBytes );
67 
68 
69     protected:
70         char mEnableInboundLog;
71         char mEnableOutboundLog;
72         unsigned long mLogSizeLimit;
73         FILE *mInboundLogFile;
74         FILE *mOutboundLogFile;
75         unsigned long mInboundSizeSoFar;
76         unsigned long mOutboundSizeSoFar;
77 
78     };
79 
80 
81 
LoggingSocketStream(Socket * inSocket,char inEnableInboundLog,char inEnableOutboundLog,unsigned long inLogSizeLimit,char * inLogNamePrefix)82 inline LoggingSocketStream::LoggingSocketStream(
83     Socket *inSocket,
84     char inEnableInboundLog,
85     char inEnableOutboundLog,
86     unsigned long inLogSizeLimit,
87     char *inLogNamePrefix )
88     : SocketStream( inSocket ),
89       mEnableInboundLog( inEnableInboundLog ),
90       mEnableOutboundLog( inEnableOutboundLog ),
91       mLogSizeLimit( inLogSizeLimit ),
92       mInboundLogFile( NULL ),
93       mOutboundLogFile( NULL ),
94       mInboundSizeSoFar( 0 ),
95       mOutboundSizeSoFar( 0 ) {
96 
97     if( mEnableInboundLog ) {
98         char *inboundFileName = autoSprintf( "%s.in", inLogNamePrefix );
99 
100         mInboundLogFile = fopen( inboundFileName, "wb" );
101 
102         delete [] inboundFileName;
103         }
104     if( mEnableOutboundLog ) {
105 
106         char *outboundFileName = autoSprintf( "%s.out", inLogNamePrefix );
107 
108         mOutboundLogFile = fopen( outboundFileName, "wb" );
109 
110         delete [] outboundFileName;
111         }
112 
113     }
114 
115 
116 
~LoggingSocketStream()117 inline LoggingSocketStream::~LoggingSocketStream() {
118     if( mInboundLogFile != NULL ) {
119         fclose( mInboundLogFile );
120         mInboundLogFile = NULL;
121         }
122     if( mOutboundLogFile != NULL ) {
123         fclose( mOutboundLogFile );
124         mOutboundLogFile = NULL;
125         }
126     }
127 
128 
129 
read(unsigned char * inBuffer,long inNumBytes)130 inline long LoggingSocketStream::read( unsigned char *inBuffer,
131                                        long inNumBytes ) {
132     long returnVal = SocketStream::read( inBuffer, inNumBytes );
133 
134     if( mEnableInboundLog &&
135         mInboundSizeSoFar < mLogSizeLimit &&
136         returnVal == inNumBytes ) {
137 
138         int numToLog = inNumBytes;
139         if( mInboundSizeSoFar + numToLog > mLogSizeLimit ) {
140             numToLog = mLogSizeLimit - mInboundSizeSoFar;
141             }
142 
143         if( mInboundLogFile != NULL ) {
144             fwrite( inBuffer, 1, numToLog, mInboundLogFile );
145             fflush( mInboundLogFile );
146             }
147         mInboundSizeSoFar += numToLog;
148         }
149 
150     return returnVal;
151     }
152 
153 
154 
write(unsigned char * inBuffer,long inNumBytes)155 inline long LoggingSocketStream::write( unsigned char *inBuffer,
156                                         long inNumBytes ) {
157 
158     long returnVal = SocketStream::write( inBuffer, inNumBytes );
159 
160     if( mEnableOutboundLog &&
161         mOutboundSizeSoFar < mLogSizeLimit &&
162         returnVal == inNumBytes ) {
163 
164         int numToLog = inNumBytes;
165         if( mOutboundSizeSoFar + numToLog > mLogSizeLimit ) {
166             numToLog = mLogSizeLimit - mOutboundSizeSoFar;
167             }
168 
169         if( mOutboundLogFile != NULL ) {
170             fwrite( inBuffer, 1, numToLog, mOutboundLogFile );
171             fflush( mOutboundLogFile );
172             }
173         mOutboundSizeSoFar += numToLog;
174         }
175 
176     return returnVal;
177     }
178 
179 
180 
181 #endif
182