Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
NativeStream.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.IO;
5 
6 namespace SiliconStudio.Core.IO
7 {
8  /// <summary>
9  /// A <see cref="Stream"/> with additional methods for native read and write operations using <see cref="IntPtr"/>.
10  /// </summary>
11  public abstract class NativeStream : Stream
12  {
13  // Helper buffer for classes needing it.
14  // If null, it should be initialized with NativeStreamBufferSize constant.
15  protected byte[] nativeStreamBuffer;
16  protected const int NativeStreamBufferSize = 1024;
17 
18  public virtual unsafe ushort ReadUInt16()
19  {
20  var temporaryBuffer = nativeStreamBuffer;
21  if (temporaryBuffer == null)
22  temporaryBuffer = nativeStreamBuffer = new byte[NativeStreamBufferSize];
23 
24  int currentReadSize = Read(temporaryBuffer, 0, sizeof(ushort));
25  if (currentReadSize != sizeof(ushort))
26  throw new InvalidOperationException("Reached end of stream.");
27 
28  fixed (byte* temporaryBufferStart = temporaryBuffer)
29  {
30  return *((ushort*)temporaryBufferStart);
31  }
32  }
33 
34  public virtual unsafe uint ReadUInt32()
35  {
36  var temporaryBuffer = nativeStreamBuffer;
37  if (temporaryBuffer == null)
38  temporaryBuffer = nativeStreamBuffer = new byte[NativeStreamBufferSize];
39 
40  int currentReadSize = Read(temporaryBuffer, 0, sizeof(uint));
41  if (currentReadSize != sizeof(uint))
42  throw new InvalidOperationException("Reached end of stream.");
43 
44  fixed (byte* temporaryBufferStart = temporaryBuffer)
45  {
46  return *((uint*)temporaryBufferStart);
47  }
48  }
49 
50  public virtual unsafe ulong ReadUInt64()
51  {
52  var temporaryBuffer = nativeStreamBuffer;
53  if (temporaryBuffer == null)
54  temporaryBuffer = nativeStreamBuffer = new byte[NativeStreamBufferSize];
55 
56  int currentReadSize = Read(temporaryBuffer, 0, sizeof(ulong));
57  if (currentReadSize != sizeof(ulong))
58  throw new InvalidOperationException("Reached end of stream.");
59 
60  fixed (byte* temporaryBufferStart = temporaryBuffer)
61  {
62  return *((ulong*)temporaryBufferStart);
63  }
64  }
65 
66  public virtual unsafe void Write(ushort i)
67  {
68  var temporaryBuffer = nativeStreamBuffer;
69  if (temporaryBuffer == null)
70  temporaryBuffer = nativeStreamBuffer = new byte[NativeStreamBufferSize];
71 
72  fixed (byte* temporaryBufferStart = temporaryBuffer)
73  *((ushort*)temporaryBufferStart) = i;
74 
75  Write(temporaryBuffer, 0, sizeof(ushort));
76  }
77 
78  public virtual unsafe void Write(uint i)
79  {
80  var temporaryBuffer = nativeStreamBuffer;
81  if (temporaryBuffer == null)
82  temporaryBuffer = nativeStreamBuffer = new byte[NativeStreamBufferSize];
83 
84  fixed (byte* temporaryBufferStart = temporaryBuffer)
85  *((uint*)temporaryBufferStart) = i;
86 
87  Write(temporaryBuffer, 0, sizeof(uint));
88  }
89 
90  public virtual unsafe void Write(ulong i)
91  {
92  var temporaryBuffer = nativeStreamBuffer;
93  if (temporaryBuffer == null)
94  temporaryBuffer = nativeStreamBuffer = new byte[NativeStreamBufferSize];
95 
96  fixed (byte* temporaryBufferStart = temporaryBuffer)
97  *((ulong*)temporaryBufferStart) = i;
98 
99  Write(temporaryBuffer, 0, sizeof(ulong));
100  }
101 
102  /// <summary>
103  /// Reads a block of bytes from the stream and writes the data in a given buffer.
104  /// </summary>
105  /// <param name="buffer">When this method returns, contains the specified buffer with the values between 0 and (count - 1) replaced by the bytes read from the current source. </param>
106  /// <param name="count">The maximum number of bytes to read. </param>
107  /// <exception cref="ArgumentNullException">array is null. </exception>
108  /// <returns>The total number of bytes read into the buffer. This might be less than the number of bytes requested if that number of bytes are not currently available, or zero if the end of the stream is reached.</returns>
109  public virtual int Read(IntPtr buffer, int count)
110  {
111  var temporaryBuffer = nativeStreamBuffer;
112  if (temporaryBuffer == null)
113  temporaryBuffer = nativeStreamBuffer = new byte[NativeStreamBufferSize];
114 
115  int readSize = 0;
116 
117  for (int offset = 0; offset < count; offset += NativeStreamBufferSize, buffer += NativeStreamBufferSize)
118  {
119  // Compute missing bytes in this block
120  int blockSize = count - offset;
121  if (blockSize > NativeStreamBufferSize)
122  blockSize = NativeStreamBufferSize;
123 
124 
125  int currentReadSize = Read(temporaryBuffer, 0, blockSize);
126  readSize += currentReadSize;
127  Utilities.Write(buffer, temporaryBuffer, 0, currentReadSize);
128 
129  // Reached end of stream?
130  if (currentReadSize < blockSize)
131  break;
132  }
133 
134  return readSize;
135  }
136 
137  /// <summary>
138  /// Writes a block of bytes to this stream using data from a buffer.
139  /// </summary>
140  /// <param name="buffer">The buffer containing data to write to the stream.</param>
141  /// <param name="count">The number of bytes to be written to the current stream. </param>
142  public unsafe virtual void Write(IntPtr buffer, int count)
143  {
144  var temporaryBuffer = nativeStreamBuffer;
145  if (temporaryBuffer == null)
146  temporaryBuffer = nativeStreamBuffer = new byte[NativeStreamBufferSize];
147 
148  for (int offset = 0; offset < count; offset += NativeStreamBufferSize, buffer += NativeStreamBufferSize)
149  {
150  // Compute missing bytes in this block
151  int blockSize = count - offset;
152  if (blockSize > NativeStreamBufferSize)
153  blockSize = NativeStreamBufferSize;
154 
155  fixed (byte* temporaryBufferStart = temporaryBuffer)
156  Utilities.CopyMemory((IntPtr)temporaryBufferStart, buffer, blockSize);
157 
158  Write(temporaryBuffer, 0, blockSize);
159  }
160  }
161  }
162 }
virtual unsafe void Write(IntPtr buffer, int count)
Writes a block of bytes to this stream using data from a buffer.
virtual unsafe ushort ReadUInt16()
Definition: NativeStream.cs:18
virtual unsafe ulong ReadUInt64()
Definition: NativeStream.cs:50
_In_ size_t count
Definition: DirectXTexP.h:174
virtual unsafe void Write(uint i)
Definition: NativeStream.cs:78
A Stream with additional methods for native read and write operations using IntPtr.
Definition: NativeStream.cs:11
virtual unsafe void Write(ulong i)
Definition: NativeStream.cs:90
virtual unsafe uint ReadUInt32()
Definition: NativeStream.cs:34
virtual unsafe void Write(ushort i)
Definition: NativeStream.cs:66
virtual int Read(IntPtr buffer, int count)
Reads a block of bytes from the stream and writes the data in a given buffer.