예제 #1
0
        /// <summary>
        /// 头部写入请求
        /// </summary>
        /// <param name="index"></param>
        internal WriteRequest(int index)
        {
            this.OnWrite = AutoCSer.Net.TcpServer.ServerCallback <ulong> .Null.Default;
            SubBuffer.Pool.GetPool(AutoCSer.Memory.BufferSize.Byte256).Get(ref Buffer);
            fixed(byte *bufferFixed = Buffer.GetFixedBuffer())
            {
                byte *start = bufferFixed + Buffer.StartIndex;

                *(int *)start = Common.PuzzleValue;
                *(int *)(start + sizeof(int))     = (int)AutoCSer.IO.FileHead.DiskBlockFile;
                *(int *)(start + sizeof(int) * 2) = index;
            }

            Size = sizeof(int) * 2;
        }
예제 #2
0
        private unsafe AppendBuffer getAppendBuffer(ref valueType value, BinarySerializer serializer, ref SubBuffer.PoolBufferFull buffer, out int size)
        {
            fixed(byte *bufferFixed = buffer.GetFixedBuffer())
            {
                byte *start = bufferFixed + buffer.StartIndex;

                serializer.SerializeNotNull(ref value, start, buffer.PoolBuffer.Pool.Size, ClientConfig.BinarySerializeConfig);
                size = serializer.Stream.Data.CurrentIndex;
                if (serializer.Stream.Data.Data == start)
                {
                    return new AppendBuffer {
                               Buffer = new SubArray <byte> {
                                   Array = buffer.Buffer, Start = buffer.StartIndex, Length = size
                               }, Index = size == Size ? Index : 0
                    }
                }
                ;
                else
                {
                    return new AppendBuffer {
                               Buffer = new SubArray <byte> {
                                   Array = serializer.Stream.Data.GetArray(), Length = size
                               }, Index = size == Size ? Index : 0
                    }
                };
            }
        }
    }
예제 #3
0
        /// <summary>
        /// 文件尾部错误备份
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="nextLength"></param>
        /// <param name="index"></param>
        /// <param name="count"></param>
        private void endError(ref SubBuffer.PoolBufferFull buffer, long nextLength, int index, int count)
        {
            if (!Config.IsIgnoreFileEndError)
            {
                throw new InvalidDataException();
            }
            FileLength -= nextLength + count;
            using (FileStream endFileStream = new FileStream(FileName + ".ERROR" + Version.toString() + "_" + FileLength.toString(), FileMode.Create, FileAccess.Write, FileShare.None, bufferPool.Size, FileOptions.None))
            {
                endFileStream.Write(buffer.Buffer, buffer.StartIndex + index, count);
                while (nextLength != 0)
                {
                    count = fileStream.Read(buffer.Buffer, buffer.StartIndex, buffer.Length);
                    endFileStream.Write(buffer.Buffer, buffer.StartIndex, count);
                    nextLength -= count;
                }
            }
            fileStream.Seek(sizeof(int) * 2, SeekOrigin.Begin);

            fixed(byte *bufferFixed = buffer.GetFixedBuffer()) * (ulong *)(bufferFixed + (buffer.StartIndex + sizeof(int) * 2)) = ++Version;

            fileStream.Write(buffer.Buffer, buffer.StartIndex + sizeof(int) * 2, sizeof(ulong));
            fileStream.SetLength(FileLength);
            fileStream.Flush(true);
            fileStream.Seek(0, SeekOrigin.End);
            IsDisposed = 0;
        }
예제 #4
0
        /// <summary>
        /// 解析压缩数据
        /// </summary>
        /// <param name="compressionBuffer"></param>
        /// <param name="dataSize"></param>
        /// <returns></returns>
        private bool load(ref SubBuffer.PoolBufferFull compressionBuffer, int dataSize)
        {
            if (compressionBuffer.Buffer == null)
            {
                return(false);
            }
            int bufferIndex = compressionBuffer.StartIndex, bufferSize = bufferIndex + dataSize;

            fixed(byte *bigBufferFixed = compressionBuffer.GetFixedBuffer())
            {
                do
                {
                    if (dataFileIdentity == writeIdentity)
                    {
                        bufferIndex += messages[writeMessageIndex].DeSerializeBuffer(bigBufferFixed + bufferIndex, compressionBuffer.Buffer, bufferIndex);
                        nextWriteIndex();
                    }
                    else
                    {
                        bufferIndex += messages[writeMessageIndex].Data.DeSerializeBuffer(bigBufferFixed + bufferIndex, compressionBuffer.Buffer, bufferIndex);
                    }
                    ++dataFileIdentity;
                }while (bufferIndex < bufferSize);
            }

            compressionBuffer.Free();
            return(bufferIndex == bufferSize);
        }
예제 #5
0
        /// <summary>
        /// 写入状态
        /// </summary>
        /// <param name="buffer"></param>
        private void writeState(ref SubBuffer.PoolBufferFull buffer)
        {
            fixed(byte *stateBufferFixed = buffer.GetFixedBuffer())
            {
                byte *start = stateBufferFixed + buffer.StartIndex;

                *(ulong *)start = identity;
                *(long *)(start + sizeof(ulong)) = dataFileLength;
            }

            if (stateFileStream.Length >= MaxStateFileSize)
            {
                stateFileStream.Dispose();
                stateFileStream = null;
                FileInfo bakFile = new FileInfo(stateBackupFileName);
                if (bakFile.Exists)
                {
                    bakFile.Delete();
                }
                System.IO.File.Move(stateFileName, stateBackupFileName);
                stateFileStream = new FileStream(stateFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, stateBufferSize, FileOptions.None);
            }
            stateFileStream.Write(buffer.Buffer, buffer.StartIndex, stateBufferSize);
            stateFileStream.Flush(true);
            StatePacketIndex.Set(identity, dataFileLength);
        }
