public MatchInfo ReadFromBuffer(byte[] bytes, int length, int minLength, TimeSpan? wait = null, bool consume = true) { MatchInfo info = new MatchInfo(); info.BytesConsumed = 0; info.BytesSkipped = 0; info.Matched = true; info.Timeout = false; info.TotalBytesRead = 0; bool timeOut; if (minLength > length) minLength = length; int count = 0; DateTime startTime = DateTime.Now; int immediate; if (BytesUsed >= length) immediate = length; else immediate = BytesUsed; int fromPos = FirstByteUsed; int toPos = 0; for (int cnt = 0; cnt < immediate; cnt++) bytes[toPos++] = LocalBuffer[fromPos++]; count = immediate; if (consume) { BytesUsed -= count; BytesRead += count; // when buffer is empty, set next byte avail to start of buffer if (BytesUsed == 0) NextByteAvail = 0; } if (count < minLength) { int remaining = length - count; // ensure buffer has room to read in the required extra bytes if (!consume && remaining > BytesAvailable) { ShiftOrReallocateBuffer(BytesUsed + remaining); if (remaining > BytesAvailable) { LogMessage("ReadFromBuffer", "Error adjusting buffer for non-consuming read: " + length, LogEntryType.ErrorMessage); info.Matched = false; return info; } } do { int readCount; readCount = ReadFromStreamToBuffer(remaining, out timeOut); if (consume) fromPos = FirstByteUsed; else fromPos = FirstByteUsed + count; toPos = count; for (int cnt = 0; cnt < readCount; cnt++) bytes[toPos++] = LocalBuffer[fromPos++]; count += readCount; if (consume) { BytesRead += readCount; BytesUsed -= readCount; if (BytesUsed == 0) NextByteAvail = 0; } remaining -= readCount; if (count >= minLength) break; if (timeOut) { info.Timeout = true; info.Matched = false; break; } } while (count < length); } info.BytesConsumed = count; info.TotalBytesRead = count; if (SystemServices.LogMessageContent) { LogMessage("ReadFromBuffer", "Matched: " + info.Matched + " - Timeout: " + info.Timeout + " - BytesRead: " + info.BytesRead + " - Bytes[" + count + "] next line", LogEntryType.MeterMessage); FormatDump(bytes, 0, count, SystemServices); } return info; }
public MatchInfo FindInBuffer(byte[] pattern, int maxSkip, bool consume, TimeSpan? wait, bool extractSkipped, out DataChunk skippedChunk) { int totalCount = 0; int maxScan = maxSkip + pattern.Length; DateTime startTime = DateTime.Now; int patternPos = 0; bool matchstarted = false; MatchInfo info = new MatchInfo(); DataChunk skipped; if (extractSkipped) skipped = new DataChunk(maxSkip); else skipped = null; skippedChunk = skipped; int bytesRequired = pattern.Length + maxSkip; if (bytesRequired > BytesAvailable + BytesUsed) ShiftOrReallocateBuffer(bytesRequired); bool skippedExceeded = false; while (totalCount < maxScan && !info.Matched && !skippedExceeded) { int remaining = maxScan - totalCount; if ((BytesUsed - totalCount) == 0) { int readCount; bool timeOut; readCount = ReadFromStreamToBuffer(remaining, out timeOut); if (timeOut) { info.Timeout = true; LogMessage("FindInBuffer", "Timeout: " + wait.Value.ToString(), LogEntryType.MeterMessage); break; } } else if ((BytesUsed - totalCount) < 0) { LogMessage("FindInBuffer", "Logic error - totalCount exceeds buffer content", LogEntryType.ErrorMessage); totalCount = 0; info.Matched = false; info.BytesSkipped = 0; info.BytesConsumed = 0; break; } if ((BytesUsed - totalCount) > 0) { while ((FirstByteUsed + totalCount) < NextByteAvail) { matchstarted = (pattern[patternPos] == LocalBuffer[FirstByteUsed + totalCount++]); if (matchstarted) { if (++patternPos == pattern.Length) { info.Matched = true; break; } } else { if (totalCount > maxSkip) { skippedExceeded = true; break; } info.BytesSkipped = totalCount; if (extractSkipped) { // increment skipped size skipped.ChunkSize = totalCount; // copy up to mismatch character int offset = (totalCount - 1) - patternPos; while (offset < totalCount) { skipped.ChunkBytes[offset] = LocalBuffer[FirstByteUsed + offset]; offset++; } } //reset to start of pattern patternPos = 0; } } } } if (consume) { BytesUsed -= totalCount; if (BytesUsed == 0) NextByteAvail = 0; info.BytesConsumed = totalCount; // total bytes matched or skipped } BytesRead += info.BytesConsumed; info.TotalBytesRead = totalCount; if (SystemServices.LogMessageContent) { if (info.BytesSkipped > 0) { LogMessage("FindInBuffer", "Skipped[" + info.BytesSkipped + "] next line", LogEntryType.MeterMessage); FormatDump(skippedChunk.ChunkBytes, 0, skippedChunk.ChunkSize, SystemServices); } LogMessage("FindInBuffer", "Matched: " + info.Matched + " - Timeout: " + info.Timeout + " - BytesRead: " + info.BytesRead + " - TotalBytesRead: " + info.TotalBytesRead + " - Pattern[" + pattern.Length + "] next line", LogEntryType.MeterMessage); FormatDump(pattern, 0, pattern.Length, SystemServices); } return info; }