1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System
.ServiceModel
.Channels
7 using System
.Diagnostics
;
11 using System
.ServiceModel
;
12 using System
.Threading
;
13 using System
.ServiceModel
.Diagnostics
.Application
;
15 // Low level abstraction for a socket/pipe
18 byte[] AsyncReadBuffer { get; }
19 int AsyncReadBufferSize { get; }
20 TraceEventType ExceptionEventType { get; set; }
21 IPEndPoint RemoteIPEndPoint { get; }
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
);
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
);
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
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()
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
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
;
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
;
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;
249 return base.EndRead();
253 class ConnectionStream
: Stream
255 TimeSpan closeTimeout
;
258 IConnection connection
;
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
);
270 public IConnection Connection
272 get { return connection; }
275 public override bool CanRead
280 public override bool CanSeek
282 get { return false; }
285 public override bool CanTimeout
290 public override bool CanWrite
295 public TimeSpan CloseTimeout
297 get { return closeTimeout; }
298 set { this.closeTimeout = value; }
301 public override int ReadTimeout
303 get { return this.readTimeout; }
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; }
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; }
370 public override void Close()
372 connection
.Close(this.CloseTimeout
, false);
375 public override void Flush()
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
481 completionException
= e
;
483 thisPtr
.Complete(false, completionException
);
487 sealed class ReadAsyncResult
: IOAsyncResult
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
);
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
);
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
;
551 ConnectionStream innerStream
;
552 AsyncCallback onRead
;
553 AsyncCallback onWrite
;
554 IAsyncResult readResult
;
555 IAsyncResult writeResult
;
556 WaitCallback readCallback
;
557 WaitCallback writeCallback
;
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)
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; }
598 get { return this.stream; }
601 public object ThisLock
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());
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
);
642 return new CommunicationException(SR
.GetString(SR
.StreamError
), ioException
);
646 public void Close(TimeSpan timeout
, bool asyncAndLinger
)
648 innerStream
.CloseTimeout
= timeout
;
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
)
709 return AsyncCompletionResult
.Queued
;
713 stream
.EndWrite(localResult
);
715 catch (IOException ioException
)
717 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperError(ConvertIOException(ioException
));
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
)
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
;
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
));
863 void OnRead(IAsyncResult result
)
865 if (result
.CompletedSynchronously
)
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);
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
);
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
)
940 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperArgumentNull("buffer");
943 ValidateBufferBounds(buffer
.Length
, offset
, size
);
946 internal static void ValidateBufferBounds(int bufferSize
, int offset
, int size
)
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
)));
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
)));