예제 #6
0
 /// <summary>
 /// 设置输出数据
 /// </summary>
 /// <param name="value"></param>
 /// <param name="isAscii"></param>
 /// <param name="encoding"></param>
 internal unsafe void SetBody(string value, bool isAscii, ref EncodingCache encoding)
 {
     if (value.Length == 0)
     {
         SetBody();
     }
     else
     {
         freeBody();
         if (isAscii && encoding.IsCompatibleAscii != 0)
         {
             int size = value.Length;
             AutoCSer.SubBuffer.Pool.GetBuffer(ref SubBuffer, size);
             fixed(char *textFixed = value)
             fixed(byte *bufferFixed = SubBuffer.GetFixedBuffer())
             {
                 if (SubBuffer.PoolBuffer.Pool == null)
                 {
                     Body.Array = SubBuffer.Buffer;
                     AutoCSer.Extensions.StringExtension.WriteBytes(textFixed, size, bufferFixed);
                     SubBuffer.Buffer = null;
                     Type             = ResponseType.ByteArray;
                 }
                 else
                 {
                     Body.Set(SubBuffer.Buffer, SubBuffer.StartIndex, size);
                     AutoCSer.Extensions.StringExtension.WriteBytes(textFixed, size, bufferFixed + Body.Start);
                     Type = ResponseType.SubBuffer;
                 }
             }
         }
         else
         {
             int size = encoding.GetByteCountNotNull(value);
             AutoCSer.SubBuffer.Pool.GetBuffer(ref SubBuffer, size);
             if (SubBuffer.PoolBuffer.Pool == null)
             {
                 encoding.WriteBytesNotEmpty(value, Body.Array = SubBuffer.Buffer);
                 SubBuffer.Buffer = null;
                 Type             = ResponseType.ByteArray;
             }
             else
             {
                 Body.Set(SubBuffer.Buffer, SubBuffer.StartIndex, size);
                 encoding.WriteBytesNotEmpty(value, Body.Array, Body.Start);
                 Type = ResponseType.SubBuffer;
             }
         }
     }
 }
예제 #7
0
파일: Sign.cs 프로젝트: AutoCSer/AutoCSer
        /// <summary>
        /// 字节拼接
        /// </summary>
        /// <param name="values"></param>
        /// <param name="buffer"></param>
        /// <param name="length"></param>
        /// <param name="key"></param>
        private unsafe static void concat(string[] values, ref SubBuffer.PoolBufferFull buffer, int length, string key)
        {
            fixed(byte *bufferFixed = buffer.GetFixedBuffer())
            {
                byte *    write = bufferFixed + buffer.StartIndex, end = write + length;
                int       isValue = 0, index = 0;
                MemoryMap utf8Map = new MemoryMap(isUtf8.Byte);

                foreach (string name in names)
                {
                    string valueString = values[index];
                    if (!string.IsNullOrEmpty(valueString))
                    {
                        if (isValue == 0)
                        {
                            isValue = 1;
                        }
                        else
                        {
                            *write++ = (byte)'&';
                            fixed(char *nameFixed = name) AutoCSer.Extensions.StringExtension.WriteBytes(nameFixed, name.Length, write);

                            write   += name.Length;
                            *write++ = (byte)'=';
                            fixed(char *valueFixed = valueString)
                            {
                                if (utf8Map.Get(index) == 0)
                                {
                                    AutoCSer.Extensions.StringExtension.WriteBytes(valueFixed, valueString.Length, write);
                                    write += valueString.Length;
                                }
                                else
                                {
                                    write += System.Text.Encoding.UTF8.GetBytes(valueFixed, valueString.Length, write, (int)(end - write));
                                }
                            }
                    }
                    ++index;
                }
                if (isValue != 0)
                {
                    *write++ = (byte)'&';
                }
                *(int *)write = 'k' + ('e' << 8) + ('y' << 16) + ('=' << 24);
                write        += sizeof(int);

                fixed(char *keyFixed = key) AutoCSer.Extensions.StringExtension.WriteBytes(keyFixed, key.Length, write);
            }
        }
예제 #8
0
        /// <summary>
        /// 创建文件流
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="version"></param>
        private void create(ref SubBuffer.PoolBufferFull buffer, ulong version)
        {
            if (buffer.Buffer == null)
            {
                bufferPool.Get(ref buffer);
                fixed(byte *bufferFixed = buffer.GetFixedBuffer())
                {
                    byte *bufferStart = bufferFixed + buffer.StartIndex;

                    *(int *)bufferStart = FileHeader;
                    *(ulong *)(bufferStart + sizeof(int) * 2) = Version;
                }

                fileStream.Write(buffer.Buffer, buffer.StartIndex, fileHeaderSize);
                FileLength = fileHeaderSize;
                IsDisposed = 0;
        }
예제 #9
0
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="md5"></param>
        /// <param name="value"></param>
        /// <param name="randomPrefix"></param>
        /// <param name="ticks"></param>
        /// <returns></returns>
        internal static byte[] Md5(MD5CryptoServiceProvider md5, string value, ulong randomPrefix, long ticks)
        {
            SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull);
            SubBuffer.Pool.GetBuffer(ref buffer, (value.Length << 1) + (sizeof(ulong) + sizeof(long)));
            try
            {
                fixed(char *valueFixed = value)
                fixed(byte *dataFixed = buffer.GetFixedBuffer())
                {
                    byte *start = dataFixed + buffer.StartIndex;

                    *(ulong *)start = randomPrefix;
                    *(long *)(start + sizeof(ulong)) = ticks;
                    AutoCSer.Extensions.StringExtension.SimpleCopyNotNull64(valueFixed, (char *)(start + (sizeof(ulong) + sizeof(long))), value.Length);
                }
                return(md5.ComputeHash(buffer.Buffer, buffer.StartIndex, (value.Length << 1) + (sizeof(ulong) + sizeof(long))));
            }
            finally { buffer.PoolBuffer.Free(); }
        }
예제 #10
0
        /// <summary>
        /// 写入数据包索引信息
        /// </summary>
        /// <param name="buffer"></param>
        private void writeIndex(ref SubBuffer.PoolBufferFull buffer)
        {
            if (indexs.Length > 1)
            {
                FileInfo indexFileInfo = new FileInfo(getIndexFileName(identity - 1));
                if (indexFileInfo.Exists)
                {
                    indexFileInfo.Delete();
                }
                using (FileStream indexFileStream = new FileStream(indexFileInfo.FullName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None))
                {
                    int count = indexs.Length;
                    fixed(byte *bufferFixed = buffer.GetFixedBuffer())
                    {
                        byte *bufferStart = bufferFixed + buffer.StartIndex, write = bufferStart, end = bufferStart + buffer.Length;
                        long  fileIndex = 0;

                        foreach (PacketIndex index in indexs.Array)
                        {
                            *(uint *)write = index.FileIdentity;
                            *(int *)(write + sizeof(int)) = (int)(index.FileIndex - fileIndex);
                            write    += sizeof(int) * 2;
                            fileIndex = index.FileIndex;
                            if (write == end)
                            {
                                indexFileStream.Write(buffer.Buffer, buffer.StartIndex, buffer.Buffer.Length);
                                write = bufferStart;
                            }
                            if (--count == 0)
                            {
                                break;
                            }
                        }
                        if ((count = (int)(write - bufferStart)) != 0)
                        {
                            indexFileStream.Write(buffer.Buffer, buffer.StartIndex, count);
                        }
                    }
                }
                indexs.Array[0].Set(baseIdentity);
                indexs.Length = 1;
            }
        }
예제 #11
0
        /// <summary>
        /// 获取商品二维码URL
        /// </summary>
        /// <param name="product_id"></param>
        /// <returns></returns>
        public unsafe string GetProductUrl(string product_id)
        {
            ProductUrlSign sign = new ProductUrlSign {
                product_id = product_id
            };

            sign.setConfig(this);
            SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull);
            int length = Sign <ProductUrlSign> .GetData(sign, key, ref buffer);

            try
            {
                fixed(byte *bufferFixed = buffer.GetFixedBuffer())
                {
                    using (MD5 md5 = new MD5CryptoServiceProvider())
                    {
                        return("weixin://wxpay/bizpayurl?" + MemoryExtensionWebClient.BytesToStringNotEmpty(bufferFixed + buffer.StartIndex, length) + "&sign=" + sign.sign);
                    }
                }
            }
            finally { buffer.Free(); }
        }
