BinaryWriter.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. private bool disposed = false;
  19. static BinaryWriter() {
  20. Null = new BinaryWriter();
  21. }
  22. protected BinaryWriter() : this (Stream.Null, Encoding.UTF8Unmarked) {
  23. }
  24. public BinaryWriter(Stream output) : this(output, Encoding.UTF8Unmarked) {
  25. }
  26. public BinaryWriter(Stream output, Encoding encoding) {
  27. if (output == null || encoding == null)
  28. throw new ArgumentNullException(Locale.GetText ("Output or Encoding is a null reference."));
  29. if (!output.CanWrite)
  30. throw new ArgumentException(Locale.GetText ("Stream does not support writing or already closed."));
  31. OutStream = output;
  32. m_encoding = encoding;
  33. buffer = new byte [16];
  34. }
  35. public virtual Stream BaseStream {
  36. get {
  37. return OutStream;
  38. }
  39. }
  40. public virtual void Close() {
  41. Dispose (true);
  42. }
  43. void IDisposable.Dispose() {
  44. Dispose (true);
  45. }
  46. protected virtual void Dispose (bool disposing)
  47. {
  48. if (disposing && OutStream != null)
  49. OutStream.Close();
  50. buffer = null;
  51. m_encoding = null;
  52. disposed = true;
  53. }
  54. public virtual void Flush() {
  55. OutStream.Flush();
  56. }
  57. public virtual long Seek(int offset, SeekOrigin origin) {
  58. return OutStream.Seek(offset, origin);
  59. }
  60. public virtual void Write(bool value) {
  61. if (disposed)
  62. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  63. buffer [0] = (byte) (value ? 1 : 0);
  64. OutStream.Write(buffer, 0, 1);
  65. }
  66. public virtual void Write(byte value) {
  67. if (disposed)
  68. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  69. OutStream.WriteByte(value);
  70. }
  71. public virtual void Write(byte[] value) {
  72. if (disposed)
  73. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  74. if (value == null)
  75. throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
  76. OutStream.Write(value, 0, value.Length);
  77. }
  78. public virtual void Write(byte[] value, int offset, int length) {
  79. if (disposed)
  80. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  81. if (value == null)
  82. throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
  83. OutStream.Write(value, offset, length);
  84. }
  85. public virtual void Write(char value) {
  86. if (disposed)
  87. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  88. char[] dec = new char[1];
  89. dec[0] = value;
  90. byte[] enc = m_encoding.GetBytes(dec, 0, 1);
  91. OutStream.Write(enc, 0, enc.Length);
  92. }
  93. public virtual void Write(char[] value) {
  94. if (disposed)
  95. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  96. if (value == null)
  97. throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
  98. byte[] enc = m_encoding.GetBytes(value, 0, value.Length);
  99. OutStream.Write(enc, 0, enc.Length);
  100. }
  101. public virtual void Write(char[] value, int offset, int length) {
  102. if (disposed)
  103. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  104. if (value == null)
  105. throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
  106. byte[] enc = m_encoding.GetBytes(value, offset, length);
  107. OutStream.Write(enc, 0, enc.Length);
  108. }
  109. unsafe public virtual void Write(decimal value) {
  110. if (disposed)
  111. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  112. byte* value_ptr = (byte *)&value;
  113. for (int i = 0; i < 16; i++) {
  114. /*
  115. * decimal in stream is lo32, mi32, hi32, ss32
  116. * but its internal structure si ss32, hi32, lo32, mi32
  117. */
  118. if (i < 4)
  119. buffer [i + 12] = value_ptr [i];
  120. else if (i < 8)
  121. buffer [i + 4] = value_ptr [i];
  122. else if (i < 12)
  123. buffer [i - 8] = value_ptr [i];
  124. else
  125. buffer [i - 8] = value_ptr [i];
  126. }
  127. OutStream.Write(buffer, 0, 16);
  128. }
  129. public virtual void Write(double value) {
  130. if (disposed)
  131. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  132. OutStream.Write(BitConverter.GetBytes(value), 0, 8);
  133. }
  134. public virtual void Write(short value) {
  135. if (disposed)
  136. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  137. buffer [0] = (byte) value;
  138. buffer [1] = (byte) (value >> 8);
  139. OutStream.Write(buffer, 0, 2);
  140. }
  141. public virtual void Write(int value) {
  142. if (disposed)
  143. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  144. buffer [0] = (byte) value;
  145. buffer [1] = (byte) (value >> 8);
  146. buffer [2] = (byte) (value >> 16);
  147. buffer [3] = (byte) (value >> 24);
  148. OutStream.Write(buffer, 0, 4);
  149. }
  150. public virtual void Write(long value) {
  151. if (disposed)
  152. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  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. [CLSCompliant(false)]
  158. public virtual void Write(sbyte value) {
  159. if (disposed)
  160. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  161. buffer [0] = (byte) value;
  162. OutStream.Write(buffer, 0, 1);
  163. }
  164. public virtual void Write(float value) {
  165. if (disposed)
  166. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  167. OutStream.Write(BitConverter.GetBytes(value), 0, 4);
  168. }
  169. public virtual void Write(string value) {
  170. if (disposed)
  171. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  172. /* The length field is the byte count, not the
  173. * char count
  174. */
  175. byte[] enc = m_encoding.GetBytes(value);
  176. Write7BitEncodedInt(enc.Length);
  177. OutStream.Write(enc, 0, enc.Length);
  178. }
  179. [CLSCompliant(false)]
  180. public virtual void Write(ushort value) {
  181. if (disposed)
  182. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  183. buffer [0] = (byte) value;
  184. buffer [1] = (byte) (value >> 8);
  185. OutStream.Write(buffer, 0, 2);
  186. }
  187. [CLSCompliant(false)]
  188. public virtual void Write(uint value) {
  189. if (disposed)
  190. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  191. buffer [0] = (byte) value;
  192. buffer [1] = (byte) (value >> 8);
  193. buffer [2] = (byte) (value >> 16);
  194. buffer [3] = (byte) (value >> 24);
  195. OutStream.Write(buffer, 0, 4);
  196. }
  197. [CLSCompliant(false)]
  198. public virtual void Write(ulong value) {
  199. if (disposed)
  200. throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
  201. for (int i = 0, sh = 0; i < 8; i++, sh += 8)
  202. buffer [i] = (byte) (value >> sh);
  203. OutStream.Write(buffer, 0, 8);
  204. }
  205. protected void Write7BitEncodedInt(int value) {
  206. do {
  207. int high = (value >> 7) & 0x01ffffff;
  208. byte b = (byte)(value & 0x7f);
  209. if (high != 0) {
  210. b = (byte)(b | 0x80);
  211. }
  212. Write(b);
  213. value = high;
  214. } while(value != 0);
  215. }
  216. }
  217. }