<PackageReference Include="Relativity.Server.Import.SDK" Version="2.9.2" />

OutputFileWriter

public class OutputFileWriter : IDisposable
using Microsoft.VisualBasic.CompilerServices; using Relativity.DataExchange.Io; using Relativity.Logging; using System; using System.Collections.Generic; using System.IO; using System.Runtime.CompilerServices; using System.Text; using System.Threading; namespace kCura.WinEDDS { public class OutputFileWriter : IDisposable { private const int _MAXIMUM_NUMBER_OF_ITEMS_IN_QUEUE = 12; private readonly Queue<string> _createdFilesPaths; private readonly object _syncRoot; private readonly ILog _logger; private readonly IFileSystem _fileSystem; private bool _filesCreated; private bool _filesOpened; private long _nativeFileWriterRollbackPos; private long _dataGridFileWriterRollbackPos; private bool _disposed; [CompilerGenerated] private string _OutputNativeFilePath; [CompilerGenerated] private string _OutputDataGridFilePath; [CompilerGenerated] private string _OutputCodeFilePath; [CompilerGenerated] private string _OutputObjectFilePath; [CompilerGenerated] private IStreamWriter _OutputNativeFileWriter; [CompilerGenerated] private IStreamWriter _OutputDataGridFileWriter; [CompilerGenerated] private IStreamWriter _OutputCodeFileWriter; [CompilerGenerated] private IStreamWriter _OutputObjectFileWriter; public string OutputNativeFilePath { get; } public string OutputDataGridFilePath { get; } public string OutputCodeFilePath { get; } public string OutputObjectFilePath { get; } public IStreamWriter OutputNativeFileWriter { get; } public IStreamWriter OutputDataGridFileWriter { get; } public IStreamWriter OutputCodeFileWriter { get; } public IStreamWriter OutputObjectFileWriter { get; } public long CombinedStreamLength { get { object syncRoot = _syncRoot; ObjectFlowControl.CheckForSyncLockOnValueType(syncRoot); bool lockTaken = false; try { Monitor.Enter(syncRoot, ref lockTaken); if (OutputNativeFileWriter != null && OutputDataGridFileWriter != null) { if (OutputNativeFileWriter.BaseStream != null && OutputDataGridFileWriter.BaseStream != null) return checked(OutputNativeFileWriter.BaseStream.Length + OutputDataGridFileWriter.BaseStream.Length); return 0; } return 0; } finally { if (lockTaken) Monitor.Exit(syncRoot); } } } public OutputFileWriter(ILog logger, IFileSystem fileSystem) { _createdFilesPaths = new Queue<string>(); _syncRoot = RuntimeHelpers.GetObjectValue(new object()); if (logger == null) throw new ArgumentNullException("logger"); if (fileSystem == null) throw new ArgumentNullException("fileSystem"); _disposed = false; _filesCreated = false; _filesOpened = false; _fileSystem = fileSystem; _logger = logger.ForContext<OutputFileWriter>(); } public void DeleteFiles() { object syncRoot = _syncRoot; ObjectFlowControl.CheckForSyncLockOnValueType(syncRoot); bool lockTaken = false; try { Monitor.Enter(syncRoot, ref lockTaken); CheckDispose(); if (_filesOpened) { _logger.LogWarning("An attempt was made to delete temp files while they were still open. Trying to close.", new object[0]); CloseWithoutLocking(); } DeleteFilesWithoutLocking(); } finally { if (lockTaken) Monitor.Exit(syncRoot); } } public void Dispose() { object syncRoot = _syncRoot; ObjectFlowControl.CheckForSyncLockOnValueType(syncRoot); bool lockTaken = false; try { Monitor.Enter(syncRoot, ref lockTaken); Dispose(true); GC.SuppressFinalize(this); } finally { if (lockTaken) Monitor.Exit(syncRoot); } } void IDisposable.Dispose() { this.Dispose(); } public void Open(bool append = false) { object syncRoot = _syncRoot; ObjectFlowControl.CheckForSyncLockOnValueType(syncRoot); bool lockTaken = false; try { Monitor.Enter(syncRoot, ref lockTaken); CheckDispose(); OpenWithoutLocking(append); } finally { if (lockTaken) Monitor.Exit(syncRoot); } } public void Close() { object syncRoot = _syncRoot; ObjectFlowControl.CheckForSyncLockOnValueType(syncRoot); bool lockTaken = false; try { Monitor.Enter(syncRoot, ref lockTaken); CheckDispose(); CloseWithoutLocking(); } finally { if (lockTaken) Monitor.Exit(syncRoot); } } public void MarkRollbackPosition() { object syncRoot = _syncRoot; ObjectFlowControl.CheckForSyncLockOnValueType(syncRoot); bool lockTaken = false; try { Monitor.Enter(syncRoot, ref lockTaken); CheckDispose(); if (OutputNativeFileWriter != null && OutputNativeFileWriter.BaseStream != null) { OutputNativeFileWriter.Flush(); _nativeFileWriterRollbackPos = OutputNativeFileWriter.BaseStream.Length; } if (OutputDataGridFileWriter != null && OutputDataGridFileWriter.BaseStream != null) { OutputDataGridFileWriter.Flush(); _dataGridFileWriterRollbackPos = OutputDataGridFileWriter.BaseStream.Length; } } finally { if (lockTaken) Monitor.Exit(syncRoot); } } public void RollbackDocumentLineWrites() { object syncRoot = _syncRoot; ObjectFlowControl.CheckForSyncLockOnValueType(syncRoot); bool lockTaken = false; try { Monitor.Enter(syncRoot, ref lockTaken); CheckDispose(); CloseWithoutLocking(); SetStreamLengths(); OpenWithoutLocking(true); } finally { if (lockTaken) Monitor.Exit(syncRoot); } } public int TryCloseAndDeleteAllTempFiles() { object syncRoot = _syncRoot; ObjectFlowControl.CheckForSyncLockOnValueType(syncRoot); bool lockTaken = false; try { Monitor.Enter(syncRoot, ref lockTaken); CheckDispose(); return TryCloseAndDeleteAllTempFilesWithoutLocking(); } finally { if (lockTaken) Monitor.Exit(syncRoot); } } private void OpenWithoutLocking(bool append) { if (!_filesOpened) { if (!_filesCreated) CreateTempFiles(); _OutputNativeFileWriter = _fileSystem.CreateStreamWriter(OutputNativeFilePath, append, Encoding.Unicode); _OutputDataGridFileWriter = _fileSystem.CreateStreamWriter(OutputDataGridFilePath, append, Encoding.Unicode); _OutputCodeFileWriter = _fileSystem.CreateStreamWriter(OutputCodeFilePath, append, Encoding.Unicode); _OutputObjectFileWriter = _fileSystem.CreateStreamWriter(OutputObjectFilePath, append, Encoding.Unicode); _filesOpened = true; } } private void CloseWithoutLocking() { if (_filesOpened) { TryCloseWriter(OutputNativeFileWriter); _OutputNativeFileWriter = null; TryCloseWriter(OutputDataGridFileWriter); _OutputDataGridFileWriter = null; TryCloseWriter(OutputCodeFileWriter); _OutputCodeFileWriter = null; TryCloseWriter(OutputObjectFileWriter); _OutputObjectFileWriter = null; _filesOpened = false; } } private void DeleteFilesWithoutLocking() { _OutputNativeFilePath = null; _OutputDataGridFilePath = null; _OutputCodeFilePath = null; _OutputObjectFilePath = null; _filesCreated = false; int count = _createdFilesPaths.Count; for (int i = 1; i <= count; i = checked(i + 1)) { string text = _createdFilesPaths.Dequeue(); try { _fileSystem.File.Delete(text); } catch (IOException ex) when () { IOException ex2; _logger.LogWarning((Exception)ex2, "Unable to delete file because it was locked. Adding to queue for retry.", new object[0]); _createdFilesPaths.Enqueue(text); ProjectData.ClearProjectError(); } } EnsureCreatedFilesQueueSizeLimit(); } private void EnsureCreatedFilesQueueSizeLimit() { checked { int num = Math.Max(0, _createdFilesPaths.Count - 12); for (int i = 1; i <= num; i++) { _createdFilesPaths.Dequeue(); } } } private int TryCloseAndDeleteAllTempFilesWithoutLocking() { CloseWithoutLocking(); DeleteFilesWithoutLocking(); return _createdFilesPaths.Count; } private void SetStreamLengths() { using (FileStream fileStream = new FileStream(OutputNativeFilePath, FileMode.Open, FileAccess.ReadWrite)) { fileStream.SetLength(_nativeFileWriterRollbackPos); fileStream.Close(); } using (FileStream fileStream2 = new FileStream(OutputDataGridFilePath, FileMode.Open, FileAccess.ReadWrite)) { fileStream2.SetLength(_dataGridFileWriterRollbackPos); fileStream2.Close(); } } private void CreateTempFiles() { _OutputNativeFilePath = CreateTempFile("rel-native"); _OutputDataGridFilePath = CreateTempFile("rel-datagrid"); _OutputCodeFilePath = CreateTempFile("rel-code"); _OutputObjectFilePath = CreateTempFile("rel-object"); _filesCreated = true; } private string CreateTempFile(string nameSuffix) { string tempFileName = _fileSystem.Path.GetTempFileName(nameSuffix); _createdFilesPaths.Enqueue(tempFileName); return tempFileName; } private void TryCloseWriter(IStreamWriter writer) { if (writer != null) try { writer.Close(); } catch (Exception ex) { ProjectData.SetProjectError(ex); Exception ex2 = ex; _logger.LogWarning(ex2, "Exception was thrown while trying to close stream writer.", new object[0]); ProjectData.ClearProjectError(); } } private void CheckDispose() { if (_disposed) throw new ObjectDisposedException("This load file operation cannot be performed because the load file writer has been disposed."); } private void Dispose(bool disposing) { if (!_disposed && disposing) try { TryCloseAndDeleteAllTempFilesWithoutLocking(); } finally { _disposed = true; } } private static bool IsExceptionDueToLockedFile(IOException exception) { int num = exception.HResult & 65535; if (num != 32) return num == 33; return true; } } }