예제 #12
0
        /// <summary>
        /// HTTP 响应头部输出
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private bool responseHeader(ref Response response)
        {
            try
            {
                if (!response.IsFile)
                {
                    ResponseError(ResponseState.NotFound404);
                    return true;
                }
                System.Net.Sockets.Socket socket;
                ResponseFlag responseFlag = response.Flag;
                if (response.Body.Length != 0 && Header.IsKeepAlive != 0 && (responseFlag & ResponseFlag.HeaderSize) != 0 && Header.IsRange == 0 && Header.Method != MethodType.HEAD)
                {
                    if ((socket = Socket) == null) return false;
                    Data = response.Body;
                    Data.MoveStart(-response.HeaderSize);
                    SendType = SendType.Next;
                    Timeout = Config.GetTimeout(Data.Length);
#if DOTNET2
                    SocketError socketError;
                    IAsyncResult async = socket.BeginSend(Data.Array, Data.Start, Data.Length, SocketFlags.None, out socketError, onSendAsyncCallback, socket);
                    if (socketError == SocketError.Success)
                    {
                        if (!async.CompletedSynchronously) Http.Header.ReceiveTimeout.Push(this, socket);
                        return true;
                    }
                    return false;
#else
                    sendAsyncLock.EnterSleepFlag();
                    sendAsyncEventArgs.SetBuffer(Data.Array, Data.Start, Data.Length);
                    if (socket.SendAsync(sendAsyncEventArgs))
                    {
                        sendAsyncLock.SleepFlag = 0;
                        Http.Header.ReceiveTimeout.Push(this, socket);
                        sendAsyncLock.Exit();
                        return true;
                    }
                    sendAsyncLock.ExitSleepFlag();
                    if (--sendDepth == 0)
                    {
                        sendDepth = maxSendDepth;
                        OnSendThreadArray.Default.CurrentThread.Add(this);
                        return true;
                    }
                    return onSend();
#endif
                }
                ResponseSize = response.BodySize;
                fixed (byte* headerBufferFixed = Header.Buffer.GetFixedBuffer())
                {
                    byte* responseSizeFixed = headerBufferFixed + (Header.Buffer.StartIndex + Http.Header.ReceiveBufferSize);
                    RangeLength responseSizeIndex, bodySizeIndex = new RangeLength(), rangeStartIndex = new RangeLength(), rangeEndIndex = new RangeLength();
                    ResponseState state = response.ResponseState;
                    if (Header.IsRange != 0 && (responseFlag & ResponseFlag.IsPool) != 0)
                    {
                        if (Header.IsFormatRange != 0 || Header.FormatRange(ResponseSize))
                        {
                            if (state == ResponseState.Ok200)
                            {
                                long rangeStart = Header.RangeStart, rangeEnd = Header.RangeEnd;
                                rangeStartIndex = NumberExtension.ToBytes((ulong)rangeStart, responseSizeFixed + 20 * 2);
                                rangeEndIndex = NumberExtension.ToBytes((ulong)rangeEnd, responseSizeFixed + 20 * 3);
                                bodySizeIndex = NumberExtension.ToBytes((ulong)ResponseSize, responseSizeFixed + 20);
                                response.State = state = ResponseState.PartialContent206;
                                ResponseSize = Header.RangeSize;
                            }
                        }
                        else
                        {
                            ResponseSize = 0;
                            ResponseError(ResponseState.RangeNotSatisfiable416);
                            return true;
                        }
                    }
                    if ((ulong)ResponseSize < 10)
                    {
                        *responseSizeFixed = (byte)((int)ResponseSize + '0');
                        responseSizeIndex = new RangeLength(0, 1);
                    }
                    else responseSizeIndex = NumberExtension.ToBytes((ulong)ResponseSize, responseSizeFixed);
                    ResponseStateAttribute stateAttribute = EnumAttribute<ResponseState, ResponseStateAttribute>.Array((byte)state);
                    if (stateAttribute == null) stateAttribute = EnumAttribute<ResponseState, ResponseStateAttribute>.Array((byte)ResponseState.ServerError500);
                    int index = httpVersionSize + stateAttribute.Text.Length + contentLengthSize + responseSizeIndex.Length + 2 + 2;
                    if (state == ResponseState.PartialContent206)
                    {
                        index += rangeSize + rangeStartIndex.Length + rangeEndIndex.Length + bodySizeIndex.Length + 2 + 2;
                    }
                    Cookie cookie = null;
                    SubBuffer.PoolBufferFull buffer = GetBuffer(index = GetResponseHeaderIndex(response, index, ref cookie));
                    fixed (byte* bufferFixed = buffer.GetFixedBuffer())
                    {
                        byte* bufferStart = bufferFixed + buffer.StartIndex, write = bufferStart + httpVersionSize;
                        writeHttpVersion(bufferStart);
                        stateAttribute.Write(write);
                        writeContentLength(write += stateAttribute.Text.Length);
                        AutoCSer.Memory.Common.SimpleCopyNotNull64(responseSizeFixed + responseSizeIndex.Start, write += contentLengthSize, responseSizeIndex.Length);
                        *(short*)(write += responseSizeIndex.Length) = 0x0a0d;
                        write += sizeof(short);
                        if (state == ResponseState.PartialContent206)
                        {
                            writeRange(write);
                            AutoCSer.Memory.Common.SimpleCopyNotNull64(responseSizeFixed + (rangeStartIndex.Start + 20 * 2), write += rangeSize, rangeStartIndex.Length);
                            *(write += rangeStartIndex.Length) = (byte)'-';
                            AutoCSer.Memory.Common.SimpleCopyNotNull64(responseSizeFixed + (rangeEndIndex.Start + 20 * 3), ++write, rangeEndIndex.Length);
                            *(write += rangeEndIndex.Length) = (byte)'/';
                            AutoCSer.Memory.Common.SimpleCopyNotNull64(responseSizeFixed + (bodySizeIndex.Start + 20), ++write, bodySizeIndex.Length);
                            *(short*)(write += bodySizeIndex.Length) = 0x0a0d;
                            write += sizeof(short);
                        }
                        index = (int)(CreateResponseHeader(response, cookie, write, index) - bufferStart);
                        //                    if (checkIndex != index)
                        //                    {
                        //                        Server.RegisterServer.TcpServer.Log.add(Log.Type.Fatal, "responseHeader checkIndex[" + checkIndex.toString() + "] != index[" + index.toString() + @"]
                        //" + System.Text.Encoding.ASCII.GetString(buffer.Buffer, buffer.StartIndex, index));
                        //                    }
                        if (ResponseSize != 0)
                        {
                            switch (response.Type)
                            {
                                case ResponseType.ByteArray:
                                    if (buffer.Length - index >= (int)ResponseSize)
                                    {
                                        System.Buffer.BlockCopy(response.Body.Array, state == ResponseState.PartialContent206 ? (int)Header.RangeStart : 0, buffer.Buffer, buffer.StartIndex + index, (int)ResponseSize);
                                        index += (int)ResponseSize;
                                        ResponseSize = 0;
                                    }
                                    break;
                                case ResponseType.SubByteArray:
                                    if (Header.IsKeepAlive != 0 && (responseFlag & ResponseFlag.CanHeaderSize) != 0 && index <= response.Body.Start && Header.IsRange == 0)
                                    {
                                        if ((socket = Socket) == null) return false;
                                        fixed (byte* bodyFixed = response.Body.GetFixedBuffer()) AutoCSer.Memory.Common.CopyNotNull(bufferStart, bodyFixed + response.Body.Start - index, index);
                                        response.SetHeaderSize(index);

                                        Data = response.Body;
                                        Data.MoveStart(-response.HeaderSize);
                                        SendType = SendType.Next;
                                        Timeout = Config.GetTimeout(Data.Length);
#if DOTNET2
                                    SocketError socketError;
                                    IAsyncResult async = socket.BeginSend(Data.Array, Data.Start, Data.Length, SocketFlags.None, out socketError, onSendAsyncCallback, socket);
                                    if (socketError == SocketError.Success)
                                    {
                                        if (!async.CompletedSynchronously) Http.Header.ReceiveTimeout.Push(this, socket);
                                        return true;
                                    }
                                    return false;
#else
                                        sendAsyncLock.EnterSleepFlag();
                                        sendAsyncEventArgs.SetBuffer(Data.Array, Data.Start, Data.Length);
                                        if (socket.SendAsync(sendAsyncEventArgs))
                                        {
                                            sendAsyncLock.SleepFlag = 0;
                                            Http.Header.ReceiveTimeout.Push(this, socket);
                                            sendAsyncLock.Exit();
                                            return true;
                                        }
                                        sendAsyncLock.ExitSleepFlag();
                                        if (--sendDepth == 0)
                                        {
                                            sendDepth = maxSendDepth;
                                            OnSendThreadArray.Default.CurrentThread.Add(this);
                                            return true;
                                        }
                                        return onSend();
#endif
                                    }
                                    goto COPY;
                                case ResponseType.SubBuffer:
                                    COPY:
                                    if (buffer.Length - index >= (int)ResponseSize)
                                    {
                                        System.Buffer.BlockCopy(response.Body.Array, state == ResponseState.PartialContent206 ? response.Body.Start + (int)Header.RangeStart : response.Body.Start, buffer.Buffer, buffer.StartIndex + index, (int)ResponseSize);
                                        index += (int)ResponseSize;
                                        ResponseSize = 0;
                                    }
                                    break;
                            }
                        }
                    }
                    if ((socket = Socket) != null)
                    {
                        if (ResponseSize == 0) SendType = SendType.Next;
                        else
                        {
                            this.HttpResponse = response;
                            SendType = SendType.Body;
                            response = null;
                        }
                        Data.Set(buffer.Buffer, buffer.StartIndex, index);
                        Timeout = Config.GetTimeout(Data.Length);
#if DOTNET2
                    SocketError socketError;
                    IAsyncResult async = socket.BeginSend(Data.Array, Data.Start, index, SocketFlags.None, out socketError, onSendAsyncCallback, socket);
                    if (socketError == SocketError.Success)
                    {
                        if (!async.CompletedSynchronously) Http.Header.ReceiveTimeout.Push(this, socket);
                        return true;
                    }
                    return false;
#else
                        sendAsyncLock.EnterSleepFlag();
                        sendAsyncEventArgs.SetBuffer(Data.Array, Data.Start, index);
                        if (socket.SendAsync(sendAsyncEventArgs))
                        {
                            sendAsyncLock.SleepFlag = 0;
                            Http.Header.ReceiveTimeout.Push(this, socket);
                            sendAsyncLock.Exit();
                            return true;
                        }
                        sendAsyncLock.ExitSleepFlag();
                        if (--sendDepth == 0)
                        {
                            sendDepth = maxSendDepth;
                            OnSendThreadArray.Default.CurrentThread.Add(this);
                            return true;
                        }
                        return onSend();
#endif
                    }
                }
            }
            catch (Exception error)
            {
                Server.RegisterServer.TcpServer.Log.Exception(error, null, LogLevel.Exception | LogLevel.AutoCSer);
            }
            finally { Http.Response.Push(ref response); }
            return false;
        }
