示例#1
0
        /// <summary>
        /// 释放资源
        /// </summary>
        public override void Dispose()
        {
            if (IsDisposed == 0)
            {
                Monitor.Enter(SocketLock);
                try
                {
                    if (IsDisposed == 0)
                    {
                        IsDisposed = 1;
                        closeSocket();

                        if (CheckTimer != null)
                        {
                            CheckTimer.Free(this);
                            ClientCheckTimer.FreeNotNull(CheckTimer);
                        }
                        outputSerializer.Free();
                        if (outputJsonSerializer != null)
                        {
                            outputJsonSerializer.Free();
                        }
                        Buffer.Free();
                    }
                }
                finally { Monitor.Exit(SocketLock); }
            }
        }
 internal void CloseFree()
 {
     ReceiveBuffer.Free();
     ReceiveBigBuffer.TryFree();
     FreeReceiveDeSerializer();
     Unmanaged.Free(ref commandData);
 }
示例#3
0
        /// <summary>
        /// 目标对象
        /// </summary>
        public async Task <MemberValue <valueType> > ValueAsync()
        {
            switch (state)
            {
            case MemberState.Unknown:
                if (Size == 0)
                {
                    return new MemberValue <valueType> {
                               State = state = MemberState.Remote
                    }
                }
                ;
                Server.TcpInternalClient client = ClientPool.Get(Index);
                if (client == null)
                {
                    return new MemberValue <valueType> {
                               State = MemberState.NoClient
                    }
                }
                ;
                SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull);
                SubBuffer.Pool.GetBuffer(ref buffer, Size);
                try
                {
                    AutoCSer.Net.TcpServer.ReturnValue <ClientBuffer> clientBuffer = await client.readAwaiter(new ClientBuffer { Buffer = new SubArray <byte>(buffer.StartIndex, Size, buffer.Buffer), IsClient = true }, Index);

                    onRead(ref clientBuffer);
                }
                finally { buffer.Free(); }
                break;
            }
            return(new MemberValue <valueType> {
                Value = value, State = state
            });
        }
示例#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.Buffer)
            {
                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="fileStream"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private bool isData(FileStream fileStream, ref SubArray <byte> data)
        {
            fileStream.Seek(Index, SeekOrigin.Begin);
            SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull);
            BlockBase.DefaultBufferPool.Get(ref buffer);
            try
            {
                byte[] bufferArray = buffer.Buffer;
                int    size        = data.Length;
                fixed(byte *dataFixed = data.GetFixedBuffer(), bufferFixed = bufferArray)
                {
                    byte *dataStart = dataFixed + data.Start, bufferStart = bufferFixed + buffer.StartIndex;

                    while (size > BlockBase.CheckSize)
                    {
                        if (fileStream.Read(bufferArray, buffer.StartIndex, BlockBase.CheckSize) != BlockBase.CheckSize)
                        {
                            return(false);
                        }
                        if (!AutoCSer.Memory.Common.EqualNotNull(dataStart, bufferStart, BlockBase.CheckSize))
                        {
                            return(false);
                        }
                        dataStart += BlockBase.CheckSize;
                        size      -= BlockBase.CheckSize;
                    }
                    return(fileStream.Read(bufferArray, buffer.StartIndex, size) == size && AutoCSer.Memory.Common.EqualNotNull(dataStart, bufferStart, size));
                }
            }
            finally { buffer.Free(); }
        }
