C# バイト配列比較/二分岐岐探査(バイナリサーチ)

// バイト配列比較
// nCompare
//
//
//
0 は等しい
0 より大きいは、bySrcXの方が大きい
0 より小さいは、bySrcXの方が小さい
// 戻り値
//
//
//
呼び出し成功 0
比較する要素がない -1
引数が不正 -2
public static int Compare( out int nCompare, int nLength, byte bySrcX, int nOffsetX, byte bySrcY, int nOffsetY )
{
nCompare = 0;
if( nLength > bySrcX.Length - nOffsetX )
{
nLength = bySrcX.Length - nOffsetX;
}
if( nLength > bySrcY.Length - nOffsetY )
{
nLength = bySrcY.Length - nOffsetY;
}
if( nLength <= 0 )
{
if( nLength == 0 )
{
return -1;
}
return -2;
}
for( int i = 0; i < nLength; i ++ )
{
nCompare = (int)bySrcX[nOffsetX + i] - (int)bySrcY[nOffsetY + i];
 
if( nCompare != 0 )
{
return nCompare;
}
}
 
return 0;
}
// バイト配列 bySrc からバイト配列 byTarget を探す
// バイト配列 bySrc は nBlockLength サイズのブロックの集まりで、
// 昇順になっていること
public static int BinarySearch( byte bySrc, byte byTarget, int nBlockLength )
{
int nBlockNum = bySrc.Length / nBlockLength;
 
int nLow = 0;
int nHigh = nBlockNum - 1;
 
while( nLow < nHigh )
{
int nIndex = (nLow + nHigh) / 2;
int nResult = Compare( out nCompare, byTarget.Length, byTarget, 0, bySrc, nBlockLength * nIndex );
if( nCompare == 0 )
{
// ヒット
return nIndex;
}
if( nCompare < 0 )
{
// 小さい側へ
nHigh = nIndex - 1;
}
else
{
// 大きい側へ
nLow = nIndex + 1;
}
}
 
return -1;
}
 
public static int SearchBlock( byte bySrc, byte byTarget, int nBlockLength )
{
int nIndex = BinarySearch( bySrc, byTarget, nBlockLength );
 
if( nIndex < 0 )
{
// 見つからなかった
return -1;
}
 
 
// 見つかった位置よりも前に一致するものを確認
 
int nBlockNum = bySrc.Length / nBlockLength;
 
while( nIndex > 0 )
{
int nOffset = nBlockLength * (nIndex - 1);
 
int nCompare = Compare( byTarget.Length, bySrc, nOffset, byTarget, 0 );
 
if( nCompare != 0 )
{
break;
}
 
nIndex --;
}
 
return nIndex;
}