예제 #13
0
        /// <summary>
        /// 接收数据
        /// </summary>
        /// <typeparam name="outputParameterType"></typeparam>
        /// <param name="commandInfo"></param>
        /// <param name="outputParameter"></param>
        /// <param name="clientBuffer"></param>
        private unsafe void receive <outputParameterType>(TcpServer.CommandInfoBase commandInfo, ref outputParameterType outputParameter, ref ClientBuffer clientBuffer)
            where outputParameterType : struct
        {
            int compressionDataSize, dataSize = 0, nextSize, receiveSize = Socket.Receive(Buffer.Buffer, Buffer.StartIndex, Buffer.Length, SocketFlags.None, out clientBuffer.SocketError);

            ++ReceiveCount;
            if (receiveSize >= sizeof(int) * 2)
            {
                fixed(byte *bufferFixed = Buffer.GetFixedBuffer())
                {
                    byte *start = bufferFixed + Buffer.StartIndex;

                    if ((compressionDataSize = *(int *)start) > 0)
                    {
                        if ((nextSize = compressionDataSize + sizeof(int) - receiveSize) == 0)
                        {
                            clientBuffer.IsError = false;
                            if (ReceiveMarkData != 0)
                            {
                                Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int), compressionDataSize);
                            }
                            clientBuffer.SetReceiveData(ref Buffer, compressionDataSize);
                            deSerialize(commandInfo, ref outputParameter, ref clientBuffer);
                            return;
                        }
                        if (nextSize > 0 && clientBuffer.SocketError == SocketError.Success)
                        {
                            if (nextSize <= Buffer.Length)
                            {
                                goto RECEIVE;
                            }
                            else
                            {
                                goto BIGBUFFER;
                            }
                        }
                    }
                    else if (compressionDataSize < 0)
                    {
                        if ((compressionDataSize = -compressionDataSize) <= (dataSize = *(int *)(start + sizeof(int))))
                        {
                            if ((nextSize = compressionDataSize + sizeof(int) * 2 - receiveSize) == 0)
                            {
                                clientBuffer.IsError = false;
                                if (ReceiveMarkData != 0)
                                {
                                    Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int) * 2, compressionDataSize);
                                }
                                if (clientBuffer.DeCompressReceiveData(ref Buffer, compressionDataSize, dataSize))
                                {
                                    deSerialize(commandInfo, ref outputParameter, ref clientBuffer);
                                }
                                return;
                            }
                            if (nextSize > 0)
                            {
                                if (nextSize <= Buffer.Length)
                                {
                                    goto RECEIVE;
                                }
                                else
                                {
                                    goto BIGBUFFER;
                                }
                            }
                        }
                    }
                    else if (receiveSize == sizeof(int) * 2)
                    {
                        clientBuffer.ReturnType = (TcpServer.ReturnType)(*(start + sizeof(int)));
                        return;
                    }
                }
            }
            clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError;
            return;