示例#6
0
        /// <summary>
        /// 设置远程对象
        /// </summary>
        /// <param name="value"></param>
        /// <param name="blockIndex">磁盘块编号</param>
        /// <param name="bufferSize">序列化缓冲区大小</param>
        /// <returns></returns>
        public unsafe bool Set(valueType value, int blockIndex, SubBuffer.Size bufferSize = SubBuffer.Size.Kilobyte4)
        {
            if (value == null)
            {
                SetNull();
                return(true);
            }
            Server.TcpInternalClient client = ClientPool.Get(blockIndex);
            if (client != null)
            {
                BinarySerialize.Serializer serializer = BinarySerialize.Serializer.YieldPool.Default.Pop() ?? new BinarySerialize.Serializer();
                SubBuffer.PoolBufferFull   buffer     = default(SubBuffer.PoolBufferFull);
                SubBuffer.Pool.GetPool(bufferSize).Get(ref buffer);
                try
                {
                    fixed(byte *bufferFixed = buffer.Buffer)
                    {
                        byte *start = bufferFixed + buffer.StartIndex;

                        serializer.SerializeNotNull(value, start, buffer.PoolBuffer.Pool.Size, ClientConfig.BinarySerializeConfig);
                        AutoCSer.Net.TcpServer.ReturnValue <ulong> index;
                        int size = serializer.Stream.ByteSize;

                        if (serializer.Stream.Data.Data == start)
                        {
                            index = client.append(new AppendBuffer {
                                Buffer = new SubArray <byte> {
                                    Array = buffer.Buffer, Start = buffer.StartIndex, Length = size
                                }, Index = size == Size ? Index : 0, BlockIndex = (ushort)blockIndex
                            });
                        }
                        else
                        {
                            index = client.append(new AppendBuffer {
                                Buffer = new SubArray <byte> {
                                    Array = serializer.Stream.GetArray(), Length = size
                                }, Index = size == Size ? Index : 0, BlockIndex = (ushort)blockIndex
                            });
                        }
                        if (index.Type == Net.TcpServer.ReturnType.Success && index.Value != 0)
                        {
                            Index = index.Value;
                            Size  = size;
                            value = Value;
                            state = MemberState.Remote;
                            return(true);
                        }
                    }
                }
                finally
                {
                    buffer.Free();
                    serializer.Free();
                }
            }
            return(false);
        }
示例#7
0
 internal void OnReceive(ref SubBuffer.PoolBufferFull buffer)
 {
     ClientCommand.Command command = CommandPool.GetCommand((int)CommandIndex);
     if (command == null)
     {
         buffer.Free();
     }
     else
     {
         SubArray <byte> data = new SubArray <byte> {
             Array = buffer.Buffer, Start = buffer.StartIndex, Length = dataSize
         };
         try
         {
             command.OnReceive(ref data);
         }
         finally { buffer.Free(); }
     }
 }
示例#8
0
        private void freeBody()
        {
            switch (Type)
            {
            case ResponseType.ByteArray: Body.Array = EmptyArray <byte> .Array; return;

            case ResponseType.SubByteArray:
                Body.Array = EmptyArray <byte> .Array;
                Flag      &= ResponseFlag.All ^ ResponseFlag.CanHeaderSize;
                return;

            case ResponseType.SubBuffer:
                Body.Array = EmptyArray <byte> .Array;
                SubBuffer.Free();
                return;

            case ResponseType.File: BodyFile = null; return;
            }
        }
示例#9
0
        internal void OnReceive(ref SubBuffer.PoolBufferFull buffer)
        {
            SubArray <byte> data = new SubArray <byte> {
                Array = buffer.Buffer, Start = buffer.StartIndex, Length = compressionDataSize
            };

            try
            {
                getCurrentCommand().OnReceive(ref data);
            }
            finally { buffer.Free(); }
            freeCommand();
        }
示例#10
0
 /// <summary>
 /// 释放资源
 /// </summary>
 public void Dispose()
 {
     isNeedDispose = 0;
     if (Interlocked.CompareExchange(ref isDisposed, 1, 0) == 0)
     {
         AutoCSer.DomainUnload.Unloader.Remove(disposeHandle, DomainUnload.Type.Action, false);
         if (!isStartQueue)
         {
             onStart();
         }
         if (dataFileStream != null)
         {
             dataFileStream.Dispose();
             dataFileStream = null;
         }
         if (stateFileStream != null)
         {
             stateFileStream.Dispose();
             stateFileStream = null;
         }
         int count = indexs.Length;
         if (count > 1)
         {
             PacketIndex[] indexArray = indexs.Array;
             while (count != 0)
             {
                 long fileIndex = indexArray[--count].FileIndex;
                 if (fileIndex == StatePacketIndex.FileIndex)
                 {
                     if (indexArray[count].Identity == StatePacketIndex.Identity && count != 0)
                     {
                         indexs.Length = count + 1;
                         SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull);
                         bufferPool.Get(ref buffer);
                         try
                         {
                             writeIndex(ref buffer);
                         }
                         finally { buffer.Free(); }
                     }
                     break;
                 }
                 if (fileIndex < StatePacketIndex.FileIndex)
                 {
                     break;
                 }
             }
         }
     }
 }
示例#11
0
        /// <summary>
        /// 释放资源
        /// </summary>
        public override void Dispose()
        {
            if (IsDisposed == 0)
            {
                Monitor.Enter(SocketLock);
                try
                {
                    if (IsDisposed == 0)
                    {
                        IsDisposed = 1;
                        closeSocket();

                        outputSerializer.Free();
                        if (outputJsonSerializer != null)
                        {
                            outputJsonSerializer.Free();
                        }
                        Buffer.Free();
                    }
                }
                finally { Monitor.Exit(SocketLock); }
            }
        }
