2 // System.IO.BinaryWriter
5 // Matt Kimball (matt@kimball.net)
10 using System.Globalization;
14 public class BinaryWriter : IDisposable {
16 // Null is a BinaryWriter with no backing store.
17 public static readonly BinaryWriter Null;
19 protected Stream OutStream;
20 private Encoding m_encoding;
21 private byte [] buffer;
22 private bool disposed = false;
24 static BinaryWriter() {
25 Null = new BinaryWriter();
28 protected BinaryWriter() : this (Stream.Null, Encoding.UTF8Unmarked) {
31 public BinaryWriter(Stream output) : this(output, Encoding.UTF8Unmarked) {
34 public BinaryWriter(Stream output, Encoding encoding) {
35 if (output == null || encoding == null)
36 throw new ArgumentNullException(Locale.GetText ("Output or Encoding is a null reference."));
38 throw new ArgumentException(Locale.GetText ("Stream does not support writing or already closed."));
41 m_encoding = encoding;
42 buffer = new byte [16];
45 public virtual Stream BaseStream {
51 public virtual void Close() {
55 void IDisposable.Dispose() {
59 protected virtual void Dispose (bool disposing)
61 if (disposing && OutStream != null)
69 public virtual void Flush() {
73 public virtual long Seek(int offset, SeekOrigin origin) {
75 return OutStream.Seek(offset, origin);
78 public virtual void Write(bool value) {
81 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
83 buffer [0] = (byte) (value ? 1 : 0);
84 OutStream.Write(buffer, 0, 1);
87 public virtual void Write(byte value) {
90 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
92 OutStream.WriteByte(value);
95 public virtual void Write(byte[] value) {
98 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
101 throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
102 OutStream.Write(value, 0, value.Length);
105 public virtual void Write(byte[] value, int offset, int length) {
108 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
111 throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
112 OutStream.Write(value, offset, length);
115 public virtual void Write(char value) {
118 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
120 char[] dec = new char[1];
122 byte[] enc = m_encoding.GetBytes(dec, 0, 1);
123 OutStream.Write(enc, 0, enc.Length);
126 public virtual void Write(char[] value) {
129 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
132 throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
133 byte[] enc = m_encoding.GetBytes(value, 0, value.Length);
134 OutStream.Write(enc, 0, enc.Length);
137 public virtual void Write(char[] value, int offset, int length) {
140 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
143 throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
144 byte[] enc = m_encoding.GetBytes(value, offset, length);
145 OutStream.Write(enc, 0, enc.Length);
148 unsafe public virtual void Write(decimal value) {
151 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
153 byte* value_ptr = (byte *)&value;
154 for (int i = 0; i < 16; i++) {
157 * decimal in stream is lo32, mi32, hi32, ss32
158 * but its internal structure si ss32, hi32, lo32, mi32
161 buffer [i + 12] = value_ptr [i];
163 buffer [i + 4] = value_ptr [i];
165 buffer [i - 8] = value_ptr [i];
167 buffer [i - 8] = value_ptr [i];
170 OutStream.Write(buffer, 0, 16);
173 public virtual void Write(double value) {
176 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
178 OutStream.Write(BitConverter.GetBytes(value), 0, 8);
181 public virtual void Write(short value) {
184 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
186 buffer [0] = (byte) value;
187 buffer [1] = (byte) (value >> 8);
188 OutStream.Write(buffer, 0, 2);
191 public virtual void Write(int value) {
194 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
196 buffer [0] = (byte) value;
197 buffer [1] = (byte) (value >> 8);
198 buffer [2] = (byte) (value >> 16);
199 buffer [3] = (byte) (value >> 24);
200 OutStream.Write(buffer, 0, 4);
203 public virtual void Write(long value) {
206 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
208 for (int i = 0, sh = 0; i < 8; i++, sh += 8)
209 buffer [i] = (byte) (value >> sh);
210 OutStream.Write(buffer, 0, 8);
213 [CLSCompliant(false)]
214 public virtual void Write(sbyte value) {
217 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
219 buffer [0] = (byte) value;
220 OutStream.Write(buffer, 0, 1);
223 public virtual void Write(float value) {
226 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
228 OutStream.Write(BitConverter.GetBytes(value), 0, 4);
231 byte [] stringBuffer;
232 int maxCharsPerRound;
234 public virtual void Write(string value) {
237 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
239 int len = m_encoding.GetByteCount (value);
240 Write7BitEncodedInt (len);
242 if (stringBuffer == null) {
243 stringBuffer = new byte [512];
244 maxCharsPerRound = 512 / m_encoding.GetMaxByteCount (1);
248 int chrem = value.Length;
250 int cch = (chrem > maxCharsPerRound) ? maxCharsPerRound : chrem;
251 int blen = m_encoding.GetBytes (value, chpos, cch, stringBuffer, 0);
252 OutStream.Write (stringBuffer, 0, blen);
259 [CLSCompliant(false)]
260 public virtual void Write(ushort value) {
263 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
265 buffer [0] = (byte) value;
266 buffer [1] = (byte) (value >> 8);
267 OutStream.Write(buffer, 0, 2);
270 [CLSCompliant(false)]
271 public virtual void Write(uint value) {
274 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
276 buffer [0] = (byte) value;
277 buffer [1] = (byte) (value >> 8);
278 buffer [2] = (byte) (value >> 16);
279 buffer [3] = (byte) (value >> 24);
280 OutStream.Write(buffer, 0, 4);
283 [CLSCompliant(false)]
284 public virtual void Write(ulong value) {
287 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
289 for (int i = 0, sh = 0; i < 8; i++, sh += 8)
290 buffer [i] = (byte) (value >> sh);
291 OutStream.Write(buffer, 0, 8);
294 protected void Write7BitEncodedInt(int value) {
296 int high = (value >> 7) & 0x01ffffff;
297 byte b = (byte)(value & 0x7f);
300 b = (byte)(b | 0x80);