int InternalRead(AsyncProtocolRequest asyncRequest, BufferOffsetSize internalBuffer, byte[] buffer, int offset, int size, out bool wantMore)
        {
            if (asyncRequest == null)
            {
                throw new InvalidOperationException();
            }

            Debug("InternalRead: {0} {1} {2}", internalBuffer, offset, size);

            /*
             * One of Apple's native functions wants to read 'size' bytes of data.
             *
             * First, we check whether we already have enough in the internal buffer.
             *
             * If the internal buffer is empty (it will be the first time we're called), we save
             * the amount of bytes that were requested and return 'SslStatus.WouldBlock' to our
             * native caller.  This native function will then return this code to managed code,
             * where we read the requested amount of data into the internal buffer, then call the
             * native function again.
             */
            if (internalBuffer.Size == 0 && !internalBuffer.Complete)
            {
                Debug("InternalRead #1: {0} {1}", internalBuffer.Offset, internalBuffer.TotalBytes);
                internalBuffer.Offset = internalBuffer.Size = 0;
                asyncRequest.RequestRead(size);
                wantMore = true;
                return(0);
            }

            /*
             * The second time we're called, the native buffer will contain the exact amount of data that the
             * previous call requested from us, so we should be able to return it all here.  However, just in
             * case that Apple's native function changed its mind, we can also return less.
             *
             * In either case, if we have any data buffered, then we return as much of it as possible - if the
             * native code isn't satisfied, then it will call us again to request more.
             */
            var len = System.Math.Min(internalBuffer.Size, size);

            Buffer.BlockCopy(internalBuffer.Buffer, internalBuffer.Offset, buffer, offset, len);
            internalBuffer.Offset += len;
            internalBuffer.Size   -= len;
            wantMore = !internalBuffer.Complete && len < size;
            return(len);
        }
Exemple #2
0
 public AsyncReadOrWriteRequest(MobileAuthenticatedStream parent, bool sync, byte[] buffer, int offset, int size)
     : base(parent, sync)
 {
     UserBuffer = new BufferOffsetSize(buffer, offset, size);
 }
Exemple #3
0
 public AsyncProtocolRequest(MobileAuthenticatedStream parent, LazyAsyncResult lazyResult, BufferOffsetSize userBuffer = null)
 {
     Parent          = parent;
     UserAsyncResult = lazyResult;
     UserBuffer      = userBuffer;
 }
        int ProcessReadOrWrite(ref AsyncProtocolRequest nestedRequest, ref BufferOffsetSize2 internalBuffer, AsyncOperation operation, BufferOffsetSize userBuffer, LazyAsyncResult lazyResult)
        {
            if (userBuffer == null || userBuffer.Buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (userBuffer.Offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (userBuffer.Size < 0 || userBuffer.Offset + userBuffer.Size > userBuffer.Buffer.Length)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            CheckThrow(true);

            var name = internalBuffer == readBuffer ? "read" : "write";

            Debug("ProcessReadOrWrite: {0} {1}", name, userBuffer);

            var asyncRequest = new AsyncProtocolRequest(this, lazyResult, userBuffer);

            return(StartOperation(ref nestedRequest, ref internalBuffer, operation, asyncRequest, name));
        }
        IAsyncResult BeginReadOrWrite(ref AsyncProtocolRequest nestedRequest, ref BufferOffsetSize2 internalBuffer, AsyncOperation operation, BufferOffsetSize userBuffer, AsyncCallback asyncCallback, object asyncState)
        {
            LazyAsyncResult lazyResult = new LazyAsyncResult(this, asyncState, asyncCallback);

            ProcessReadOrWrite(ref nestedRequest, ref internalBuffer, operation, userBuffer, lazyResult);
            return(lazyResult);
        }