Beispiel #1
0
        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
                }
            }
        }
Beispiel #2
0
            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);
            }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
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;
            }
        }
Beispiel #6
0
            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);
            }
Beispiel #7
0
            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);
            }
Beispiel #8
0
            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);
            }
Beispiel #9
0
 public bool SendRequest(ushort reqId, DAsyncResultHandler ash, DDiscarded discarded, DOnExceptionFromServer exception)
 {
     return(SendRequest(reqId, (byte[])null, (uint)0, ash, discarded, exception));
 }
Beispiel #10
0
 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));
 }
Beispiel #11
0
 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));
 }
Beispiel #12
0
 public CResultCb(DAsyncResultHandler rh, DDiscarded d, DOnExceptionFromServer ex)
 {
     AsyncResultHandler  = rh;
     Discarded           = d;
     ExceptionFromServer = ex;
 }