示例#12
0
 internal void CloseFree()
 {
     ReceiveBuffer.Free();
     ReceiveBigBuffer.TryFree();
     FreeReceiveDeSerializer();
     if (Sender != null)
     {
         Sender.Close();
     }
     if (ClientCreator.CommandClient.IsDisposed != 0)
     {
         LazyLog.KeepMode = AutoCSer.Threading.SecondTimerKeepMode.Canceled;
     }
 }
示例#13
0
 /// <summary>
 /// 是否缓冲区
 /// </summary>
 internal void Free()
 {
     if (SendFileStream != null)
     {
         SendFileStream.Dispose();
         SendFileStream = null;
     }
     if ((Flag & SocketFlag.IsLoadForm) != 0)
     {
         Form.Clear();
         FormBuffer.Clear();
     }
     if ((Flag & SocketFlag.GetForm) != 0)
     {
         GetFormPage.CancelGetForm();
         GetFormPage = null;
     }
     if ((Flag & SocketFlag.BigBuffer) != 0)
     {
         BigBuffer.Free();
     }
     Http.Response.Push(ref HttpResponse);
     Flag = SocketFlag.None;
 }
示例#14
0
 internal void CloseFree()
 {
     ReceiveBuffer.Free();
     ReceiveBigBuffer.TryFree();
     if (CheckTimer != null)
     {
         CheckTimer.Free(this);
         ClientCheckTimer.FreeNotNull(CheckTimer);
         CheckTimer = null;
     }
     FreeReceiveDeSerializer();
     if (Sender != null)
     {
         Sender.Close();
     }
 }
示例#15
0
        /// <summary>
        /// 数据压缩
        /// </summary>
        /// <param name="data"></param>
        /// <param name="compressData">压缩数据</param>
        /// <param name="seek">起始位置</param>
        /// <param name="compressHeadSize">压缩多余头部</param>
        /// <returns>是否压缩成功</returns>
        internal static bool Get(ref SubArray <byte> data, ref SubArray <byte> compressData, int seek = 0, int compressHeadSize = 0)
#endif

        {
            int length = data.Length + seek;

            SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull);
            SubBuffer.Pool.GetSingleBuffer(ref buffer, length);
            try
            {
                using (MemoryStream dataStream = AutoCSer.Extensions.MemoryStreamExtension.New(buffer.Buffer, buffer.StartIndex, buffer.Length))
                {
                    if (seek != 0)
                    {
                        dataStream.Seek(seek, SeekOrigin.Begin);
                    }
#if DOTNET2 || DOTNET4
                    using (GZipStream compressStream = new GZipStream(dataStream, CompressionMode.Compress, true))
#else
                    using (GZipStream compressStream = isFastest ? new GZipStream(dataStream, CompressionLevel.Fastest, true) : new GZipStream(dataStream, CompressionMode.Compress, true))
#endif
                    {
                        compressStream.Write(data.Array, data.Start, data.Length);
                    }
                    if (dataStream.Position + compressHeadSize < length)
                    {
                        byte[] streamBuffer = dataStream.GetBuffer();
                        if (streamBuffer == buffer.Buffer && buffer.PoolBuffer.Pool != null)
                        {
                            byte[] newData = new byte[(int)dataStream.Position];
                            Buffer.BlockCopy(streamBuffer, buffer.StartIndex + seek, newData, seek, compressHeadSize = (int)dataStream.Position - seek);
                            compressData.Set(newData, seek, compressHeadSize);
                        }
                        else
                        {
                            compressData.Set(streamBuffer, seek, (int)dataStream.Position - seek);
                        }
                        return(true);
                    }
                }
            }
            finally { buffer.Free(); }
            return(false);
        }
示例#16
0
 /// <summary>
 /// 重建文件流
 /// </summary>
 /// <param name="cacheFile"></param>
 /// <returns></returns>
 internal ReturnType Start(FileStreamWriter cacheFile)
 {
     IsDisposed = 1;
     SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull);
     try
     {
         snapshot = new Snapshot.Cache(cache, true);
         FileInfo file = new FileInfo(cacheFile.isSwitchFile ? Config.GetFileName : Config.GetSwitchFileName);
         FileName = file.FullName;
         if (file.Exists)
         {
             AutoCSer.IO.File.MoveBak(FileName);
         }
         fileStream = new FileStream(FileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None);
         create(ref buffer, 0);
         return(ReturnType.Success);
     }
     catch (Exception error)
     {
         cache.TcpServer.AddLog(error);
     }
     finally
     {
         buffer.Free();
         if (IsDisposed == 0)
         {
             Interlocked.Exchange(ref fileFlushSeconds, Config.FileFlushSeconds);
             AutoCSer.Threading.ThreadPool.TinyBackground.Start(writeCache);
         }
         else
         {
             cache.NextGetter();
             if (fileStream != null)
             {
                 fileStream.Dispose();
             }
         }
     }
     return(ReturnType.SnapshotFileStartError);
 }
