using System; using System.IO; using System.Runtime.Serialization; namespace Mirror.SimpleWeb { public static class ReadHelper { /// /// Reads exactly length from stream /// /// outOffset + length /// 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 interrupt is called we don't care about Exceptions Utils.CheckForInterupt(); // rethrow ae.Handle(e => false); } if (received != length) { throw new ReadHelperException("returned not equal to length"); } return outOffset + received; } /// /// Reads and returns results. This should never throw an exception /// 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) { } } }