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;
}
}
}