/// <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); }
/// <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 }); }
/// <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); }
/// <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(); } }
/// <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); }
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(); } } }
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; } }
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(); }
/// <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; } } } } }
/// <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); } } }
internal void CloseFree() { ReceiveBuffer.Free(); ReceiveBigBuffer.TryFree(); FreeReceiveDeSerializer(); if (Sender != null) { Sender.Close(); } if (ClientCreator.CommandClient.IsDisposed != 0) { LazyLog.KeepMode = AutoCSer.Threading.SecondTimerKeepMode.Canceled; } }
/// <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; }
internal void CloseFree() { ReceiveBuffer.Free(); ReceiveBigBuffer.TryFree(); if (CheckTimer != null) { CheckTimer.Free(this); ClientCheckTimer.FreeNotNull(CheckTimer); CheckTimer = null; } FreeReceiveDeSerializer(); if (Sender != null) { Sender.Close(); } }
/// <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); }
/// <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); }
/// <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(); } }
/// <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); }
/// <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(); } }
/// <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(); } } } }
internal void CloseFree() { ReceiveBuffer.Free(); ReceiveBigBuffer.TryFree(); FreeReceiveDeSerializer(); }
internal void Free() { Buffer.Free(); CompressionBuffer.TryFree(); }
protected void freeCopyBuffer() { CopyBuffer.Free(); CompressBuffer.Free(); }
/// <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; } }
/// <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); }
internal WriteRequest Write(File file) { Index = file.Write(ref Buffer, Size); Buffer.Free(); return(LinkNext); }