示例#17
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.Buffer)
                {
                    using (MD5 md5 = new MD5CryptoServiceProvider())
                    {
                        return("weixin://wxpay/bizpayurl?" + Memory_WebClient.BytesToStringNotEmpty(bufferFixed + buffer.StartIndex, length) + "&sign=" + sign.sign);
                    }
                }
            }
            finally { buffer.Free(); }
        }
示例#18
0
        /// <summary>
        /// 设置远程对象
        /// </summary>
        /// <param name="value"></param>
        /// <param name="blockIndex">磁盘块编号</param>
        /// <param name="bufferSize">序列化缓冲区大小</param>
        /// <returns></returns>
        public async Task <bool> SetAsync(valueType value, int blockIndex, SubBuffer.Size bufferSize = SubBuffer.Size.Kilobyte4)
        {
            if (value == null)
            {
                SetNull();
                return(true);
            }
            Server.TcpInternalClient client = ClientPool.Get(blockIndex);
            if (client != null)
            {
                BinarySerialize.Serializer serializer = BinarySerialize.Serializer.YieldPool.Default.Pop() ?? new BinarySerialize.Serializer();
                SubBuffer.PoolBufferFull   buffer     = default(SubBuffer.PoolBufferFull);
                SubBuffer.Pool.GetPool(bufferSize).Get(ref buffer);
                try
                {
                    int          size;
                    AppendBuffer appendBuffer = getAppendBuffer(ref value, serializer, ref buffer, out size);
                    appendBuffer.BlockIndex = (ushort)blockIndex;
                    AutoCSer.Net.TcpServer.ReturnValue <ulong> index = await client.appendAwaiter(appendBuffer);

                    if (index.Type == Net.TcpServer.ReturnType.Success && index.Value != 0)
                    {
                        Index = index.Value;
                        Size  = size;
                        value = Value;
                        state = MemberState.Remote;
                        return(true);
                    }
                }
                finally
                {
                    buffer.Free();
                    serializer.Free();
                }
            }
            return(false);
        }
示例#19
0
        /// <summary>
        /// 执行命令
        /// </summary>
        /// <returns></returns>
        private bool isDoCommandBig()
        {
#if !DOTNET2
            asyncEventArgs.SetBuffer(Buffer.Buffer, Buffer.StartIndex, bufferSize);
#endif
            SubBuffer.PoolBufferFull receiveBigBuffer = ReceiveBigBuffer;
            ReceiveBigBuffer.Clear();
            try
            {
                System.Buffer.BlockCopy(Buffer.Buffer, Buffer.StartIndex + receiveIndex, receiveBigBuffer.Buffer, receiveBigBuffer.StartIndex, receiveCount - receiveIndex);
                if (compressionDataSize == dataSize)
                {
                    SubArray<byte> data = new SubArray<byte> { Array = receiveBigBuffer.Buffer, Start = receiveBigBuffer.StartIndex, Length = dataSize };
                    return doCommandMark(ref data);
                }
                if (MarkData != 0) TcpServer.CommandBuffer.Mark(receiveBigBuffer.Buffer, MarkData, receiveBigBuffer.StartIndex, compressionDataSize);
                SubBuffer.PoolBufferFull buffer = new SubBuffer.PoolBufferFull { StartIndex = dataSize };
                AutoCSer.IO.Compression.DeflateDeCompressor.Get(receiveBigBuffer.Buffer, receiveBigBuffer.StartIndex, compressionDataSize, ref buffer);
                if (buffer.Buffer == null) return false;
                if (buffer.PoolBuffer.Pool == null) ++Server.ReceiveNewBufferCount;
                return doCommand(ref buffer);
            }
            finally { receiveBigBuffer.Free(); }
        }
