protected override void OnPostProcessing(uint hint, ulong data) { CContext ctx = null; CClientSocket cs = AttachedClientSocket; lock (m_csFile) { if (m_vContext.Count > 0) { CContext context = m_vContext[0]; if (context.Uploading) { OpenLocalRead(context); } else { OpenLocalWrite(context); } DAsyncResultHandler rh = null; DOnExceptionFromServer se = null; if (context.HasError) { ctx = context; } else if (context.Uploading) { if (!SendRequest(idUpload, context.FilePath, context.Flags, context.FileSize, rh, context.Discarded, se)) { ctx = context; context.ErrCode = cs.ErrorCode; context.ErrMsg = cs.ErrorMsg; } } else { if (!SendRequest(idDownload, context.LocalFile, context.FilePath, context.Flags, context.InitSize, rh, context.Discarded, se)) { ctx = context; context.ErrCode = cs.ErrorCode; context.ErrMsg = cs.ErrorMsg; } } } } if (ctx == null) { return; } if (ctx.Download != null) { ctx.Download(this, ctx.ErrCode, ctx.ErrMsg); } lock (m_csFile) { CloseFile(m_vContext.RemoveFromFront()); if (m_vContext.Count > 0) { ClientCoreLoader.PostProcessing(AttachedClientSocket.Handle, 0, 0); AttachedClientSocket.DoEcho(); //make sure WaitAll works correctly } } }
public static DOnExceptionFromServer get_se <R>(TaskCompletionSource <R> tcs) { DOnExceptionFromServer se = (sender, rid, errMessage, errWhere, errCode) => { tcs.TrySetException(new CServerError(errCode, errMessage, errWhere, rid)); }; return(se); }
private bool Transfer() { int index = 0; DAsyncResultHandler rh = null; DOnExceptionFromServer se = null; CClientSocket cs = AttachedClientSocket; if (!cs.Sendable) { return(false); } uint sent_buffer_size = cs.BytesInSendingBuffer; if (sent_buffer_size > 3 * STREAM_CHUNK_SIZE) { return(true); } while (index < m_vContext.Count) { CContext context = m_vContext[index]; if (context.Sent) { ++index; continue; } if (context.Uploading && context.Tried && context.File == null) { if (index == 0) { if (context.Upload != null) { context.Upload(this, CANNOT_OPEN_LOCAL_FILE_FOR_READING, context.ErrMsg); } m_vContext.RemoveFromFront(); } else { ++index; } continue; } if (context.Uploading) { if (!context.Tried) { context.Tried = true; try { FileShare fs = FileShare.None; if ((context.Flags & FILE_OPEN_SHARE_READ) == FILE_OPEN_SHARE_READ) { fs = FileShare.Read; } context.File = new FileStream(context.LocalFile, FileMode.Open, FileAccess.Read, fs); context.FileSize = context.File.Length; IClientQueue cq = AttachedClientSocket.ClientQueue; if (cq.Available) { if (!cq.StartJob()) { context.File.Close(); context.File = null; throw new Exception("Cannot start queue job"); } } if (!SendRequest(idUpload, context.FilePath, context.Flags, context.FileSize, rh, context.Discarded, se)) { return(false); } } catch (Exception err) { context.ErrMsg = err.Message; } finally { } } if (context.File == null) { if (index == 0) { if (context.Upload != null) { context.Upload(this, CANNOT_OPEN_LOCAL_FILE_FOR_READING, context.ErrMsg); } m_vContext.RemoveFromFront(); } else { ++index; } continue; } else { using (CScopeUQueue sb = new CScopeUQueue()) { if (sb.UQueue.MaxBufferSize < STREAM_CHUNK_SIZE) { sb.UQueue.Realloc(STREAM_CHUNK_SIZE); } byte[] buffer = sb.UQueue.IntenalBuffer; int ret = context.File.Read(buffer, 0, (int)STREAM_CHUNK_SIZE); while (ret > 0) { if (!SendRequest(idUploading, buffer, (uint)ret, rh, context.Discarded, se)) { return(false); } sent_buffer_size = cs.BytesInSendingBuffer; if (ret < (int)STREAM_CHUNK_SIZE) { break; } if (sent_buffer_size >= 5 * STREAM_CHUNK_SIZE) { break; } ret = context.File.Read(buffer, 0, (int)STREAM_CHUNK_SIZE); } if (ret < (int)STREAM_CHUNK_SIZE) { context.Sent = true; if (!SendRequest(idUploadCompleted, rh, context.Discarded, se)) { return(false); } IClientQueue cq = AttachedClientSocket.ClientQueue; if (cq.Available) { cq.EndJob(); } } if (sent_buffer_size >= 4 * STREAM_CHUNK_SIZE) { break; } } } } else { if (!SendRequest(idDownload, context.FilePath, context.Flags, rh, context.Discarded, se)) { return(false); } context.Sent = true; context.Tried = true; sent_buffer_size = cs.BytesInSendingBuffer; if (sent_buffer_size > 3 * STREAM_CHUNK_SIZE) { break; } } ++index; } return(true); }
public virtual bool Download(string localFile, string remoteFile, DDownload dl, DTransferring trans, DDiscarded discarded, uint flags, DOnExceptionFromServer se) { if (localFile == null || localFile.Length == 0) { throw new ArgumentException("localFile cannot be empty"); } if (remoteFile == null || remoteFile.Length == 0) { throw new ArgumentException("remoteFile cannot be empty"); } CContext context = new CContext(false, flags); context.Download = dl; context.Transferring = trans; context.Discarded = discarded; context.FilePath = remoteFile; context.LocalFile = localFile; context.Se = se; lock (m_csFile) { m_vContext.AddToBack(context); uint filesOpened = GetFilesOpened(); if (m_MaxDownloading > filesOpened) { ClientCoreLoader.PostProcessing(Socket.Handle, 0, 0); if (filesOpened == 0) { Socket.DoEcho(); //make sure WaitAll works correctly } } } return(true); }
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; } }
public virtual bool SendRequest(ushort reqId, byte[] data, uint len, DAsyncResultHandler ash, DDiscarded discarded, DOnExceptionFromServer exception) { bool sent; byte batching; MyKeyValue <ushort, CResultCb> kv; if (reqId <= (ushort)tagBaseRequestID.idReservedTwo) { throw new ArgumentException("Request id must be larger than 0x2001"); } if (null == m_ClientSocket) { return(false); } IntPtr h = m_ClientSocket.Handle; if (data != null && len > (uint)data.Length) { len = (uint)data.Length; } if (ash != null || discarded != null || exception != null) { CResultCb rcb = new CResultCb(ash, discarded, exception); kv = new MyKeyValue <ushort, CResultCb>(reqId, rcb); batching = ClientCoreLoader.IsBatching(h); lock (m_csSend) { lock (m_cs) { if (batching != 0) { m_kvBatching.AddToBack(kv); } else { m_kvCallback.AddToBack(kv); } } unsafe { fixed(byte *buffer = data) { sent = (ClientCoreLoader.SendRequest(h, reqId, buffer, len) != 0); } } } } else { kv = null; batching = 0; unsafe { fixed(byte *buffer = data) { sent = (ClientCoreLoader.SendRequest(h, reqId, buffer, len) != 0); } } } if (sent) { return(true); } if (kv != null) { lock (m_cs) { if (batching > 0) { m_kvBatching.Clear(); } else { m_kvCallback.Clear(); } } } return(false); }
public bool SendRequest <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(ushort reqId, T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, DAsyncResultHandler ash, DDiscarded discarded, DOnExceptionFromServer exception) { CUQueue su = CScopeUQueue.Lock(); su.Save(t0).Save(t1).Save(t2).Save(t3).Save(t4).Save(t5).Save(t6).Save(t7).Save(t8).Save(t9); bool ok = SendRequest(reqId, su, ash, discarded, exception); CScopeUQueue.Unlock(su); return(ok); }
public bool SendRequest <T0, T1, T2, T3>(ushort reqId, T0 t0, T1 t1, T2 t2, T3 t3, DAsyncResultHandler ash, DDiscarded discarded, DOnExceptionFromServer exception) { CUQueue su = CScopeUQueue.Lock(); su.Save(t0).Save(t1).Save(t2).Save(t3); bool ok = SendRequest(reqId, su, ash, discarded, exception); CScopeUQueue.Unlock(su); return(ok); }
public bool SendRequest(ushort reqId, DAsyncResultHandler ash, DDiscarded discarded, DOnExceptionFromServer exception) { return(SendRequest(reqId, (byte[])null, (uint)0, ash, discarded, exception)); }
public virtual bool SendRequest(ushort reqId, CScopeUQueue q, DAsyncResultHandler ash, DDiscarded discarded, DOnExceptionFromServer exception) { if (q == null) { return(SendRequest(reqId, ash, discarded, exception)); } return(SendRequest(reqId, q.UQueue, ash, discarded, exception)); }
public virtual bool SendRequest(ushort reqId, CUQueue q, DAsyncResultHandler ash, DDiscarded discarded, DOnExceptionFromServer exception) { if (q == null) { return(SendRequest(reqId, ash, discarded, exception)); } if (q.HeadPosition > 0) { return(SendRequest(reqId, q.GetBuffer(), q.GetSize(), ash, discarded, exception)); } return(SendRequest(reqId, q.m_bytes, q.GetSize(), ash, discarded, exception)); }
public CResultCb(DAsyncResultHandler rh, DDiscarded d, DOnExceptionFromServer ex) { AsyncResultHandler = rh; Discarded = d; ExceptionFromServer = ex; }