BIGBUFFER:
            clientBuffer.CopyBufferData(ref Buffer, receiveSize + nextSize, receiveSize);
            if (clientBuffer.CopyBuffer.Length > SendBufferMaxSize)
            {
                do
                {
                    int count = Socket.Receive(Buffer.Buffer, Buffer.StartIndex + receiveSize, nextSize, SocketFlags.None, out clientBuffer.SocketError);
                    ++ReceiveCount;
                    if ((nextSize -= count) == 0)
                    {
                        clientBuffer.IsError = false;
                        if (dataSize == 0)
                        {
                            if (ReceiveMarkData != 0)
                            {
                                Mark(clientBuffer.CopyBuffer.Buffer, ReceiveMarkData, clientBuffer.CopyBuffer.StartIndex + sizeof(int), compressionDataSize);
                            }
                            clientBuffer.SetReceiveData(compressionDataSize);
                            deSerialize(commandInfo, ref outputParameter, ref clientBuffer);
                        }
                        else
                        {
                            if (ReceiveMarkData != 0)
                            {
                                Mark(clientBuffer.CopyBuffer.Buffer, ReceiveMarkData, clientBuffer.CopyBuffer.StartIndex + sizeof(int) * 2, compressionDataSize);
                            }
                            if (clientBuffer.DeCompressReceiveData(compressionDataSize, dataSize))
                            {
                                deSerialize(commandInfo, ref outputParameter, ref clientBuffer);
                            }
                        }
                        return;
                    }
                    if (count <= 0 || clientBuffer.SocketError != SocketError.Success)
                    {
                        clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError;
                        return;
                    }
                    receiveSize += count;
                }while (true);
            }
            Buffer.Free();
            clientBuffer.CopyBuffer.CopyToClear(ref Buffer);
RECEIVE:
            do
            {
                int count = Socket.Receive(Buffer.Buffer, Buffer.StartIndex + receiveSize, nextSize, SocketFlags.None, out clientBuffer.SocketError);
                ++ReceiveCount;
                if ((nextSize -= count) == 0)
                {
                    clientBuffer.IsError = false;
                    if (dataSize == 0)
                    {
                        if (ReceiveMarkData != 0)
                        {
                            Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int), compressionDataSize);
                        }
                        clientBuffer.SetReceiveData(ref Buffer, compressionDataSize);
                        deSerialize(commandInfo, ref outputParameter, ref clientBuffer);
                    }
                    else
                    {
                        if (ReceiveMarkData != 0)
                        {
                            Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int) * 2, compressionDataSize);
                        }
                        if (clientBuffer.DeCompressReceiveData(ref Buffer, compressionDataSize, dataSize))
                        {
                            deSerialize(commandInfo, ref outputParameter, ref clientBuffer);
                        }
                    }
                    return;
                }
                if (count <= 0 || clientBuffer.SocketError != SocketError.Success)
                {
                    clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError;
                    return;
                }
                receiveSize += count;
            }while (true);
        }
