Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Channels / Connection.cs
blobc795e66a15eaf27843efd0fb4029429e8ea6d436
1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System.ServiceModel.Channels
7 using System.Diagnostics;
8 using System.IO;
9 using System.Net;
10 using System.Runtime;
11 using System.ServiceModel;
12 using System.Threading;
13 using System.ServiceModel.Diagnostics.Application;
15 // Low level abstraction for a socket/pipe
16 interface IConnection
18 byte[] AsyncReadBuffer { get; }
19 int AsyncReadBufferSize { get; }
20 TraceEventType ExceptionEventType { get; set; }
21 IPEndPoint RemoteIPEndPoint { get; }
23 void Abort();
24 void Close(TimeSpan timeout, bool asyncAndLinger);
25 void Shutdown(TimeSpan timeout);
27 AsyncCompletionResult BeginWrite(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout,
28 WaitCallback callback, object state);
29 void EndWrite();
30 void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout);
31 void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout, BufferManager bufferManager);
33 int Read(byte[] buffer, int offset, int size, TimeSpan timeout);
34 AsyncCompletionResult BeginRead(int offset, int size, TimeSpan timeout, WaitCallback callback, object state);
35 int EndRead();
37 // very ugly listener stuff
38 object DuplicateAndClose(int targetProcessId);
39 object GetCoreTransport();
40 IAsyncResult BeginValidate(Uri uri, AsyncCallback callback, object state);
41 bool EndValidate(IAsyncResult result);
44 // Low level abstraction for connecting a socket/pipe
45 interface IConnectionInitiator
47 IConnection Connect(Uri uri, TimeSpan timeout);
48 IAsyncResult BeginConnect(Uri uri, TimeSpan timeout, AsyncCallback callback, object state);
49 IConnection EndConnect(IAsyncResult result);
52 // Low level abstraction for listening for sockets/pipes
53 interface IConnectionListener : IDisposable
55 void Listen();
56 IAsyncResult BeginAccept(AsyncCallback callback, object state);
57 IConnection EndAccept(IAsyncResult result);
60 abstract class DelegatingConnection : IConnection
62 IConnection connection;
64 protected DelegatingConnection(IConnection connection)
66 this.connection = connection;
69 public virtual byte[] AsyncReadBuffer
71 get { return connection.AsyncReadBuffer; }
74 public virtual int AsyncReadBufferSize
76 get { return connection.AsyncReadBufferSize; }
79 public TraceEventType ExceptionEventType
81 get { return connection.ExceptionEventType; }
82 set { connection.ExceptionEventType = value; }
85 protected IConnection Connection
87 get { return connection; }
90 public IPEndPoint RemoteIPEndPoint
92 get { return connection.RemoteIPEndPoint; }
95 public virtual void Abort()
97 connection.Abort();
100 public virtual void Close(TimeSpan timeout, bool asyncAndLinger)
102 connection.Close(timeout, asyncAndLinger);
105 public virtual void Shutdown(TimeSpan timeout)
107 connection.Shutdown(timeout);
110 public virtual object DuplicateAndClose(int targetProcessId)
112 return connection.DuplicateAndClose(targetProcessId);
115 public virtual object GetCoreTransport()
117 return connection.GetCoreTransport();
120 public virtual IAsyncResult BeginValidate(Uri uri, AsyncCallback callback, object state)
122 return connection.BeginValidate(uri, callback, state);
125 public virtual bool EndValidate(IAsyncResult result)
127 return connection.EndValidate(result);
130 public virtual AsyncCompletionResult BeginWrite(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout,
131 WaitCallback callback, object state)
133 return connection.BeginWrite(buffer, offset, size, immediate, timeout, callback, state);
136 public virtual void EndWrite()
138 connection.EndWrite();
141 public virtual void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout)
143 connection.Write(buffer, offset, size, immediate, timeout);
146 public virtual void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout, BufferManager bufferManager)
148 connection.Write(buffer, offset, size, immediate, timeout, bufferManager);
151 public virtual int Read(byte[] buffer, int offset, int size, TimeSpan timeout)
153 return connection.Read(buffer, offset, size, timeout);
156 public virtual AsyncCompletionResult BeginRead(int offset, int size, TimeSpan timeout,
157 WaitCallback callback, object state)
159 return connection.BeginRead(offset, size, timeout, callback, state);
162 public virtual int EndRead()
164 return connection.EndRead();
168 class PreReadConnection : DelegatingConnection
170 int asyncBytesRead;
171 byte[] preReadData;
172 int preReadOffset;
173 int preReadCount;
175 public PreReadConnection(IConnection innerConnection, byte[] initialData)
176 : this(innerConnection, initialData, 0, initialData.Length)
180 public PreReadConnection(IConnection innerConnection, byte[] initialData, int initialOffset, int initialSize)
181 : base(innerConnection)
183 this.preReadData = initialData;
184 this.preReadOffset = initialOffset;
185 this.preReadCount = initialSize;
188 public void AddPreReadData(byte[] initialData, int initialOffset, int initialSize)
190 if (this.preReadCount > 0)
192 byte[] tempBuffer = this.preReadData;
193 this.preReadData = DiagnosticUtility.Utility.AllocateByteArray(initialSize + this.preReadCount);
194 Buffer.BlockCopy(tempBuffer, this.preReadOffset, this.preReadData, 0, this.preReadCount);
195 Buffer.BlockCopy(initialData, initialOffset, this.preReadData, this.preReadCount, initialSize);
196 this.preReadOffset = 0;
197 this.preReadCount += initialSize;
199 else
201 this.preReadData = initialData;
202 this.preReadOffset = initialOffset;
203 this.preReadCount = initialSize;
207 public override int Read(byte[] buffer, int offset, int size, TimeSpan timeout)
209 ConnectionUtilities.ValidateBufferBounds(buffer, offset, size);
211 if (this.preReadCount > 0)
213 int bytesToCopy = Math.Min(size, this.preReadCount);
214 Buffer.BlockCopy(this.preReadData, this.preReadOffset, buffer, offset, bytesToCopy);
215 this.preReadOffset += bytesToCopy;
216 this.preReadCount -= bytesToCopy;
217 return bytesToCopy;
220 return base.Read(buffer, offset, size, timeout);
223 public override AsyncCompletionResult BeginRead(int offset, int size, TimeSpan timeout, WaitCallback callback, object state)
225 ConnectionUtilities.ValidateBufferBounds(AsyncReadBufferSize, offset, size);
227 if (this.preReadCount > 0)
229 int bytesToCopy = Math.Min(size, this.preReadCount);
230 Buffer.BlockCopy(this.preReadData, this.preReadOffset, AsyncReadBuffer, offset, bytesToCopy);
231 this.preReadOffset += bytesToCopy;
232 this.preReadCount -= bytesToCopy;
233 this.asyncBytesRead = bytesToCopy;
234 return AsyncCompletionResult.Completed;
237 return base.BeginRead(offset, size, timeout, callback, state);
240 public override int EndRead()
242 if (this.asyncBytesRead > 0)
244 int retValue = this.asyncBytesRead;
245 this.asyncBytesRead = 0;
246 return retValue;
249 return base.EndRead();
253 class ConnectionStream : Stream
255 TimeSpan closeTimeout;
256 int readTimeout;
257 int writeTimeout;
258 IConnection connection;
259 bool immediate;
261 public ConnectionStream(IConnection connection, IDefaultCommunicationTimeouts defaultTimeouts)
263 this.connection = connection;
264 this.closeTimeout = defaultTimeouts.CloseTimeout;
265 this.ReadTimeout = TimeoutHelper.ToMilliseconds(defaultTimeouts.ReceiveTimeout);
266 this.WriteTimeout = TimeoutHelper.ToMilliseconds(defaultTimeouts.SendTimeout);
267 immediate = true;
270 public IConnection Connection
272 get { return connection; }
275 public override bool CanRead
277 get { return true; }
280 public override bool CanSeek
282 get { return false; }
285 public override bool CanTimeout
287 get { return true; }
290 public override bool CanWrite
292 get { return true; }
295 public TimeSpan CloseTimeout
297 get { return closeTimeout; }
298 set { this.closeTimeout = value; }
301 public override int ReadTimeout
303 get { return this.readTimeout; }
306 if (value < -1)
308 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value,
309 SR.GetString(SR.ValueMustBeInRange, -1, int.MaxValue)));
312 this.readTimeout = value;
316 public override int WriteTimeout
318 get { return this.writeTimeout; }
321 if (value < -1)
323 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value,
324 SR.GetString(SR.ValueMustBeInRange, -1, int.MaxValue)));
327 this.writeTimeout = value;
331 public bool Immediate
333 get { return immediate; }
334 set { immediate = value; }
337 public override long Length
341 #pragma warning suppress 56503 // Microsoft, required by the Stream.Length contract
342 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupported)));
346 public override long Position
350 #pragma warning suppress 56503 // Microsoft, required by the Stream.Position contract
351 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupported)));
355 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupported)));
359 public TraceEventType ExceptionEventType
361 get { return connection.ExceptionEventType; }
362 set { connection.ExceptionEventType = value; }
365 public void Abort()
367 connection.Abort();
370 public override void Close()
372 connection.Close(this.CloseTimeout, false);
375 public override void Flush()
377 // NOP
380 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
382 return new WriteAsyncResult(this.connection, buffer, offset, count, this.Immediate, TimeoutHelper.FromMilliseconds(this.WriteTimeout), callback, state);
385 public override void EndWrite(IAsyncResult asyncResult)
387 WriteAsyncResult.End(asyncResult);
390 public override void Write(byte[] buffer, int offset, int count)
392 connection.Write(buffer, offset, count, this.Immediate, TimeoutHelper.FromMilliseconds(this.WriteTimeout));
395 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
397 return new ReadAsyncResult(connection, buffer, offset, count, TimeoutHelper.FromMilliseconds(this.ReadTimeout), callback, state);
400 public override int EndRead(IAsyncResult asyncResult)
402 return ReadAsyncResult.End(asyncResult);
405 public override int Read(byte[] buffer, int offset, int count)
407 return this.Read(buffer, offset, count, TimeoutHelper.FromMilliseconds(this.ReadTimeout));
410 protected int Read(byte[] buffer, int offset, int count, TimeSpan timeout)
412 return connection.Read(buffer, offset, count, timeout);
415 public override long Seek(long offset, SeekOrigin origin)
417 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupported)));
421 public override void SetLength(long value)
423 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupported)));
426 public void Shutdown(TimeSpan timeout)
428 connection.Shutdown(timeout);
431 public IAsyncResult BeginValidate(Uri uri, AsyncCallback callback, object state)
433 return this.connection.BeginValidate(uri, callback, state);
436 public bool EndValidate(IAsyncResult result)
438 return this.connection.EndValidate(result);
441 abstract class IOAsyncResult : AsyncResult
443 static WaitCallback onAsyncIOComplete;
444 IConnection connection;
446 protected IOAsyncResult(IConnection connection, AsyncCallback callback, object state)
447 : base(callback, state)
449 this.connection = connection;
452 protected WaitCallback GetWaitCompletion()
454 if (onAsyncIOComplete == null)
456 onAsyncIOComplete = new WaitCallback(OnAsyncIOComplete);
459 return onAsyncIOComplete;
462 protected abstract void HandleIO(IConnection connection);
464 static void OnAsyncIOComplete(object state)
466 IOAsyncResult thisPtr = (IOAsyncResult)state;
468 Exception completionException = null;
471 thisPtr.HandleIO(thisPtr.connection);
473 #pragma warning suppress 56500 // Microsoft, transferring exception to another thread
474 catch (Exception e)
476 if (Fx.IsFatal(e))
478 throw;
481 completionException = e;
483 thisPtr.Complete(false, completionException);
487 sealed class ReadAsyncResult : IOAsyncResult
489 int bytesRead;
490 byte[] buffer;
491 int offset;
493 public ReadAsyncResult(IConnection connection, byte[] buffer, int offset, int count, TimeSpan timeout,
494 AsyncCallback callback, object state)
495 : base(connection, callback, state)
497 this.buffer = buffer;
498 this.offset = offset;
500 AsyncCompletionResult readResult = connection.BeginRead(0, Math.Min(count, connection.AsyncReadBufferSize),
501 timeout, GetWaitCompletion(), this);
502 if (readResult == AsyncCompletionResult.Completed)
504 HandleIO(connection);
505 base.Complete(true);
509 protected override void HandleIO(IConnection connection)
511 bytesRead = connection.EndRead();
512 Buffer.BlockCopy(connection.AsyncReadBuffer, 0, buffer, offset, bytesRead);
515 public static int End(IAsyncResult result)
517 ReadAsyncResult thisPtr = AsyncResult.End<ReadAsyncResult>(result);
518 return thisPtr.bytesRead;
522 sealed class WriteAsyncResult : IOAsyncResult
524 public WriteAsyncResult(IConnection connection, byte[] buffer, int offset, int count, bool immediate, TimeSpan timeout, AsyncCallback callback, object state)
525 : base(connection, callback, state)
527 AsyncCompletionResult writeResult = connection.BeginWrite(buffer, offset, count, immediate, timeout, GetWaitCompletion(), this);
528 if (writeResult == AsyncCompletionResult.Completed)
530 HandleIO(connection);
531 base.Complete(true);
535 protected override void HandleIO(IConnection connection)
537 connection.EndWrite();
540 public static void End(IAsyncResult result)
542 AsyncResult.End<WriteAsyncResult>(result);
547 class StreamConnection : IConnection
549 byte[] asyncReadBuffer;
550 int bytesRead;
551 ConnectionStream innerStream;
552 AsyncCallback onRead;
553 AsyncCallback onWrite;
554 IAsyncResult readResult;
555 IAsyncResult writeResult;
556 WaitCallback readCallback;
557 WaitCallback writeCallback;
558 Stream stream;
560 public StreamConnection(Stream stream, ConnectionStream innerStream)
562 Fx.Assert(stream != null, "StreamConnection: Stream cannot be null.");
563 Fx.Assert(innerStream != null, "StreamConnection: Inner stream cannot be null.");
565 this.stream = stream;
566 this.innerStream = innerStream;
568 onRead = Fx.ThunkCallback(new AsyncCallback(OnRead));
569 onWrite = Fx.ThunkCallback(new AsyncCallback(OnWrite));
572 public byte[] AsyncReadBuffer
576 if (this.asyncReadBuffer == null)
578 lock (ThisLock)
580 if (this.asyncReadBuffer == null)
582 this.asyncReadBuffer = DiagnosticUtility.Utility.AllocateByteArray(innerStream.Connection.AsyncReadBufferSize);
587 return this.asyncReadBuffer;
591 public int AsyncReadBufferSize
593 get { return innerStream.Connection.AsyncReadBufferSize; }
596 public Stream Stream
598 get { return this.stream; }
601 public object ThisLock
603 get { return this; }
606 public TraceEventType ExceptionEventType
608 get { return innerStream.ExceptionEventType; }
609 set { innerStream.ExceptionEventType = value; }
612 public IPEndPoint RemoteIPEndPoint
616 #pragma warning suppress 56503 // Not publicly accessible and this should never be called.
617 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
621 public void Abort()
623 innerStream.Abort();
626 Exception ConvertIOException(IOException ioException)
628 if (ioException.InnerException is TimeoutException)
630 return new TimeoutException(ioException.InnerException.Message, ioException);
632 else if (ioException.InnerException is CommunicationObjectAbortedException)
634 return new CommunicationObjectAbortedException(ioException.InnerException.Message, ioException);
636 else if (ioException.InnerException is CommunicationException)
638 return new CommunicationException(ioException.InnerException.Message, ioException);
640 else
642 return new CommunicationException(SR.GetString(SR.StreamError), ioException);
646 public void Close(TimeSpan timeout, bool asyncAndLinger)
648 innerStream.CloseTimeout = timeout;
651 stream.Close();
653 catch (IOException ioException)
655 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertIOException(ioException));
659 public void Shutdown(TimeSpan timeout)
661 innerStream.Shutdown(timeout);
664 public object DuplicateAndClose(int targetProcessId)
666 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
669 public virtual object GetCoreTransport()
671 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
674 public IAsyncResult BeginValidate(Uri uri, AsyncCallback callback, object state)
676 return this.innerStream.BeginValidate(uri, callback, state);
679 public bool EndValidate(IAsyncResult result)
681 return this.innerStream.EndValidate(result);
684 public AsyncCompletionResult BeginWrite(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout,
685 WaitCallback callback, object state)
687 if (callback == null)
689 Fx.AssertAndThrow("Cannot call BeginWrite without a callback");
692 if (this.writeCallback != null)
694 Fx.AssertAndThrow("BeginWrite cannot be called twice");
697 this.writeCallback = callback;
698 bool throwing = true;
702 innerStream.Immediate = immediate;
703 SetWriteTimeout(timeout);
704 IAsyncResult localResult = stream.BeginWrite(buffer, offset, size, this.onWrite, state);
706 if (!localResult.CompletedSynchronously)
708 throwing = false;
709 return AsyncCompletionResult.Queued;
712 throwing = false;
713 stream.EndWrite(localResult);
715 catch (IOException ioException)
717 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertIOException(ioException));
719 finally
721 if (throwing)
723 this.writeCallback = null;
727 return AsyncCompletionResult.Completed;
730 public void EndWrite()
732 IAsyncResult localResult = this.writeResult;
733 this.writeResult = null;
734 this.writeCallback = null;
736 if (localResult != null)
740 stream.EndWrite(localResult);
742 catch (IOException ioException)
744 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertIOException(ioException));
749 void OnWrite(IAsyncResult result)
751 if (result.CompletedSynchronously)
753 return;
756 if (this.writeResult != null)
758 throw Fx.AssertAndThrow("StreamConnection: OnWrite called twice.");
761 this.writeResult = result;
762 this.writeCallback(result.AsyncState);
765 public void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout)
769 innerStream.Immediate = immediate;
770 SetWriteTimeout(timeout);
771 stream.Write(buffer, offset, size);
773 catch (IOException ioException)
775 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertIOException(ioException));
779 public void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout, BufferManager bufferManager)
781 Write(buffer, offset, size, immediate, timeout);
782 bufferManager.ReturnBuffer(buffer);
785 void SetReadTimeout(TimeSpan timeout)
787 int timeoutInMilliseconds = TimeoutHelper.ToMilliseconds(timeout);
788 if (stream.CanTimeout)
790 stream.ReadTimeout = timeoutInMilliseconds;
792 innerStream.ReadTimeout = timeoutInMilliseconds;
795 void SetWriteTimeout(TimeSpan timeout)
797 int timeoutInMilliseconds = TimeoutHelper.ToMilliseconds(timeout);
798 if (stream.CanTimeout)
800 stream.WriteTimeout = timeoutInMilliseconds;
802 innerStream.WriteTimeout = timeoutInMilliseconds;
805 public int Read(byte[] buffer, int offset, int size, TimeSpan timeout)
809 SetReadTimeout(timeout);
810 return stream.Read(buffer, offset, size);
812 catch (IOException ioException)
814 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertIOException(ioException));
818 public AsyncCompletionResult BeginRead(int offset, int size, TimeSpan timeout, WaitCallback callback, object state)
820 ConnectionUtilities.ValidateBufferBounds(AsyncReadBufferSize, offset, size);
821 readCallback = callback;
825 SetReadTimeout(timeout);
826 IAsyncResult localResult = stream.BeginRead(AsyncReadBuffer, offset, size, onRead, state);
828 if (!localResult.CompletedSynchronously)
830 return AsyncCompletionResult.Queued;
833 bytesRead = stream.EndRead(localResult);
835 catch (IOException ioException)
837 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertIOException(ioException));
840 return AsyncCompletionResult.Completed;
843 public int EndRead()
845 IAsyncResult localResult = this.readResult;
846 this.readResult = null;
848 if (localResult != null)
852 bytesRead = stream.EndRead(localResult);
854 catch (IOException ioException)
856 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertIOException(ioException));
860 return bytesRead;
863 void OnRead(IAsyncResult result)
865 if (result.CompletedSynchronously)
867 return;
870 if (this.readResult != null)
872 throw Fx.AssertAndThrow("StreamConnection: OnRead called twice.");
875 this.readResult = result;
876 readCallback(result.AsyncState);
880 class ConnectionMessageProperty
882 IConnection connection;
884 public ConnectionMessageProperty(IConnection connection)
886 this.connection = connection;
889 public static string Name
891 get { return "iconnection"; }
894 public IConnection Connection
896 get { return this.connection; }
900 static class ConnectionUtilities
902 internal static void CloseNoThrow(IConnection connection, TimeSpan timeout)
904 bool success = false;
907 connection.Close(timeout, false);
908 success = true;
910 catch (TimeoutException e)
912 if (TD.CloseTimeoutIsEnabled())
914 TD.CloseTimeout(e.Message);
916 DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
918 catch (CommunicationException e)
920 DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
922 finally
924 if (!success)
926 connection.Abort();
931 internal static void ValidateBufferBounds(ArraySegment<byte> buffer)
933 ValidateBufferBounds(buffer.Array, buffer.Offset, buffer.Count);
936 internal static void ValidateBufferBounds(byte[] buffer, int offset, int size)
938 if (buffer == null)
940 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer");
943 ValidateBufferBounds(buffer.Length, offset, size);
946 internal static void ValidateBufferBounds(int bufferSize, int offset, int size)
948 if (offset < 0)
950 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", offset, SR.GetString(
951 SR.ValueMustBeNonNegative)));
954 if (offset > bufferSize)
956 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", offset, SR.GetString(
957 SR.OffsetExceedsBufferSize, bufferSize)));
960 if (size <= 0)
962 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("size", size, SR.GetString(
963 SR.ValueMustBePositive)));
966 int remainingBufferSpace = bufferSize - offset;
967 if (size > remainingBufferSpace)
969 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("size", size, SR.GetString(
970 SR.SizeExceedsRemainingBufferSpace, remainingBufferSpace)));