PageRenderTime 92ms CodeModel.GetById 4ms RepoModel.GetById 0ms app.codeStats 0ms

/WCFWebApi/src/System.Net.Http/System/Net/Logging.cs

#
C# | 773 lines | 597 code | 78 blank | 98 comment | 95 complexity | 1785009a6d946b2a01592c078e46613d MD5 | raw file
Possible License(s): CC-BY-SA-3.0, Apache-2.0
  1. //------------------------------------------------------------------------------
  2. // <copyright file="Logging.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. //------------------------------------------------------------------------------
  6. namespace System.Net
  7. {
  8. using System.Collections;
  9. using System.IO;
  10. using System.Threading;
  11. using System.Diagnostics;
  12. using System.Security;
  13. using System.Security.Permissions;
  14. using System.Runtime.InteropServices;
  15. using System.Globalization;
  16. using Microsoft.Win32;
  17. using System.Diagnostics.CodeAnalysis;
  18. using System.Runtime.CompilerServices;
  19. using System.Text;
  20. using System.Net.Http;
  21. using System.Linq;
  22. using System.Collections.ObjectModel;
  23. internal class Logging
  24. {
  25. private static volatile bool s_LoggingEnabled = true;
  26. private static volatile bool s_LoggingInitialized;
  27. private static volatile bool s_AppDomainShutdown;
  28. private const int DefaultMaxDumpSize = 1024;
  29. private const bool DefaultUseProtocolTextOnly = false;
  30. private const string AttributeNameMaxSize = "maxdatasize";
  31. private const string AttributeNameTraceMode = "tracemode";
  32. private static readonly string[] SupportedAttributes = new string[] { AttributeNameMaxSize, AttributeNameTraceMode };
  33. private const string AttributeValueProtocolOnly = "protocolonly";
  34. //private const string AttributeValueIncludeHex = "includehex";
  35. private const string TraceSourceWebName = "System.Net";
  36. private const string TraceSourceHttpListenerName = "System.Net.HttpListener";
  37. private const string TraceSourceSocketsName = "System.Net.Sockets";
  38. private const string TraceSourceWebSocketsName = "System.Net.WebSockets";
  39. private const string TraceSourceCacheName = "System.Net.Cache";
  40. private const string TraceSourceHttpName = "System.Net.Http";
  41. private static TraceSource s_WebTraceSource;
  42. private static TraceSource s_HttpListenerTraceSource;
  43. private static TraceSource s_SocketsTraceSource;
  44. private static TraceSource s_WebSocketsTraceSource;
  45. private static TraceSource s_CacheTraceSource;
  46. private static TraceSource s_TraceSourceHttpName;
  47. private Logging()
  48. {
  49. }
  50. private static object s_InternalSyncObject;
  51. private static object InternalSyncObject
  52. {
  53. get
  54. {
  55. if (s_InternalSyncObject == null)
  56. {
  57. object o = new Object();
  58. Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
  59. }
  60. return s_InternalSyncObject;
  61. }
  62. }
  63. internal static bool On
  64. {
  65. get
  66. {
  67. if (!s_LoggingInitialized)
  68. {
  69. InitializeLogging();
  70. }
  71. return s_LoggingEnabled;
  72. }
  73. }
  74. internal static bool IsVerbose(TraceSource traceSource)
  75. {
  76. return ValidateSettings(traceSource, TraceEventType.Verbose);
  77. }
  78. internal static TraceSource Web
  79. {
  80. get
  81. {
  82. if (!s_LoggingInitialized)
  83. {
  84. InitializeLogging();
  85. }
  86. if (!s_LoggingEnabled)
  87. {
  88. return null;
  89. }
  90. return s_WebTraceSource;
  91. }
  92. }
  93. internal static TraceSource Http
  94. {
  95. get
  96. {
  97. if (!s_LoggingInitialized)
  98. {
  99. InitializeLogging();
  100. }
  101. if (!s_LoggingEnabled)
  102. {
  103. return null;
  104. }
  105. return s_TraceSourceHttpName;
  106. }
  107. }
  108. internal static TraceSource HttpListener
  109. {
  110. get
  111. {
  112. if (!s_LoggingInitialized)
  113. {
  114. InitializeLogging();
  115. }
  116. if (!s_LoggingEnabled)
  117. {
  118. return null;
  119. }
  120. return s_HttpListenerTraceSource;
  121. }
  122. }
  123. internal static TraceSource Sockets
  124. {
  125. get
  126. {
  127. if (!s_LoggingInitialized)
  128. {
  129. InitializeLogging();
  130. }
  131. if (!s_LoggingEnabled)
  132. {
  133. return null;
  134. }
  135. return s_SocketsTraceSource;
  136. }
  137. }
  138. internal static TraceSource RequestCache
  139. {
  140. get
  141. {
  142. if (!s_LoggingInitialized)
  143. {
  144. InitializeLogging();
  145. }
  146. if (!s_LoggingEnabled)
  147. {
  148. return null;
  149. }
  150. return s_CacheTraceSource;
  151. }
  152. }
  153. internal static TraceSource WebSockets
  154. {
  155. get
  156. {
  157. if (!s_LoggingInitialized)
  158. {
  159. InitializeLogging();
  160. }
  161. if (!s_LoggingEnabled)
  162. {
  163. return null;
  164. }
  165. return s_WebSocketsTraceSource;
  166. }
  167. }
  168. private static bool GetUseProtocolTextSetting(TraceSource traceSource)
  169. {
  170. bool useProtocolTextOnly = DefaultUseProtocolTextOnly;
  171. if (traceSource.Attributes[AttributeNameTraceMode] == AttributeValueProtocolOnly)
  172. {
  173. useProtocolTextOnly = true;
  174. }
  175. return useProtocolTextOnly;
  176. }
  177. private static int GetMaxDumpSizeSetting(TraceSource traceSource)
  178. {
  179. int maxDumpSize = DefaultMaxDumpSize;
  180. if (traceSource.Attributes.ContainsKey(AttributeNameMaxSize))
  181. {
  182. try
  183. {
  184. maxDumpSize = Int32.Parse(traceSource.Attributes[AttributeNameMaxSize], NumberFormatInfo.InvariantInfo);
  185. }
  186. catch (Exception exception)
  187. {
  188. if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException)
  189. {
  190. throw;
  191. }
  192. traceSource.Attributes[AttributeNameMaxSize] = maxDumpSize.ToString(NumberFormatInfo.InvariantInfo);
  193. }
  194. }
  195. return maxDumpSize;
  196. }
  197. /// <devdoc>
  198. /// <para>Sets up internal config settings for logging. (MUST be called under critsec) </para>
  199. /// </devdoc>
  200. private static void InitializeLogging()
  201. {
  202. lock (InternalSyncObject)
  203. {
  204. if (!s_LoggingInitialized)
  205. {
  206. bool loggingEnabled = false;
  207. s_WebTraceSource = new NclTraceSource(TraceSourceWebName);
  208. s_HttpListenerTraceSource = new NclTraceSource(TraceSourceHttpListenerName);
  209. s_SocketsTraceSource = new NclTraceSource(TraceSourceSocketsName);
  210. s_WebSocketsTraceSource = new NclTraceSource(TraceSourceWebSocketsName);
  211. s_CacheTraceSource = new NclTraceSource(TraceSourceCacheName);
  212. s_TraceSourceHttpName = new NclTraceSource(TraceSourceHttpName);
  213. try
  214. {
  215. loggingEnabled = (s_WebTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
  216. s_HttpListenerTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
  217. s_SocketsTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
  218. s_WebSocketsTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
  219. s_CacheTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
  220. s_TraceSourceHttpName.Switch.ShouldTrace(TraceEventType.Critical));
  221. }
  222. catch (SecurityException)
  223. {
  224. // These may throw if the caller does not have permission to hook up trace listeners.
  225. // We treat this case as though logging were disabled.
  226. Close();
  227. loggingEnabled = false;
  228. }
  229. if (loggingEnabled)
  230. {
  231. AppDomain currentDomain = AppDomain.CurrentDomain;
  232. currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
  233. currentDomain.DomainUnload += new EventHandler(AppDomainUnloadEvent);
  234. currentDomain.ProcessExit += new EventHandler(ProcessExitEvent);
  235. }
  236. s_LoggingEnabled = loggingEnabled;
  237. s_LoggingInitialized = true;
  238. }
  239. }
  240. }
  241. [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Logging functions must work in partial trust mode")]
  242. private static void Close()
  243. {
  244. if (s_WebTraceSource != null) s_WebTraceSource.Close();
  245. if (s_HttpListenerTraceSource != null) s_HttpListenerTraceSource.Close();
  246. if (s_SocketsTraceSource != null) s_SocketsTraceSource.Close();
  247. if (s_WebSocketsTraceSource != null) s_WebSocketsTraceSource.Close();
  248. if (s_CacheTraceSource != null) s_CacheTraceSource.Close();
  249. if (s_TraceSourceHttpName != null) s_TraceSourceHttpName.Close();
  250. }
  251. /// <devdoc>
  252. /// <para>Logs any unhandled exception through this event handler</para>
  253. /// </devdoc>
  254. private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
  255. {
  256. Exception e = (Exception)args.ExceptionObject;
  257. Exception(Web, sender, "UnhandledExceptionHandler", e);
  258. }
  259. private static void ProcessExitEvent(object sender, EventArgs e)
  260. {
  261. Close();
  262. s_AppDomainShutdown = true;
  263. }
  264. /// <devdoc>
  265. /// <para>Called when the system is shutting down, used to prevent additional logging post-shutdown</para>
  266. /// </devdoc>
  267. private static void AppDomainUnloadEvent(object sender, EventArgs e)
  268. {
  269. Close();
  270. s_AppDomainShutdown = true;
  271. }
  272. /// <devdoc>
  273. /// <para>Confirms logging is enabled, given current logging settings</para>
  274. /// </devdoc>
  275. private static bool ValidateSettings(TraceSource traceSource, TraceEventType traceLevel)
  276. {
  277. if (!s_LoggingEnabled)
  278. {
  279. return false;
  280. }
  281. if (!s_LoggingInitialized)
  282. {
  283. InitializeLogging();
  284. }
  285. if (traceSource == null || !traceSource.Switch.ShouldTrace(traceLevel))
  286. {
  287. return false;
  288. }
  289. if (s_AppDomainShutdown)
  290. {
  291. return false;
  292. }
  293. return true;
  294. }
  295. /// <devdoc>
  296. /// <para>Converts an object to a normalized string that can be printed
  297. /// takes System.Net.ObjectNamedFoo and coverts to ObjectNamedFoo,
  298. /// except IPAddress, IPEndPoint, and Uri, which return ToString()
  299. /// </para>
  300. /// </devdoc>
  301. private static string GetObjectName(object obj)
  302. {
  303. if (obj is Uri || obj is System.Net.IPAddress || obj is System.Net.IPEndPoint)
  304. {
  305. return obj.ToString();
  306. }
  307. else
  308. {
  309. return obj.GetType().Name;
  310. }
  311. }
  312. [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass", Justification = "code is clone of System.Net.Http")]
  313. [DllImport("kernel32.dll", ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
  314. internal static extern uint GetCurrentThreadId();
  315. internal static uint GetThreadId()
  316. {
  317. uint threadId = GetCurrentThreadId();
  318. if (threadId == 0)
  319. {
  320. threadId = (uint)Thread.CurrentThread.GetHashCode();
  321. }
  322. return threadId;
  323. }
  324. internal static void PrintLine(TraceSource traceSource, TraceEventType eventType, int id, string msg)
  325. {
  326. string logHeader = "[" + GetThreadId().ToString("d4", CultureInfo.InvariantCulture) + "] ";
  327. traceSource.TraceEvent(eventType, id, logHeader + msg);
  328. }
  329. /// <devdoc>
  330. /// <para>Indicates that two objects are getting used with one another</para>
  331. /// </devdoc>
  332. internal static void Associate(TraceSource traceSource, object objA, object objB)
  333. {
  334. if (!ValidateSettings(traceSource, TraceEventType.Information))
  335. {
  336. return;
  337. }
  338. string lineA = GetObjectName(objA) + "#" + ValidationHelper.HashString(objA);
  339. string lineB = GetObjectName(objB) + "#" + ValidationHelper.HashString(objB);
  340. PrintLine(traceSource, TraceEventType.Information, 0, "Associating " + lineA + " with " + lineB);
  341. }
  342. /// <devdoc>
  343. /// <para>Logs entrance to a function</para>
  344. /// </devdoc>
  345. internal static void Enter(TraceSource traceSource, object obj, string method, string param)
  346. {
  347. if (!ValidateSettings(traceSource, TraceEventType.Information))
  348. {
  349. return;
  350. }
  351. Enter(traceSource, GetObjectName(obj) + "#" + ValidationHelper.HashString(obj), method, param);
  352. }
  353. /// <devdoc>
  354. /// <para>Logs entrance to a function</para>
  355. /// </devdoc>
  356. internal static void Enter(TraceSource traceSource, object obj, string method, object paramObject)
  357. {
  358. if (!ValidateSettings(traceSource, TraceEventType.Information))
  359. {
  360. return;
  361. }
  362. Enter(traceSource, GetObjectName(obj) + "#" + ValidationHelper.HashString(obj), method, paramObject);
  363. }
  364. /// <devdoc>
  365. /// <para>Logs entrance to a function</para>
  366. /// </devdoc>
  367. internal static void Enter(TraceSource traceSource, string obj, string method, string param)
  368. {
  369. if (!ValidateSettings(traceSource, TraceEventType.Information))
  370. {
  371. return;
  372. }
  373. Enter(traceSource, obj + "::" + method + "(" + param + ")");
  374. }
  375. /// <devdoc>
  376. /// <para>Logs entrance to a function</para>
  377. /// </devdoc>
  378. internal static void Enter(TraceSource traceSource, string obj, string method, object paramObject)
  379. {
  380. if (!ValidateSettings(traceSource, TraceEventType.Information))
  381. {
  382. return;
  383. }
  384. string paramObjectValue = "";
  385. if (paramObject != null)
  386. {
  387. paramObjectValue = GetObjectName(paramObject) + "#" + ValidationHelper.HashString(paramObject);
  388. }
  389. Enter(traceSource, obj + "::" + method + "(" + paramObjectValue + ")");
  390. }
  391. /// <devdoc>
  392. /// <para>Logs entrance to a function, indents and points that out</para>
  393. /// </devdoc>
  394. internal static void Enter(TraceSource traceSource, string method, string parameters)
  395. {
  396. if (!ValidateSettings(traceSource, TraceEventType.Information))
  397. {
  398. return;
  399. }
  400. Enter(traceSource, method + "(" + parameters + ")");
  401. }
  402. /// <devdoc>
  403. /// <para>Logs entrance to a function, indents and points that out</para>
  404. /// </devdoc>
  405. internal static void Enter(TraceSource traceSource, string msg)
  406. {
  407. if (!ValidateSettings(traceSource, TraceEventType.Information))
  408. {
  409. return;
  410. }
  411. // Trace.CorrelationManager.StartLogicalOperation();
  412. PrintLine(traceSource, TraceEventType.Verbose, 0, msg);
  413. }
  414. /// <devdoc>
  415. /// <para>Logs exit from a function</para>
  416. /// </devdoc>
  417. internal static void Exit(TraceSource traceSource, object obj, string method, object retObject)
  418. {
  419. if (!ValidateSettings(traceSource, TraceEventType.Information))
  420. {
  421. return;
  422. }
  423. string retValue = "";
  424. if (retObject != null)
  425. {
  426. retValue = GetObjectName(retObject) + "#" + ValidationHelper.HashString(retObject);
  427. }
  428. Exit(traceSource, obj, method, retValue);
  429. }
  430. /// <devdoc>
  431. /// <para>Logs exit from a function</para>
  432. /// </devdoc>
  433. internal static void Exit(TraceSource traceSource, string obj, string method, object retObject)
  434. {
  435. if (!ValidateSettings(traceSource, TraceEventType.Information))
  436. {
  437. return;
  438. }
  439. string retValue = "";
  440. if (retObject != null)
  441. {
  442. retValue = GetObjectName(retObject) + "#" + ValidationHelper.HashString(retObject);
  443. }
  444. Exit(traceSource, obj, method, retValue);
  445. }
  446. /// <devdoc>
  447. /// <para>Logs exit from a function</para>
  448. /// </devdoc>
  449. internal static void Exit(TraceSource traceSource, object obj, string method, string retValue)
  450. {
  451. if (!ValidateSettings(traceSource, TraceEventType.Information))
  452. {
  453. return;
  454. }
  455. Exit(traceSource, GetObjectName(obj) + "#" + ValidationHelper.HashString(obj), method, retValue);
  456. }
  457. /// <devdoc>
  458. /// <para>Logs exit from a function</para>
  459. /// </devdoc>
  460. internal static void Exit(TraceSource traceSource, string obj, string method, string retValue)
  461. {
  462. if (!ValidateSettings(traceSource, TraceEventType.Information))
  463. {
  464. return;
  465. }
  466. if (!ValidationHelper.IsBlankString(retValue))
  467. {
  468. retValue = "\t-> " + retValue;
  469. }
  470. Exit(traceSource, obj + "::" + method + "() " + retValue);
  471. }
  472. /// <devdoc>
  473. /// <para>Logs exit from a function</para>
  474. /// </devdoc>
  475. internal static void Exit(TraceSource traceSource, string method, string parameters)
  476. {
  477. if (!ValidateSettings(traceSource, TraceEventType.Information))
  478. {
  479. return;
  480. }
  481. Exit(traceSource, method + "() " + parameters);
  482. }
  483. /// <devdoc>
  484. /// <para>Logs exit from a function</para>
  485. /// </devdoc>
  486. internal static void Exit(TraceSource traceSource, string msg)
  487. {
  488. if (!ValidateSettings(traceSource, TraceEventType.Information))
  489. {
  490. return;
  491. }
  492. PrintLine(traceSource, TraceEventType.Verbose, 0, "Exiting " + msg);
  493. // Trace.CorrelationManager.StopLogicalOperation();
  494. }
  495. /// <devdoc>
  496. /// <para>Logs Exception, restores indenting</para>
  497. /// </devdoc>
  498. internal static void Exception(TraceSource traceSource, object obj, string method, Exception e)
  499. {
  500. if (!ValidateSettings(traceSource, TraceEventType.Error))
  501. {
  502. return;
  503. }
  504. StringBuilder exceptionMessageBuilder = new StringBuilder(e.Message);
  505. if (e is AggregateException)
  506. {
  507. AggregateException aggregateException = e as AggregateException;
  508. ReadOnlyCollection<Exception> innerExceptions = aggregateException.Flatten().InnerExceptions;
  509. if (innerExceptions.Count > 0)
  510. {
  511. string innerExceptionMessages = string.Join(", ", innerExceptions.Select(innerException => innerException.Message));
  512. exceptionMessageBuilder.AppendFormat(CultureInfo.InvariantCulture, " InnerExceptions: {0}", innerExceptionMessages);
  513. }
  514. }
  515. string infoLine = string.Format(CultureInfo.InvariantCulture, SysSR.net_log_exception, GetObjectLogHash(obj), method, exceptionMessageBuilder.ToString());
  516. if (!ValidationHelper.IsBlankString(e.StackTrace))
  517. {
  518. infoLine += "\r\n" + e.StackTrace;
  519. }
  520. PrintLine(traceSource, TraceEventType.Error, 0, infoLine);
  521. }
  522. /// <devdoc>
  523. /// <para>Logs an Info line</para>
  524. /// </devdoc>
  525. internal static void PrintInfo(TraceSource traceSource, string msg)
  526. {
  527. if (!ValidateSettings(traceSource, TraceEventType.Information))
  528. {
  529. return;
  530. }
  531. PrintLine(traceSource, TraceEventType.Information, 0, msg);
  532. }
  533. /// <devdoc>
  534. /// <para>Logs an Info line</para>
  535. /// </devdoc>
  536. internal static void PrintInfo(TraceSource traceSource, object obj, string msg)
  537. {
  538. if (!ValidateSettings(traceSource, TraceEventType.Information))
  539. {
  540. return;
  541. }
  542. PrintLine(traceSource, TraceEventType.Information, 0,
  543. GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
  544. + " - " + msg);
  545. }
  546. /// <devdoc>
  547. /// <para>Logs an Info line</para>
  548. /// </devdoc>
  549. internal static void PrintInfo(TraceSource traceSource, object obj, string method, string param)
  550. {
  551. if (!ValidateSettings(traceSource, TraceEventType.Information))
  552. {
  553. return;
  554. }
  555. PrintLine(traceSource, TraceEventType.Information, 0,
  556. GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
  557. + "::" + method + "(" + param + ")");
  558. }
  559. /// <devdoc>
  560. /// <para>Logs a Warning line</para>
  561. /// </devdoc>
  562. internal static void PrintWarning(TraceSource traceSource, string msg)
  563. {
  564. if (!ValidateSettings(traceSource, TraceEventType.Warning))
  565. {
  566. return;
  567. }
  568. PrintLine(traceSource, TraceEventType.Warning, 0, msg);
  569. }
  570. /// <devdoc>
  571. /// <para>Logs a Warning line</para>
  572. /// </devdoc>
  573. internal static void PrintWarning(TraceSource traceSource, object obj, string method, string msg)
  574. {
  575. if (!ValidateSettings(traceSource, TraceEventType.Warning))
  576. {
  577. return;
  578. }
  579. PrintLine(traceSource, TraceEventType.Warning, 0,
  580. GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
  581. + "::" + method + "() - " + msg);
  582. }
  583. /// <devdoc>
  584. /// <para>Logs an Error line</para>
  585. /// </devdoc>
  586. internal static void PrintError(TraceSource traceSource, string msg)
  587. {
  588. if (!ValidateSettings(traceSource, TraceEventType.Error))
  589. {
  590. return;
  591. }
  592. PrintLine(traceSource, TraceEventType.Error, 0, msg);
  593. }
  594. /// <devdoc>
  595. /// <para>Logs an Error line</para>
  596. /// </devdoc>
  597. internal static void PrintError(TraceSource traceSource, object obj, string method, string msg)
  598. {
  599. if (!ValidateSettings(traceSource, TraceEventType.Error))
  600. {
  601. return;
  602. }
  603. PrintLine(traceSource, TraceEventType.Error, 0,
  604. GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
  605. + "::" + method + "() - " + msg);
  606. }
  607. internal static string GetObjectLogHash(object obj)
  608. {
  609. return GetObjectName(obj) + "#" + ValidationHelper.HashString(obj);
  610. }
  611. /// <devdoc>
  612. /// <para>Marhsalls a buffer ptr to an array and then dumps the byte array to the log</para>
  613. /// </devdoc>
  614. internal static void Dump(TraceSource traceSource, object obj, string method, IntPtr bufferPtr, int length)
  615. {
  616. if (!ValidateSettings(traceSource, TraceEventType.Verbose) || bufferPtr == IntPtr.Zero || length < 0)
  617. {
  618. return;
  619. }
  620. byte[] buffer = new byte[length];
  621. Marshal.Copy(bufferPtr, buffer, 0, length);
  622. Dump(traceSource, obj, method, buffer, 0, length);
  623. }
  624. // Latin-1 encoding (ISO-88591-1)
  625. private static Encoding headerEncoding = Encoding.GetEncoding(28591);
  626. /// <devdoc>
  627. /// <para>Dumps a byte array to the log</para>
  628. /// </devdoc>
  629. internal static void Dump(TraceSource traceSource, object obj, string method, byte[] buffer, int offset, int length)
  630. {
  631. if (!ValidateSettings(traceSource, TraceEventType.Verbose))
  632. {
  633. return;
  634. }
  635. if (buffer == null)
  636. {
  637. PrintLine(traceSource, TraceEventType.Verbose, 0, "(null)");
  638. return;
  639. }
  640. if (offset > buffer.Length)
  641. {
  642. PrintLine(traceSource, TraceEventType.Verbose, 0, "(offset out of range)");
  643. return;
  644. }
  645. PrintLine(traceSource, TraceEventType.Verbose, 0, "Data from " + GetObjectName(obj) + "#" + ValidationHelper.HashString(obj) + "::" + method);
  646. int maxDumpSize = GetMaxDumpSizeSetting(traceSource);
  647. if (length > maxDumpSize)
  648. {
  649. PrintLine(traceSource, TraceEventType.Verbose, 0, "(printing " + maxDumpSize.ToString(NumberFormatInfo.InvariantInfo) + " out of " + length.ToString(NumberFormatInfo.InvariantInfo) + ")");
  650. length = maxDumpSize;
  651. }
  652. if ((length < 0) || (length > buffer.Length - offset))
  653. {
  654. length = buffer.Length - offset;
  655. }
  656. if (GetUseProtocolTextSetting(traceSource))
  657. {
  658. string output = "<<" + headerEncoding.GetString(buffer, offset, length) + ">>";
  659. PrintLine(traceSource, TraceEventType.Verbose, 0, output);
  660. return;
  661. }
  662. do
  663. {
  664. int n = Math.Min(length, 16);
  665. string disp = String.Format(CultureInfo.CurrentCulture, "{0:X8} : ", offset);
  666. for (int i = 0; i < n; ++i)
  667. {
  668. disp += String.Format(CultureInfo.CurrentCulture, "{0:X2}", buffer[offset + i]) + ((i == 7) ? '-' : ' ');
  669. }
  670. for (int i = n; i < 16; ++i)
  671. {
  672. disp += " ";
  673. }
  674. disp += ": ";
  675. for (int i = 0; i < n; ++i)
  676. {
  677. disp += ((buffer[offset + i] < 0x20) || (buffer[offset + i] > 0x7e))
  678. ? '.'
  679. : (char)(buffer[offset + i]);
  680. }
  681. PrintLine(traceSource, TraceEventType.Verbose, 0, disp);
  682. offset += n;
  683. length -= n;
  684. } while (length > 0);
  685. }
  686. private class NclTraceSource : TraceSource
  687. {
  688. internal NclTraceSource(string name) : base(name) { }
  689. protected override string[] GetSupportedAttributes()
  690. {
  691. return Logging.SupportedAttributes;
  692. }
  693. }
  694. }
  695. }