133 lines
3.8 KiB
C#
133 lines
3.8 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Runtime.Serialization;
|
|
|
|
namespace JamesFrowen.SimpleWeb
|
|
{
|
|
public static class ReadHelper
|
|
{
|
|
/// <summary>
|
|
/// Reads exactly length from stream
|
|
/// </summary>
|
|
/// <returns>outOffset + length</returns>
|
|
/// <exception cref="ReadHelperException"></exception>
|
|
public static int Read(Stream stream, byte[] outBuffer, int outOffset, int length)
|
|
{
|
|
int received = 0;
|
|
try
|
|
{
|
|
while (received < length)
|
|
{
|
|
int read = stream.Read(outBuffer, outOffset + received, length - received);
|
|
if (read == 0)
|
|
{
|
|
throw new ReadHelperException("returned 0");
|
|
}
|
|
received += read;
|
|
}
|
|
}
|
|
catch (AggregateException ae)
|
|
{
|
|
// if interupt is called we dont care about Exceptions
|
|
Utils.CheckForInterupt();
|
|
|
|
// rethrow
|
|
ae.Handle(e => false);
|
|
}
|
|
|
|
if (received != length)
|
|
{
|
|
throw new ReadHelperException("returned not equal to length");
|
|
}
|
|
|
|
return outOffset + received;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads and returns results. This should never throw an exception
|
|
/// </summary>
|
|
public static bool TryRead(Stream stream, byte[] outBuffer, int outOffset, int length)
|
|
{
|
|
try
|
|
{
|
|
Read(stream, outBuffer, outOffset, length);
|
|
return true;
|
|
}
|
|
catch (ReadHelperException)
|
|
{
|
|
return false;
|
|
}
|
|
catch (IOException)
|
|
{
|
|
return false;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Exception(e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static int? SafeReadTillMatch(Stream stream, byte[] outBuffer, int outOffset, int maxLength, byte[] endOfHeader)
|
|
{
|
|
try
|
|
{
|
|
int read = 0;
|
|
int endIndex = 0;
|
|
int endLength = endOfHeader.Length;
|
|
while (true)
|
|
{
|
|
int next = stream.ReadByte();
|
|
if (next == -1) // closed
|
|
return null;
|
|
|
|
if (read >= maxLength)
|
|
{
|
|
Log.Error("SafeReadTillMatch exceeded maxLength");
|
|
return null;
|
|
}
|
|
|
|
outBuffer[outOffset + read] = (byte)next;
|
|
read++;
|
|
|
|
// if n is match, check n+1 next
|
|
if (endOfHeader[endIndex] == next)
|
|
{
|
|
endIndex++;
|
|
// when all is match return with read length
|
|
if (endIndex >= endLength)
|
|
{
|
|
return read;
|
|
}
|
|
}
|
|
// if n not match reset to 0
|
|
else
|
|
{
|
|
endIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
Log.InfoException(e);
|
|
return null;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Exception(e);
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class ReadHelperException : Exception
|
|
{
|
|
public ReadHelperException(string message) : base(message) { }
|
|
|
|
protected ReadHelperException(SerializationInfo info, StreamingContext context) : base(info, context)
|
|
{
|
|
}
|
|
}
|
|
}
|