Пример #1
0
        protected override void OnPostProcessing(uint hint, ulong data)
        {
            uint d = 0;
            DAsyncResultHandler rh = null;

            System.Threading.Monitor.Enter(m_csFile);
            foreach (CContext it in m_vContext)
            {
                if (d >= m_MaxDownloading)
                {
                    break;
                }
                if (it.File != null)
                {
                    if (it.Uploading)
                    {
                        break;
                    }
                    else
                    {
                        ++d;
                        continue;
                    }
                }
                if (it.HasError)
                {
                    continue;
                }
                if (it.Uploading)
                {
                    OpenLocalRead(it);
                    if (!it.HasError)
                    {
                        if (!SendRequest(idUpload, it.FilePath, it.Flags, it.FileSize, rh, it.Discarded, it.Se))
                        {
                            CClientSocket cs = Socket;
                            it.ErrCode = cs.ErrorCode;
                            if (it.ErrCode == 0)
                            {
                                it.ErrCode = SESSION_CLOSED_BEFORE;
                                it.ErrMsg  = SESSION_CLOSED_BEFORE_ERR_MSG;
                            }
                            else
                            {
                                it.ErrMsg = cs.ErrorMsg;
                            }
#if TASKS_ENABLED
                            if (it.Fut != null)
                            {
                                it.Fut.TrySetException(new CSocketError(it.ErrCode, it.ErrMsg, idUpload, true));
                                it.Discarded = null;
                                it.Se        = null;
                            }
#endif
                            continue;
                        }
                        break;
                    }
                }
                else
                {
                    OpenLocalWrite(it);
                    if (!it.HasError)
                    {
                        if (!SendRequest(idDownload, it.LocalFile, it.FilePath, it.Flags, it.InitSize, rh, it.Discarded, it.Se))
                        {
                            CClientSocket cs = Socket;
                            it.ErrCode = cs.ErrorCode;
                            if (it.ErrCode == 0)
                            {
                                it.ErrCode = SESSION_CLOSED_BEFORE;
                                it.ErrMsg  = SESSION_CLOSED_BEFORE_ERR_MSG;
                            }
                            else
                            {
                                it.ErrMsg = cs.ErrorMsg;
                            }
#if TASKS_ENABLED
                            if (it.Fut != null)
                            {
                                it.Fut.TrySetException(new CSocketError(it.ErrCode, it.ErrMsg, idDownload, true));
                                it.Discarded = null;
                                it.Se        = null;
                            }
#endif
                        }
                        ++d;
                    }
                }
            }
            while (m_vContext.Count > 0)
            {
                CContext it = m_vContext[0];
                if (it.HasError)
                {
                    CloseFile(it);
                    if (it.Uploading)
                    {
                        DUpload cb = it.Upload;
                        if (cb != null)
                        {
                            int    errCode = it.ErrCode;
                            string errMsg  = it.ErrMsg;
                            try
                            {
                                System.Threading.Monitor.Exit(m_csFile);
                                cb.Invoke(this, errCode, errMsg);
                            }
                            finally
                            {
                                System.Threading.Monitor.Enter(m_csFile);
                            }
                        }
                    }
                    else
                    {
                        DDownload cb = it.Download;
                        if (cb != null)
                        {
                            int    errCode = it.ErrCode;
                            string errMsg  = it.ErrMsg;
                            try
                            {
                                System.Threading.Monitor.Exit(m_csFile);
                                cb.Invoke(this, errCode, errMsg);
                            }
                            finally
                            {
                                System.Threading.Monitor.Enter(m_csFile);
                            }
                        }
                    }
                    m_vContext.RemoveFromFront();
                }
                else
                {
                    break;
                }
            }
            System.Threading.Monitor.Exit(m_csFile);
        }
