From 47210041b2551bcb4a26da37fc77f37f061f7aae Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Mon, 21 Oct 2019 01:58:22 +0900 Subject: [PATCH] Provide Wim.ErrorPrintState - Add more locking for stability - More error print tests --- ManagedWimLib.Tests/ErrorTests.cs | 31 ++++++++--- ManagedWimLib/WimLibLoader.cs | 93 ++++++++++++++++++++----------- ManagedWimLib/WimStruct.cs | 19 ++++++- 3 files changed, 102 insertions(+), 41 deletions(-) diff --git a/ManagedWimLib.Tests/ErrorTests.cs b/ManagedWimLib.Tests/ErrorTests.cs index 144d722..5ed4af3 100644 --- a/ManagedWimLib.Tests/ErrorTests.cs +++ b/ManagedWimLib.Tests/ErrorTests.cs @@ -37,11 +37,18 @@ public class ErrorTests public void GetLastError() { string[] paths = new string[] { @"\NOTEXIST.bin", @"NOTGLOB?.cue" }; - CheckErrorTemplate("XPRESS.wim", paths); - CheckErrorTemplate("XPRESS.wim", paths); + + // Default is Wim.SetPrintErrors(true); + CheckErrorTemplate("XPRESS.wim", paths, true); + + Wim.SetPrintErrors(false); + CheckErrorTemplate("LZX.wim", paths, false); + + Wim.SetPrintErrors(true); + CheckErrorTemplate("LZMS.wim", paths, true); } - public void CheckErrorTemplate(string fileName, string[] paths) + public void CheckErrorTemplate(string fileName, string[] paths, bool printError) { string destDir = TestHelper.GetTempDir(); try @@ -127,10 +134,20 @@ CallbackStatus ProgressCallback(ProgressMsg msg, object info, object progctx) // Read error message string[] errorMsgs = Wim.GetErrors(); - Assert.IsNotNull(errorMsgs); - Assert.IsTrue(0 < errorMsgs.Length); - foreach (string errorMsg in errorMsgs) - Console.WriteLine(errorMsg); + ErrorPrintState printState = Wim.ErrorPrintState; + if (printError) + { + Assert.IsNotNull(errorMsgs); + Assert.AreEqual(ErrorPrintState.PrintOn, printState); + Assert.IsTrue(0 < errorMsgs.Length); + foreach (string errorMsg in errorMsgs) + Console.WriteLine(errorMsg); + } + else + { + Assert.IsNull(errorMsgs); + Assert.AreEqual(ErrorPrintState.PrintOff, printState); + } } finally { diff --git a/ManagedWimLib/WimLibLoader.cs b/ManagedWimLib/WimLibLoader.cs index a6aeaa7..6d28cd9 100644 --- a/ManagedWimLib/WimLibLoader.cs +++ b/ManagedWimLib/WimLibLoader.cs @@ -61,9 +61,24 @@ public WimLibLoader(string libPath) : base(libPath) { } #endregion #region Error Settings - internal string ErrorFile = null; - internal ErrorPrintState ErrorPrintState = ErrorPrintState.PrintOff; + private string _errorFile = null; + private ErrorPrintState _errorPrintState = ErrorPrintState.PrintOff; + internal static readonly object _errorFileLock = new object(); + internal string GetErrorFilePath() + { + lock (_errorFileLock) + { + return _errorFile; + } + } + internal ErrorPrintState GetErrorPrintState() + { + lock (_errorFileLock) + { + return _errorPrintState; + } + } #endregion #region (override) DefaultLibFileName @@ -332,7 +347,7 @@ protected override void LoadFunctions() #endregion #region (Code) Set ErrorFile and PrintError - SetupErrorFile(); + SetErrorFile(); #endregion } @@ -500,23 +515,8 @@ protected override void ResetFunctions() #endregion #region (Code) Cleanup ErrorFile - CleanupErrorFile(); - #endregion - } - #endregion - - #region ErrorFile Handling - private void SetupErrorFile() - { - ErrorFile = Path.GetTempFileName(); - SetErrorFile(ErrorFile); - } - - private void CleanupErrorFile() - { SetPrintErrors(false); - if (File.Exists(ErrorFile)) - File.Delete(ErrorFile); + #endregion } #endregion @@ -1285,6 +1285,12 @@ internal delegate void wimlib_register_progress_function( internal delegate IntPtr wimlib_get_error_string(ErrorCode code); internal wimlib_get_error_string GetErrorString; + internal void SetErrorFile() + { + string errorFile = Path.GetTempFileName(); + SetErrorFile(errorFile); + } + internal void SetErrorFile(string path) { if (path == null) @@ -1307,12 +1313,23 @@ internal void SetErrorFile(string path) // In that case, ManagedWimLib must not throw WimLibException. if (ret == ErrorCode.UNSUPPORTED) { - ErrorPrintState = ErrorPrintState.NotSupported; + _errorPrintState = ErrorPrintState.NotSupported; + + // ErrorFile is no longer used, delete it + if (_errorFile != null) + { + if (File.Exists(_errorFile)) + File.Delete(_errorFile); + _errorFile = null; + } } else { WimLibException.CheckWimLibError(ret); - ErrorPrintState = ErrorPrintState.PrintOn; + + // Set new ErrorFile and report state as ErrorPrintState.PrintOn. + _errorPrintState = ErrorPrintState.PrintOn; + _errorFile = path; } } @@ -1342,12 +1359,12 @@ internal void SetPrintErrors(bool showMessages) // In that case, ManagedWimLib must not throw WimLibException. if (ret == ErrorCode.UNSUPPORTED) { - ErrorPrintState = ErrorPrintState.NotSupported; + _errorPrintState = ErrorPrintState.NotSupported; } else { WimLibException.CheckWimLibError(ret); - ErrorPrintState = showMessages ? ErrorPrintState.PrintOn : ErrorPrintState.PrintOff; + _errorPrintState = showMessages ? ErrorPrintState.PrintOn : ErrorPrintState.PrintOff; } } } @@ -1356,12 +1373,12 @@ internal string[] GetErrors() { lock (_errorFileLock) { - if (ErrorFile == null) + if (_errorFile == null) return null; - if (ErrorPrintState != ErrorPrintState.PrintOn) + if (_errorPrintState != ErrorPrintState.PrintOn) return null; - using (FileStream fs = new FileStream(ErrorFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (FileStream fs = new FileStream(_errorFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (StreamReader r = new StreamReader(fs, UnicodeEncoding, false)) { return r.ReadToEnd().Split('\n').Select(x => x.Trim()).Where(x => 0 < x.Length).ToArray(); @@ -1373,12 +1390,12 @@ internal string GetLastError() { lock (_errorFileLock) { - if (ErrorFile == null) + if (_errorFile == null) return null; - if (ErrorPrintState != ErrorPrintState.PrintOn) + if (_errorPrintState != ErrorPrintState.PrintOn) return null; - using (FileStream fs = new FileStream(ErrorFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (FileStream fs = new FileStream(_errorFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (StreamReader r = new StreamReader(fs, UnicodeEncoding, false)) { var lines = r.ReadToEnd().Split('\n').Select(x => x.Trim()).Where(x => 0 < x.Length); @@ -1391,13 +1408,13 @@ internal void ResetErrorFile() { lock (_errorFileLock) { - if (ErrorFile == null) + if (_errorFile == null) return; - if (ErrorPrintState != ErrorPrintState.PrintOn) + if (_errorPrintState != ErrorPrintState.PrintOn) return; // Overwrite to Empty File - using (FileStream fs = new FileStream(ErrorFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) + using (FileStream fs = new FileStream(_errorFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) using (StreamWriter w = new StreamWriter(fs, UnicodeEncoding)) { w.WriteLine(); @@ -2014,10 +2031,22 @@ internal static bool GetBitField(uint bitField, int bitShift) } #region enum ErrorPrintState + /// + /// Represents whether wimlib is printing error messages or not. + /// public enum ErrorPrintState { + /// + /// Error messages are not being printed to ErrorFile. + /// PrintOff = 0, + /// + /// Error messages are being printed to ErrorFile. + /// PrintOn = 1, + /// + /// wimlib was not built with --without-error-messages option. + /// NotSupported = 2, } #endregion diff --git a/ManagedWimLib/WimStruct.cs b/ManagedWimLib/WimStruct.cs index d748d7c..fcc349e 100644 --- a/ManagedWimLib/WimStruct.cs +++ b/ManagedWimLib/WimStruct.cs @@ -49,6 +49,9 @@ public class Wim : IDisposable #region Const public const int NoImage = 0; public const int AllImages = -1; + /// + /// Let wimlib determine best thread count to use. + /// public const int DefaultThreads = 0; #endregion @@ -58,9 +61,18 @@ public class Wim : IDisposable #endregion #region Properties - public static string ErrorFile => Lib.ErrorFile; - public static ErrorPrintState ErrorPrintState => Lib.ErrorPrintState; + /// + /// The error file which wimlib prints error message to. Valid only if ErrorPrintState is PrintOn, else the property returns null. + /// + public static string ErrorFile => Lib.GetErrorFilePath(); + /// + /// Represents whether wimlib is printing error messages or not. + /// + public static ErrorPrintState ErrorPrintState => Lib.GetErrorPrintState(); + /// + /// Does the same job with Path.DirectorySeparatorChar, as string. Provided for the compatibility with old releases. + /// public static string PathSeparator { get @@ -79,6 +91,9 @@ public static string PathSeparator #endif } } + /// + /// Does the same job with Path.DirectorySeparatorChar, as string. Provided for the compatibility with old releases. + /// public static string RootPath => PathSeparator; #endregion