private Log4JFile(UnmanagedMemoryHandle buffer, long size) { buffer_ = buffer; Size = size; var status = Log4JParserC.Log4JEventSourceInitXmlString(out impl_, buffer_.DangerousGetHandle()); switch (status) { case Log4JParserC.Status.Success: break; case Log4JParserC.Status.DocumentErrors: break; case Log4JParserC.Status.MemoryError: impl_.Dispose(); throw new OutOfMemoryException(); default: impl_.Dispose(); throw new InvalidOperationException(); } Encoding = Encoding.ASCII; }
public static Log4JFile Create(Stream source, long?maxSize = null) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (!source.CanRead) { throw new ArgumentException("Source stream must support reading.", nameof(source)); } if (maxSize != null && maxSize < 0L) { const string message = "Maximum size must be a positive value."; throw new ArgumentOutOfRangeException(nameof(maxSize), message); } if (maxSize == null && !source.CanSeek) { using (var seekableCopy = new MemoryStream()) { Debug.Assert(seekableCopy.CanSeek); source.CopyTo(seekableCopy); seekableCopy.Seek(0, SeekOrigin.Begin); return(Create(seekableCopy)); } } long bufferSize; if (maxSize != null) { var maxBufferSize = checked ((long)maxSize + 1); bufferSize = source.CanSeek ? Math.Min(source.Length + 1, maxBufferSize) : maxBufferSize; } else { bufferSize = source.Length + 1; } UnmanagedMemoryHandle buffer = null; long size; try { try { } finally { buffer = new UnmanagedMemoryHandle(bufferSize); } unsafe { var bufferHandle = (byte *)buffer.DangerousGetHandle(); using (var memory = new UnmanagedMemoryStream(bufferHandle, bufferSize, bufferSize, FileAccess.Write)) { var copyBuffer = new byte[Math.Max(bufferSize - 1, 81920)]; var remainingToCopy = bufferSize - 1L; while (remainingToCopy > 0L) { var toRead = (int)Math.Min(copyBuffer.Length, remainingToCopy); var read = source.Read(copyBuffer, 0, toRead); if (read != 0) { remainingToCopy -= read; memory.Write(copyBuffer, 0, read); } else { remainingToCopy = 0L; } } size = memory.Position; memory.WriteByte(0); } } return(new Log4JFile(buffer, size)); } catch { if (buffer != null) { buffer.Dispose(); } throw; } }