2009-04-27 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / corlib / Test / System.IO / UnmanagedMemoryStreamTest.cs
1 //
2 // System.IO.UnmanagedMemoryStreamTest.cs
3 //
4 // Authors:
5 //      Sridhar Kulkarni (sridharkulkarni@gmail.com)
6 //      Gert Driesen (drieseng@users.sourceforge.net)
7 //
8 // (c) 2006 Sridhar Kulkarni.
9 // Copyright (C) 2004 Novell (http://www.novell.com)
10 //
11
12 #if NET_2_0 && !TARGET_JVM
13 using System;
14 using System.Collections;
15 using System.IO;
16 using System.Runtime.InteropServices;
17 using System.Text;
18
19 using NUnit.Framework;
20
21 namespace MonoTests.System.IO
22 {
23         [TestFixture]
24         public unsafe class UnmanagedMemoryStreamTest {
25                 byte[] testStreamData;
26                 byte[] readData;
27                 IntPtr mem_intptr = IntPtr.Zero;
28                 byte* mem_byteptr = null;
29                 int length;
30                 int capacity;
31                 
32                 [SetUp]
33                 public void SetUp()
34                 {
35                         testStreamData = UnicodeEncoding.Unicode.GetBytes("Here is some mono testdata");
36                         length = testStreamData.Length;
37                         capacity = testStreamData.Length * 2;
38                         mem_intptr = Marshal.AllocHGlobal(capacity);
39                         mem_byteptr = (byte*)mem_intptr.ToPointer();
40                         readData = new byte[length];
41                 }
42
43                 [TearDown]
44                 public void TearDown ()
45                 {
46                         if (mem_intptr != IntPtr.Zero)
47                                 Marshal.FreeHGlobal (mem_intptr);
48                 }
49
50                 //
51                 // Verify that the first count bytes in testBytes are the same as
52                 // the count bytes from index start in testStreamData
53                 //
54                 void VerifyTestData (string id, byte [] testBytes, int start, int count)
55                 {
56                         if (testBytes == null)
57                                 Assert.Fail(id + "+1 testBytes is null");
58                         
59                         if (start < 0 ||
60                             count < 0 ||
61                             start + count > testStreamData.Length ||
62                             start > testStreamData.Length)
63                                 throw new ArgumentOutOfRangeException(id + "+2");
64                         
65                         for (int test = 0; test < count; test++)
66                         {
67                                 if (testBytes[test] == testStreamData[start + test])
68                                         continue;
69                                 
70                                 string failStr = "testByte {0} (testStream {1}) was <{2}>, expecting <{3}>";
71                                 failStr = String.Format(failStr,
72                                                         test,
73                                                         start + test,
74                                                         testBytes[test],
75                                                         testStreamData[start + test]);
76                                 Assert.Fail(id + "-3" + failStr);
77                         }
78                 }
79
80                 [Test]
81                 public void Constructor1 ()
82                 {
83                         UnmanagedMemoryStream ums = new 
84                                 UnmanagedMemoryStream(mem_byteptr, length);
85                         Assert.AreEqual ((long) length, ums.Capacity, "#1");
86                         Assert.AreEqual ((long) length, ums.Length, "#2");
87                         Assert.AreEqual (0L, ums.Position, "#3");
88                         ums.Position = (length-2);
89                         Assert.AreEqual ((long)(length - 2), ums.Position, "#4");
90                         ums.Position = 0;
91                         ums.Seek(3L, SeekOrigin.Begin);
92                         Assert.AreEqual (3L, ums.Position, "#5");
93                         Assert.IsTrue (ums.CanRead, "#6");
94                         Assert.IsFalse (ums.CanWrite, "#7");
95                         ums.Close();
96                 }
97
98                 [Test]
99                 public void Constructor1_Length_Negative ()
100                 {
101                         try {
102                                 new UnmanagedMemoryStream(mem_byteptr, -1);
103                                 Assert.Fail ("#1");
104                         } catch (ArgumentOutOfRangeException ex) {
105                                 // Non-negative number required
106                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
107                                 Assert.IsNull (ex.InnerException, "#3");
108                                 Assert.IsNotNull (ex.Message, "#4");
109                                 Assert.IsNotNull (ex.ParamName, "#5");
110                                 Assert.AreEqual ("length", ex.ParamName, "#6");
111                         }
112                 }
113
114                 [Test]
115                 public void Constructor1_Pointer_Null ()
116                 {
117                         try {
118                                 new UnmanagedMemoryStream((byte*) null, -1);
119                                 Assert.Fail ("#1");
120                         } catch (ArgumentNullException ex) {
121                                 // Value cannot be null
122                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
123                                 Assert.IsNull (ex.InnerException, "#3");
124                                 Assert.IsNotNull (ex.Message, "#4");
125                                 Assert.IsNotNull (ex.ParamName, "#5");
126                                 Assert.AreEqual ("pointer", ex.ParamName, "#6");
127                         }
128                 }
129
130                 [Test]
131                 public void Constructor2 ()
132                 {
133                         UnmanagedMemoryStream ums;
134
135                         ums = new UnmanagedMemoryStream(mem_byteptr,
136                                 length, 999, FileAccess.Read);
137                         Assert.IsTrue (ums.CanRead, "#A1");
138                         Assert.IsTrue (ums.CanSeek, "#A2");
139                         Assert.IsFalse (ums.CanWrite, "#A3");
140                         Assert.AreEqual (999, ums.Capacity, "#A4");
141                         Assert.AreEqual (length, ums.Length, "#A5");
142                         Assert.AreEqual (0, ums.Position, "#A6");
143                         ums.Close ();
144
145                         ums = new UnmanagedMemoryStream(mem_byteptr,
146                                 length, 666, FileAccess.Write);
147                         Assert.IsFalse (ums.CanRead, "#B1");
148                         Assert.IsTrue (ums.CanSeek, "#B2");
149                         Assert.IsTrue (ums.CanWrite, "#B3");
150                         Assert.AreEqual (666, ums.Capacity, "#B4");
151                         Assert.AreEqual (length, ums.Length, "#B5");
152                         Assert.AreEqual (0, ums.Position, "#B6");
153                         ums.Close ();
154
155                         ums = new UnmanagedMemoryStream(mem_byteptr,
156                                 0, 0, FileAccess.ReadWrite);
157                         Assert.IsTrue (ums.CanRead, "#C1");
158                         Assert.IsTrue (ums.CanSeek, "#C2");
159                         Assert.IsTrue (ums.CanWrite, "#C3");
160                         Assert.AreEqual (0, ums.Capacity, "#C4");
161                         Assert.AreEqual (0, ums.Length, "#C5");
162                         Assert.AreEqual (0, ums.Position, "#C6");
163                         ums.Close ();
164                 }
165
166                 [Test]
167                 public void Constructor2_Access_Invalid ()
168                 {
169                         try {
170                                 new UnmanagedMemoryStream(mem_byteptr, 0, 0, (FileAccess) 666);
171                                 Assert.Fail ("#1");
172                         } catch (ArgumentOutOfRangeException ex) {
173                                 // Enum value was out of legal range
174                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
175                                 Assert.IsNull (ex.InnerException, "#3");
176                                 Assert.IsNotNull (ex.Message, "#4");
177                                 Assert.IsNotNull (ex.ParamName, "#5");
178                                 Assert.AreEqual ("access", ex.ParamName, "#6");
179                         }
180                 }
181
182                 [Test]
183                 public void Constructor2_Capacity_Negative ()
184                 {
185                         try {
186                                 new UnmanagedMemoryStream(mem_byteptr, 0, -1, FileAccess.Read);
187                                 Assert.Fail ("#1");
188                         } catch (ArgumentOutOfRangeException ex) {
189                                 // Non-negative number required
190                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
191                                 Assert.IsNull (ex.InnerException, "#3");
192                                 Assert.IsNotNull (ex.Message, "#4");
193                                 Assert.IsNotNull (ex.ParamName, "#5");
194                                 Assert.AreEqual ("capacity", ex.ParamName, "#6");
195                         }
196                 }
197
198                 [Test]
199                 public void Constructor2_Length_Negative ()
200                 {
201                         try {
202                                 new UnmanagedMemoryStream(mem_byteptr, -1, 0, FileAccess.Read);
203                                 Assert.Fail ("#1");
204                         } catch (ArgumentOutOfRangeException ex) {
205                                 // Non-negative number required
206                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
207                                 Assert.IsNull (ex.InnerException, "#3");
208                                 Assert.IsNotNull (ex.Message, "#4");
209                                 Assert.IsNotNull (ex.ParamName, "#5");
210                                 Assert.AreEqual ("length", ex.ParamName, "#6");
211                         }
212                 }
213
214                 [Test]
215                 public void Constructor2_Length_Overflow ()
216                 {
217                         try {
218                                 new UnmanagedMemoryStream(mem_byteptr, 5, 3, FileAccess.Read);
219                                 Assert.Fail ("#1");
220                         } catch (ArgumentOutOfRangeException ex) {
221                                 // The length cannot be greater than the capacity
222                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
223                                 Assert.IsNull (ex.InnerException, "#3");
224                                 Assert.IsNotNull (ex.Message, "#4");
225                                 Assert.IsNotNull (ex.ParamName, "#5");
226                                 Assert.AreEqual ("length", ex.ParamName, "#6");
227                         }
228                 }
229
230                 [Test]
231                 public void Constructor2_Pointer_Null ()
232                 {
233                         try {
234                                 new UnmanagedMemoryStream((byte*) null, 5, 3, FileAccess.Read);
235                                 Assert.Fail ("#1");
236                         } catch (ArgumentNullException ex) {
237                                 // Value cannot be null
238                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
239                                 Assert.IsNull (ex.InnerException, "#3");
240                                 Assert.IsNotNull (ex.Message, "#4");
241                                 Assert.IsNotNull (ex.ParamName, "#5");
242                                 Assert.AreEqual ("pointer", ex.ParamName, "#6");
243                         }
244                 }
245
246                 [Test]
247                 [ExpectedException (typeof (ObjectDisposedException))]
248                 public void Flush_Stream_Closed ()
249                 {
250                         UnmanagedMemoryStream ums = new 
251                                 UnmanagedMemoryStream(mem_byteptr, length);
252                         ums.Close();
253                         ums.Flush();
254                 }
255
256                 [Test]
257                 public void CanRead ()
258                 {
259                         UnmanagedMemoryStream ums = new 
260                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.Read);
261                         Assert.IsTrue (ums.CanRead, "#1");
262                         ums.Seek (length, SeekOrigin.Begin);
263                         Assert.IsTrue (ums.CanRead, "#2");
264                         ums.Seek (capacity, SeekOrigin.Begin);
265                         Assert.IsTrue (ums.CanRead, "#3");
266                         ums.Seek (capacity + 1, SeekOrigin.Begin);
267                         Assert.IsTrue (ums.CanRead, "#4");
268                         ums.Seek (0, SeekOrigin.Begin);
269                         Assert.IsTrue (ums.CanRead, "#5");
270                         ums.Close ();
271                 }
272
273                 [Test]
274                 public void CanRead_Stream_Closed ()
275                 {
276                         UnmanagedMemoryStream ums = new 
277                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
278                         ums.Close ();
279                         Assert.IsFalse (ums.CanRead);
280                 }
281
282                 [Test]
283                 public void CanSeek ()
284                 {
285                         UnmanagedMemoryStream ums = new 
286                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.Read);
287                         Assert.IsTrue (ums.CanSeek, "#1");
288                         ums.Seek (length, SeekOrigin.Begin);
289                         Assert.IsTrue (ums.CanSeek, "#2");
290                         ums.Seek (capacity, SeekOrigin.Begin);
291                         Assert.IsTrue (ums.CanSeek, "#3");
292                         ums.Seek (capacity + 1, SeekOrigin.Begin);
293                         Assert.IsTrue (ums.CanSeek, "#4");
294                         ums.Seek (0, SeekOrigin.Begin);
295                         Assert.IsTrue (ums.CanSeek, "#5");
296                         ums.Close ();
297                 }
298
299                 [Test]
300                 public void CanSeek_Stream_Closed ()
301                 {
302                         UnmanagedMemoryStream ums = new 
303                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
304                         Assert.IsTrue (ums.CanSeek, "#1");
305                         ums.Close ();
306                         Assert.IsFalse (ums.CanSeek, "#2");
307                 }
308
309                 [Test]
310                 public void CanWrite ()
311                 {
312                         UnmanagedMemoryStream ums = new 
313                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
314                         Assert.IsTrue (ums.CanWrite, "#1");
315                         ums.Seek (length, SeekOrigin.Begin);
316                         Assert.IsTrue (ums.CanWrite, "#2");
317                         ums.Seek (capacity, SeekOrigin.Begin);
318                         Assert.IsTrue (ums.CanWrite, "#3");
319                         ums.Seek (capacity + 1, SeekOrigin.Begin);
320                         Assert.IsTrue (ums.CanWrite, "#4");
321                         ums.Seek (0, SeekOrigin.Begin);
322                         Assert.IsTrue (ums.CanWrite, "#5");
323                         ums.Close ();
324                 }
325
326                 [Test]
327                 public void CanWrite_Stream_Closed ()
328                 {
329                         UnmanagedMemoryStream ums = new 
330                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
331                         Assert.IsTrue (ums.CanWrite, "#1");
332                         ums.Close ();
333                         Assert.IsFalse (ums.CanWrite, "#2");
334                 }
335
336                 [Test]
337                 public void Read ()
338                 {
339                         UnmanagedMemoryStream ums = new 
340                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
341                         ums.Write (testStreamData, 0, testStreamData.Length);
342                         ums.Position = 0;
343
344                         Assert.AreEqual (length / 2, ums.Read (readData, 0, (length / 2)), "#1");
345                         VerifyTestData ("#2", readData, 0, (length / 2));
346                         Assert.AreEqual (length / 2, ums.Position, "#3");
347                         
348                         //Seek back to begining
349                         ums.Seek (0, SeekOrigin.Begin);
350                         
351                         //Read complete stream
352                         Assert.AreEqual (length, ums.Read (readData, 0, length), "#4");
353                         VerifyTestData ("#5", readData, 0, length);
354                         Assert.AreEqual (length, ums.Position, "#6");
355                         
356                         //Seek to mid of the stream and read till end
357                         ums.Seek ((length / 2), SeekOrigin.Begin);
358                         ums.Read (readData, 0, (length / 2));
359                         VerifyTestData ("#7", readData, (length / 2), (length / 2));
360                         Assert.AreEqual (length, ums.Position, "#8");
361                         ums.Close ();
362                 }
363
364                 [Test]
365                 public void Read_Buffer_Null ()
366                 {
367                         UnmanagedMemoryStream ums = new 
368                                 UnmanagedMemoryStream(mem_byteptr, length);
369                         try {
370                                 ums.Read((byte []) null, 0, 0);
371                                 Assert.Fail ("#1");
372                         } catch (ArgumentNullException ex) {
373                                 // Value cannot be null
374                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
375                                 Assert.IsNull (ex.InnerException, "#3");
376                                 Assert.IsNotNull (ex.Message, "#4");
377                                 Assert.IsNotNull (ex.ParamName, "#5");
378                                 Assert.AreEqual ("buffer", ex.ParamName, "#6");
379                         }
380                 }
381
382                 [Test]
383                 [ExpectedException (typeof (ObjectDisposedException))]
384                 public void Read_Stream_Closed ()
385                 {
386                         UnmanagedMemoryStream ums = new 
387                                 UnmanagedMemoryStream(mem_byteptr, length);
388                         ums.Close();
389                         ums.Read(readData, 0, 0);
390                 }
391
392                 [Test]
393                 public void Read_Count_Negative ()
394                 {
395                         UnmanagedMemoryStream ums = new 
396                                 UnmanagedMemoryStream(mem_byteptr, length, length, FileAccess.ReadWrite);
397                         ums.Write (testStreamData, 0, testStreamData.Length);
398                         ums.Position = 0;
399                         try {
400                                 ums.Read (readData, 0, -1);
401                                 Assert.Fail ("#1");
402                         } catch (ArgumentOutOfRangeException ex) {
403                                 // Non-negative number required
404                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
405                                 Assert.IsNull (ex.InnerException, "#3");
406                                 Assert.IsNotNull (ex.Message, "#4");
407                                 Assert.IsNotNull (ex.ParamName, "#5");
408                                 Assert.AreEqual ("count", ex.ParamName, "#6");
409                         }
410                 }
411
412                 [Test]
413                 public void Read_Count_Overlow ()
414                 {
415                         UnmanagedMemoryStream ums = new 
416                                 UnmanagedMemoryStream(mem_byteptr, length, length, FileAccess.ReadWrite);
417                         ums.Write (testStreamData, 0, testStreamData.Length);
418                         ums.Position = 0;
419                         try {
420                                 ums.Read (readData, 1, readData.Length);
421                                 Assert.Fail ("#1");
422                         } catch (ArgumentException ex) {
423                                 // Offset and length were out of bounds for the array or count
424                                 // is greater than the number of elements from index to the end
425                                 // of the source collection
426                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
427                                 Assert.IsNull (ex.InnerException, "#3");
428                                 Assert.IsNotNull (ex.Message, "#4");
429                                 Assert.IsNull (ex.ParamName, "#5");
430                         }
431                 }
432
433                 [Test]
434                 //[Category ("NotWorking")] // when reading on or beyond the end of the stream we must return 0
435                 public void Read_EndOfStream ()
436                 {
437                         UnmanagedMemoryStream ums = new 
438                                 UnmanagedMemoryStream(mem_byteptr, length, length * 2, FileAccess.ReadWrite);
439                         ums.Write (testStreamData, 0, testStreamData.Length);
440                         Assert.AreEqual (0, ums.Read (readData, 0, 1), "#1");
441                         ums.Seek(length + 1, SeekOrigin.Begin);
442                         Assert.AreEqual (0, ums.Read (readData, 0, 1), "#2");
443                         ums.Seek(length - 3, SeekOrigin.Begin);
444                         Assert.AreEqual (3, ums.Read (readData, 0, 5), "#3");
445                         ums.Seek(capacity + 1, SeekOrigin.Begin);
446                         Assert.AreEqual (0, ums.Read (readData, 0, 1), "#4");
447                         ums.Close ();
448                 }
449
450                 [Test]
451                 public void Read_Offset_Negative ()
452                 {
453                         UnmanagedMemoryStream ums = new 
454                                 UnmanagedMemoryStream(mem_byteptr, length, length, FileAccess.ReadWrite);
455                         ums.Write (testStreamData, 0, testStreamData.Length);
456                         ums.Position = 0;
457                         try {
458                                 ums.Read (readData, -1, 0);
459                                 Assert.Fail ("#1");
460                         } catch (ArgumentOutOfRangeException ex) {
461                                 // Non-negative number required
462                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
463                                 Assert.IsNull (ex.InnerException, "#3");
464                                 Assert.IsNotNull (ex.Message, "#4");
465                                 Assert.IsNotNull (ex.ParamName, "#5");
466                                 Assert.AreEqual ("offset", ex.ParamName, "#6");
467                         }
468                 }
469
470                 [Test]
471                 public void Read_WriteOnly ()
472                 {
473                         UnmanagedMemoryStream ums = new
474                                 UnmanagedMemoryStream(mem_byteptr, length, length, FileAccess.Write);
475                         try {
476                                 ums.Read(readData, 0, 1);
477                                 Assert.Fail ("#1");
478                         } catch (NotSupportedException ex) {
479                                 // Stream does not support reading
480                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
481                                 Assert.IsNull (ex.InnerException, "#3");
482                                 Assert.IsNotNull (ex.Message, "#4");
483                         }
484                         ums.Close();
485                 }
486
487                 [Test]
488                 public void ReadByte ()
489                 {
490                         UnmanagedMemoryStream ums = new
491                                 UnmanagedMemoryStream(mem_byteptr, length, length, FileAccess.ReadWrite);
492                         ums.Write (testStreamData, 0, testStreamData.Length);
493                         ums.Position = 0;
494                         Assert.AreEqual (testStreamData [0], ums.ReadByte (), "#1");
495                         Assert.AreEqual (testStreamData [1], ums.ReadByte (), "#2");
496                         ums.Close();
497                 }
498
499                 [Test]
500                 [ExpectedException (typeof (ObjectDisposedException))]
501                 public void ReadByte_Stream_Closed ()
502                 {
503                         UnmanagedMemoryStream ums = new 
504                                 UnmanagedMemoryStream(mem_byteptr, length);
505                         ums.Close();
506                         ums.ReadByte();
507                 }
508
509                 [Test]
510                 //[Category ("NotWorking")] // when reading on or beyond the end of the stream we must return -1
511                 public void ReadByte_EndOfStream ()
512                 {
513                         UnmanagedMemoryStream ums = new
514                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
515                         ums.Write (testStreamData, 0, testStreamData.Length);
516                         ums.Position = 0;
517                         ums.Seek(length, SeekOrigin.Begin);
518                         Assert.AreEqual (-1, ums.ReadByte (), "#3");
519                         ums.Seek(length + 1, SeekOrigin.Begin);
520                         Assert.AreEqual (-1, ums.ReadByte (), "#4");
521                         ums.Seek(capacity, SeekOrigin.Begin);
522                         Assert.AreEqual (-1, ums.ReadByte (), "#5");
523                         ums.Seek(capacity + 1, SeekOrigin.Begin);
524                         Assert.AreEqual (-1, ums.ReadByte (), "#6");
525                         ums.Close();
526                 }
527
528                 [Test]
529                 public void ReadByte_WriteOnly ()
530                 {
531                         UnmanagedMemoryStream ums = new
532                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.Write);
533                         try {
534                                 ums.ReadByte ();
535                                 Assert.Fail ("#1");
536                         } catch (NotSupportedException ex) {
537                                 // Stream does not support reading
538                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
539                                 Assert.IsNull (ex.InnerException, "#3");
540                                 Assert.IsNotNull (ex.Message, "#4");
541                         }
542                         ums.Close();
543                 }
544
545                 [Test]
546                 public void Seek ()
547                 {
548                         UnmanagedMemoryStream ums = new
549                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.Write);
550                         Assert.AreEqual (5, ums.Seek (5, SeekOrigin.Begin), "#A1");
551                         Assert.AreEqual (5, ums.Position, "#A2");
552                         Assert.AreEqual (length, ums.Length, "#A3");
553
554                         ums.Seek (2, SeekOrigin.Current);
555                         //Assert.AreEqual (7, ums.Seek (2, SeekOrigin.Current), "#B1");
556                         Assert.AreEqual (7, ums.Position, "#B2");
557                         Assert.AreEqual (length, ums.Length, "#B3");
558
559                         Assert.AreEqual (length + 2, ums.Seek (2, SeekOrigin.End), "#C1");
560                         Assert.AreEqual (length + 2, ums.Position, "#C2");
561                         Assert.AreEqual (length, ums.Length, "#C3");
562
563                         Assert.AreEqual (0, ums.Seek (0, SeekOrigin.Begin), "#D1");
564                         Assert.AreEqual (0, ums.Position, "#D2");
565                         Assert.AreEqual (length, ums.Length, "#D3");
566
567                         Assert.AreEqual (length - 2, ums.Seek (-2, SeekOrigin.End), "#E1");
568                         Assert.AreEqual (length - 2, ums.Position, "#E2");
569                         Assert.AreEqual (length, ums.Length, "#E3");
570
571                         Assert.AreEqual (length - 5, ums.Seek (-3, SeekOrigin.Current), "#F1");
572                         Assert.AreEqual (length - 5, ums.Position, "#F2");
573                         Assert.AreEqual (length, ums.Length, "#F3");
574
575                         Assert.AreEqual (capacity + 5, ums.Seek (capacity + 5, SeekOrigin.Begin), "#G1");
576                         Assert.AreEqual (capacity + 5, ums.Position, "#G2");
577                         Assert.AreEqual (length, ums.Length, "#G3");
578                 }
579
580                 [Test]
581                 public void Seek_Origin_Invalid ()
582                 {
583                         UnmanagedMemoryStream ums = new
584                                 UnmanagedMemoryStream(mem_byteptr, 5, 10, FileAccess.Read);
585                         try {
586                                 ums.Seek(1, (SeekOrigin) 666);
587                                 Assert.Fail ("#1");
588                         } catch (ArgumentException ex) {
589                                 // Invalid seek origin
590                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
591                                 Assert.IsNull (ex.InnerException, "#3");
592                                 Assert.IsNotNull (ex.Message, "#4");
593                                 Assert.IsNull (ex.ParamName, "#5");
594                         }
595                         ums.Close();
596                 }
597
598                 [Test]
599                 public void Seek_Offset_Invalid ()
600                 {
601                         UnmanagedMemoryStream ums = new
602                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
603                         ums.Write (testStreamData, 0, testStreamData.Length);
604                         ums.Position = 0;
605                         try {
606                                 ums.Seek(-1, SeekOrigin.Begin);
607                                 Assert.Fail ("#A1");
608                         } catch (IOException ex) {
609                                 // An attempt was made to move the position before the beginning
610                                 // of the stream
611                                 Assert.AreEqual (typeof (IOException), ex.GetType (), "#A2");
612                                 Assert.IsNull (ex.InnerException, "#A3");
613                                 Assert.IsNotNull (ex.Message, "#A4");
614                         }
615
616                         ums.Position = 2;
617                         try {
618                                 ums.Seek(-3, SeekOrigin.Current);
619                                 Assert.Fail ("#B1");
620                         } catch (IOException ex) {
621                                 // An attempt was made to move the position before the beginning
622                                 // of the stream
623                                 Assert.AreEqual (typeof (IOException), ex.GetType (), "#B2");
624                                 Assert.IsNull (ex.InnerException, "#B3");
625                                 Assert.IsNotNull (ex.Message, "#B4");
626                         }
627
628                         ums.Close();
629                 }
630
631                 [Test]
632                 [ExpectedException (typeof (ObjectDisposedException))]
633                 public void Seek_Stream_Closed () 
634                 {
635                         UnmanagedMemoryStream ums = new
636                                 UnmanagedMemoryStream(mem_byteptr, length);
637                         ums.Close ();
638                         ums.Seek (0, SeekOrigin.Begin);
639                 }
640
641                 [Test]
642                 public void Write ()
643                 {
644                         UnmanagedMemoryStream ums = new 
645                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
646                         ums.Write (testStreamData, 0, length);
647                         Assert.AreEqual (capacity, ums.Capacity, "#A1");
648                         Assert.AreEqual (length, ums.Position, "#A2");
649                         Assert.AreEqual (length, ums.Length, "#A3");
650                         ums.Position = 0;
651                         ums.Read (readData, 0, length);
652                         Assert.AreEqual (capacity, ums.Capacity, "#B1");
653                         Assert.AreEqual (length, ums.Position, "#B2");
654                         Assert.AreEqual (length, ums.Length, "#B3");
655                         VerifyTestData ("#B4", readData, 0, length);
656                         ums.Write (testStreamData, 2, 2);
657                         Assert.AreEqual (capacity, ums.Capacity, "#C1");
658                         Assert.AreEqual (length + 2, ums.Position, "#C1");
659                         Assert.AreEqual (length + 2, ums.Length, "#C2");
660                         ums.Position = length;
661                         Assert.AreEqual (testStreamData [2], ums.ReadByte (), "#D1");
662                         Assert.AreEqual (testStreamData [3], ums.ReadByte (), "#D2");
663                         ums.Close();
664                 }
665
666                 [Test]
667                 public void Write_Capacity_Exceeded ()
668                 {
669                         UnmanagedMemoryStream ums = new 
670                                 UnmanagedMemoryStream(mem_byteptr, length, length + 2, FileAccess.ReadWrite);
671                         ums.Write (testStreamData, 0, length);
672                         ums.Write (testStreamData, 0, 2);
673                         try {
674                                 ums.Write (testStreamData, 0, 1);
675                                 Assert.Fail ("#1");
676                         } catch (NotSupportedException ex) {
677                                 // Unable to expand length of this stream beyond its capacity
678                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
679                                 Assert.IsNull (ex.InnerException, "#3");
680                                 Assert.IsNotNull (ex.Message, "#4");
681                         }
682                         ums.Close();
683                 }
684
685                 [Test]
686                 public void Write_Count_Negative ()
687                 {
688                         UnmanagedMemoryStream ums = new
689                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
690                         try {
691                                 ums.Write (testStreamData, 0, -1);
692                                 Assert.Fail ("#1");
693                         } catch (ArgumentOutOfRangeException ex) {
694                                 // Non-negative number required
695                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
696                                 Assert.IsNull (ex.InnerException, "#3");
697                                 Assert.IsNotNull (ex.Message, "#4");
698                                 Assert.IsNotNull (ex.ParamName, "#5");
699                                 Assert.AreEqual ("count", ex.ParamName, "#6");
700                         }
701                         ums.Close();
702                 }
703
704                 [Test]
705                 public void Write_Offset_Negative ()
706                 {
707                         UnmanagedMemoryStream ums = new
708                                 UnmanagedMemoryStream(mem_byteptr, length, capacity, FileAccess.ReadWrite);
709                         try {
710                                 ums.Write (testStreamData, -1, testStreamData.Length);
711                                 Assert.Fail ("#1");
712                         } catch (ArgumentOutOfRangeException ex) {
713                                 // Non-negative number required
714                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
715                                 Assert.IsNull (ex.InnerException, "#3");
716                                 Assert.IsNotNull (ex.Message, "#4");
717                                 Assert.IsNotNull (ex.ParamName, "#5");
718                                 Assert.AreEqual ("offset", ex.ParamName, "#6");
719                         }
720                         ums.Close();
721                 }
722
723                 [Test]
724                 [ExpectedException (typeof (ObjectDisposedException))]
725                 public void Write_Stream_Closed ()
726                 {
727                         UnmanagedMemoryStream ums = new 
728                                 UnmanagedMemoryStream(mem_byteptr, length);
729                         ums.Close();
730                         ums.Write(testStreamData, 0, length);
731                 }
732
733                 [Test]
734                 public void Write_Stream_ReadOnly ()
735                 {
736                         UnmanagedMemoryStream ums = new
737                                 UnmanagedMemoryStream(mem_byteptr, length);
738                         try {
739                                 ums.Write(testStreamData, 0, length);
740                                 Assert.Fail ("#1");
741                         } catch (NotSupportedException ex) {
742                                 // Stream does not support writing
743                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
744                                 Assert.IsNull (ex.InnerException, "#3");
745                                 Assert.IsNotNull (ex.Message, "#4");
746                         }
747                         ums.Close();
748                 }
749
750                 [Test]
751                 public void WriteByte ()
752                 {
753                         UnmanagedMemoryStream ums = new 
754                                 UnmanagedMemoryStream(mem_byteptr, 3, 5, FileAccess.ReadWrite);
755                         ums.WriteByte (testStreamData [0]);
756                         Assert.AreEqual (5, ums.Capacity, "#A1");
757                         Assert.AreEqual (1, ums.Position, "#A2");
758                         Assert.AreEqual (3, ums.Length, "#A3");
759                         ums.WriteByte (testStreamData [1]);
760                         Assert.AreEqual (5, ums.Capacity, "#B1");
761                         Assert.AreEqual (2, ums.Position, "#B2");
762                         Assert.AreEqual (3, ums.Length, "#B3");
763                         ums.WriteByte (testStreamData [2]);
764                         Assert.AreEqual (5, ums.Capacity, "#C1");
765                         Assert.AreEqual (3, ums.Position, "#C2");
766                         Assert.AreEqual (3, ums.Length, "#C3");
767                         ums.WriteByte (testStreamData [3]);
768                         Assert.AreEqual (5, ums.Capacity, "#D1");
769                         Assert.AreEqual (4, ums.Position, "#D2");
770                         Assert.AreEqual (4, ums.Length, "#D3");
771                         ums.WriteByte (testStreamData [4]);
772                         Assert.AreEqual (5, ums.Capacity, "#E1");
773                         Assert.AreEqual (5, ums.Position, "#E2");
774                         Assert.AreEqual (5, ums.Length, "#E3");
775                         ums.Seek (0, SeekOrigin.Begin);
776                         Assert.AreEqual (testStreamData [0], ums.ReadByte (), "#F1");
777                         Assert.AreEqual (testStreamData [1], ums.ReadByte (), "#F2");
778                         Assert.AreEqual (testStreamData [2], ums.ReadByte (), "#F3");
779                         Assert.AreEqual (testStreamData [3], ums.ReadByte (), "#F4");
780                         Assert.AreEqual (testStreamData [4], ums.ReadByte (), "#F5");
781                         ums.Close ();
782                 }
783
784                 [Test]
785                 [ExpectedException (typeof (ObjectDisposedException))]
786                 public void WriteByte_Stream_Closed ()
787                 {
788                         UnmanagedMemoryStream ums = new UnmanagedMemoryStream(mem_byteptr,
789                                 length, length, FileAccess.Write);
790                         ums.Close();
791                         ums.WriteByte(0x12);
792                 }
793
794                 [Test]
795                 public void WriteByte_Capacity_Exceeded ()
796                 {
797                         UnmanagedMemoryStream ums = new 
798                                 UnmanagedMemoryStream(mem_byteptr, 1, 2, FileAccess.ReadWrite);
799                         ums.WriteByte (0x44);
800                         ums.WriteByte (0x45);
801                         try {
802                                 ums.WriteByte (0x46);
803                                 Assert.Fail ("#1");
804                         } catch (NotSupportedException ex) {
805                                 // Unable to expand length of this stream beyond its capacity
806                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
807                                 Assert.IsNull (ex.InnerException, "#3");
808                                 Assert.IsNotNull (ex.Message, "#4");
809                         }
810                         ums.Close();
811                 }
812
813                 [Test]
814                 public void WriteByte_Stream_ReadOnly ()
815                 {
816                         UnmanagedMemoryStream ums = new 
817                                 UnmanagedMemoryStream(mem_byteptr, length);
818                         try {
819                                 ums.WriteByte (testStreamData [0]);
820                                 Assert.Fail ("#1");
821                         } catch (NotSupportedException ex) {
822                                 // Stream does not support writing
823                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
824                                 Assert.IsNull (ex.InnerException, "#3");
825                                 Assert.IsNotNull (ex.Message, "#4");
826                         }
827                         ums.Close ();
828                 }
829
830                 [Test]
831                 public void SetLength ()
832                 {
833                         UnmanagedMemoryStream ums = new UnmanagedMemoryStream(mem_byteptr,
834                                 length, capacity, FileAccess.ReadWrite);
835                         ums.Write (testStreamData, 0, testStreamData.Length);
836                         ums.SetLength (length - 1);
837                         Assert.AreEqual (capacity, ums.Capacity, "#A1");
838                         Assert.AreEqual (length - 1, ums.Length, "#A2");
839                         Assert.AreEqual (length - 1, ums.Position, "#A3");
840                         ums.SetLength (length + 1);
841                         Assert.AreEqual (capacity, ums.Capacity, "#B1");
842                         Assert.AreEqual (length + 1, ums.Length, "#B2");
843                         Assert.AreEqual (length - 1, ums.Position, "#B3");
844                         ums.SetLength (length);
845                         Assert.AreEqual (capacity, ums.Capacity, "#C1");
846                         Assert.AreEqual (length, ums.Length, "#C2");
847                         Assert.AreEqual (length - 1, ums.Position, "#C3");
848                         ums.SetLength (0);
849                         Assert.AreEqual (capacity, ums.Capacity, "#D1");
850                         Assert.AreEqual (0, ums.Length, "#D2");
851                         Assert.AreEqual (0, ums.Position, "#D3");
852                         ums.SetLength (capacity);
853                         Assert.AreEqual (capacity, ums.Capacity, "#E1");
854                         Assert.AreEqual (capacity, ums.Length, "#E2");
855                         Assert.AreEqual (0, ums.Position, "#E3");
856                         ums.Close();
857                 }
858
859                 [Test]
860                 public void SetLength_Capacity_Exceeded ()
861                 {
862                         UnmanagedMemoryStream ums = new UnmanagedMemoryStream(mem_byteptr,
863                                 length, capacity, FileAccess.ReadWrite);
864                         try {
865                                 ums.SetLength (capacity + 1);
866                                 Assert.Fail ("#1");
867                         } catch (IOException ex) {
868                                 // Unable to expand length of this stream beyond its capacity
869                                 Assert.AreEqual (typeof (IOException), ex.GetType (), "#2");
870                                 Assert.IsNull (ex.InnerException, "#3");
871                                 Assert.IsNotNull (ex.Message, "#4");
872                         }
873                         ums.Close();
874                 }
875
876                 [Test]
877                 public void SetLength_Negative ()
878                 {
879                         UnmanagedMemoryStream ums = new UnmanagedMemoryStream(mem_byteptr,
880                                 length, capacity, FileAccess.ReadWrite);
881                         try {
882                                 ums.SetLength(-1);
883                                 Assert.Fail ("#1");
884                         } catch (ArgumentOutOfRangeException ex) {
885                                 // Non-negative number required
886                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
887                                 Assert.IsNull (ex.InnerException, "#3");
888                                 Assert.IsNotNull (ex.Message, "#4");
889                                 Assert.IsNotNull (ex.ParamName, "#5");
890                                 Assert.AreEqual ("length", ex.ParamName, "#6");
891                         }
892                         ums.Close();
893                 }
894
895                 [Test]
896                 public void SetLength_Stream_ReadOnly ()
897                 {
898                         UnmanagedMemoryStream ums = new UnmanagedMemoryStream(mem_byteptr,
899                                 length);
900                         try {
901                                 ums.SetLength (length);
902                                 Assert.Fail ("#1");
903                         } catch (NotSupportedException ex) {
904                                 // Stream does not support writing
905                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
906                                 Assert.IsNull (ex.InnerException, "#3");
907                                 Assert.IsNotNull (ex.Message, "#4");
908                         }
909                         ums.Close();
910                 }
911
912                 [Test]
913                 [ExpectedException (typeof (ObjectDisposedException))]
914                 public void Capacity_Stream_Closed ()
915                 {
916                         UnmanagedMemoryStream ums = new 
917                                 UnmanagedMemoryStream(mem_byteptr, length);
918                         ums.Close();
919                         long capacity = ums.Capacity;
920                 }
921
922                 [Test]
923                 [ExpectedException (typeof (ObjectDisposedException))]
924                 public void Length_Stream_Closed ()
925                 {
926                         UnmanagedMemoryStream ums = new 
927                                 UnmanagedMemoryStream(mem_byteptr, length);
928                         ums.Close();
929                         long x = ums.Length;
930                 }
931
932                 [Test]
933                 public void Position ()
934                 {
935                         UnmanagedMemoryStream ums = new UnmanagedMemoryStream(mem_byteptr,
936                                 length, capacity, FileAccess.ReadWrite);
937                         Assert.AreEqual (0, ums.Position, "#1");
938                         ums.Position = capacity;
939                         Assert.AreEqual (capacity, ums.Position, "#2");
940                         ums.Position = length;
941                         Assert.AreEqual (length, ums.Position, "#3");
942                         ums.Position = int.MaxValue;
943                         Assert.AreEqual (int.MaxValue, ums.Position, "#4");
944                         ums.Position = 0;
945                         Assert.AreEqual (0, ums.Position, "#5");
946                         ums.Close();
947                 }
948
949                 [Test]
950                 public void Position_MaxValue_Exceeded ()
951                 {
952                         UnmanagedMemoryStream ums = new UnmanagedMemoryStream(mem_byteptr,
953                                 length, capacity, FileAccess.ReadWrite);
954                         try {
955                                 ums.Position = 0x80000000;
956                                 Assert.Fail ("#1");
957                         } catch (ArgumentOutOfRangeException ex) {
958                                 // MemoryStream length must be non-negative and less than
959                                 // 2^31 - 1 - origin
960                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
961                                 Assert.IsNull (ex.InnerException, "#3");
962                                 Assert.IsNotNull (ex.Message, "#4");
963                                 Assert.IsNotNull (ex.ParamName, "#5");
964                                 Assert.AreEqual ("value", ex.ParamName, "#6");
965                         }
966                         ums.Close();
967                 }
968
969                 [Test]
970                 public void Position_Negative ()
971                 {
972                         UnmanagedMemoryStream ums = new 
973                                 UnmanagedMemoryStream(mem_byteptr, length);
974                         try {
975                                 ums.Position = -1;
976                                 Assert.Fail ("#1");
977                         } catch (ArgumentOutOfRangeException ex) {
978                                 // Non-negative number required
979                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
980                                 Assert.IsNull (ex.InnerException, "#3");
981                                 Assert.IsNotNull (ex.Message, "#4");
982                                 Assert.IsNotNull (ex.ParamName, "#5");
983                                 Assert.AreEqual ("value", ex.ParamName, "#6");
984                         }
985                         ums.Close ();
986                 }
987
988                 [Test]
989                 public void Position_Stream_Closed ()
990                 {
991                         UnmanagedMemoryStream ums = new 
992                                 UnmanagedMemoryStream(mem_byteptr, length);
993                         ums.Close();
994                         try {
995                                 long x = ums.Position;
996                                 Assert.Fail ("#1: " + x);
997                         } catch (ObjectDisposedException) {
998                         }
999
1000                         try {
1001                                 ums.Position = 0;
1002                                 Assert.Fail ("#2");
1003                         } catch (ObjectDisposedException) {
1004                         }
1005                 }
1006
1007                 [Test]
1008                 [Category ("NotWorking")]
1009                 public void PositionPointer_Stream_Closed ()
1010                 {
1011                         UnmanagedMemoryStream ums = new 
1012                                 UnmanagedMemoryStream(mem_byteptr, length);
1013                         ums.Close();
1014                         try {
1015                                 byte* bptr = ums.PositionPointer;
1016                                 Assert.Fail ("#1");
1017                         } catch (ObjectDisposedException) {
1018                         }
1019
1020                         try {
1021                                 // position pointer to somewhere within the capacity
1022                                 ums.PositionPointer = (byte*) (capacity - 1);
1023                                 Assert.Fail ("#2");
1024                         } catch (ObjectDisposedException) {
1025                         }
1026                 }
1027
1028                 [Test]
1029                 [ExpectedException (typeof(IOException))]
1030                 public void PositionPointer_Underflow ()
1031                 {
1032                         byte [] n = new byte [8];
1033                         fixed (byte *p = n){
1034                                 UnmanagedMemoryStream m = new UnmanagedMemoryStream (p, 8);
1035                                 m.PositionPointer = p-1;
1036                         }
1037                 }
1038
1039                 [Test]
1040                 [ExpectedException (typeof(ArgumentOutOfRangeException))]
1041                 public void PositionPointer_Overflow ()
1042                 {
1043                         byte [] n = new byte [8];
1044                         fixed (byte *p = n){
1045                                 UnmanagedMemoryStream m = new UnmanagedMemoryStream (p, 8);
1046                                 m.PositionPointer = p+9;
1047                         }
1048                 }
1049
1050                 [Test]
1051                 public void PositionPointer_Set ()
1052                 {
1053                         byte [] n = new byte [8];
1054                         n [4] = 65;
1055                         fixed (byte *p = n){
1056                                 UnmanagedMemoryStream m = new UnmanagedMemoryStream (p, 8);
1057                                 m.PositionPointer = p + 4;
1058                                 Assert.AreEqual (65, m.ReadByte ());
1059                         }
1060                 }
1061                 
1062         }
1063 }
1064 #endif