2 // System.IO.BinaryWriter
5 // Matt Kimball (matt@kimball.net)
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Globalization;
37 public class BinaryWriter : IDisposable {
39 // Null is a BinaryWriter with no backing store.
40 public static readonly BinaryWriter Null = new BinaryWriter ();
42 protected Stream OutStream;
43 private Encoding m_encoding;
44 private byte [] buffer;
45 private bool disposed = false;
47 protected BinaryWriter() : this (Stream.Null, Encoding.UTF8Unmarked) {
50 public BinaryWriter(Stream output) : this(output, Encoding.UTF8Unmarked) {
53 public BinaryWriter(Stream output, Encoding encoding) {
54 if (output == null || encoding == null)
55 throw new ArgumentNullException(Locale.GetText ("Output or Encoding is a null reference."));
57 throw new ArgumentException(Locale.GetText ("Stream does not support writing or already closed."));
60 m_encoding = encoding;
61 buffer = new byte [16];
64 public virtual Stream BaseStream {
70 public virtual void Close() {
74 void IDisposable.Dispose() {
78 protected virtual void Dispose (bool disposing)
80 if (disposing && OutStream != null)
88 public virtual void Flush() {
92 public virtual long Seek(int offset, SeekOrigin origin) {
94 return OutStream.Seek(offset, origin);
97 public virtual void Write(bool value) {
100 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
102 buffer [0] = (byte) (value ? 1 : 0);
103 OutStream.Write(buffer, 0, 1);
106 public virtual void Write(byte value) {
109 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
111 OutStream.WriteByte(value);
114 public virtual void Write(byte[] value) {
117 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
120 throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
121 OutStream.Write(value, 0, value.Length);
124 public virtual void Write(byte[] value, int offset, int length) {
127 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
130 throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
131 OutStream.Write(value, offset, length);
134 public virtual void Write(char value) {
137 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
139 char[] dec = new char[1];
141 byte[] enc = m_encoding.GetBytes(dec, 0, 1);
142 OutStream.Write(enc, 0, enc.Length);
145 public virtual void Write(char[] value) {
148 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
151 throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
152 byte[] enc = m_encoding.GetBytes(value, 0, value.Length);
153 OutStream.Write(enc, 0, enc.Length);
156 public virtual void Write(char[] value, int offset, int length) {
159 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
162 throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
163 byte[] enc = m_encoding.GetBytes(value, offset, length);
164 OutStream.Write(enc, 0, enc.Length);
167 unsafe public virtual void Write(decimal value) {
170 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
172 byte* value_ptr = (byte *)&value;
173 for (int i = 0; i < 16; i++) {
176 * decimal in stream is lo32, mi32, hi32, ss32
177 * but its internal structure si ss32, hi32, lo32, mi32
180 buffer [i + 12] = value_ptr [i];
182 buffer [i + 4] = value_ptr [i];
184 buffer [i - 8] = value_ptr [i];
186 buffer [i - 8] = value_ptr [i];
189 OutStream.Write(buffer, 0, 16);
192 public virtual void Write(double value) {
195 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
197 OutStream.Write(BitConverter.GetBytes(value), 0, 8);
200 public virtual void Write(short value) {
203 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
205 buffer [0] = (byte) value;
206 buffer [1] = (byte) (value >> 8);
207 OutStream.Write(buffer, 0, 2);
210 public virtual void Write(int value) {
213 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
215 buffer [0] = (byte) value;
216 buffer [1] = (byte) (value >> 8);
217 buffer [2] = (byte) (value >> 16);
218 buffer [3] = (byte) (value >> 24);
219 OutStream.Write(buffer, 0, 4);
222 public virtual void Write(long value) {
225 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
227 for (int i = 0, sh = 0; i < 8; i++, sh += 8)
228 buffer [i] = (byte) (value >> sh);
229 OutStream.Write(buffer, 0, 8);
232 [CLSCompliant(false)]
233 public virtual void Write(sbyte value) {
236 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
238 buffer [0] = (byte) value;
239 OutStream.Write(buffer, 0, 1);
242 public virtual void Write(float value) {
245 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
247 OutStream.Write(BitConverter.GetBytes(value), 0, 4);
250 byte [] stringBuffer;
251 int maxCharsPerRound;
253 public virtual void Write(string value) {
256 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
258 int len = m_encoding.GetByteCount (value);
259 Write7BitEncodedInt (len);
261 if (stringBuffer == null) {
262 stringBuffer = new byte [512];
263 maxCharsPerRound = 512 / m_encoding.GetMaxByteCount (1);
267 int chrem = value.Length;
269 int cch = (chrem > maxCharsPerRound) ? maxCharsPerRound : chrem;
270 int blen = m_encoding.GetBytes (value, chpos, cch, stringBuffer, 0);
271 OutStream.Write (stringBuffer, 0, blen);
278 [CLSCompliant(false)]
279 public virtual void Write(ushort value) {
282 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
284 buffer [0] = (byte) value;
285 buffer [1] = (byte) (value >> 8);
286 OutStream.Write(buffer, 0, 2);
289 [CLSCompliant(false)]
290 public virtual void Write(uint value) {
293 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
295 buffer [0] = (byte) value;
296 buffer [1] = (byte) (value >> 8);
297 buffer [2] = (byte) (value >> 16);
298 buffer [3] = (byte) (value >> 24);
299 OutStream.Write(buffer, 0, 4);
302 [CLSCompliant(false)]
303 public virtual void Write(ulong value) {
306 throw new ObjectDisposedException ("BinaryWriter", "Cannot write to a closed BinaryWriter");
308 for (int i = 0, sh = 0; i < 8; i++, sh += 8)
309 buffer [i] = (byte) (value >> sh);
310 OutStream.Write(buffer, 0, 8);
313 protected void Write7BitEncodedInt(int value) {
315 int high = (value >> 7) & 0x01ffffff;
316 byte b = (byte)(value & 0x7f);
319 b = (byte)(b | 0x80);