forked from msgpack/msgpack-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUnpackingStream.cs
More file actions
209 lines (192 loc) · 6.6 KB
/
UnpackingStream.cs
File metadata and controls
209 lines (192 loc) · 6.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#region -- License Terms --
//
// MessagePack for CLI
//
// Copyright (C) 2010-2014 FUJIWARA, Yusuke
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion -- License Terms --
#if UNITY_STANDALONE || UNITY_WEBPLAYER || UNITY_WII || UNITY_IPHONE || UNITY_ANDROID || UNITY_PS3 || UNITY_XBOX360 || UNITY_FLASH || UNITY_BKACKBERRY || UNITY_WINRT
#define UNITY
#endif
using System;
#if !UNITY
using System.Diagnostics.Contracts;
#endif // !UNITY
using System.IO;
namespace MsgPack
{
/// <summary>
/// Represents raw binary as read only <see cref="Stream"/>.
/// </summary>
/// <remarks>
/// <para>
/// This object behaves as wrapper of the underlying <see cref="Stream"/> which contains message pack encoded byte array.
/// But, this object does not own the stream, so that stream is not closed when this stream is closed.
/// </para>
/// <para>
/// The value of <see cref="M:Stream.CanSeek"/>, timeout, and async API depends on the underlying stream.
/// </para>
/// </remarks>
public abstract class UnpackingStream : Stream
{
internal readonly Stream Underlying;
internal readonly long RawLength;
internal long CurrentOffset;
/// <summary>
/// Gets a value indicating whether the current stream supports reading.
/// </summary>
/// <value>Always <c>true</c>.</value>
public sealed override bool CanRead
{
get { return true; }
}
/// <summary>
/// Gets a value indicating whether the current stream supports writing.
/// </summary>
/// <value>Always <c>false</c>.</value>
public sealed override bool CanWrite
{
get { return false; }
}
/// <summary>
/// Gets the length in bytes of the stream.
/// </summary>
/// <value>
/// A long value representing the length of the raw binary length.
/// This value must be between 0 and <see cref="Int32.MaxValue"/>.
/// </value>
/// <exception cref="T:System.ObjectDisposedException">
/// Methods were called after the stream was closed.
/// </exception>
/// <remarks>
/// This property never throws <see cref="NotSupportedException"/> even if <see cref="M:Stream.CanSeek" /> is <c>false</c>.
/// </remarks>
public sealed override long Length
{
get { return this.RawLength; }
}
/// <summary>
/// Gets a value that determines whether the current stream can time out.
/// </summary>
/// <value>
/// A value that determines whether the current stream can time out.
/// </value>
/// <exception cref="T:System.ObjectDisposedException">
/// Methods were called after the stream was closed.
/// </exception>
public sealed override bool CanTimeout
{
get { return this.Underlying.CanTimeout; }
}
internal UnpackingStream( Stream underlying, long rawLength )
{
this.Underlying = underlying;
this.RawLength = rawLength;
}
/// <summary>
/// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
/// </summary>
/// <param name="buffer">
/// An array of bytes. When this method returns,
/// the buffer contains the specified byte array with the values between <paramref name="offset"/> and ( <paramref name="offset"/> + <paramref name="count"/> - 1)
/// replaced by the bytes read from the current source.
/// </param>
/// <param name="offset">
/// The zero-based byte offset in <paramref name="buffer"/> at which to begin storing the data read from the current stream.
/// </param>
/// <param name="count">
/// The maximum number of bytes to be read from the current stream.
/// </param>
/// <returns>
/// The total number of bytes read into the buffer.
/// This can be less than the number of bytes requested if that many bytes are not currently available,
/// or zero (0) if the end of the stream has been reached.
/// </returns>
/// <exception cref="T:System.ArgumentException">
/// The sum of <paramref name="offset"/> and <paramref name="count"/> is larger than the buffer length.
/// </exception>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="buffer"/> is <c>null</c>.
/// </exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="offset"/> or <paramref name="count"/> is negative.
/// </exception>
/// <exception cref="T:System.IO.IOException">
/// An I/O error occurs.
/// </exception>
/// <exception cref="T:System.ObjectDisposedException">
/// Methods were called after the stream was closed.
/// </exception>
/// <remarks>
/// <note>
/// Arguments might be passed to the underlying <see cref="Stream"/> without any validation.
/// </note>
/// </remarks>
public sealed override int Read( byte[] buffer, int offset, int count )
{
if ( count < 0 )
{
throw new ArgumentOutOfRangeException( "count" );
}
#if !UNITY
Contract.EndContractBlock();
#endif // !UNITY
if ( this.CurrentOffset == this.RawLength )
{
return 0;
}
int realCount = count;
var exceeds = this.CurrentOffset + count - this.RawLength;
if ( exceeds > 0 )
{
realCount -= checked( ( int )exceeds );
}
var readCount = this.Underlying.Read( buffer, offset, realCount );
this.CurrentOffset += readCount;
return readCount;
}
/// <summary>
/// Overrides <see cref="M:Stream.Flush()"/> so that no action is performed.
/// </summary>
public sealed override void Flush()
{
// nop
}
/// <summary>
/// Throws <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="value">Never used.</param>
/// <exception cref="T:System.NotSupportedException">
/// Always thrown.
/// </exception>
public sealed override void SetLength( long value )
{
throw new NotSupportedException();
}
/// <summary>
/// Throws <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="buffer">Never used.</param>
/// <param name="offset">Never used.</param>
/// <param name="count">Never used.</param>
/// <exception cref="T:System.NotSupportedException">
/// Always thrown.
/// </exception>
public sealed override void Write( byte[] buffer, int offset, int count )
{
throw new NotSupportedException();
}
}
}