1 /* 2 * GioStream.cs: provide a System.IO.Stream api to [Input|Output]Streams 3 * 4 * Author(s): 5 * Stephane Delcroix (stephane@delcroix.org) 6 * 7 * Copyright (c) 2008 Novell, Inc. 8 * 9 * 10 * Permission is hereby granted, free of charge, to any person obtaining 11 * a copy of this software and associated documentation files (the 12 * "Software"), to deal in the Software without restriction, including 13 * without limitation the rights to use, copy, modify, merge, publish, 14 * distribute, sublicense, and/or sell copies of the Software, and to 15 * permit persons to whom the Software is furnished to do so, subject to 16 * the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be 19 * included in all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 * 29 */ 30 using System; 31 32 namespace GLib 33 { 34 public class GioStream : System.IO.Stream 35 { 36 object stream; 37 bool can_read; 38 bool can_seek; 39 bool can_write; 40 bool is_disposed; 41 GioStream(Uri uri, System.IO.FileMode mode)42 public GioStream (Uri uri, System.IO.FileMode mode) 43 { 44 throw new NotImplementedException (); 45 } 46 GioStream(string filename, System.IO.FileMode mode)47 public GioStream (string filename, System.IO.FileMode mode) 48 { 49 throw new NotImplementedException (); 50 } 51 GioStream(InputStream stream)52 public GioStream (InputStream stream) 53 { 54 this.stream = stream; 55 can_read = true; 56 can_seek = stream is ISeekable && (stream as ISeekable).CanSeek; 57 } 58 GioStream(OutputStream stream)59 public GioStream (OutputStream stream) 60 { 61 this.stream = stream; 62 can_write = true; 63 can_seek = stream is ISeekable && (stream as ISeekable).CanSeek; 64 } 65 GioStream(IOStream stream)66 public GioStream (IOStream stream) 67 { 68 this.stream = stream; 69 can_read = true; 70 can_write = true; 71 can_seek = stream is ISeekable && (stream as ISeekable).CanSeek; 72 } 73 74 public override bool CanSeek { 75 get { return can_seek; } 76 } 77 78 public override bool CanRead { 79 get { return can_read; } 80 } 81 82 public override bool CanWrite { 83 get { return can_write; } 84 } 85 86 public override long Length { 87 get { 88 if (!CanSeek) 89 throw new NotSupportedException ("This stream doesn't support seeking"); 90 if (is_disposed) 91 throw new ObjectDisposedException ("The stream is closed"); 92 93 if (stream is FileInputStream) { 94 FileInfo info = (stream as FileInputStream).QueryInfo ("standard::size", null); 95 return info.Size; 96 } 97 if (stream is FileOutputStream) { 98 FileInfo info = (stream as FileOutputStream).QueryInfo ("standard::size", null); 99 return info.Size; 100 } 101 if (stream is FileIOStream) { 102 FileInfo info = (stream as FileIOStream).QueryInfo ("standard::size", null); 103 return info.Size; 104 } 105 throw new NotImplementedException (String.Format ("not implemented for {0} streams", stream.GetType())); 106 } 107 } 108 109 public override long Position { 110 get { 111 if (!CanSeek) 112 throw new NotSupportedException ("This stream doesn't support seeking"); 113 if (is_disposed) 114 throw new ObjectDisposedException ("The stream is closed"); 115 return (stream as ISeekable).Position; 116 } 117 set { 118 Seek (value, System.IO.SeekOrigin.Begin); 119 } 120 } 121 Flush()122 public override void Flush () 123 { 124 if (is_disposed) 125 throw new ObjectDisposedException ("The stream is closed"); 126 } 127 Read(byte[] buffer, int offset, int count)128 public override int Read (byte[] buffer, int offset, int count) 129 { 130 if (buffer == null) 131 throw new ArgumentNullException ("buffer"); 132 if (offset + count - 1 > buffer.Length) 133 throw new ArgumentException ("(offset + count - 1) is greater than the length of buffer"); 134 if (offset < 0) 135 throw new ArgumentOutOfRangeException ("offset"); 136 if (count < 0) 137 throw new ArgumentOutOfRangeException ("count"); 138 if (!CanRead) 139 throw new NotSupportedException ("The stream does not support reading"); 140 if (is_disposed) 141 throw new ObjectDisposedException ("The stream is closed"); 142 InputStream input_stream = null; 143 if (stream is InputStream) 144 input_stream = stream as InputStream; 145 else if (stream is IOStream) 146 input_stream = (stream as IOStream).InputStream; 147 if (input_stream == null) 148 throw new System.Exception ("this shouldn't happen"); 149 150 if (offset == 0) 151 return (int)input_stream.Read (buffer, (ulong)count, null); 152 else { 153 byte[] buf = new byte[count]; 154 int ret = (int)input_stream.Read (buf, (ulong)count, null); 155 buf.CopyTo (buffer, offset); 156 return ret; 157 } 158 } 159 Write(byte[] buffer, int offset, int count)160 public override void Write (byte[] buffer, int offset, int count) 161 { 162 if (buffer == null) 163 throw new ArgumentNullException ("buffer"); 164 if (offset + count > buffer.Length) 165 throw new ArgumentException ("(offset + count) is greater than the length of buffer"); 166 if (offset < 0) 167 throw new ArgumentOutOfRangeException ("offset"); 168 if (count < 0) 169 throw new ArgumentOutOfRangeException ("count"); 170 if (!CanWrite) 171 throw new NotSupportedException ("The stream does not support writing"); 172 if (is_disposed) 173 throw new ObjectDisposedException ("The stream is closed"); 174 OutputStream output_stream = null; 175 if (stream is OutputStream) 176 output_stream = stream as OutputStream; 177 else if (stream is IOStream) 178 output_stream = (stream as IOStream).OutputStream; 179 if (output_stream == null) 180 throw new System.Exception ("this shouldn't happen"); 181 if (offset == 0) { 182 output_stream.Write (buffer, (ulong)count, null); 183 return; 184 } else { 185 byte[] buf = new byte[count]; 186 Array.Copy (buffer, offset, buf, 0, count); 187 output_stream.Write (buf, (ulong)count, null); 188 return; 189 } 190 } 191 Seek(long offset, System.IO.SeekOrigin origin)192 public override long Seek (long offset, System.IO.SeekOrigin origin) 193 { 194 if (!CanSeek) 195 throw new NotSupportedException ("This stream doesn't support seeking"); 196 if (is_disposed) 197 throw new ObjectDisposedException ("The stream is closed"); 198 var seekable = stream as ISeekable; 199 200 SeekType seek_type; 201 switch (origin) { 202 case System.IO.SeekOrigin.Current: 203 seek_type = SeekType.Cur; 204 break; 205 case System.IO.SeekOrigin.End: 206 seek_type = SeekType.End; 207 break; 208 case System.IO.SeekOrigin.Begin: 209 default: 210 seek_type = SeekType.Set; 211 break; 212 } 213 seekable.Seek (offset, seek_type, null); 214 return Position; 215 } 216 SetLength(long value)217 public override void SetLength (long value) 218 { 219 if (!CanSeek || !CanWrite) 220 throw new NotSupportedException ("This stream doesn't support seeking"); 221 222 var seekable = stream as ISeekable; 223 224 if (!seekable.CanTruncate ()) 225 throw new NotSupportedException ("This stream doesn't support truncating"); 226 227 if (is_disposed) 228 throw new ObjectDisposedException ("The stream is closed"); 229 230 seekable.Truncate (value, null); 231 } 232 Close()233 public override void Close () 234 { 235 if (stream is InputStream) 236 (stream as InputStream).Close (null); 237 if (stream is OutputStream) 238 (stream as OutputStream).Close (null); 239 if (stream is IOStream) 240 (stream as IOStream).Close (null); 241 is_disposed = true; 242 } 243 } 244 } 245