QuietTextWriter.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #region Apache License
  2. //
  3. // Licensed to the Apache Software Foundation (ASF) under one or more
  4. // contributor license agreements. See the NOTICE file distributed with
  5. // this work for additional information regarding copyright ownership.
  6. // The ASF licenses this file to you under the Apache License, Version 2.0
  7. // (the "License"); you may not use this file except in compliance with
  8. // the License. You may obtain a copy of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS,
  14. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. // See the License for the specific language governing permissions and
  16. // limitations under the License.
  17. //
  18. #endregion
  19. using System;
  20. using System.IO;
  21. using log4net.Core;
  22. namespace log4net.Util
  23. {
  24. /// <summary>
  25. /// <see cref="TextWriter"/> that does not leak exceptions
  26. /// </summary>
  27. /// <remarks>
  28. /// <para>
  29. /// <see cref="QuietTextWriter"/> does not throw exceptions when things go wrong.
  30. /// Instead, it delegates error handling to its <see cref="IErrorHandler"/>.
  31. /// </para>
  32. /// </remarks>
  33. /// <author>Nicko Cadell</author>
  34. /// <author>Gert Driesen</author>
  35. public class QuietTextWriter : TextWriterAdapter
  36. {
  37. #region Public Instance Constructors
  38. /// <summary>
  39. /// Constructor
  40. /// </summary>
  41. /// <param name="writer">the writer to actually write to</param>
  42. /// <param name="errorHandler">the error handler to report error to</param>
  43. /// <remarks>
  44. /// <para>
  45. /// Create a new QuietTextWriter using a writer and error handler
  46. /// </para>
  47. /// </remarks>
  48. public QuietTextWriter(TextWriter writer, IErrorHandler errorHandler) : base(writer)
  49. {
  50. if (errorHandler == null)
  51. {
  52. throw new ArgumentNullException("errorHandler");
  53. }
  54. ErrorHandler = errorHandler;
  55. }
  56. #endregion Public Instance Constructors
  57. #region Public Instance Properties
  58. /// <summary>
  59. /// Gets or sets the error handler that all errors are passed to.
  60. /// </summary>
  61. /// <value>
  62. /// The error handler that all errors are passed to.
  63. /// </value>
  64. /// <remarks>
  65. /// <para>
  66. /// Gets or sets the error handler that all errors are passed to.
  67. /// </para>
  68. /// </remarks>
  69. public IErrorHandler ErrorHandler
  70. {
  71. get { return m_errorHandler; }
  72. set
  73. {
  74. if (value == null)
  75. {
  76. // This is a programming error on the part of the enclosing appender.
  77. throw new ArgumentNullException("value");
  78. }
  79. m_errorHandler = value;
  80. }
  81. }
  82. /// <summary>
  83. /// Gets a value indicating whether this writer is closed.
  84. /// </summary>
  85. /// <value>
  86. /// <c>true</c> if this writer is closed, otherwise <c>false</c>.
  87. /// </value>
  88. /// <remarks>
  89. /// <para>
  90. /// Gets a value indicating whether this writer is closed.
  91. /// </para>
  92. /// </remarks>
  93. public bool Closed
  94. {
  95. get { return m_closed; }
  96. }
  97. #endregion Public Instance Properties
  98. #region Override Implementation of TextWriter
  99. /// <summary>
  100. /// Writes a character to the underlying writer
  101. /// </summary>
  102. /// <param name="value">the char to write</param>
  103. /// <remarks>
  104. /// <para>
  105. /// Writes a character to the underlying writer
  106. /// </para>
  107. /// </remarks>
  108. public override void Write(char value)
  109. {
  110. try
  111. {
  112. base.Write(value);
  113. }
  114. catch(Exception e)
  115. {
  116. m_errorHandler.Error("Failed to write [" + value + "].", e, ErrorCode.WriteFailure);
  117. }
  118. }
  119. /// <summary>
  120. /// Writes a buffer to the underlying writer
  121. /// </summary>
  122. /// <param name="buffer">the buffer to write</param>
  123. /// <param name="index">the start index to write from</param>
  124. /// <param name="count">the number of characters to write</param>
  125. /// <remarks>
  126. /// <para>
  127. /// Writes a buffer to the underlying writer
  128. /// </para>
  129. /// </remarks>
  130. public override void Write(char[] buffer, int index, int count)
  131. {
  132. try
  133. {
  134. base.Write(buffer, index, count);
  135. }
  136. catch(Exception e)
  137. {
  138. m_errorHandler.Error("Failed to write buffer.", e, ErrorCode.WriteFailure);
  139. }
  140. }
  141. /// <summary>
  142. /// Writes a string to the output.
  143. /// </summary>
  144. /// <param name="value">The string data to write to the output.</param>
  145. /// <remarks>
  146. /// <para>
  147. /// Writes a string to the output.
  148. /// </para>
  149. /// </remarks>
  150. override public void Write(string value)
  151. {
  152. try
  153. {
  154. base.Write(value);
  155. }
  156. catch(Exception e)
  157. {
  158. m_errorHandler.Error("Failed to write [" + value + "].", e, ErrorCode.WriteFailure);
  159. }
  160. }
  161. /// <summary>
  162. /// Closes the underlying output writer.
  163. /// </summary>
  164. /// <remarks>
  165. /// <para>
  166. /// Closes the underlying output writer.
  167. /// </para>
  168. /// </remarks>
  169. override public void Close()
  170. {
  171. m_closed = true;
  172. base.Close();
  173. }
  174. #endregion Public Instance Methods
  175. #region Private Instance Fields
  176. /// <summary>
  177. /// The error handler instance to pass all errors to
  178. /// </summary>
  179. private IErrorHandler m_errorHandler;
  180. /// <summary>
  181. /// Flag to indicate if this writer is closed
  182. /// </summary>
  183. private bool m_closed = false;
  184. #endregion Private Instance Fields
  185. }
  186. }