1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 namespace IceInternal
6 {
7     using System.Collections.Generic;
8     using System.Diagnostics;
9     using System.Globalization;
10 
11     sealed class TraceUtil
12     {
traceSend(Ice.OutputStream str, Ice.Logger logger, TraceLevels tl)13         internal static void traceSend(Ice.OutputStream str, Ice.Logger logger, TraceLevels tl)
14         {
15             if(tl.protocol >= 1)
16             {
17                 int p = str.pos();
18                 Ice.InputStream iss = new Ice.InputStream(str.instance(), str.getEncoding(), str.getBuffer(), false);
19                 iss.pos(0);
20 
21                 using(System.IO.StringWriter s = new System.IO.StringWriter(CultureInfo.CurrentCulture))
22                 {
23                     byte type = printMessage(s, iss);
24 
25                     logger.trace(tl.protocolCat, "sending " + getMessageTypeAsString(type) + " " + s.ToString());
26                 }
27                 str.pos(p);
28             }
29         }
30 
traceRecv(Ice.InputStream str, Ice.Logger logger, TraceLevels tl)31         internal static void traceRecv(Ice.InputStream str, Ice.Logger logger, TraceLevels tl)
32         {
33             if(tl.protocol >= 1)
34             {
35                 int p = str.pos();
36                 str.pos(0);
37 
38                 using(System.IO.StringWriter s = new System.IO.StringWriter(CultureInfo.CurrentCulture))
39                 {
40                     byte type = printMessage(s, str);
41 
42                     logger.trace(tl.protocolCat, "received " + getMessageTypeAsString(type) + " " + s.ToString());
43                 }
44                 str.pos(p);
45             }
46         }
47 
trace(string heading, Ice.OutputStream str, Ice.Logger logger, TraceLevels tl)48         internal static void trace(string heading, Ice.OutputStream str, Ice.Logger logger, TraceLevels tl)
49         {
50             if(tl.protocol >= 1)
51             {
52                 int p = str.pos();
53                 Ice.InputStream iss = new Ice.InputStream(str.instance(), str.getEncoding(), str.getBuffer(), false);
54                 iss.pos(0);
55 
56                 using(System.IO.StringWriter s = new System.IO.StringWriter(CultureInfo.CurrentCulture))
57                 {
58                     s.Write(heading);
59                     printMessage(s, iss);
60 
61                     logger.trace(tl.protocolCat, s.ToString());
62                 }
63                 str.pos(p);
64             }
65         }
66 
trace(string heading, Ice.InputStream str, Ice.Logger logger, TraceLevels tl)67         internal static void trace(string heading, Ice.InputStream str, Ice.Logger logger, TraceLevels tl)
68         {
69             if(tl.protocol >= 1)
70             {
71                 int p = str.pos();
72                 str.pos(0);
73 
74                 using(System.IO.StringWriter s = new System.IO.StringWriter(CultureInfo.CurrentCulture))
75                 {
76                     s.Write(heading);
77                     printMessage(s, str);
78 
79                     logger.trace(tl.protocolCat, s.ToString());
80                 }
81                 str.pos(p);
82             }
83         }
84 
85         private static HashSet<string> slicingIds = new HashSet<string>();
86 
traceSlicing(string kind, string typeId, string slicingCat, Ice.Logger logger)87         internal static void traceSlicing(string kind, string typeId, string slicingCat, Ice.Logger logger)
88         {
89             lock(typeof(TraceUtil))
90             {
91                 if(slicingIds.Add(typeId))
92                 {
93                     using(System.IO.StringWriter s = new System.IO.StringWriter(CultureInfo.CurrentCulture))
94                     {
95                         s.Write("unknown " + kind + " type `" + typeId + "'");
96                         logger.trace(slicingCat, s.ToString());
97                     }
98                 }
99             }
100         }
101 
dumpStream(Ice.InputStream stream)102         public static void dumpStream(Ice.InputStream stream)
103         {
104             int pos = stream.pos();
105             stream.pos(0);
106 
107             byte[] data = new byte[stream.size()];
108             stream.readBlob(data);
109             dumpOctets(data);
110 
111             stream.pos(pos);
112         }
113 
dumpOctets(byte[] data)114         public static void dumpOctets(byte[] data)
115         {
116             const int inc = 8;
117 
118             for(int i = 0; i < data.Length; i += inc)
119             {
120                 for(int j = i; j - i < inc; j++)
121                 {
122                     if(j < data.Length)
123                     {
124                         int n = data[j];
125                         if(n < 0)
126                         {
127                             n += 256;
128                         }
129                         string s;
130                         if(n < 10)
131                         {
132                             s = "  " + n;
133                         }
134                         else if(n < 100)
135                         {
136                             s = " " + n;
137                         }
138                         else
139                         {
140                             s = "" + n;
141                         }
142                         System.Console.Out.Write(s + " ");
143                     }
144                     else
145                     {
146                         System.Console.Out.Write("    ");
147                     }
148                 }
149 
150                 System.Console.Out.Write('"');
151 
152                 for(int j = i; j < data.Length && j - i < inc; j++)
153                 {
154                     // TODO: this needs fixing
155                     if(data[j] >= 32 && data[j] < 127)
156                     {
157                         System.Console.Out.Write((char) data[j]);
158                     }
159                     else
160                     {
161                         System.Console.Out.Write('.');
162                     }
163                 }
164 
165                 System.Console.Out.WriteLine('"');
166             }
167         }
168 
printIdentityFacetOperation(System.IO.StringWriter s, Ice.InputStream str)169         private static void printIdentityFacetOperation(System.IO.StringWriter s, Ice.InputStream str)
170         {
171             try
172             {
173                 Ice.ToStringMode toStringMode = Ice.ToStringMode.Unicode;
174                 if(str.instance() != null)
175                 {
176                     toStringMode = str.instance().toStringMode();
177                 }
178 
179                 Ice.Identity identity = new Ice.Identity();
180                 identity.ice_readMembers(str);
181                 s.Write("\nidentity = " + Ice.Util.identityToString(identity, toStringMode));
182 
183                 string[] facet = str.readStringSeq();
184                 s.Write("\nfacet = ");
185                 if(facet.Length > 0)
186                 {
187                     s.Write(IceUtilInternal.StringUtil.escapeString(facet[0], "", toStringMode));
188                 }
189 
190                 string operation = str.readString();
191                 s.Write("\noperation = " + operation);
192             }
193             catch(System.IO.IOException)
194             {
195                 Debug.Assert(false);
196             }
197         }
198 
printRequest(System.IO.StringWriter s, Ice.InputStream str)199         private static void printRequest(System.IO.StringWriter s, Ice.InputStream str)
200         {
201             int requestId = str.readInt();
202             s.Write("\nrequest id = " + requestId);
203             if(requestId == 0)
204             {
205                 s.Write(" (oneway)");
206             }
207 
208             printRequestHeader(s, str);
209         }
210 
printBatchRequest(System.IO.StringWriter s, Ice.InputStream str)211         private static void printBatchRequest(System.IO.StringWriter s, Ice.InputStream str)
212         {
213             int batchRequestNum = str.readInt();
214             s.Write("\nnumber of requests = " + batchRequestNum);
215 
216             for(int i = 0; i < batchRequestNum; ++i)
217             {
218                 s.Write("\nrequest #" + i + ':');
219                 printRequestHeader(s, str);
220             }
221         }
222 
printReply(System.IO.StringWriter s, Ice.InputStream str)223         private static void printReply(System.IO.StringWriter s, Ice.InputStream str)
224         {
225             int requestId = str.readInt();
226             s.Write("\nrequest id = " + requestId);
227 
228             byte replyStatus = str.readByte();
229             s.Write("\nreply status = " + (int)replyStatus + ' ');
230 
231             switch(replyStatus)
232             {
233             case ReplyStatus.replyOK:
234             {
235                 s.Write("(ok)");
236                 break;
237             }
238 
239             case ReplyStatus.replyUserException:
240             {
241                 s.Write("(user exception)");
242                 break;
243             }
244 
245             case ReplyStatus.replyObjectNotExist:
246             case ReplyStatus.replyFacetNotExist:
247             case ReplyStatus.replyOperationNotExist:
248             {
249                 switch(replyStatus)
250                 {
251                 case ReplyStatus.replyObjectNotExist:
252                 {
253                     s.Write("(object not exist)");
254                     break;
255                 }
256 
257                 case ReplyStatus.replyFacetNotExist:
258                 {
259                     s.Write("(facet not exist)");
260                     break;
261                 }
262 
263                 case ReplyStatus.replyOperationNotExist:
264                 {
265                     s.Write("(operation not exist)");
266                     break;
267                 }
268 
269                 default:
270                 {
271                     Debug.Assert(false);
272                     break;
273                 }
274                 }
275 
276                 printIdentityFacetOperation(s, str);
277                 break;
278             }
279 
280             case ReplyStatus.replyUnknownException:
281             case ReplyStatus.replyUnknownLocalException:
282             case ReplyStatus.replyUnknownUserException:
283             {
284                 switch(replyStatus)
285                 {
286                 case ReplyStatus.replyUnknownException:
287                 {
288                     s.Write("(unknown exception)");
289                     break;
290                 }
291 
292                 case ReplyStatus.replyUnknownLocalException:
293                 {
294                     s.Write("(unknown local exception)");
295                     break;
296                 }
297 
298                 case ReplyStatus.replyUnknownUserException:
299                 {
300                     s.Write("(unknown user exception)");
301                     break;
302                 }
303 
304                 default:
305                 {
306                     Debug.Assert(false);
307                     break;
308                 }
309                 }
310 
311                 string unknown = str.readString();
312                 s.Write("\nunknown = " + unknown);
313                 break;
314             }
315 
316             default:
317             {
318                 s.Write("(unknown)");
319                 break;
320             }
321             }
322 
323             if(replyStatus == ReplyStatus.replyOK || replyStatus == ReplyStatus.replyUserException)
324             {
325                 Ice.EncodingVersion v = str.skipEncapsulation();
326                 if(!v.Equals(Ice.Util.Encoding_1_0))
327                 {
328                     s.Write("\nencoding = ");
329                     s.Write(Ice.Util.encodingVersionToString(v));
330                 }
331             }
332         }
333 
printRequestHeader(System.IO.StringWriter s, Ice.InputStream str)334         private static void printRequestHeader(System.IO.StringWriter s, Ice.InputStream str)
335         {
336             printIdentityFacetOperation(s, str);
337 
338             try
339             {
340                 byte mode = str.readByte();
341                 s.Write("\nmode = " + (int)mode + ' ');
342                 switch((Ice.OperationMode)mode)
343                 {
344                 case Ice.OperationMode.Normal:
345                 {
346                     s.Write("(normal)");
347                     break;
348                 }
349 
350                 case Ice.OperationMode.Nonmutating:
351                 {
352                     s.Write("(nonmutating)");
353                     break;
354                 }
355 
356                 case Ice.OperationMode.Idempotent:
357                 {
358                     s.Write("(idempotent)");
359                     break;
360                 }
361 
362                 default:
363                 {
364                     s.Write("(unknown)");
365                     break;
366                 }
367                 }
368 
369                 int sz = str.readSize();
370                 s.Write("\ncontext = ");
371                 while(sz-- > 0)
372                 {
373                     string key = str.readString();
374                     string val = str.readString();
375                     s.Write(key + '/' + val);
376                     if(sz > 0)
377                     {
378                         s.Write(", ");
379                     }
380                 }
381 
382                 Ice.EncodingVersion v = str.skipEncapsulation();
383                 if(!v.Equals(Ice.Util.Encoding_1_0))
384                 {
385                     s.Write("\nencoding = ");
386                     s.Write(Ice.Util.encodingVersionToString(v));
387                 }
388             }
389             catch(System.IO.IOException)
390             {
391                 Debug.Assert(false);
392             }
393         }
394 
printHeader(System.IO.StringWriter s, Ice.InputStream str)395         private static byte printHeader(System.IO.StringWriter s, Ice.InputStream str)
396         {
397             try
398             {
399                 str.readByte(); // Don't bother printing the magic number
400                 str.readByte();
401                 str.readByte();
402                 str.readByte();
403 
404                 /* byte pMajor = */ str.readByte();
405                 /* byte pMinor = */ str.readByte();
406                 //s.Write("\nprotocol version = " + (int)pMajor + "." + (int)pMinor);
407 
408                 /* byte eMajor = */ str.readByte();
409                 /* byte eMinor = */ str.readByte();
410                 //s.Write("\nencoding version = " + (int)eMajor + "." + (int)eMinor);
411 
412                 byte type = str.readByte();
413                 s.Write("\nmessage type = " + (int)type + " (" + getMessageTypeAsString(type) + ')');
414 
415                 byte compress = str.readByte();
416                 s.Write("\ncompression status = " + (int)compress + ' ');
417                 switch(compress)
418                 {
419                 case 0:
420                 {
421                     s.Write("(not compressed; do not compress response, if any)");
422                     break;
423                 }
424 
425                 case 1:
426                 {
427                     s.Write("(not compressed; compress response, if any)");
428                     break;
429                 }
430 
431                 case 2:
432                 {
433                     s.Write("(compressed; compress response, if any)");
434                     break;
435                 }
436 
437                 default:
438                 {
439                     s.Write("(unknown)");
440                     break;
441                 }
442                 }
443 
444                 int size = str.readInt();
445                 s.Write("\nmessage size = " + size);
446                 return type;
447             }
448             catch(System.IO.IOException)
449             {
450                 Debug.Assert(false);
451                 return 0;
452             }
453         }
454 
printMessage(System.IO.StringWriter s, Ice.InputStream str)455         private static byte printMessage(System.IO.StringWriter s, Ice.InputStream str)
456         {
457             byte type = printHeader(s, str);
458 
459             switch(type)
460             {
461             case Protocol.closeConnectionMsg:
462             case Protocol.validateConnectionMsg:
463             {
464                 // We're done.
465                 break;
466             }
467 
468             case Protocol.requestMsg:
469             {
470                 printRequest(s, str);
471                 break;
472             }
473 
474             case Protocol.requestBatchMsg:
475             {
476                 printBatchRequest(s, str);
477                 break;
478             }
479 
480             case Protocol.replyMsg:
481             {
482                 printReply(s, str);
483                 break;
484             }
485 
486             default:
487             {
488                 s.Write("(unknown)");
489                 break;
490             }
491             }
492 
493             return type;
494         }
495 
traceHeader(string heading, Ice.InputStream str, Ice.Logger logger, TraceLevels tl)496         internal static void traceHeader(string heading, Ice.InputStream str, Ice.Logger logger, TraceLevels tl)
497         {
498             if(tl.protocol >= 1)
499             {
500                 int p = str.pos();
501                 str.pos(0);
502 
503                 using(System.IO.StringWriter s = new System.IO.StringWriter(CultureInfo.CurrentCulture))
504                 {
505                     s.Write(heading);
506                     printHeader(s, str);
507 
508                     logger.trace(tl.protocolCat, s.ToString());
509                 }
510                 str.pos(p);
511             }
512         }
513 
getMessageTypeAsString(byte type)514         private static string getMessageTypeAsString(byte type)
515         {
516             switch(type)
517             {
518             case Protocol.requestMsg:
519                 return "request";
520             case Protocol.requestBatchMsg:
521                 return "batch request";
522             case Protocol.replyMsg:
523                 return "reply";
524             case Protocol.closeConnectionMsg:
525                 return "close connection";
526             case Protocol.validateConnectionMsg:
527                 return  "validate connection";
528             default:
529                 return "unknown";
530             }
531         }
532     }
533 
534 }
535