예제 #14
0
        private static readonly SubBuffer.Pool stringBufferPool = SubBuffer.Pool.GetPool(AutoCSer.Memory.BufferSize.Kilobyte32);//4097 * 8
        /// <summary>
        /// LZW压缩解码
        /// </summary>
        /// <param name="input">输入数据</param>
        /// <param name="output">输出数据缓冲</param>
        /// <param name="size">编码长度</param>
        /// <returns>解码数据长度,失败返回-1</returns>
        private unsafe static int lzwDecode(byte[] input, byte *output, byte size)
        {
            int   tableSize = (int)size + 1;
            short clearIndex = (short)(1 << size), nextIndex = clearIndex;

            SubBuffer.PoolBufferFull stringBuffer = default(SubBuffer.PoolBufferFull);
            stringBufferPool.Get(ref stringBuffer);
            try
            {
                fixed(byte *inputFixed = input, stringFixed = stringBuffer.GetFixedBuffer())
                {
                    byte *nextStrings = null, stringStart = stringFixed + stringBuffer.StartIndex;
                    byte *currentInput = inputFixed, inputEnd = inputFixed + input.Length;
                    byte *currentOutput = output, outputEnd = output + Writer.LzwEncodeTableBufferPool.Size;
                    int   valueBits = 0, inputSize = 0, inputOffset = (int)inputEnd & (sizeof(ulong) - 1), startSize = tableSize;
                    ulong inputValue = 0, inputMark = ushort.MaxValue, startMark = ((ulong)1UL << startSize) - 1;
                    short endIndex = (short)(clearIndex + 1), prefixIndex, currentIndex = 0;

                    if (inputOffset == 0)
                    {
                        inputEnd   -= sizeof(ulong);
                        inputOffset = sizeof(ulong);
                    }
                    else
                    {
                        inputEnd -= inputOffset;
                    }
                    if (size == 1)
                    {
                        ++startSize;
                    }
                    while (currentIndex != endIndex)
                    {
                        if (valueBits >= startSize)
                        {
                            prefixIndex  = (short)(inputValue & startMark);
                            valueBits   -= startSize;
                            inputValue >>= startSize;
                        }
                        else
                        {
                            if (currentInput > inputEnd)
                            {
                                return(-1);
                            }
                            ulong nextValue = *(ulong *)currentInput;
                            prefixIndex = (short)((inputValue | (nextValue << valueBits)) & startMark);
                            inputValue  = nextValue >> -(valueBits -= startSize);
                            valueBits  += sizeof(ulong) << 3;
                            if (currentInput == inputEnd && (valueBits -= (sizeof(ulong) - inputOffset) << 3) < 0)
                            {
                                return(-1);
                            }
                            currentInput += sizeof(ulong);
                        }
                        if (prefixIndex == clearIndex)
                        {
                            continue;
                        }
                        if (prefixIndex == endIndex)
                        {
                            break;
                        }
                        if (currentOutput == outputEnd)
                        {
                            return(-1);
                        }

                        AutoCSer.Memory.Common.Clear((ulong *)stringStart, 4097);
                        inputSize = startSize;
                        inputMark = startMark;
                        nextIndex = (short)(endIndex + 1);
                        *(short *)(nextStrings = stringStart + (nextIndex << 3)) = prefixIndex;
                        *(short *)(nextStrings + 2) = prefixIndex;
                        *(int *)(nextStrings + 4)   = 2;
                        *currentOutput++ = (byte)prefixIndex;
                        do
                        {
                            if (valueBits >= inputSize)
                            {
                                currentIndex = (short)(inputValue & inputMark);
                                valueBits   -= inputSize;
                                inputValue >>= inputSize;
                            }
                            else
                            {
                                if (currentInput > inputEnd)
                                {
                                    return(-1);
                                }
                                ulong nextValue = *(ulong *)currentInput;
                                currentIndex = (short)((inputValue | (nextValue << valueBits)) & inputMark);
                                inputValue   = nextValue >> -(valueBits -= inputSize);
                                valueBits   += sizeof(ulong) << 3;
                                if (currentInput == inputEnd && (valueBits -= (sizeof(ulong) - inputOffset) << 3) < 0)
                                {
                                    return(-1);
                                }
                                currentInput += sizeof(ulong);
                            }
                            *(short *)(nextStrings += 8) = currentIndex;
                            if (currentIndex < clearIndex)
                            {
                                if (currentOutput == outputEnd)
                                {
                                    return(-1);
                                }
                                *(short *)(nextStrings + 2) = currentIndex;
                                *(int *)(nextStrings + 4)   = 2;
                                *currentOutput++ = (byte)currentIndex;
                            }
                            else if (currentIndex > endIndex)
                            {
                                byte *currentString = stringStart + (currentIndex << 3);
                                int   outputCount   = *(int *)(currentString + 4);
                                if (outputCount == 0)
                                {
                                    return(-1);
                                }
                                *(short *)(nextStrings + 2) = *(short *)(currentString + 2);
                                *(int *)(nextStrings + 4)   = outputCount + 1;
                                if ((currentOutput += outputCount) > outputEnd)
                                {
                                    return(-1);
                                }
                                do
                                {
                                    *--currentOutput = *(currentString + 2 + 8);
                                    prefixIndex      = *(short *)currentString;
                                    if (prefixIndex < clearIndex)
                                    {
                                        break;
                                    }
                                    currentString = stringStart + (prefixIndex << 3);
                                }while (true);
                                *--currentOutput = (byte)prefixIndex;
                                currentOutput   += outputCount;
                            }
                            else
                            {
                                break;
                            }
                            prefixIndex = currentIndex;
                            if (nextIndex++ == (short)inputMark)
                            {
                                if (inputSize == 12)
                                {
                                    return(-1);
                                }
                                inputMark <<= 1;
                                ++inputSize;
                                ++inputMark;
                            }
                        }while (true);
                    }
                    return((int)(currentOutput - output));
                }
            }
            finally { stringBufferPool.Push(ref stringBuffer); }
        }
