/// <summary> /// 设置输出数据 /// </summary> /// <param name="charStream"></param> /// <param name="encoding"></param> internal unsafe void SetBody(CharStream charStream, ref EncodingCache encoding) { if (charStream.Data.CurrentIndex == 0) { SetBody(); } else { freeBody(); int size = encoding.GetByteCountNotNull(charStream); AutoCSer.SubBuffer.Pool.GetBuffer(ref SubBuffer, size); if (SubBuffer.PoolBuffer.Pool == null) { encoding.WriteBytes(charStream, Body.Array = SubBuffer.Buffer); SubBuffer.Buffer = null; Type = ResponseType.ByteArray; } else { Body.Set(SubBuffer.Buffer, SubBuffer.StartIndex, size); encoding.WriteBytes(charStream, ref Body); Type = ResponseType.SubBuffer; } } }
/// <summary> /// 数据压缩 /// </summary> /// <param name="data"></param> /// <param name="startIndex"></param> /// <param name="count"></param> /// <param name="buffer">输出缓冲区</param> /// <param name="compressData">压缩数据</param> /// <param name="seek">起始位置</param> /// <param name="compressHeadSize">压缩多余头部</param> /// <returns>是否压缩成功</returns> internal static bool Get(byte[] data, int startIndex, int count, ref SubBuffer.PoolBufferFull buffer, ref SubArray <byte> compressData, int seek = 0, int compressHeadSize = 0) { int length = count + seek; SubBuffer.Pool.GetBuffer(ref buffer, length); using (MemoryStream dataStream = AutoCSer.Extension.MemoryStreamExtension.New(buffer.Buffer, buffer.StartIndex, buffer.Length)) { if (seek != 0) { dataStream.Seek(seek, SeekOrigin.Begin); } #if DOTNET2 || DOTNET4 || UNITY3D using (DeflateStream compressStream = new DeflateStream(dataStream, CompressionMode.Compress, true)) compressStream.Write(data, startIndex, count); #else using (DeflateStream compressStream = new DeflateStream(dataStream, CompressionLevel.Fastest, true)) compressStream.Write(data, startIndex, count); #endif if (dataStream.Position + compressHeadSize < length) { byte[] streamBuffer = dataStream.GetBuffer(); if (streamBuffer == buffer.Buffer && buffer.PoolBuffer.Pool != null) { compressData.Set(streamBuffer, buffer.StartIndex + seek, (int)dataStream.Position - seek); } else { compressData.Set(streamBuffer, seek, (int)dataStream.Position - seek); } return(true); } } return(false); }
internal void SetLocation(byte[] data, ResponseState state = ResponseState.Found302) { if (data == null) { Location.Set(EmptyArray <byte> .Array, 0, 0); } else { Location.Set(data, 0, data.Length); } State = state; Flag = (Flag | ResponseFlag.Location | ResponseFlag.State) & (ResponseFlag.All ^ ResponseFlag.AccessControlAllowOrigin); }
//[AutoCSer.IOS.Preserve(Conditional = true)] internal void subArrayDeSerialize <valueType>(ref SubArray <valueType> value) { valueType[] array = null; isReferenceArray = false; TypeDeSerializer <valueType[]> .DefaultDeSerializer(this, ref array); value.Set(array, 0, array.Length); }
internal void CopyPath() { if (path.Length != 0) { byte[] data = path.GetArray(); path.Set(data, 0, data.Length); } }
internal void Set(byte[] value, DateTime expires, byte[] domain, byte[] path, bool isSecure, bool isHttpOnly) { Value = value; Domain.Set(domain); Path = path; Expires = expires; IsSecure = isSecure; IsHttpOnly = isHttpOnly; }
/// <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="end"></param> ///// <returns></returns> //[MethodImpl(AutoCSer.MethodImpl.AggressiveInlining)] //public byte* GetRead(out byte* end) //{ // end = this.end; // return Read; //} /// <summary> /// 获取数据缓冲区 /// </summary> /// <param name="buffer"></param> /// <returns></returns> public bool GetBuffer(ref SubArray <byte> buffer) { if (Buffer == null) { return(false); fixed(byte *bufferFixed = Buffer) buffer.Set(Buffer, (int)(Read - bufferFixed), (int)(End - Read)); return(true); }
internal BufferCount Get(ref SubArray <byte> data) { if (Size >= data.Length) { data.Set(Buffer.Buffer, index, data.Length); index += data.Length; Size -= data.Length; Interlocked.Increment(ref Count); return(this); } return(null); }
/// <summary> /// 执行压缩命令 /// </summary> /// <param name="buffer"></param> /// <returns></returns> private bool doCompressionCommand(ref SubBuffer.PoolBufferFull buffer) { if (buffer.Buffer != null) { receiveIndex += compressionDataSize; SubArray<byte> data = new SubArray<byte> { Array = buffer.Buffer }; fixed (byte* dataFixed = buffer.Buffer) { byte* start = dataFixed + buffer.StartIndex, end = start + dataSize; do { CommandIndex = (uint)(command = *(int*)start) & TcpServer.Server.CommandFlagsAnd; if (Server.IsCommand(command &= (int)TcpServer.Server.CommandIndexAnd)) { if (command != TcpServer.Server.CheckCommandIndex) { if ((CommandIndex & (uint)TcpServer.CommandFlags.NullData) == 0) { if ((compressionDataSize = *(int*)(start + sizeof(int))) > 0 && (start += sizeof(int) * 2) + compressionDataSize <= end) { if (MarkData != 0) TcpServer.CommandBuffer.Mark(start, MarkData, compressionDataSize); data.Set((int)(start - dataFixed), compressionDataSize); Server.DoCommand(command, Sender, ref data); start += compressionDataSize; } else { buffer.PoolBuffer.Free(); return false; } } else { Server.DoCommand(command, Sender, ref SubArray<byte>.Null); start += sizeof(int); } } else start += sizeof(int); } else { buffer.PoolBuffer.Free(); return false; } } while (start < end); } return true; } return false; }
/// <summary> /// 填充数据块 /// </summary> /// <param name="blockData"></param> /// <returns></returns> private bool getBlocks(ref SubArray <byte> blockData) { byte *dataStart = currentData; for (byte count = *currentData; count != 0; count = *currentData) { currentData += count; if (++currentData >= dataEnd) { return(false); } } blockData.Set(data, (int)(dataStart - dataPoint), (int)(currentData - dataStart)); ++currentData; return(true); }
/// <summary> /// 获取数据分配缓冲区 /// </summary> /// <param name="data"></param> /// <returns></returns> internal static AutoCSer.CacheServer.BufferCount GetBufferCount(ref SubArray <byte> data) { if (data.Length > (int)AutoCSer.CacheServer.BufferCount.BufferSize) { data.Set(new byte[data.Length], 0, data.Length); return(null); } AutoCSer.CacheServer.BufferCount buffer; while (System.Threading.Interlocked.CompareExchange(ref bufferCountLock, 1, 0) != 0) { AutoCSer.Threading.ThreadYield.Yield(AutoCSer.Threading.ThreadYield.Type.MessageQueueGetBuffer); } buffer = bufferCount.Get(ref data); bufferCountLock = 0; if (buffer == null) { Monitor.Enter(newBufferCountLock); AutoCSer.CacheServer.BufferCount oldBufferCount = bufferCount; try { while (System.Threading.Interlocked.CompareExchange(ref bufferCountLock, 1, 0) != 0) { AutoCSer.Threading.ThreadYield.Yield(AutoCSer.Threading.ThreadYield.Type.MessageQueueGetBuffer); } buffer = oldBufferCount.Get(ref data); bufferCountLock = 0; if (buffer == null) { AutoCSer.CacheServer.BufferCount newBufferCount = new AutoCSer.CacheServer.BufferCount(); buffer = newBufferCount.Get(ref data); if (newBufferCount.Size > oldBufferCount.Size) { bufferCount = newBufferCount; oldBufferCount.Free(); } else { newBufferCount.Free(); } } } finally { Monitor.Exit(newBufferCountLock); } } return(buffer); }
/// <summary> /// 获取缩略图 /// </summary> /// <param name="data">输出数据</param> /// <param name="width">缩略宽度</param> /// <param name="height">缩略高度</param> /// <param name="type">目标图像文件格式</param> /// <param name="backColor">背景色</param> /// <param name="seek">输出数据起始位置</param> public void Pad(ref SubArray <byte> data, ref int width, ref int height, ImageFormat type, Color backColor, int seek) { if (checkPad(ref width, ref height)) { using (MemoryStream stream = new MemoryStream()) { if (seek != 0) { stream.Seek(seek, SeekOrigin.Begin); } pad(stream, width, height, type, backColor); data.Set(stream.GetBuffer(), seek, (int)stream.Position - seek); return; } } data.SetNull(); }
/// <summary> /// 获取数据分配缓冲区 /// </summary> /// <param name="data"></param> /// <returns></returns> internal static AutoCSer.CacheServer.BufferCount GetBufferCount(ref SubArray <byte> data) { if (data.Length > (int)AutoCSer.CacheServer.BufferCount.BufferSize) { data.Set(new byte[data.Length], 0, data.Length); return(null); } AutoCSer.CacheServer.BufferCount buffer; bufferCountLock.EnterYield(); buffer = bufferCount.Get(ref data); bufferCountLock.Exit(); if (buffer == null) { Monitor.Enter(newBufferCountLock); AutoCSer.CacheServer.BufferCount oldBufferCount = bufferCount; try { bufferCountLock.EnterYield(); buffer = oldBufferCount.Get(ref data); bufferCountLock.Exit(); if (buffer == null) { AutoCSer.CacheServer.BufferCount newBufferCount = new AutoCSer.CacheServer.BufferCount(); buffer = newBufferCount.Get(ref data); if (newBufferCount.Size > oldBufferCount.Size) { bufferCount = newBufferCount; oldBufferCount.Free(); } else { newBufferCount.Free(); } } } finally { Monitor.Exit(newBufferCountLock); } } return(buffer); }
public void CallDeSerialize(ref SubArray <byte> value) { int length = *(int *)Read; if (length == 0) { value.Length = 0; Read += sizeof(int); } else { if (((length + (3 + sizeof(int))) & (int.MaxValue - 3)) <= (int)(End - Read)) { byte[] array = new byte[length]; Read = DeSerialize(Read + sizeof(int), array); value.Set(array, 0, length); } else { State = DeSerializeState.IndexOutOfRange; } } }
/// <summary> /// 设置下载数据 /// </summary> /// <param name="data">下载数据</param> /// <param name="size"></param> internal void Set(byte[] data, int size) { State = SynchronousState.Success; Data.Set(data, 0, size); }
internal void ToSubByteArray(ref SubArray <byte> data) { data.Set(Buffer, StartIndex, Length); }
/// <summary> /// 执行压缩命令 /// </summary> /// <param name="buffer"></param> /// <returns></returns> private bool doCompressionCommand(ref SubBuffer.PoolBufferFull buffer) { if (buffer.Buffer != null) { receiveIndex += compressionDataSize; SubArray<byte> data = new SubArray<byte> { Array = buffer.Buffer }; fixed (byte* dataFixed = buffer.Buffer) { byte* start = dataFixed + buffer.StartIndex, end = start + dataSize; do { CommandIndex = (uint)(command = *(int*)start) & TcpServer.Server.CommandFlagsAnd; if (Server.IsCommand(command &= (int)TcpServer.Server.CommandIndexAnd) && IsCommand(command)) { switch (command - TcpServer.Server.MinCommandIndex) { case TcpServer.Server.CheckCommandIndex - TcpServer.Server.MinCommandIndex: start += sizeof(int); break; case TcpServer.Server.RemoteExpressionCommandIndex - TcpServer.Server.MinCommandIndex: case TcpServer.Server.RemoteExpressionNodeIdCommandIndex - TcpServer.Server.MinCommandIndex: if ((CommandIndex & (uint)TcpServer.CommandFlags.NullData) == 0 && (compressionDataSize = *(int*)(start + sizeof(int))) > 0 && (start += sizeof(int) * 2) + compressionDataSize <= end) { if (MarkData != 0) TcpServer.CommandBuffer.Mark(start, MarkData, compressionDataSize); data.Set((int)(start - dataFixed), compressionDataSize); if (command == TcpServer.Server.RemoteExpressionCommandIndex) Sender.GetRemoteExpression(ref data, Server.Attribute.IsServerBuildOutputThread); else Sender.GetRemoteExpressionNodeId(ref data, Server.Attribute.IsServerBuildOutputThread); start += compressionDataSize; break; } buffer.PoolBuffer.Free(); return false; default: if ((CommandIndex & (uint)TcpServer.CommandFlags.NullData) == 0) { if ((compressionDataSize = *(int*)(start + sizeof(int))) > 0 && (start += sizeof(int) * 2) + compressionDataSize <= end) { if (MarkData != 0) TcpServer.CommandBuffer.Mark(start, MarkData, compressionDataSize); data.Set((int)(start - dataFixed), compressionDataSize); Server.DoCommand(command, Sender, ref data); start += compressionDataSize; break; } buffer.PoolBuffer.Free(); return false; } Server.DoCommand(command, Sender, ref SubArray<byte>.Null); start += sizeof(int); break; } } else { buffer.PoolBuffer.Free(); return false; } } while (start < end); } return true; } return false; }
/// <summary> /// 数据缓冲区 /// </summary> /// <param name="bufferCount">数据缓冲区计数</param> /// <param name="index">起始位置</param> /// <param name="count">字节数量</param> internal Buffer(BufferCount bufferCount, int index, int count) { this.bufferCount = bufferCount; array.Set(bufferCount.Buffer.Buffer, index, count); ++bufferCount.Count; }
/// <summary> /// 流合并命令处理 /// </summary> /// <param name="data">输入数据</param> internal void Merge(ref SubArray<byte> data) { int receiveCount = data.Length; if (receiveCount >= (sizeof(int) + sizeof(uint))) { try { byte[] dataArray = data.GetFixedBuffer(); fixed (byte* dataFixed = dataArray) { int receiveIndex = data.Start, receiveSize; receiveCount += data.Start; do { byte* start = dataFixed + receiveIndex; if (!Server.IsCommand(command = *(int*)start) || !IsCommand(command)) break; switch (command - TcpServer.Server.MinCommandIndex) { case TcpServer.Server.CancelKeepCommandIndex - TcpServer.Server.MinCommandIndex: if (*(int*)(start + (sizeof(int) * 2)) != 0 || receiveCount - (receiveIndex += sizeof(int) * 3) < 0) { DisposeSocket(); return; } Sender.CancelKeepCallback(*(int*)(start + sizeof(int))); break; case TcpServer.Server.CustomDataCommandIndex - TcpServer.Server.MinCommandIndex: if ((dataSize = *(int*)(start + (sizeof(uint) + sizeof(int)))) < 0 || dataSize > receiveCount - (receiveIndex += (sizeof(int) * 2 + sizeof(uint))) || (customDataSize = *(int*)(start + sizeof(int))) < 0 || (uint)(dataSize - customDataSize) >= 4) { DisposeSocket(); return; } data.Set(receiveIndex, customDataSize); Server.CustomData(ref data); receiveIndex += dataSize; break; case TcpServer.Server.RemoteExpressionCommandIndex - TcpServer.Server.MinCommandIndex: case TcpServer.Server.RemoteExpressionNodeIdCommandIndex - TcpServer.Server.MinCommandIndex: if (((CommandIndex = *(uint*)(start + sizeof(int))) & (uint)TcpServer.CommandFlags.NullData) != 0 || (dataSize = *(int*)(start + (sizeof(uint) + sizeof(int)))) <= 0 || dataSize > receiveCount - (receiveIndex += (sizeof(int) * 2 + sizeof(uint)))) { DisposeSocket(); return; } data.Set(receiveIndex, dataSize); if (command == TcpServer.Server.RemoteExpressionCommandIndex) Sender.GetRemoteExpression(ref data); else Sender.GetRemoteExpressionNodeId(ref data); receiveIndex += dataSize; break; default: if (((CommandIndex = *(uint*)(start + sizeof(int))) & (uint)TcpServer.CommandFlags.NullData) == 0) { if ((dataSize = *(int*)(start + (sizeof(uint) + sizeof(int)))) <= 0 || dataSize > receiveCount - (receiveIndex += (sizeof(int) * 2 + sizeof(uint)))) { DisposeSocket(); return; } data.Set(receiveIndex, dataSize); Server.DoCommand(command, Sender, ref data); receiveIndex += dataSize; } else { Server.DoCommand(command, Sender, ref SubArray<byte>.Null); receiveIndex += (sizeof(int) + sizeof(uint)); } break; } if ((receiveSize = receiveCount - receiveIndex) == 0) return; } while (receiveSize >= (sizeof(int) + sizeof(uint))); } } catch (Exception error) { Server.Log.Exception(error, null, LogLevel.Exception | LogLevel.AutoCSer); } } DisposeSocket(); }
/// <summary> /// 合并命令处理 /// </summary> /// <param name="data"></param> internal void Merge(ref SubArray <byte> data) { try { byte[] dataArray = data.Array; ClientCommand.Command command; int receiveIndex = data.Start, receiveCount = data.EndIndex; ReturnType type; fixed(byte *dataFixed = data.Array) { byte *start; do { int receiveSize = receiveCount - receiveIndex; if (receiveSize < sizeof(uint)) { if (receiveSize == 0) { return; } break; } CommandIndex = *(uint *)(start = dataFixed + receiveIndex); if ((type = Server.GetReturnType(ref CommandIndex)) == ReturnType.Unknown) { if (receiveSize < (sizeof(uint) + sizeof(int))) { break; } if ((dataSize = *(int *)(start + sizeof(uint))) <= 0) { break; } if (dataSize > (receiveSize -= (sizeof(uint) + sizeof(int)))) { break; } receiveIndex += (sizeof(uint) + sizeof(int)); //if ((command = CommandIndex == keepCallbackCommandIndex ? keepCallbackCommand : getCommand()) != null) if ((command = CommandPool.GetCommand((int)CommandIndex)) != null) { //if (command.CommandInfo.TaskType == ClientTaskType.Synchronous) //{ // data.Set(receiveIndex, dataSize); // command.OnReceiveSynchronous(ref data); //} //else if (command.CommandInfo.IsKeepCallback == 0) command.CopyDataRunTask(dataArray, receiveIndex, dataSize); //else new CommandKeepDataTask().CopyData(command, dataArray, receiveIndex, dataSize); data.Set(receiveIndex, dataSize); command.OnReceive(ref data); } receiveIndex += dataSize; } else { onReceive(type); receiveIndex += sizeof(uint); } }while (true); } } catch (Exception error) { Log.Add(AutoCSer.Log.LogType.Error, error); } mergeError(); }
internal void SetName(byte[] buffer, int startIndex, int length) { name.Set(buffer, startIndex, length); value.Set(0, 0); FileName = null; }
/// <summary> /// 数据缓冲区 /// </summary> /// <param name="size">字节数量</param> internal Buffer(int size) { Array.Set(new byte[size], 0, size); }
internal void SetSendDataCopyBuffer(int size) { Data.Set(CopyBuffer.Buffer, CopyBuffer.StartIndex, size); }
internal void DeSerializeTcpServer(ref SubArray <byte> data, byte *read, int size) { data.Set(Buffer, (int)(read - start) + bufferIndex, size); }