示例#20
0
 /// <summary>
 /// 数据解压缩
 /// </summary>
 /// <param name="data"></param>
 /// <param name="startIndex"></param>
 /// <param name="count"></param>
 /// <param name="buffer">输出缓冲区</param>
 internal static void Get(byte[] data, int startIndex, int count, ref SubBuffer.PoolBufferFull buffer)
 {
     using (MemoryStream memoryStream = new MemoryStream(data, startIndex, count))
         using (DeflateStream compressStream = new DeflateStream(memoryStream, CompressionMode.Decompress, true))
         //using (DeflateStream compressStream = new DeflateStream(memoryStream, CompressionMode.Decompress, false))
         {
             int size = buffer.StartIndex;
             SubBuffer.Pool.GetBuffer(ref buffer, size);
             try
             {
                 if (compressStream.Read(buffer.Buffer, buffer.StartIndex, size) == size)
                 {
                     size = 0;
                 }
             }
             finally
             {
                 if (size != 0)
                 {
                     buffer.Free();
                 }
             }
         }
 }
示例#21
0
 internal void CloseFree()
 {
     ReceiveBuffer.Free();
     ReceiveBigBuffer.TryFree();
     FreeReceiveDeSerializer();
 }
示例#22
0
 internal void Free()
 {
     Buffer.Free();
     CompressionBuffer.TryFree();
 }
示例#23
0
 protected void freeCopyBuffer()
 {
     CopyBuffer.Free();
     CompressBuffer.Free();
 }
示例#24
0
        /// <summary>
        /// 压缩数据
        /// </summary>
        /// <param name="isFastestCompressionLevel"></param>
        internal void Compress(bool isFastestCompressionLevel)
#endif
        {
            switch (Type)
            {
            case Net.Http.ResponseType.ByteArray:
                Body.SetFull();
                goto SUBBYTEARRAY;

            case Net.Http.ResponseType.SubByteArray:
SUBBYTEARRAY:
                if (Body.Length > GZipHeaderSize + 256)
                {
                    SubArray <byte> compressData = new SubArray <byte>();
                    try
                    {
#if DOTNET2 || DOTNET4
                        if (AutoCSer.IO.Compression.GzipCompressor.Get(Body.Array, Body.Start, Body.Length, ref SubBuffer, ref compressData, 0, GZipHeaderSize))
#else
                        if (AutoCSer.IO.Compression.GzipCompressor.Get(Body.Array, Body.Start, Body.Length, ref SubBuffer, ref compressData, 0, GZipHeaderSize, isFastestCompressionLevel))
#endif
                        {
                            Body            = compressData;
                            Type            = compressData.Array == SubBuffer.Buffer ? ResponseType.SubBuffer : ResponseType.SubByteArray;
                            ContentEncoding = GZipEncoding;
                            Flag           |= ResponseFlag.ContentEncoding;
                        }
                    }
                    finally
                    {
                        if (Type != ResponseType.SubBuffer)
                        {
                            SubBuffer.Free();
                        }
                    }
                }
                return;

            case Net.Http.ResponseType.SubBuffer:
                if (Body.Length > GZipHeaderSize + 256)
                {
                    SubBuffer.PoolBufferFull compressBuffer = default(SubBuffer.PoolBufferFull);
                    SubArray <byte>          compressData   = new SubArray <byte>();
                    byte isCompress = 0;
                    try
                    {
#if DOTNET2 || DOTNET4
                        if (AutoCSer.IO.Compression.GzipCompressor.Get(Body.Array, Body.Start, Body.Length, ref compressBuffer, ref compressData, 0, GZipHeaderSize))
#else
                        if (AutoCSer.IO.Compression.GzipCompressor.Get(Body.Array, Body.Start, Body.Length, ref compressBuffer, ref compressData, 0, GZipHeaderSize, isFastestCompressionLevel))
#endif
                        {
                            isCompress = 1;
                            SubBuffer.Free();
                            Body = compressData;
                            if (compressData.Array == compressBuffer.Buffer)
                            {
                                SubBuffer = compressBuffer;
                            }
                            else
                            {
                                Type = ResponseType.SubByteArray;
                            }
                            ContentEncoding = GZipEncoding;
                            Flag           |= ResponseFlag.ContentEncoding;
                        }
                    }
                    finally
                    {
                        if (isCompress == 0 || Type != ResponseType.SubBuffer)
                        {
                            compressBuffer.Free();
                        }
                    }
                }
                return;
            }
        }
示例#25
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.Buffer)
                    {
                        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);
        }
示例#26
0
 internal WriteRequest Write(File file)
 {
     Index = file.Write(ref Buffer, Size);
     Buffer.Free();
     return(LinkNext);
 }