예제 #15
0
        /// <summary>
        /// 获取数据包索引信息
        /// </summary>
        /// <param name="identity">需要定位的数据标识</param>
        /// <param name="startIdentity"></param>
        /// <param name="fileIndex"></param>
        /// <returns></returns>
        internal bool GetIndex(ulong identity, ref ulong startIdentity, ref long fileIndex)
        {
            startIdentity = identity & (ulong.MaxValue - (DataCountPerFile - 1));
            uint fileIdentity = (uint)identity & (DataCountPerFile - 1);

            if (fileIdentity == 0)
            {
                fileIndex = 0;
                return(true);
            }
            ulong baseIdentity = startIdentity;

            if (this.baseIdentity == startIdentity)
            {
                int length = indexs.Length;
                if (length > 1)
                {
                    #region 二分查找当前数据文件数据包索引信息
                    int           start = 0, average;
                    PacketIndex[] indexArray = indexs.Array;
                    do
                    {
                        if (identity > indexArray[average = start + ((length - start) >> 1)].Identity)
                        {
                            start = average + 1;
                        }
                        else
                        {
                            length = average;
                        }
                    }while (start != length);
                    if (identity != indexArray[start].Identity)
                    {
                        --start;
                    }
                    indexArray[start].Get(out startIdentity, out fileIndex);
                    if (this.baseIdentity == baseIdentity)
                    {
                        return(true);
                    }
                    #endregion
                }
            }
            FileInfo dataFileInfo = new FileInfo(GetFileName(identity));
            if (dataFileInfo.Exists && dataFileInfo.Length != 0)
            {
                SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull);
                SubBuffer.Pool.GetBuffer(ref buffer, createIndexBufferSize + sizeof(int));
                try
                {
                    fixed(byte *bufferFixed = buffer.GetFixedBuffer())
                    {
                        byte *bufferStart = bufferFixed + buffer.StartIndex;

                        #region 从索引数据文件获取数据包索引信息
                        FileInfo indexFileInfo = new FileInfo(getIndexFileName(identity));
                        if (indexFileInfo.Exists && indexFileInfo.Length >= sizeof(int) * 2)
                        {
                            uint lastFileIdentity = 0;
                            fileIndex = 0;
                            using (FileStream indexFileStream = new FileStream(indexFileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, createIndexBufferSize, FileOptions.None))
                            {
                                do
                                {
                                    int readSize = indexFileStream.Read(buffer.Buffer, buffer.StartIndex, createIndexBufferSize);
                                    if (readSize <= 0)
                                    {
                                        break;
                                    }
                                    byte *read = bufferStart, end = bufferStart + readSize;
                                    do
                                    {
                                        if (*(uint *)read < fileIdentity)
                                        {
                                            lastFileIdentity = *(uint *)read;
                                            fileIndex       += *(int *)(read + sizeof(int));
                                        }
                                        else
                                        {
                                            if (*(uint *)read == fileIdentity)
                                            {
                                                lastFileIdentity = *(uint *)read;
                                                fileIndex       += *(int *)(read + sizeof(int));
                                            }
                                            startIdentity = baseIdentity + lastFileIdentity;
                                            return(true);
                                        }
                                    }while ((read += sizeof(int) * 2) < end);
                                }while (true);
                            }
                            startIdentity = baseIdentity + lastFileIdentity;
                            return(true);
                        }
                        #endregion

                        #region 从数据文件获取数据包索引信息
                        int bufferIndex = 0, dataSize;
                        fileIndex     = 0;
                        startIdentity = baseIdentity;
                        using (FileStream fileStream = new FileStream(dataFileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, createIndexBufferSize, FileOptions.None))
                        {
                            long nextFileSize = fileStream.Length;
                            do
                            {
                                int endBufferIndex = fileStream.Read(buffer.Buffer, buffer.StartIndex + bufferIndex, createIndexBufferSize - bufferIndex);
                                nextFileSize   -= endBufferIndex;
                                endBufferIndex += bufferIndex - sizeof(int) * 3;
                                bufferIndex     = 0;
                                do
                                {
                                    byte *read = bufferStart + bufferIndex;
                                    dataSize = *(int *)read;
                                    ulong nextIdentity = startIdentity + *(uint *)(read + (dataSize < 0 ? sizeof(int) * 2 : sizeof(int)));
                                    if (nextIdentity >= identity)
                                    {
                                        if (nextIdentity == identity)
                                        {
                                            startIdentity = nextIdentity;
                                            bufferIndex  += dataSize < 0 ? (-dataSize + PacketHeaderSize + sizeof(int)) : (dataSize + PacketHeaderSize);
                                        }
                                        fileIndex += bufferIndex;
                                        return(true);
                                    }
                                    startIdentity = nextIdentity;
                                    bufferIndex  += dataSize < 0 ? (-dataSize + PacketHeaderSize + sizeof(int)) : (dataSize + PacketHeaderSize);
                                }while (bufferIndex <= endBufferIndex);
                                fileIndex += bufferIndex;
                                switch (dataSize = bufferIndex - endBufferIndex)
                                {
                                case 1:
                                case 2:
                                case 3:
                                    *(ulong *)bufferStart = *(ulong *)(bufferStart + bufferIndex);
                                    *(uint *)(bufferStart + sizeof(ulong)) = *(uint *)(bufferStart + (bufferIndex + sizeof(ulong)));
                                    bufferIndex = sizeof(int) * 3 - dataSize;
                                    break;

                                case 4:
                                case 5:
                                case 6:
                                case 7:
                                    *(ulong *)bufferStart = *(ulong *)(bufferStart + bufferIndex);
                                    bufferIndex           = sizeof(int) * 3 - dataSize;
                                    break;

                                case 8:
                                case 9:
                                case 10:
                                case 11:
                                    *(uint *)bufferStart = *(uint *)(bufferStart + bufferIndex);
                                    bufferIndex          = sizeof(int) * 3 - dataSize;
                                    break;

                                case 12: bufferIndex = 0; break;

                                default:
                                    fileStream.Seek(dataSize -= sizeof(int) * 3, SeekOrigin.Current);
                                    nextFileSize             -= dataSize;
                                    bufferIndex = 0;
                                    break;
                                }
                            }while (nextFileSize > 0);
                        }
                        return(true);

                        #endregion
                    }
                }
                finally { buffer.Free(); }
            }
            return(false);
        }