Пример #2
0
        protected override void OnResultReturned(ushort reqId, CUQueue mc)
        {
            switch (reqId)
            {
            case idDownload:
            {
                int    res;
                string errMsg;
                mc.Load(out res).Load(out errMsg);
                DDownload dl = null;
                lock (m_csFile)
                {
                    if (m_vContext.Count > 0)
                    {
                        CContext ctx = m_vContext[0];
                        ctx.ErrCode = res;
                        ctx.ErrMsg  = errMsg;
                        dl          = ctx.Download;
                    }
                }
                if (dl != null)
                {
                    dl.Invoke(this, res, errMsg);
                }
                lock (m_csFile)
                {
                    if (m_vContext.Count > 0)
                    {
                        CloseFile(m_vContext.RemoveFromFront());
                    }
                }
                OnPostProcessing(0, 0);
            }
            break;

            case idStartDownloading:
                lock (m_csFile)
                {
                    long   fileSize;
                    string localFile, remoteFile;
                    uint   flags;
                    long   initSize;
                    mc.Load(out fileSize).Load(out localFile).Load(out remoteFile).Load(out flags).Load(out initSize);
                    lock (m_csFile)
                    {
                        if (m_vContext.Count == 0)
                        {
                            CContext ctx = new CContext(false, flags);
                            ctx.LocalFile = localFile;
                            ctx.FilePath  = remoteFile;
                            OpenLocalWrite(ctx);
                            ctx.InitSize = initSize;
                            m_vContext.AddToBack(ctx);
                        }
                        CContext context = m_vContext[0];
                        context.FileSize = fileSize;
                        initSize         = (context.InitSize > 0) ? context.InitSize : 0;
                        if (context.File.Position > initSize)
                        {
                            context.File.SetLength(initSize);
                        }
                    }
                }
                break;

            case idDownloading:
            {
                long          downloaded = 0;
                DTransferring trans      = null;
                CContext      context    = null;
                lock (m_csFile)
                {
                    if (m_vContext.Count > 0)
                    {
                        context = m_vContext[0];
                        trans   = context.Transferring;
                        byte[] buffer = mc.IntenalBuffer;
                        try
                        {
                            context.File.Write(buffer, 0, (int)mc.GetSize());
                            long initSize = (context.InitSize > 0) ? context.InitSize : 0;
                            downloaded = context.File.Position - initSize;
                        }
                        catch (System.IO.IOException err)
                        {
                            context.ErrMsg = err.Message;
#if NO_HRESULT
                            context.ErrCode = CANNOT_OPEN_LOCAL_FILE_FOR_WRITING;
#else
                            context.ErrCode = err.HResult;
#endif
                        }
                    }
                }
                mc.SetSize(0);
                if (context != null && context.HasError)
                {
                    if (context.Download != null)
                    {
                        context.Download.Invoke(this, context.ErrCode, context.ErrMsg);
                    }
                    CloseFile(m_vContext.RemoveFromFront());
                    OnPostProcessing(0, 0);
                }
                else if (trans != null)
                {
                    trans.Invoke(this, downloaded);
                }
            }
            break;

            case idUploadBackup:
                break;

            case idUpload:
            {
                CContext context = null;
                int      res;
                string   errMsg;
                mc.Load(out res).Load(out errMsg);
                if (res != 0 || (errMsg != null && errMsg.Length > 0))
                {
                    lock (m_csFile)
                    {
                        if (m_vContext.Count > 0)
                        {
                            context = m_vContext[0];
                            mc.Load(out context.InitSize);
                            context.ErrCode = res;
                            context.ErrMsg  = errMsg;
                        }
                    }
                }
                else
                {
                    CClientSocket cs = Socket;
                    lock (m_csFile)
                    {
                        if (m_vContext.Count > 0)
                        {
                            context = m_vContext[0];
                            mc.Load(out context.InitSize);
                            using (CScopeUQueue sb = new CScopeUQueue())
                            {
                                DAsyncResultHandler    rh = null;
                                DOnExceptionFromServer se = null;
                                if (sb.UQueue.MaxBufferSize < STREAM_CHUNK_SIZE)
                                {
                                    sb.UQueue.Realloc(STREAM_CHUNK_SIZE);
                                }
                                byte[] buffer = sb.UQueue.IntenalBuffer;
                                try
                                {
                                    context.QueueOk = cs.ClientQueue.StartJob();
                                    bool queue_enabled = cs.ClientQueue.Available;
                                    if (queue_enabled)
                                    {
                                        SendRequest(idUploadBackup, context.FilePath, context.Flags, context.FileSize, context.InitSize, rh, context.Discarded, se);
                                    }
                                    int ret = context.File.Read(buffer, 0, (int)STREAM_CHUNK_SIZE);
                                    while (ret == STREAM_CHUNK_SIZE)
                                    {
                                        if (!SendRequest(idUploading, buffer, (uint)ret, rh, context.Discarded, se))
                                        {
                                            context.ErrCode = cs.ErrorCode;
                                            context.ErrMsg  = cs.ErrorMsg;
                                            break;
                                        }
                                        ret = context.File.Read(buffer, 0, (int)STREAM_CHUNK_SIZE);
                                        if (queue_enabled)
                                        {
                                            //save file into client message queue
                                        }
                                        else if (cs.BytesInSendingBuffer > 40 * STREAM_CHUNK_SIZE)
                                        {
                                            break;
                                        }
                                    }
                                    if (ret > 0 && !context.HasError)
                                    {
                                        if (!SendRequest(idUploading, buffer, (uint)ret, rh, context.Discarded, se))
                                        {
                                            context.ErrCode = cs.ErrorCode;
                                            context.ErrMsg  = cs.ErrorMsg;
                                        }
                                    }
                                    if (ret < STREAM_CHUNK_SIZE && !context.HasError)
                                    {
                                        context.Sent = true;
                                        SendRequest(idUploadCompleted, rh, context.Discarded, se);
                                        if (context.QueueOk)
                                        {
                                            Socket.ClientQueue.EndJob();
                                        }
                                    }
                                }
                                catch (System.IO.IOException err)
                                {
                                    errMsg = err.Message;
#if NO_HRESULT
                                    res = CANNOT_OPEN_LOCAL_FILE_FOR_READING;
#else
                                    res = err.HResult;
#endif
                                    context.ErrCode = res;
                                    context.ErrMsg  = errMsg;
                                }
                            }
                        }
                    }
                }
                if (context != null && context.HasError)
                {
                    if (context.Upload != null)
                    {
                        context.Upload.Invoke(this, context.ErrCode, context.ErrMsg);
                    }
                    lock (m_csFile)
                    {
                        CloseFile(m_vContext.RemoveFromFront());
                    }
                    if (context.QueueOk)
                    {
                        Socket.ClientQueue.AbortJob();
                    }
                    OnPostProcessing(0, 0);
                }
            }
            break;

            case idUploading:
            {
                int           errCode = 0;
                string        errMsg  = "";
                CContext      context = null;
                DTransferring trans   = null;
                long          uploaded;
                mc.Load(out uploaded);
                if (mc.GetSize() >= 8)
                {
                    mc.Load(out errCode).Load(out errMsg);
                }
                lock (m_csFile)
                {
                    if (m_vContext.Count > 0)
                    {
                        context = m_vContext[0];
                        trans   = context.Transferring;
                        if (uploaded < 0 || errCode != 0 || errMsg.Length != 0)
                        {
                            context.ErrCode = errCode;
                            context.ErrMsg  = errMsg;
                            CloseFile(context);
                        }
                        else if (!context.Sent)
                        {
                            using (CScopeUQueue sb = new CScopeUQueue())
                            {
                                DAsyncResultHandler    rh = null;
                                DOnExceptionFromServer se = null;
                                if (sb.UQueue.MaxBufferSize < STREAM_CHUNK_SIZE)
                                {
                                    sb.UQueue.Realloc(STREAM_CHUNK_SIZE);
                                }
                                byte[] buffer = sb.UQueue.IntenalBuffer;
                                try
                                {
                                    int ret = context.File.Read(buffer, 0, (int)STREAM_CHUNK_SIZE);
                                    if (ret > 0)
                                    {
                                        SendRequest(idUploading, buffer, (uint)ret, rh, context.Discarded, se);
                                    }
                                    if (ret < STREAM_CHUNK_SIZE)
                                    {
                                        context.Sent = true;
                                        SendRequest(idUploadCompleted, rh, context.Discarded, se);
                                    }
                                }
                                catch (System.IO.IOException err)
                                {
                                    context.ErrMsg = err.Message;
#if NO_HRESULT
                                    context.ErrCode = CANNOT_OPEN_LOCAL_FILE_FOR_READING;
#else
                                    context.ErrCode = err.HResult;
#endif
                                }
                            }
                        }
                    }
                }
                if (context != null && context.HasError)
                {
                    if (context.Upload != null)
                    {
                        context.Upload.Invoke(this, context.ErrCode, context.ErrMsg);
                    }
                    lock (m_csFile)
                    {
                        CloseFile(m_vContext.RemoveFromFront());
                    }
                    OnPostProcessing(0, 0);
                }
                else if (trans != null)
                {
                    trans.Invoke(this, uploaded);
                }
            }
            break;

            case idUploadCompleted:
            {
                DUpload upl = null;
                lock (m_csFile)
                {
                    if (m_vContext.Count > 0)
                    {
                        if (m_vContext[0].File != null)
                        {
                            upl = m_vContext[0].Upload;
                        }
                        else
                        {
                            m_vContext[0].QueueOk = false;
                            m_vContext[0].Sent    = false;
                            CloseFile(m_vContext[0]);
                        }
                    }
                }
                if (upl != null)
                {
                    upl.Invoke(this, 0, "");
                }
                lock (m_csFile)
                {
                    if (m_vContext.Count > 0)
                    {
                        if (m_vContext[0].File != null)
                        {
                            CloseFile(m_vContext.RemoveFromFront());
                        }
                    }
                }
                OnPostProcessing(0, 0);
            }
            break;

            default:
                base.OnResultReturned(reqId, mc);
                break;
            }
        }