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); }
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; } }