BinaryWriter.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. //
  2. // System.IO.BinaryWriter
  3. //
  4. // Author:
  5. // Matt Kimball ([email protected])
  6. //
  7. using System;
  8. using System.Text;
  9. using System.Globalization;
  10. namespace System.IO {
  11. [Serializable]
  12. public class BinaryWriter : IDisposable {
  13. // Null is a BinaryWriter with no backing store.
  14. public static readonly BinaryWriter Null;
  15. protected Stream OutStream;
  16. private Encoding m_encoding;
  17. private byte [] buffer;
  18. static BinaryWriter() {
  19. Null = new BinaryWriter();
  20. }
  21. protected BinaryWriter() : this (Stream.Null, Encoding.UTF8Unmarked) {
  22. }
  23. public BinaryWriter(Stream output) : this(output, Encoding.UTF8Unmarked) {
  24. }
  25. public BinaryWriter(Stream output, Encoding encoding) {
  26. if (output == null || encoding == null)
  27. throw new ArgumentNullException(Locale.GetText ("Output or Encoding is a null reference."));
  28. if (!output.CanWrite)
  29. throw new ArgumentException(Locale.GetText ("Stream does not support writing or already closed."));
  30. OutStream = output;
  31. m_encoding = encoding;
  32. buffer = new byte [16];
  33. }
  34. public virtual Stream BaseStream {
  35. get {
  36. return OutStream;
  37. }
  38. }
  39. public virtual void Close() {
  40. Dispose (true);
  41. }
  42. void IDisposable.Dispose() {
  43. Dispose (true);
  44. }
  45. protected virtual void Dispose (bool disposing)
  46. {
  47. if (disposing && OutStream != null)
  48. OutStream.Close();
  49. buffer = null;
  50. m_encoding = null;
  51. OutStream = null;
  52. }
  53. public virtual void Flush() {
  54. OutStream.Flush();
  55. }
  56. public virtual long Seek(int offset, SeekOrigin origin) {
  57. return OutStream.Seek(offset, origin);
  58. }
  59. public virtual void Write(bool value) {
  60. buffer [0] = (byte) (value ? 1 : 0);
  61. OutStream.Write(buffer, 0, 1);
  62. }
  63. public virtual void Write(byte value) {
  64. OutStream.WriteByte(value);
  65. }
  66. public virtual void Write(byte[] value) {
  67. if (value == null)
  68. throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
  69. OutStream.Write(value, 0, value.Length);
  70. }
  71. public virtual void Write(byte[] value, int offset, int length) {
  72. if (value == null)
  73. throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
  74. OutStream.Write(value, offset, length);
  75. }
  76. public virtual void Write(char value) {
  77. char[] dec = new char[1];
  78. dec[0] = value;
  79. byte[] enc = m_encoding.GetBytes(dec, 0, 1);
  80. OutStream.Write(enc, 0, enc.Length);
  81. }
  82. public virtual void Write(char[] value) {
  83. if (value == null)
  84. throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
  85. byte[] enc = m_encoding.GetBytes(value, 0, value.Length);
  86. OutStream.Write(enc, 0, enc.Length);
  87. }
  88. public virtual void Write(char[] value, int offset, int length) {
  89. if (value == null)
  90. throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
  91. byte[] enc = m_encoding.GetBytes(value, offset, length);
  92. OutStream.Write(enc, 0, enc.Length);
  93. }
  94. unsafe public virtual void Write(decimal value) {
  95. byte* value_ptr = (byte *)&value;
  96. for (int i = 0; i < 16; i++) {
  97. buffer [i] = value_ptr [i];
  98. }
  99. OutStream.Write(buffer, 0, 16);
  100. }
  101. public virtual void Write(double value) {
  102. OutStream.Write(BitConverter.GetBytes(value), 0, 8);
  103. }
  104. public virtual void Write(short value) {
  105. buffer [0] = (byte) value;
  106. buffer [1] = (byte) (value >> 8);
  107. OutStream.Write(buffer, 0, 2);
  108. }
  109. public virtual void Write(int value) {
  110. buffer [0] = (byte) value;
  111. buffer [1] = (byte) (value >> 8);
  112. buffer [2] = (byte) (value >> 16);
  113. buffer [3] = (byte) (value >> 24);
  114. OutStream.Write(buffer, 0, 4);
  115. }
  116. public virtual void Write(long value) {
  117. for (int i = 0, sh = 0; i < 8; i++, sh += 8)
  118. buffer [i] = (byte) (value >> sh);
  119. OutStream.Write(buffer, 0, 8);
  120. }
  121. [CLSCompliant(false)]
  122. public virtual void Write(sbyte value) {
  123. buffer [0] = (byte) value;
  124. OutStream.Write(buffer, 0, 1);
  125. }
  126. public virtual void Write(float value) {
  127. OutStream.Write(BitConverter.GetBytes(value), 0, 4);
  128. }
  129. public virtual void Write(string value) {
  130. /* The length field is the byte count, not the
  131. * char count
  132. */
  133. byte[] enc = m_encoding.GetBytes(value);
  134. Write7BitEncodedInt(enc.Length);
  135. OutStream.Write(enc, 0, enc.Length);
  136. }
  137. [CLSCompliant(false)]
  138. public virtual void Write(ushort value) {
  139. buffer [0] = (byte) value;
  140. buffer [1] = (byte) (value >> 8);
  141. OutStream.Write(buffer, 0, 2);
  142. }
  143. [CLSCompliant(false)]
  144. public virtual void Write(uint value) {
  145. buffer [0] = (byte) value;
  146. buffer [1] = (byte) (value >> 8);
  147. buffer [2] = (byte) (value >> 16);
  148. buffer [3] = (byte) (value >> 24);
  149. OutStream.Write(buffer, 0, 4);
  150. }
  151. [CLSCompliant(false)]
  152. public virtual void Write(ulong value) {
  153. for (int i = 0, sh = 0; i < 8; i++, sh += 8)
  154. buffer [i] = (byte) (value >> sh);
  155. OutStream.Write(buffer, 0, 8);
  156. }
  157. protected void Write7BitEncodedInt(int value) {
  158. do {
  159. int high = (value >> 7) & 0x01ffffff;
  160. byte b = (byte)(value & 0x7f);
  161. if (high != 0) {
  162. b = (byte)(b | 0x80);
  163. }
  164. Write(b);
  165. value = high;
  166. } while(value != 0);
  167. }
  168. }
  169. }