예제 #16
0
        /// <summary>
        /// 初始化
        /// </summary>
        internal void Start()
        {
            int isDisposed = 1;

            SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull);
            try
            {
                if (checkStateFile())
                {
                    byte[] stateData = new byte[stateBufferSize];
                    stateFileStream = new FileStream(stateFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, stateBufferSize, FileOptions.None);
                    stateFileStream.Seek(-stateBufferSize, SeekOrigin.End);
                    stateFileStream.Read(stateData, 0, stateBufferSize);
                    fixed(byte *stateDataFixed = stateData)
                    {
                        identity       = *(ulong *)stateDataFixed;
                        dataFileLength = *(long *)(stateDataFixed + sizeof(ulong));
                    }
                    if (((uint)identity & (DataCountPerFile - 1)) == 0)
                    {
                        dataFileLength = 0;
                    }
                    if (dataFileLength == 0)
                    {
                        FileInfo dataFileInfo = new FileInfo(dataFileName);
                        if (dataFileInfo.Exists)
                        {
                            if (dataFileInfo.Length == 0)
                            {
                                dataFileInfo.Delete();
                            }
                            else
                            {
                                AutoCSer.IO.File.MoveBak(dataFileInfo.FullName);
                            }
                        }
                        dataFileStream = new FileStream(dataFileInfo.FullName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None);
                    }
                    else
                    {
                        FileInfo dataFileInfo = new FileInfo(dataFileName);
                        if (!dataFileInfo.Exists)
                        {
                            Node.Cache.TcpServer.Log.Error("没有找到消息队列数据文件 " + dataFileInfo.FullName, LogLevel.Error | LogLevel.AutoCSer);
                            return;
                        }
                        if (dataFileInfo.Length < dataFileLength)
                        {
                            Node.Cache.TcpServer.Log.Error("消息队列数据文件 " + dataFileInfo.FullName + " 大小错误 " + dataFileInfo.Length.toString() + " < " + dataFileLength.toString(), LogLevel.Error | LogLevel.AutoCSer);
                            return;
                        }
                        dataFileStream = new FileStream(dataFileInfo.FullName, FileMode.Open, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None);
                        if (dataFileStream.Length > dataFileLength)
                        {
                            dataFileStream.SetLength(dataFileLength);
                            dataFileStream.Flush(true);
                        }
                        dataFileStream.Seek(0, SeekOrigin.End);

                        FileInfo indexFileInfo = new FileInfo(getIndexFileName(identity));
                        bufferPool.Get(ref buffer);
                        fixed(byte *bufferFixed = buffer.GetFixedBuffer())
                        {
                            byte *bufferStart = bufferFixed + buffer.StartIndex, end = bufferStart + buffer.Length;
                            ulong baseIdentity = this.baseIdentity;

                            if (indexFileInfo.Exists && indexFileInfo.Length >= sizeof(int) * 2)
                            {
                                #region 初始化数据文件数据包索引信息
                                int  count = (int)(indexFileInfo.Length >> 3), index = 0;
                                long fileIndex = 0;
                                indexs = new LeftArray <PacketIndex>(count);
                                PacketIndex[] indexArray = indexs.Array;
                                using (FileStream indexFileStream = new FileStream(indexFileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferPool.Size, FileOptions.None))
                                {
                                    do
                                    {
                                        indexFileStream.Read(buffer.Buffer, buffer.StartIndex, buffer.Length);
                                        byte *read = bufferStart;
                                        do
                                        {
                                            indexArray[index].Set(baseIdentity + *(uint *)read, fileIndex += *(int *)(read + sizeof(int)));
                                            if (++index == count)
                                            {
                                                break;
                                            }
                                        }while ((read += sizeof(int) * 2) != end);
                                    }while (index != count);
                                }
                                while (index != 0)
                                {
                                    if ((fileIndex = indexArray[--index].FileIndex) == dataFileLength)
                                    {
                                        if (indexArray[index].Identity == identity)
                                        {
                                            indexs.Length = index + 1;
                                        }
                                        break;
                                    }
                                    if (fileIndex < dataFileLength)
                                    {
                                        break;
                                    }
                                }
                                #endregion
                            }
                            if (indexs.Length == 0)
                            {
                                #region 重建数据文件数据包索引信息
                                if (indexs.Array.Length == 0)
                                {
                                    indexs = new LeftArray <PacketIndex>(1 << 10);
                                }
                                indexs.Array[0].Set(baseIdentity);
                                indexs.Length = 1;
                                int  bufferIndex = 0, readBufferSize = Math.Min(buffer.Length, createIndexBufferSize), bufferEndIndex, dataSize;
                                long nextFileSize = dataFileLength, fileIndex = 0;
                                using (FileStream fileStream = new FileStream(dataFileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, readBufferSize, FileOptions.None))
                                {
                                    readBufferSize -= sizeof(int);
                                    do
                                    {
                                        bufferEndIndex  = fileStream.Read(buffer.Buffer, buffer.StartIndex + bufferIndex, readBufferSize - bufferIndex);
                                        nextFileSize   -= bufferEndIndex;
                                        bufferEndIndex += bufferIndex - sizeof(int) * 3;
                                        bufferIndex     = 0;
                                        do
                                        {
                                            byte *read = bufferStart + bufferIndex;
                                            dataSize = *(int *)read;
                                            if (dataSize < 0)
                                            {
                                                baseIdentity += *(uint *)(read + sizeof(int) * 2);
                                                bufferIndex  += -dataSize + PacketHeaderSize + sizeof(int);
                                            }
                                            else
                                            {
                                                baseIdentity += *(uint *)(read + sizeof(int));
                                                bufferIndex  += dataSize + PacketHeaderSize;
                                            }
                                            indexs.PrepLength(1);
                                            indexs.Array[indexs.Length].Set(baseIdentity, fileIndex + bufferIndex);
                                            ++indexs.Length;
                                        }while (bufferIndex <= bufferEndIndex);
                                        fileIndex += bufferIndex;
                                        switch (dataSize = bufferIndex - bufferEndIndex)
                                        {
                                        case 1:
                                        case 2:
                                        case 3:
                                            *(ulong *)bufferStart = *(ulong *)(bufferStart + bufferIndex);
                                            *(uint *)(bufferStart + sizeof(ulong)) = *(uint *)(bufferStart + (bufferIndex + sizeof(ulong)));
                                            bufferIndex = sizeof(int) * 3 - dataSize;
                                            break;

                                        case 4:
                                        case 5:
                                        case 6:
                                        case 7:
                                            *(ulong *)bufferStart = *(ulong *)(bufferStart + bufferIndex);
                                            bufferIndex           = sizeof(int) * 3 - dataSize;
                                            break;

                                        case 8:
                                        case 9:
                                        case 10:
                                        case 11:
                                            *(uint *)bufferStart = *(uint *)(bufferStart + bufferIndex);
                                            bufferIndex          = sizeof(int) * 3 - dataSize;
                                            break;

                                        case 12: bufferIndex = 0; break;

                                        default:
                                            fileStream.Seek(dataSize -= sizeof(int) * 3, SeekOrigin.Current);
                                            nextFileSize             -= dataSize;
                                            bufferIndex = 0;
                                            break;
                                        }
                                    }while (nextFileSize > 0);
                                }
                                #endregion
                            }
                        }
                    }
                }
                else
                {
                    stateFileStream = new FileStream(stateFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, stateBufferSize, FileOptions.None);
                    FileInfo dataFileInfo = new FileInfo(dataFileName);
                    if (dataFileInfo.Exists)
                    {
                        if (dataFileInfo.Length == 0)
                        {
                            dataFileInfo.Delete();
                        }
                        else
                        {
                            AutoCSer.IO.File.MoveBak(dataFileInfo.FullName);
                        }
                    }
                    dataFileStream = new FileStream(dataFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None);
                }
                if (indexs.Array.Length == 0)
                {
                    indexs = new LeftArray <PacketIndex>(1 << 10);
                }
                if (indexs.Length == 0)
                {
                    indexs.Array[0].Set(baseIdentity);
                    indexs.Length = 1;
                }
                writeHandle = write;
                StatePacketIndex.Set(identity, dataFileLength);
                AutoCSer.DomainUnload.Unloader.Add(disposeHandle, DomainUnload.Type.Action);
                isDisposed = 0;
            }
            finally
            {
                buffer.TryFree();
                if (isDisposed == 0)
                {
                    Interlocked.Exchange(ref isWrite, 0);
                    onStart();
                    if (!bufferQueue.IsEmpty && Interlocked.CompareExchange(ref isWrite, 1, 0) == 0)
                    {
                        write();
                    }
                }
                else
                {
                    indexs.Length = 0;
                    Dispose();
                }
            }
        }