예제 #1
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;
                 }
             }
         }
     }
 }
예제 #2
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.Buffer)
                {
                    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;
        }
예제 #3
0
파일: Image.cs 프로젝트: rebider/AutoCSer
        private static readonly SubBuffer.Pool stringBufferPool = SubBuffer.Pool.GetPool(SubBuffer.Size.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.Buffer)
                {
                    byte* nextStrings = null, stringStart = stringFixed + stringBuffer.StartIndex;
                    byte* currentInput = inputFixed, inputEnd = inputFixed + input.Length;
                    byte* currentOutput = output, outputEnd = output + FileWriter.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.ClearUnsafe((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); }
        }
예제 #4
0
 internal void Get(SubBuffer.Pool bufferPool)
 {
     bufferPool.Get(ref Buffer);
     WriteIndex = Buffer.StartIndex;
     IsWait     = false;
 }
예제 #5
0
        /// <summary>
        /// 文件流写入器
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="config"></param>
        internal FileStreamWriter(CacheManager cache, MasterServerConfig config)
        {
            this.cache = cache;
            Config     = config;
            bufferPool = SubBuffer.Pool.GetPool(config.BufferSize);
            FileInfo file = new FileInfo(config.GetFileName);

            FileName   = file.FullName;
            IsDisposed = 1;
            FileMode    createMode = FileMode.CreateNew;
            FileBuffers buffer     = default(FileBuffers);

            try
            {
                if (file.Exists)
                {
                    if (file.Length == 0)
                    {
                        createMode = FileMode.Create;
                    }
                    else
                    {
                        fileStream = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, bufferPool.Size, FileOptions.None);
                        bufferPool.Get(ref buffer.Buffer);
                        if (fileStream.Read(buffer.Buffer.Buffer, buffer.Buffer.StartIndex, fileHeaderSize) == fileHeaderSize)
                        {
                            fixed(byte *bufferFixed = buffer.Buffer.Buffer)
                            {
                                byte *bufferStart = bufferFixed + buffer.Buffer.StartIndex;

                                if (*(int *)bufferStart == FileHeader)
                                {
                                    Version = *(ulong *)(bufferStart + sizeof(int) * 2);
                                    FileInfo switchFile = new FileInfo(config.GetSwitchFileName);
                                    if (switchFile.Exists)
                                    {
                                        FileStream switchFileStream = new FileStream(switchFile.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, bufferPool.Size, FileOptions.None);
                                        if (switchFileStream.Read(buffer.Buffer.Buffer, buffer.Buffer.StartIndex, fileHeaderSize) == fileHeaderSize && *(int *)bufferStart == FileHeader &&
                                            *(ulong *)(bufferStart + sizeof(int) * 2) > Version)
                                        {
                                            fileStream.Dispose();
                                            Version      = *(ulong *)(bufferStart + sizeof(int) * 2);
                                            fileStream   = switchFileStream;
                                            FileName     = switchFile.FullName;
                                            isSwitchFile = true;
                                        }
                                    }
                                    if (Version > 0)
                                    {
                                        LoadData loadData = new LoadData {
                                            Buffer = BufferLink.Head
                                        };
                                        int  count = fileStream.Read(buffer.Buffer.Buffer, buffer.Buffer.StartIndex, buffer.Buffer.Length), index = 0, compressionDataSize;
                                        long nextLength = (FileLength = fileStream.Length) - fileHeaderSize - count;
                                        do
                                        {
                                            while (count >= sizeof(int) * 2)
                                            {
                                                byte *read = bufferStart + index;
                                                if ((compressionDataSize = *(int *)read) < 0)
                                                {
                                                    if (count >= (compressionDataSize = -compressionDataSize) + sizeof(int) * 2)
                                                    {
                                                        buffer.CompressionBuffer.StartIndex = *(int *)(read + sizeof(int));
                                                        AutoCSer.IO.Compression.DeflateDeCompressor.Get(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + (index += sizeof(int) * 2), compressionDataSize, ref buffer.CompressionBuffer);
                                                        if (buffer.CompressionBuffer.Buffer != null)
                                                        {
                                                            fixed(byte *dataFixed = buffer.CompressionBuffer.Buffer)
                                                            {
                                                                loadData.Set(buffer.CompressionBuffer.Buffer, buffer.CompressionBuffer.StartIndex, *(int *)(read + sizeof(int)), dataFixed);
                                                                if (!cache.Load(ref loadData))
                                                                {
                                                                    throw new InvalidDataException();
                                                                }
                                                            }
                                                            index += compressionDataSize;
                                                            count -= compressionDataSize + sizeof(int) * 2;
                                                            buffer.CompressionBuffer.Free();
                                                        }
                                                        else
                                                        {
                                                            throw new InvalidDataException();
                                                        }
                                                    }
                                                    else if (count + nextLength >= compressionDataSize + sizeof(int) * 2)
                                                    {
                                                        if (compressionDataSize + sizeof(int) * 2 <= buffer.Buffer.StartIndex)
                                                        {
                                                            break;
                                                        }
                                                        if (bigBuffer.Length < compressionDataSize)
                                                        {
                                                            bigBuffer = new byte[Math.Max(compressionDataSize, bigBuffer.Length << 1)];
                                                        }
                                                        System.Buffer.BlockCopy(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + (index + sizeof(int) * 2), bigBuffer, 0, count -= sizeof(int) * 2);
                                                        do
                                                        {
                                                            index       = fileStream.Read(bigBuffer, count, compressionDataSize - count);
                                                            nextLength -= index;
                                                            count      += index;
                                                        }while (count != compressionDataSize);
                                                        buffer.CompressionBuffer.StartIndex = *(int *)(read + sizeof(int));
                                                        AutoCSer.IO.Compression.DeflateDeCompressor.Get(bigBuffer, 0, compressionDataSize, ref buffer.CompressionBuffer);
                                                        if (buffer.CompressionBuffer.Buffer != null)
                                                        {
                                                            fixed(byte *dataFixed = buffer.CompressionBuffer.Buffer)
                                                            {
                                                                loadData.Set(buffer.CompressionBuffer.Buffer, buffer.CompressionBuffer.StartIndex, *(int *)(read + sizeof(int)), dataFixed);
                                                                if (!cache.Load(ref loadData))
                                                                {
                                                                    throw new InvalidDataException();
                                                                }
                                                            }
                                                            index = count = 0;
                                                            buffer.CompressionBuffer.Free();
                                                        }
                                                        else
                                                        {
                                                            throw new InvalidDataException();
                                                        }
                                                    }
                                                    else
                                                    {
                                                        endError(ref buffer.Buffer, nextLength, index, count);
                                                        return;
                                                    }
                                                }
                                                else if (count >= compressionDataSize + sizeof(int))
                                                {
                                                    loadData.Set(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + (index += sizeof(int)), compressionDataSize, bufferFixed);
                                                    if (!cache.Load(ref loadData))
                                                    {
                                                        throw new InvalidDataException();
                                                    }
                                                    index += compressionDataSize;
                                                    count -= compressionDataSize + sizeof(int);
                                                }
                                                else if (count + nextLength >= compressionDataSize + sizeof(int))
                                                {
                                                    if (compressionDataSize + sizeof(int) <= buffer.Buffer.StartIndex)
                                                    {
                                                        break;
                                                    }
                                                    if (bigBuffer.Length < compressionDataSize)
                                                    {
                                                        bigBuffer = new byte[Math.Max(compressionDataSize, bigBuffer.Length << 1)];
                                                    }
                                                    System.Buffer.BlockCopy(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + (index + sizeof(int)), bigBuffer, 0, count -= sizeof(int));
                                                    do
                                                    {
                                                        index       = fileStream.Read(bigBuffer, count, compressionDataSize - count);
                                                        nextLength -= index;
                                                        count      += index;
                                                    }while (count != compressionDataSize);
                                                    fixed(byte *dataFixed = bigBuffer)
                                                    {
                                                        loadData.Set(bigBuffer, 0, compressionDataSize, dataFixed);
                                                        if (!cache.Load(ref loadData))
                                                        {
                                                            throw new InvalidDataException();
                                                        }
                                                    }
                                                    index = count = 0;
                                                }
                                                else
                                                {
                                                    endError(ref buffer.Buffer, nextLength, index, count);
                                                    return;
                                                }
                                            }
                                            if (nextLength == 0)
                                            {
                                                if (count == 0)
                                                {
                                                    fileStream.Seek(0, SeekOrigin.End);
                                                    IsDisposed = 0;
                                                }
                                                else
                                                {
                                                    endError(ref buffer.Buffer, nextLength, index, count);
                                                }
                                                return;
                                            }
                                            if (count != 0)
                                            {
                                                System.Buffer.BlockCopy(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + index, buffer.Buffer.Buffer, buffer.Buffer.StartIndex, count);
                                            }
                                            index       = fileStream.Read(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + count, buffer.Buffer.Length - count);
                                            nextLength -= index;
                                            count      += index;
                                            index       = 0;
                                        }while (true);
                                    }
                                }
                            }
                        }
                        if (!config.IsMoveBakUnknownFile)
                        {
                            throw new InvalidDataException();
                        }
                        fileStream.Dispose();
                        AutoCSer.IO.File.MoveBak(FileName);
                    }
                }
                fileStream = new FileStream(FileName, createMode, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None);
                create(ref buffer.Buffer, Version);
            }
            finally
            {
                buffer.Free();
                BufferLink.Head.Array.SetNull();
                if (IsDisposed == 0)
                {
                    fileFlushSeconds = config.FileFlushSeconds;
                    Writers.PushNotNull(this);
                    OnTime.Set(Date.NowTime.OnTimeFlag.CacheFile);
                }
                else if (fileStream != null)
                {
                    fileStream.Dispose();
                }
            }
        }