using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; namespace SuperSocket.Common { /// /// Binary util class /// public static class BinaryUtil { /// /// Search target from source. /// /// /// The source. /// The target. /// The pos. /// The length. /// public static int IndexOf(this IList source, T target, int pos, int length) where T : IEquatable { for (int i = pos; i < pos + length; i++) { if (source[i].Equals(target)) return i; } return -1; } /// /// Searches the mark from source. /// /// /// The source. /// The mark. /// Length of the parsed. /// public static int? SearchMark(this IList source, T[] mark, out int parsedLength) where T : IEquatable { return SearchMark(source, 0, source.Count, mark, 0, out parsedLength); } /// /// Searches the mark from source. /// /// /// The source. /// The mark. /// public static int? SearchMark(this IList source, T[] mark) where T : IEquatable { int parsedLength; return SearchMark(source, 0, source.Count, mark, 0, out parsedLength); } /// /// Searches the mark from source. /// /// /// The source. /// The offset. /// The length. /// The mark. /// public static int? SearchMark(this IList source, int offset, int length, T[] mark) where T : IEquatable { int parsedLength; return SearchMark(source, offset, length, mark, 0, out parsedLength); } /// /// Searches the mark from source. /// /// /// The source. /// The offset. /// The length. /// The mark. /// Length of the parsed. /// public static int? SearchMark(this IList source, int offset, int length, T[] mark, out int parsedLength) where T : IEquatable { return SearchMark(source, offset, length, mark, 0, out parsedLength); } /// /// Searches the mark from source. /// /// /// The source. /// The offset. /// The length. /// The mark. /// The matched. /// public static int? SearchMark(this IList source, int offset, int length, T[] mark, int matched) where T : IEquatable { int parsedLength; return source.SearchMark(offset, length, mark, matched, out parsedLength); } /// /// Searches the mark from source. /// /// /// The source. /// The offset. /// The length. /// The mark. /// The matched. /// Length of the parsed. /// public static int? SearchMark(this IList source, int offset, int length, T[] mark, int matched, out int parsedLength) where T : IEquatable { int pos = offset; int endOffset = offset + length - 1; int matchCount = matched; parsedLength = 0; if (matched > 0) { for (int i = matchCount; i < mark.Length; i++) { if (!source[pos++].Equals(mark[i])) break; matchCount++; if (pos > endOffset) { if (matchCount == mark.Length) { parsedLength = mark.Length - matched; return offset; } else { return (0 - matchCount); } } } if (matchCount == mark.Length) { parsedLength = mark.Length - matched; return offset; } pos = offset; matchCount = 0; } while (true) { pos = source.IndexOf(mark[matchCount], pos, length - pos + offset); if (pos < 0) return null; matchCount += 1; for (int i = matchCount; i < mark.Length; i++) { int checkPos = pos + i; if (checkPos > endOffset) { //found end, return matched chars count return (0 - matchCount); } if (!source[checkPos].Equals(mark[i])) break; matchCount++; } //found the full end mark if (matchCount == mark.Length) { parsedLength = pos - offset + mark.Length; return pos; } //Reset next round read pos pos += 1; //clear matched chars count matchCount = 0; } } /// /// Searches the mark from source. /// /// /// The source. /// The offset. /// The length. /// State of the search. /// Length of the parsed. /// public static int SearchMark(this IList source, int offset, int length, SearchMarkState searchState, out int parsedLength) where T : IEquatable { int? result = source.SearchMark(offset, length, searchState.Mark, searchState.Matched, out parsedLength); if (!result.HasValue) { searchState.Matched = 0; return -1; } if (result.Value < 0) { searchState.Matched = 0 - result.Value; return -1; } searchState.Matched = 0; return result.Value; } /// /// Searches the mark from source. /// /// /// The source. /// The offset. /// The length. /// State of the search. /// public static int SearchMark(this IList source, int offset, int length, SearchMarkState searchState) where T : IEquatable { var parsedLen = 0; return SearchMark(source, offset, length, searchState, out parsedLen); } /// /// Startses the with. /// /// /// The source. /// The mark. /// public static int StartsWith(this IList source, T[] mark) where T : IEquatable { return source.StartsWith(0, source.Count, mark); } /// /// Startses the with. /// /// /// The source. /// The offset. /// The length. /// The mark. /// public static int StartsWith(this IList source, int offset, int length, T[] mark) where T : IEquatable { int pos = offset; int endOffset = offset + length - 1; for (int i = 0; i < mark.Length; i++) { int checkPos = pos + i; if (checkPos > endOffset) return i; if (!source[checkPos].Equals(mark[i])) return -1; } return mark.Length; } /// /// Endses the with. /// /// /// The source. /// The mark. /// public static bool EndsWith(this IList source, T[] mark) where T : IEquatable { return source.EndsWith(0, source.Count, mark); } /// /// Endses the with. /// /// /// The source. /// The offset. /// The length. /// The mark. /// public static bool EndsWith(this IList source, int offset, int length, T[] mark) where T : IEquatable { if (mark.Length > length) return false; for (int i = 0; i < Math.Min(length, mark.Length); i++) { if (!mark[i].Equals(source[offset + length - mark.Length + i])) return false; } return true; } /// /// Clones the elements in the specific range. /// /// /// The source. /// The offset. /// The length. /// public static T[] CloneRange(this IList source, int offset, int length) { T[] target; var array = source as T[]; if (array != null) { target = new T[length]; Array.Copy(array, offset, target, 0, length); return target; } target = new T[length]; for (int i = 0; i < length; i++) { target[i] = source[offset + i]; } return target; } } }