/// <summary> /// DataTable拆包 /// </summary> /// <param name="table"></param> /// <param name="builder">数据对象拆包器</param> private unsafe void get(DataTable table, dataReader builder) { int index = 0; DataColumn[] columns = new DataColumn[columnNames.Length]; fixed(byte *columnFixed = columnTypes) { byte *columnIndex = columnFixed; foreach (string columnName in columnNames) { columns[index++] = new DataColumn(columnName, *columnIndex < types.Length ? types[*columnIndex] : typeof(object)); ++columnIndex; } table.Columns.AddRange(columns); fixed(byte *nullFixed = dbNull) { fixedMap nullMap = new fixedMap(nullFixed); for (index = 0; rowCount != 0; --rowCount) { object[] values = new object[columnNames.Length]; columnIndex = columnFixed; for (int valueIndex = 0; valueIndex != columnNames.Length; ++valueIndex) { values[valueIndex] = nullMap.Get(index++) ? DBNull.Value : builder.Get(*columnIndex); ++columnIndex; } DataRow row = table.NewRow(); row.ItemArray = values; table.Rows.Add(row); } } } }
/// <summary> /// 注销TCP服务信息 /// </summary> /// <param name="identity">TCP服务端标识</param> /// <param name="service">TCP服务信息</param> /// <returns>TCP服务端口信息集合信息是否被修改</returns> private unsafe bool removeRegister(indexIdentity identity, services service) { int count = (service.Hosts.Length + 7) >> 3, index = 0; byte * isRemove = stackalloc byte[count]; fixedMap removeMap = new fixedMap(isRemove, count); count = 0; indexIdentity hostIdentity; foreach (host host in service.Hosts) { if (hostClients.TryGetValue(host, out hostIdentity) && hostIdentity.Equals(identity) == 0) { removeMap.Set(index); } else { ++count; } ++index; } if (count == service.Hosts.Length) { return(false); } hashString serviceName = service.Name; if (count == 0) { foreach (host host in service.Hosts) { hostClients.Remove(host); } service.Hosts = nullValue <host> .Array; return(true); } host[] hosts = new host[count]; count = index = 0; foreach (host host in service.Hosts) { if (removeMap.Get(index++)) { hostClients.Remove(host); } else { hosts[count++] = host; } } service.Hosts = hosts; serviceCache[serviceName] = service; return(true); }
unsafe static httpUtility() { urlMap = new fixedMap(unmanaged.GetStatic(256 >> 3, true)); urlMap.Set('0', 10); urlMap.Set('A', 26); urlMap.Set('a', 26); urlMap.Set('('); urlMap.Set(')'); urlMap.Set('*'); urlMap.Set('-'); urlMap.Set('.'); urlMap.Set('!'); urlMap.Set('_'); }
/// <summary> /// DataTable包装 /// </summary> /// <param name="table"></param> /// <param name="builder">数据流包装器</param> private unsafe void from(DataTable table, dataWriter builder) { int index = 0; columnNames = new string[table.Columns.Count]; fixed(byte *columnFixed = columnTypes = new byte[columnNames.Length]) { byte *columnIndex = columnFixed; foreach (DataColumn column in table.Columns) { if (!typeIndexs.TryGetValue(column.DataType, out *columnIndex)) { *columnIndex = 255; } ++columnIndex; columnNames[index++] = column.ColumnName; } fixed(byte *nullFixed = dbNull = new byte[(columnNames.Length *rowCount + 7) >> 3]) { fixedMap nullMap = new fixedMap(nullFixed); index = 0; foreach (DataRow row in table.Rows) { columnIndex = columnFixed; foreach (object value in row.ItemArray) { if (value == DBNull.Value) { nullMap.Set(index); } else { builder.Append(value, *columnIndex); } ++index; ++columnIndex; } } } } }
/// <summary> /// 解析HTML节点 /// </summary> /// <param name="html"></param> private void create(string html) { int length = html.Length; children = new list<htmlNode>(); if (length < 2) { children.Add(new htmlNode { nodeText = new htmlText { FormatHtml = html }, Parent = this }); } else { int nextIndex, nodeCount; htmlNode nextNode; fixed (char* htmlFixed = html + "<") { fixedMap spaceFixedMap = new fixedMap(spaceMap.Map); fixedMap spaceSplitFixedMap = new fixedMap(spaceSplitMap); fixedMap tagNameFixedMap = new fixedMap(tagNameMap); fixedMap tagNameSplitFixedMap = new fixedMap(tagNameSplitMap); fixedMap attributeSplitFixedMap = new fixedMap(attributeSplitMap); fixedMap attributeNameSplitFixedMap = new fixedMap(attributeNameSplitMap); int startIndex, tagNameLength; string name, htmlValue; char* startChar = htmlFixed, currentChar = htmlFixed, endChar = htmlFixed + length, scriptChar; char splitChar; while (currentChar != endChar) { for (*endChar = '<'; *currentChar != '<'; ++currentChar) ; if (currentChar != endChar) { if ((*++currentChar & 0xff80) == 0) { if (tagNameFixedMap.Get(*currentChar)) { while ((*startChar & 0xffc0) == 0 && spaceFixedMap.Get(*startChar)) ++startChar; if (startChar != currentChar - 1) { for (scriptChar = currentChar - 2; (*scriptChar & 0xffc0) == 0 && spaceFixedMap.Get(*scriptChar); --scriptChar) ; children.Add(new htmlNode { nodeText = new htmlText { FormatHtml = html.Substring((int)(startChar - htmlFixed), (int)(scriptChar - startChar) + 1) } }); } if (*currentChar == '/') { #region 标签回合 startChar = currentChar - 1; if (++currentChar != endChar) { while ((*currentChar & 0xffc0) == 0 && spaceFixedMap.Get(*currentChar)) ++currentChar; if (currentChar != endChar) { if ((uint)((*currentChar | 0x20) - 'a') <= 26) { for (*endChar = '>'; (*currentChar & 0xffc0) != 0 || !tagNameSplitFixedMap.Get(*currentChar); ++currentChar) ; TagName = html.Substring((int)((startChar += 2) - htmlFixed), (int)(currentChar - startChar)).toLower(); for (startIndex = children.Count - 1; startIndex >= 0 && (children[startIndex].nodeText.FormatHtml != null || children[startIndex].TagName != TagName); --startIndex) ; if (startIndex != -1) { for (nextIndex = children.Count - 1; nextIndex != startIndex; --nextIndex) { nextNode = children[nextIndex]; if (nextNode.nodeText.FormatHtml == null) { if (web.html.MustRoundTagNames.Contains(nextNode.TagName) && (nodeCount = (children.Count - nextIndex - 1)) != 0) { nextNode.children = new list<htmlNode>(children.GetSub(nextIndex + 1, nodeCount), true); children.RemoveRange(nextIndex + 1, nodeCount); foreach (htmlNode value in nextNode.children) value.Parent = nextNode; } } else if (nextNode.nodeText.FormatHtml.Length == 0) nextNode.nodeText.FormatHtml = null; } nextNode = children[startIndex]; if ((nodeCount = children.Count - ++startIndex) != 0) { nextNode.children = new list<htmlNode>(children.GetSub(startIndex, nodeCount), true); children.RemoveRange(startIndex, nodeCount); foreach (htmlNode value in nextNode.children) value.Parent = nextNode; } nextNode.nodeText.FormatHtml = string.Empty;//已回合标识 } while (*currentChar != '>') ++currentChar; if (currentChar != endChar) ++currentChar; } else { for (*endChar = '>'; *currentChar != '>'; ++currentChar) ; if (currentChar != endChar) ++currentChar; htmlValue = html.Substring((int)(startChar - htmlFixed), (int)(currentChar - startChar)); children.Add(new htmlNode { TagName = "/", nodeText = new htmlText { FormatHtml = htmlValue, FormatText = htmlValue } }); } startChar = currentChar; } } #endregion } else if (*currentChar != '!') { #region 标签开始 startChar = currentChar; children.Add(nextNode = new htmlNode()); for (*endChar = '>'; (*currentChar & 0xffc0) != 0 || !tagNameSplitFixedMap.Get(*currentChar); ++currentChar) ; nextNode.TagName = html.Substring((int)(startChar - htmlFixed), (int)(currentChar - startChar)).toLower(); if (currentChar == endChar) startChar = endChar; else { #region 属性解析 if (*currentChar != '>') { startChar = ++currentChar; while (currentChar != endChar) { while ((*currentChar & 0xffc0) == 0 && attributeSplitFixedMap.Get(*currentChar)) ++currentChar; if (*currentChar == '>') { if (currentChar != endChar) { if (*(currentChar - 1) == '/') nextNode.nodeText.FormatHtml = string.Empty; startChar = ++currentChar; } break; } else { for (startChar = currentChar++; (*currentChar & 0xffc0) != 0 || !tagNameSplitFixedMap.Get(*currentChar); ++currentChar) ; htmlValue = name = checkName(html.Substring((int)(startChar - htmlFixed), (int)(currentChar - startChar)).toLower()); if (currentChar != endChar && ((*currentChar & 0xffc0) != 0 || !attributeNameSplitFixedMap.Get(*currentChar))) { if (*currentChar != '=') { while ((*currentChar & 0xffc0) == 0 && spaceFixedMap.Get(*currentChar)) ++currentChar; } if (*currentChar == '=') { while ((*++currentChar & 0xffc0) == 0 && spaceFixedMap.Get(*currentChar)) ; if ((splitChar = *currentChar) != '>') { if (splitChar == '"' || splitChar == '\'') { for (startChar = ++currentChar, *endChar = splitChar; *currentChar != splitChar; ++currentChar) ; *endChar = '>'; } else { for (startChar = currentChar++; (*currentChar & 0xffc0) != 0 || !spaceSplitFixedMap.Get(*currentChar); ++currentChar) ; } htmlValue = html.Substring((int)(startChar - htmlFixed), (int)(currentChar - startChar)); } } } if (nextNode.attributes == null) nextNode.attributes = new Dictionary<string, htmlText>(); nextNode.attributes[name] = new htmlText { FormatHtml = htmlValue }; if (currentChar != endChar) { if (*currentChar == '>') { if (*(currentChar - 1) == '/') nextNode.nodeText.FormatHtml = string.Empty; startChar = ++currentChar; break; } startChar = ++currentChar; } } } } else startChar = ++currentChar; #endregion #region 非解析标签 if (currentChar == endChar) startChar = endChar; else if (web.html.NonanalyticTagNames.Contains(TagName = nextNode.TagName)) { scriptChar = endChar; tagNameLength = TagName.Length + 2; fixed (char* tagNameFixed = TagName) { while ((int)(endChar - currentChar) > tagNameLength) { for (currentChar += tagNameLength; *currentChar != '>'; ++currentChar) ; if (currentChar != endChar && *(int*)(currentChar - tagNameLength) == (('/' << 16) + '<')) { if (unsafer.String.EqualCase(currentChar - TagName.Length, tagNameFixed, TagName.Length)) { scriptChar = currentChar - tagNameLength; if (currentChar != endChar) ++currentChar; break; } } } } if (startChar != scriptChar) { nextNode.nodeText.FormatHtml = nextNode.nodeText.FormatText = html.Substring((int)(startChar - htmlFixed), (int)(scriptChar - startChar)); } if (scriptChar == endChar) currentChar = endChar; startChar = currentChar; } #endregion } #endregion } else { #region 注释 startChar = currentChar - 1; if (++currentChar != endChar) { *endChar = '>'; if ((length = (int)(endChar - currentChar)) > 2 && *(int*)currentChar == (('-' << 16) + '-')) { for (currentChar += 2; *currentChar != '>'; ++currentChar) ; while (currentChar != endChar && *(int*)(currentChar - 2) != (('-' << 16) + '-')) { if ((currentChar += 3) < endChar) { while (*currentChar != '>') ++currentChar; } else currentChar = endChar; } } else if (length > 9 && (*(int*)currentChar & 0x200000) == ('[' + ('c' << 16)) && (*(int*)(currentChar + 2) & 0x200020) == ('d' + ('a' << 16)) && (*(int*)(currentChar + 4) & 0x200020) == ('t' + ('a' << 16)) && *(currentChar + 6) == '[') { for (currentChar += 9; *currentChar != '>'; ++currentChar) ; while (currentChar != endChar && *(int*)(currentChar - 2) != ((']' << 16) + ']')) { if ((currentChar += 3) < endChar) { while (*currentChar != '>') ++currentChar; } else currentChar = endChar; } } else { while (*currentChar != '>') ++currentChar; } if (currentChar != endChar) ++currentChar; } htmlValue = html.Substring((int)(startChar - htmlFixed), (int)(currentChar - startChar) + (*(currentChar - 1) == '>' ? 0 : 1)); children.Add(new htmlNode { TagName = "!", nodeText = new htmlText { FormatHtml = htmlValue, FormatText = htmlValue } }); startChar = currentChar; #endregion } } } else ++currentChar; } } if (startChar != endChar) { *endChar = '>'; while ((*startChar & 0xffc0) == 0 && spaceFixedMap.Get(*startChar)) ++startChar; if (startChar != endChar) { for (scriptChar = endChar - 1; (*scriptChar & 0xffc0) == 0 && spaceFixedMap.Get(*scriptChar); --scriptChar) ; children.Add(new htmlNode { nodeText = new htmlText { FormatHtml = html.Substring((int)(startChar - htmlFixed), (int)(scriptChar - startChar) + 1) } }); } } } for (nextIndex = children.Count - 1; nextIndex != -1; nextIndex--) { nextNode = children[nextIndex]; if (nextNode.nodeText.FormatHtml == null) { if (web.html.MustRoundTagNames.Contains(nextNode.TagName) && (nodeCount = (children.Count - nextIndex - 1)) != 0) { nextNode.children = new list<htmlNode>(children.GetSub(nextIndex + 1, nodeCount), true); children.RemoveRange(nextIndex + 1, nodeCount); foreach (htmlNode value in children) value.Parent = nextNode; } } else if (nextNode.nodeText.FormatHtml.Length == 0) nextNode.nodeText.FormatHtml = null; } foreach (htmlNode value in children) value.Parent = this; } }
/// <summary> /// URL编码 /// </summary> /// <param name="value"></param> /// <returns></returns> public static unsafe string UrlEncode(string value) { if (!string.IsNullOrEmpty(value)) { fixedMap map = urlMap; fixed(char *valueFixed = value) { char *start = valueFixed, end = valueFixed + value.Length; int length = 0, isSpace = 0; do { if (*((byte *)start + 1) == 0) { if (!map.Get(*(byte *)start)) { if (*start == ' ') { isSpace = 1; } else { length += 2; } } } else { length += 5; } }while (++start != end); if ((length | isSpace) != 0) { string url = fastCSharp.String.FastAllocateString(value.Length + length); fixed(char *urlFixed = url) { char *write = urlFixed; start = valueFixed; do { if (*((byte *)start + 1) == 0) { if (map.Get(*(byte *)start)) { *write++ = *start; } else if (*start == ' ') { *write++ = '+'; } else { * write = '%'; int code = *((byte *)start) >> 4; *(write + 1) = (char)(code + (code < 10 ? '0' : ('0' + 'A' - '9' - 1))); code = *((byte *)start) & 0xf; *(write + 2) = (char)(code + (code < 10 ? '0' : ('0' + 'A' - '9' - 1))); write += 3; } } else { int code = *((byte *)start + 1) >> 4; *(int *)write = '%' + ('u' << 16); *(write + 2) = (char)(code + (code < 10 ? '0' : ('0' + 'A' - '9' - 1))); code = *((byte *)start + 1) & 0xf; *(write + 3) = (char)(code + (code < 10 ? '0' : ('0' + 'A' - '9' - 1))); code = *((byte *)start) >> 4; *(write + 4) = (char)(code + (code < 10 ? '0' : ('0' + 'A' - '9' - 1))); code = *((byte *)start) & 0xf; *(write + 5) = (char)(code + (code < 10 ? '0' : ('0' + 'A' - '9' - 1))); write += 6; } }while (++start != end); } return(url); } } } return(value); }
/// <summary> /// 文本分词 /// </summary> /// <param name="text">文本</param> /// <param name="length">文本长度</param> /// <returns>分词结果</returns> private unsafe list <subString> getWords(string text, int length) { fixed(char *textFixed = text) { simplified.Format(textFixed, length); int count = (length + 7) >> 3; byte * match = stackalloc byte[count]; fixedMap matchMap = new fixedMap(match, count, 0); list <subString> words = typePool <list <subString> > .Pop(); if (words == null) { words = new list <subString>(); } else if (words.Count != 0) { words.Clear(); } list <keyValue <int, int> > matchs = typePool <list <keyValue <int, int> > > .Pop() ?? new list <keyValue <int, int> >(); byte * charTypes = charTypePointer.Byte; subString matchWord = default(subString); for (char *start = textFixed, end = textFixed + length; start != end;) { if (*start == ' ') { *end = '?'; while (*++start == ' ') { ; } } else { * end = ' '; char *segment = start; if ((uint)(*start - 0x4E00) <= 0X9FA5 - 0x4E00) { while ((uint)(*++start - 0x4E00) <= 0X9FA5 - 0x4E00) { ; } if ((length = (int)(start - segment)) == 1) { words.Add(subString.Unsafe(text, (int)(segment - textFixed), 1)); } else { int startIndex = (int)(segment - textFixed); matchs.Empty(); matchWord.UnsafeSet(text, startIndex, length); wordTrieGraph.LeftRightMatchs(ref matchWord, matchs); if ((count = matchs.Count) != 0) { foreach (keyValue <int, int> value in matchs.UnsafeArray) { words.Add(subString.Unsafe(text, value.Key, value.Value)); matchMap.Set(value.Key, value.Value); if (--count == 0) { break; } } } int index = startIndex; for (int endIndex = startIndex + length; index != endIndex; ++index) { if (matchMap.Get(index)) { if ((count = index - startIndex) != 1) { words.Add(subString.Unsafe(text, startIndex, count)); } startIndex = index; } else { words.Add(subString.Unsafe(text, index, 1)); } } if ((index -= startIndex) > 1) { words.Add(subString.Unsafe(text, startIndex, index)); } } } else { byte type = charTypes[*start]; if (type == (byte)charType.OtherLetter) { while (charTypes[*++start] == (byte)charType.OtherLetter) { ; } } else { char *word = start; for (byte newType = charTypes[*++start]; newType >= (byte)charType.Letter; newType = charTypes[*++start]) { if (type != newType) { if (type != (byte)charType.Keep) { words.Add(subString.Unsafe(text, (int)(word - textFixed), (int)(start - word))); } type = newType; word = start; } } } words.Add(subString.Unsafe(text, (int)(segment - textFixed), (int)(start - segment))); } } } typePool <list <keyValue <int, int> > > .PushNotNull(matchs); if ((count = words.Count) == 0) { typePool <list <subString> > .PushNotNull(words); return(null); } return(words); } }