public unsafe static TmphSubArray<int> splitIntNoCheck(this string ints, char split) { TmphSubArray<int> values = new TmphSubArray<int>(); if (ints != null && ints.Length != 0) { fixed (char* intPoint = ints) { int intValue = 0; for (char* next = intPoint, end = intPoint + ints.Length; next != end; ++next) { if (*next == split) { values.Add(intValue); intValue = 0; } else { intValue *= 10; intValue += *next; intValue -= '0'; } } values.Add(intValue); } } return values; }
/// <summary> /// 字节数组比较 /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <returns>是否相等</returns> public static unsafe bool equal(this TmphSubArray<byte> left, TmphSubArray<byte> right) { if (left.Array == null) return right.Array == null; if (left.Count == right.Count) { fixed (byte* leftFixed = left.Array, rightFixed = right.Array) { return Unsafe.TmphMemory.Equal(leftFixed + left.StartIndex, rightFixed + right.StartIndex, left.Count); } } return false; }
/// <summary> /// 获取字段成员集合 /// </summary> /// <param name="type"></param> /// <param name="attribute"></param> /// <param name="memberCountVerify"></param> /// <param name="fixedSize"></param> /// <param name="nullMapSize"></param> /// <returns>字段成员集合</returns> public static TmphSubArray<TmphMemberInfo> GetFields(Type type, TmphDataSerialize attribute, out int memberCountVerify, out int fixedSize, out int nullMapSize) { var fieldIndexs = (TmphFieldIndex[]) typeof(TmphMemberIndexGroup<>).MakeGenericType(type) .GetMethod("GetFields", BindingFlags.Static | BindingFlags.Public) .Invoke(null, new object[] { attribute.MemberFilter }); var fields = new TmphSubArray<TmphMemberInfo>(fieldIndexs.Length); var nullMapIndex = 0; fixedSize = nullMapSize = 0; foreach (var field in fieldIndexs) { type = field.Member.FieldType; if (!type.IsPointer && (!type.IsArray || type.GetArrayRank() == 1) && !field.IsIgnore) { var memberAttribute = field.GetAttribute<TmphBinarySerialize.TmphMember>(true, true); if (memberAttribute == null || memberAttribute.IsSetup) { var value = TmphMemberInfo.GetSerialize(field); if (type != typeof(bool)) fixedSize += value.SerializeFixedSize; nullMapSize += value.NullMapSize; if (value.NullMapSize == 2) { value.SerializeNullMapIndex = nullMapIndex; nullMapIndex += 2; --fixedSize; } fields.Add(value); } } } memberCountVerify = fields.Count + 0x40000000; fixedSize = (fixedSize + 3) & (int.MaxValue - 3); nullMapSize = ((nullMapSize + 31) >> 5) << 2; fields.Sort(TmphMemberInfo.SerializeFixedSizeSort); foreach (var value in fields) { if (value.NullMapSize == 1) value.SerializeNullMapIndex = nullMapIndex++; } return fields; }
/// <summary> /// 获取压缩数据 /// </summary> /// <param name="data">数据</param> /// <returns>压缩数据,失败返回null</returns> internal static TmphSubArray<byte> GetCompress(TmphSubArray<byte> data, TmphMemoryPool memoryPool = null, int seek = 0) { if (data.Count > GZipSize) { var compressData = TmphStream.GZip.GetCompress(data.Array, data.StartIndex, data.Count, seek, memoryPool); if (compressData.Count != 0) { if (compressData.Count + GZipSize < data.Count) return compressData; if (memoryPool != null) memoryPool.Push(ref compressData.array); } } return default(TmphSubArray<byte>); }
/// <summary> /// 添加TCP调用服务端 /// </summary> /// <param name="socket">TCP调用套接字</param> /// <param name="data">参数序列化数据</param> private void newServer(TmphSocket socket, TmphSubArray<byte> data) { try { var host = new TmphHost(); if (TmphDataDeSerializer.DeSerialize(data, ref host)) { TmphThreadPool.TinyPool.FastStart(server.newServerHandle, new TmphServerInfo { Socket = socket, Identity = socket.Identity, Host = host }, null, null); return; } } catch (Exception error) { TmphLog.Error.Add(error, null, true); } socket.SendStream(socket.Identity, new TmphAsynchronousMethod.TmphReturnValue { IsReturn = false }); }
/// <summary> /// HTTP响应Cookie /// </summary> /// <param name="name">名称</param> /// <param name="value">值</param> /// <param name="domain">有效域名</param> /// <param name="path">有效路径</param> /// <param name="isSecure">是否安全</param> /// <param name="isHttpOnly">是否HTTP Only</param> public TmphCookie(string name, string value, string domain, string path, bool isSecure, bool isHttpOnly) { if (name.Length() != 0) Name = name.GetBytes(); if (value.Length() != 0) Value = value.GetBytes(); if (domain.Length() != 0) { var data = domain.GetBytes(); Domain = TmphSubArray<byte>.Unsafe(data, 0, data.Length); } if (path.Length() != 0) Path = path.GetBytes(); IsSecure = isSecure; IsHttpOnly = isHttpOnly; }
/// <summary> /// IPv6包 /// </summary> /// <param name="data">数据</param> public unsafe TmphIp6(TmphSubArray<byte> data) { headerEndIndex = (uint)DefaultHeaderSize; if (data.Count >= DefaultHeaderSize) { fixed (byte* dataFixed = data.Array) { byte* start = dataFixed + data.StartIndex; int packetSize = (*(start + 4) << 8) + *(start + 5), dataLength = DefaultHeaderSize + packetSize; if (dataLength <= data.Count) { data.UnsafeSetLength(dataLength); byte protocol = *(start + 6); if (protocol < 64) { if ((ExpandProtocol & (1UL << protocol)) == 0) this.data = data; else if (packetSize >= 8) { do { protocol = *(start + headerEndIndex); headerEndIndex += 8; if (protocol == (byte)TmphIp.TmphProtocol.IPv6FragmentHeader) { if (headerEndIndex > dataLength) break; } else { headerEndIndex += (uint)(start + headerEndIndex + 1) << 3; if (headerEndIndex > dataLength) break; if (protocol >= 64 || (ExpandProtocol & (1UL << protocol)) == 0) { this.data = data; return; } } } while (true); this.data = default(TmphSubArray<byte>); } else this.data = default(TmphSubArray<byte>); } else this.data = data; } else this.data = default(TmphSubArray<byte>); } } else this.data = default(TmphSubArray<byte>); }
public unsafe int Append(TmphSubArray<byte> data) { fixed (byte* dataFixed = data.array) return Append(dataFixed + data.StartIndex, data.Count); }
/// <summary> /// 字节流转换成JSON字符串 /// </summary> /// <param name="jsonStream">JSON输出流</param> /// <param name="TmphBuffer">字节流数组</param> public static unsafe void ToJson(TmphCharStream jsonStream, TmphSubArray<byte> TmphBuffer) { if (TmphBuffer.Array == null) TmphAjax.WriteNull(jsonStream); else if (TmphBuffer.Count == 0) TmphAjax.WriteArray(jsonStream); else { fixed (byte* bufferFixed = TmphBuffer.Array) { var start = bufferFixed + TmphBuffer.StartIndex; ToJson(jsonStream, start, start + TmphBuffer.Count); } } }
/// <summary> /// 创建数据库文件 /// </summary> /// <param name="identity">数据库物理层唯一标识</param> /// <param name="header">文件头数据</param> /// <returns>是否创建成功</returns> internal bool Create(TmphIdentity identity, TmphSubArray<byte> header) { var physical = physicals[identity.Index]; if (physical.Identity == identity.Identity) { if (physical.Physical.Create(header)) return true; Close(identity, false); } return false; }
/// <summary> /// linuxSLL数据包 /// </summary> /// <param name="data">数据</param> public unsafe TmphLinuxSLL(TmphSubArray<byte> data) { if (data.Count >= HeaderSize) { fixed (byte* dataFixed = data.Array) { byte* start = dataFixed + data.StartIndex; if (data.Count >= ((uint)*(start + 4) << 8) + *(start + 5) + 6) { this.data = data; return; } } } this.data = default(TmphSubArray<byte>); }
/// <summary> /// 图像缩略切剪 /// </summary> /// <param name="data">图像文件数据</param> /// <param name="width">缩略宽度,0表示与高度同比例</param> /// <param name="height">缩略高度,0表示与宽度同比例</param> /// <param name="type">目标图像文件格式</param> /// <returns>图像缩略文件数据</returns> public static TmphSubArray<byte> Cut(TmphSubArray<byte> data, int width, int height, ImageFormat type, TmphMemoryPool TmphMemoryPool = null, int seek = 0) { if (data.Count != 0 && width > 0 && height > 0 && (width | height) != 0 && seek >= 0) { try { using (MemoryStream memory = new MemoryStream(data.Array, data.StartIndex, data.Count)) { TmphBuilder TmphBuilder = new TmphBuilder(); using (Image TmphImage = TmphBuilder.CreateImage(memory)) return TmphBuilder.Get(ref width, ref height, type, TmphMemoryPool, seek); } } catch (Exception error) { TmphLog.Error.Add(error, null, false); } } return default(TmphSubArray<byte>); }
/// <summary> /// IGMP数据包 /// </summary> /// <param name="data">数据</param> public TmphIgmp(TmphSubArray<byte> data) { this.data = data.Count >= DefaultSize ? data : default(TmphSubArray<byte>); }
/// <summary> /// 获取校验和,IP、ICMP、IGMP、TCP和UDP协议采用相同的检验和算法(对首部中每个16bit进行二进制反码求和,如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该为全1。) /// </summary> /// <param name="data">待校验数据</param> /// <param name="checkSum">校验和初始值,默认应为0</param> /// <returns>校验和</returns> public unsafe static ushort CreateCheckSum(TmphSubArray<byte> data, uint checkSum = 0) { fixed (byte* fixedData = data.Array) { byte* start = fixedData + data.StartIndex, end = start + data.Count - 1; while (start < end) { checkSum += *((ushort*)start); start += 2; } if (start == end) checkSum += *start; } checkSum = (checkSum >> 16) + (checkSum & 0xffffU); return (ushort)(~(checkSum + (checkSum >> 16))); }
/// <summary> /// 初始化IP数据包 /// </summary> /// <param name="data">数据</param> public unsafe TmphIp(TmphSubArray<byte> data) { if (data.Count >= DefaultHeaderSize) { fixed (byte* dataFixed = data.Array) { byte* start = dataFixed + data.StartIndex; uint packetSize = ((uint)*(start + 2) << 8) + *(start + 3); if (packetSize >= ((*start & 15) << 2) && packetSize <= data.Count) { this.data = TmphSubArray<byte>.Unsafe(data.Array, data.StartIndex, (int)packetSize); return; } } } this.data = default(TmphSubArray<byte>); }
/// <summary> /// ICMP V6数据包 /// </summary> /// <param name="data">数据</param> public TmphIcmp6(TmphSubArray<byte> data) { if (data.Count >= 8) { byte type = data.Array[data.StartIndex]; if (type < typeCount) { int minSize = minTypeSize[type]; if (minSize != 0 && data.Count >= minSize) { this.data = data; return; } } } this.data = default(TmphSubArray<byte>); }
/// <summary> /// 写入文件数据 /// </summary> /// <param name="data">数据</param> /// <returns>写入文件字节数</returns> private int writeFile(TmphSubArray<byte> data) { int count = data.Count, length = currentIndex + count; if (length < bufferLength) { Buffer.BlockCopy(data.Array, data.StartIndex, TmphBuffer, currentIndex, count); currentIndex = length; return 0; } var dataArray = data.Array; var index = data.StartIndex; length = bufferLength - currentIndex; if (currentIndex == startIndex) { fileStream.Write(dataArray, index, length += ((count - length) / bufferLength) * bufferLength); index += length; count -= length; } else { Buffer.BlockCopy(dataArray, index, TmphBuffer, currentIndex, length); index += length; count -= length; fileStream.Write(TmphBuffer, startIndex, length = bufferLength - startIndex); var size = count / bufferLength; if (size != 0) { fileStream.Write(dataArray, index, size *= bufferLength); index += size; count -= size; length += size; } } Buffer.BlockCopy(dataArray, index, TmphBuffer, startIndex = 0, currentIndex = count); return length; }
/// <summary> /// 写入日志 /// </summary> /// <param name="identity">数据库物理层唯一标识</param> /// <param name="data">日志数据</param> /// <returns>是否成功写入缓冲区</returns> internal int Append(TmphIdentity identity, TmphSubArray<byte> data) { var physical = physicals[identity.Index]; if (physical.Identity == identity.Identity) { var value = physical.Physical.Append(data); if (value != 0) return value; Close(identity, false); } return 0; }
/// <summary> /// UDP数据包 /// </summary> /// <param name="data">数据</param> public unsafe TmphUdp(TmphSubArray<byte> data) { if (data.Count >= HeaderSize) { fixed (byte* dataFixed = data.Array) { byte* start = dataFixed + data.StartIndex; uint packetSize = (uint)(((int)*(start + 4) << 8) + *(start + 5)); if (data.Count >= packetSize) { this.data = TmphSubArray<byte>.Unsafe(data.Array, data.StartIndex, (int)packetSize); return; } } } this.data = default(TmphSubArray<byte>); }
/// <summary> /// 以太网会话点到点协议数据包 /// </summary> /// <param name="data">数据</param> public unsafe TmphEthernetSessionP2P(TmphSubArray<byte> data) { if (data.Count >= HeaderSize) { fixed (byte* dataFixed = data.Array) { byte* start = dataFixed + data.StartIndex; uint packetSize = ((uint)*(start + 4) << 8) + *(start + 5); if (data.Count >= packetSize) { this.data = data; return; } } } this.data = default(TmphSubArray<byte>); }
public unsafe bool Create(TmphSubArray<byte> data) { fixed (byte* dataFixed = data.array) return Create(dataFixed + data.StartIndex, data.Count); }
public int Search(TmphSubArray<byte> data) { fixed (byte* dataFixed = data.array) { var start = dataFixed + data.StartIndex; return search(start, start + data.Count); } }
/// <summary> /// 读取文件线程 /// </summary> private unsafe void read() { int startIndex = 0, nextCount = sizeof(int) * 3; try { var headerBuffer = new byte[sizeof(int) * 3]; if (fileStream.Read(headerBuffer, 0, sizeof(int) * 3) != sizeof(int) * 3) return; fixed (byte* bufferFixed = headerBuffer) { if (*(int*)bufferFixed != Emit.TmphPub.PuzzleValue) return; var headerSize = *(int*)(bufferFixed + sizeof(int)); if (headerSize > size || headerSize < sizeof(int) * 3 || (headerSize & 3) != 0) return; var bufferSize = *(int*)(bufferFixed + sizeof(int) * 2); if ((bufferSize & (bufferSize - 1)) != 0 || (bufferSize >> 12) == 0 || headerSize > bufferSize) return; size -= headerSize; physical.setLoadBuffer(bufferSize); if (fileStream.Read(physical.loadBuffer, sizeof(int), headerSize -= sizeof(int) * 3) != headerSize) return; fixed (byte* loaderBufferFixed = physical.loadBuffer) *(int*)loaderBufferFixed = bufferSize; data.UnsafeSet(physical.loadBuffer, 0, headerSize + sizeof(int)); waitHandle.Set(); nextCount = 0; } byte[] TmphBuffer = physical.TmphBuffer, bigBuffer = TmphNullValue<byte>.Array; var isBigBuffer = 0; fixed (byte* bufferFixed = TmphBuffer) { while (isDisposed == 0 && (size | (uint)nextCount) != 0) { if (nextCount == 0) { if ( fileStream.Read(TmphBuffer, startIndex = 0, nextCount = (int)Math.Min(TmphBuffer.Length, size)) != nextCount) return; size -= nextCount; } var dataStart = bufferFixed + startIndex; int dataSize = *(int*)dataStart, bufferSize; if (dataSize < 0) { bufferSize = dataSize & 3; bufferSize += (dataSize = -dataSize); } else { if ((dataSize & 3) != 0) return; bufferSize = dataSize; } if (bufferSize > TmphBuffer.Length) { var count = bufferSize - nextCount; if ((size -= count) < 0) return; if (bufferSize > bigBuffer.Length) { var bigSize = (uint)(bigBuffer.Length == 0 ? TmphBuffer.Length : bigBuffer.Length); while (bigSize < bufferSize) bigSize <<= 1; if (bigSize == 0x80000000U) return; bigBuffer = new byte[bigSize]; isBigBuffer = 0; } if (isBigBuffer == 0) { Buffer.BlockCopy(TmphBuffer, startIndex, bigBuffer, 0, nextCount); if (fileStream.Read(bigBuffer, nextCount, count) != count) return; if (*(int*)dataStart < 0) { var newBuffer = TmphStream.Deflate.GetDeCompressUnsafe(bigBuffer, sizeof(int), dataSize - sizeof(int), physical.memoryPool); waitBuffer(); physical.setLoadBuffer(newBuffer.array); data = newBuffer; } else { waitBuffer(); physical.setLoadBuffer(); data.UnsafeSet(bigBuffer, sizeof(int), dataSize - sizeof(int)); isBigBuffer = 1; } } else { waitBuffer(); Buffer.BlockCopy(TmphBuffer, startIndex, bigBuffer, 0, nextCount); if (fileStream.Read(bigBuffer, nextCount, count) != count) return; if (*(int*)dataStart < 0) { var newBuffer = TmphStream.Deflate.GetDeCompressUnsafe(bigBuffer, sizeof(int), dataSize - sizeof(int), physical.memoryPool); physical.setLoadBuffer(newBuffer.array); data = newBuffer; isBigBuffer = 0; } else { physical.setLoadBuffer(); data.UnsafeSet(bigBuffer, sizeof(int), dataSize - sizeof(int)); } } waitHandle.Set(); nextCount = 0; } else { var count = bufferSize - nextCount; if (count > 0) { if (size < count) return; Buffer.BlockCopy(TmphBuffer, startIndex, TmphBuffer, 0, nextCount); if ( fileStream.Read(TmphBuffer, nextCount, count = (int)Math.Min(TmphBuffer.Length - nextCount, size)) != count) return; dataStart = bufferFixed; startIndex = 0; size -= count; nextCount += count; } if (*(int*)dataStart < 0) { var newBuffer = TmphStream.Deflate.GetDeCompressUnsafe(TmphBuffer, startIndex + sizeof(int), bufferSize - sizeof(int), physical.memoryPool); waitBuffer(); physical.setLoadBuffer(newBuffer.array); data = newBuffer; isBigBuffer = 0; } else { waitBuffer(); byte[] newBuffer; if (isBigBuffer == 0) { if (bigBuffer.Length == 0) newBuffer = physical.getLoadBuffer(); else { newBuffer = bigBuffer; isBigBuffer = 1; } } else { newBuffer = physical.getLoadBuffer(); isBigBuffer = 0; } Buffer.BlockCopy(TmphBuffer, startIndex + sizeof(int), newBuffer, 0, bufferSize - sizeof(int)); data.UnsafeSet(newBuffer, 0, bufferSize - sizeof(int)); } waitHandle.Set(); nextCount -= bufferSize; startIndex += bufferSize; } } } if (isDisposed == 0) { waitBuffer(); data.UnsafeSet(physical.TmphBuffer, 0, 0); } } finally { if (nextCount == 0) Dispose(); else { data.Null(); Dispose(); TmphPub.Dispose(ref physical); } } }
/// <summary> /// 获取域名服务信息 /// </summary> /// <param name="domain">域名</param> /// <returns>域名服务信息</returns> internal virtual TmphDomainServer GetServer(TmphSubArray<byte> domain) { var server = domains.Get(domain); return server != null && server.IsStart ? server : null; }
/// <summary> /// HTTP响应Cookie /// </summary> /// <param name="name">名称</param> /// <param name="value">值</param> /// <param name="expires">超时时间,DateTime.MinValue表示忽略</param> /// <param name="domain">有效域名</param> /// <param name="path">有效路径</param> /// <param name="isSecure">是否安全</param> /// <param name="isHttpOnly">是否HTTP Only</param> internal TmphCookie(byte[] name, byte[] value, DateTime expires, TmphSubArray<byte> domain, byte[] path, bool isSecure, bool isHttpOnly) { Name = name; Value = value; Expires = expires; Domain = domain; Path = path; IsSecure = isSecure; IsHttpOnly = isHttpOnly; }
/// <summary> /// 获取域名服务信息 /// </summary> /// <param name="domain">域名</param> /// <returns>域名服务信息</returns> public TmphDomainServer Get(TmphSubArray<byte> domain) { var data = this.data; if (domain.Count != 0 && data.Data != null) { var index = new TmphSearcher(data).Search(domain); if (index >= 0) return Servers[index]; } return null; }
/// <summary> /// TCP调用服务端验证 /// </summary> /// <param name="socket">TCP调用套接字</param> /// <param name="data">参数序列化数据</param> private void verify(TmphSocket socket, TmphSubArray<byte> data) { try { string inputParameter = null; if (TmphDataDeSerializer.DeSerialize(data, ref inputParameter)) { var isVerify = false; if (this.isVerify == null) { if (Config.TmphTcpRegister.Default.Verify == null && !Config.TmphPub.Default.IsDebug) { TmphLog.Error.Add("TCP服务注册验证数据不能为空", false, true); } else isVerify = Config.TmphTcpRegister.Default.Verify == inputParameter; } else isVerify = this.isVerify(data); socket.IsVerifyMethod = true; socket.SendStream(socket.Identity, new TmphAsynchronousMethod.TmphReturnValue<bool> { IsReturn = true, Value = isVerify }); return; } } catch (Exception error) { TmphLog.Error.Add(error, null, true); } socket.SendStream(socket.Identity, new TmphAsynchronousMethod.TmphReturnValue { IsReturn = false }); }
/// <summary> /// 获取数据库物理层唯一标识 /// </summary> /// <param name="data">数据</param> /// <returns>数据库物理层唯一标识</returns> private static unsafe TmphTimeIdentity getIdentity(ref TmphSubArray<byte> data) { TmphTimeIdentity identity; fixed (byte* dataFixed = data.Array) { identity = *(TmphTimeIdentity*)(dataFixed + data.StartIndex); if (identity.TimeTick == TmphPub.StartTime.Ticks) { data.UnsafeSet(data.StartIndex + sizeof(TmphTimeIdentity), data.Count - sizeof(TmphTimeIdentity)); } else data.UnsafeSet(null, 0, 0); } return identity; }
/// <summary> /// 移除TCP调用服务端 /// </summary> /// <param name="socket">TCP调用套接字</param> /// <param name="data">参数序列化数据</param> private void removeServer(TmphSocket socket, TmphSubArray<byte> data) { try { var host = new TmphHost(); if (TmphDataDeSerializer.DeSerialize(data, ref host)) { socket.SendStream(socket.Identity, new TmphAsynchronousMethod.TmphReturnValue<bool> { IsReturn = true, Value = server.removeServer(host) }); return; } } catch (Exception error) { TmphLog.Error.Add(error, null, true); } socket.SendStream(socket.Identity, new TmphAsynchronousMethod.TmphReturnValue { IsReturn = false }); }
/// <summary> /// 根据域名获取IP地址 /// </summary> /// <param name="domain">域名</param> /// <returns>IP地址,失败返回null</returns> public unsafe static IPAddress[] GetIPAddress(TmphSubArray<byte> domain) { try { fixed (byte* domainFixed = domain.Array) { byte* domainStart = domainFixed + domain.StartIndex; Unsafe.TmphMemory.ToLower(domainStart, domainStart + domain.Count); TmphHashBytes key = domain; TmphIpAddress value; TmphInterlocked.NoCheckCompareSetSleep0(ref domainIpLock); try { value = domainIps.Get(key, default(TmphIpAddress)); if (value.Ips != null && value.Timeout < TmphDate.NowSecond) { domainIps.Remove(key, out value); value.Ips = null; } } finally { domainIpLock = 0; } if (value.Ips == null) { if (value.Domain == null) value.Domain = TmphString.DeSerialize(domainStart, -domain.Count); IPAddress ip; if (IPAddress.TryParse(value.Domain, out ip)) { value.Timeout = DateTime.MaxValue; value.Domain = null; setDomainIp(key.Copy(), value); return value.Ips = new IPAddress[] { ip }; } value.Ips = Dns.GetHostEntry(value.Domain).AddressList; if (value.Ips.Length != 0) { value.Timeout = TmphDate.NowSecond.AddTicks(domainIpTimeoutTicks); setDomainIp(key.Copy(), value); return value.Ips; } } else return value.Ips; } } catch (Exception error) { TmphLog.Default.Add(error, null, false); } return null; }