From ee4621beec99ca8b7c956c00ed148a4566573a8e Mon Sep 17 00:00:00 2001 From: Taritsyn Date: Thu, 20 Dec 2018 16:52:24 +0300 Subject: [PATCH] Part of the auxiliary code was moved to external libraries: PolyfillsForOldDotNet and AdvancedStringBuilder --- .../Extensions/StringBuilderExtensions.cs | 95 ------------ src/LibSassHost/FileManager.cs | 7 +- src/LibSassHost/Helpers/MarshallingHelpers.cs | 4 +- src/LibSassHost/Helpers/SassErrorHelpers.cs | 18 ++- .../Internal/FileManagerMarshaler.cs | 8 +- src/LibSassHost/LibSassHost.csproj | 8 +- .../Runtime/InteropServices/Architecture.cs | 12 -- .../Runtime/InteropServices/OSPlatform.cs | 76 ---------- .../InteropServices/RuntimeInformation.cs | 69 --------- src/LibSassHost/SassCompiler.cs | 13 +- src/LibSassHost/SassException.cs | 11 +- .../Utilities/SourceCodeNavigator.cs | 7 +- .../Utilities/StringBuilderPool.cs | 142 ------------------ src/LibSassHost/Utilities/Utils.cs | 50 ------ src/LibSassHost/readme.txt | 6 +- 15 files changed, 52 insertions(+), 474 deletions(-) delete mode 100644 src/LibSassHost/Extensions/StringBuilderExtensions.cs delete mode 100644 src/LibSassHost/Polyfills/System/Runtime/InteropServices/Architecture.cs delete mode 100644 src/LibSassHost/Polyfills/System/Runtime/InteropServices/OSPlatform.cs delete mode 100644 src/LibSassHost/Polyfills/System/Runtime/InteropServices/RuntimeInformation.cs delete mode 100644 src/LibSassHost/Utilities/StringBuilderPool.cs diff --git a/src/LibSassHost/Extensions/StringBuilderExtensions.cs b/src/LibSassHost/Extensions/StringBuilderExtensions.cs deleted file mode 100644 index 6cb9b34..0000000 --- a/src/LibSassHost/Extensions/StringBuilderExtensions.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Text; -using System.Text.RegularExpressions; - -namespace LibSassHost.Utilities -{ - /// - /// Extensions for StringBuilder - /// - internal static class StringBuilderExtensions - { - /// - /// Regular expression for format placeholder - /// - private static readonly Regex _formatPlaceholderRegExp = - new Regex(@"\{[0-9]\}", RegexOptions.Multiline); - - /// - /// Appends the default line terminator to the end of the current instance - /// - /// Instance of - /// Instance of - public static StringBuilder AppendFormatLine(this StringBuilder source) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.AppendLine(); - } - - /// - /// Appends the string returned by processing a composite format string, which - /// contains zero or more format items, with default line terminator to this instance. - /// Each format item is replaced by the string representation of a corresponding - /// argument in a parameter array. - /// - /// Instance of - /// A composite format string - /// An array of objects to format - /// Instance of - public static StringBuilder AppendFormatLine(this StringBuilder source, string format, params object[] args) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (_formatPlaceholderRegExp.IsMatch(format)) - { - return source.AppendFormat(format, args).AppendLine(); - } - - return source.AppendLine(format.Replace("{{", "{").Replace("}}", "}")); - } - - /// - /// Removes the all trailing white-space characters from the current instance - /// - /// Instance of - /// Instance of without trailing white-space characters - public static StringBuilder TrimEnd(this StringBuilder source) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - int charCount = source.Length; - if (charCount == 0) - { - return source; - } - - int charIndex = charCount - 1; - - for (; charIndex >= 0; charIndex--) - { - char charValue = source[charIndex]; - if (!char.IsWhiteSpace(charValue)) - { - break; - } - } - - if (charIndex < source.Length - 1) - { - source.Length = charIndex + 1; - } - - return source; - } - } -} \ No newline at end of file diff --git a/src/LibSassHost/FileManager.cs b/src/LibSassHost/FileManager.cs index 5a3814f..94bf356 100644 --- a/src/LibSassHost/FileManager.cs +++ b/src/LibSassHost/FileManager.cs @@ -3,11 +3,12 @@ #if NET45 || NET471 || NETSTANDARD using System.Runtime.InteropServices; #endif - -using LibSassHost.Helpers; #if NET40 -using LibSassHost.Polyfills.System.Runtime.InteropServices; + +using PolyfillsForOldDotNet.System.Runtime.InteropServices; #endif + +using LibSassHost.Helpers; using LibSassHost.Resources; using LibSassHost.Utilities; diff --git a/src/LibSassHost/Helpers/MarshallingHelpers.cs b/src/LibSassHost/Helpers/MarshallingHelpers.cs index f682a8b..06f4541 100644 --- a/src/LibSassHost/Helpers/MarshallingHelpers.cs +++ b/src/LibSassHost/Helpers/MarshallingHelpers.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; - #if NET40 -using LibSassHost.Polyfills.System.Runtime.InteropServices; + +using PolyfillsForOldDotNet.System.Runtime.InteropServices; #endif namespace LibSassHost.Helpers diff --git a/src/LibSassHost/Helpers/SassErrorHelpers.cs b/src/LibSassHost/Helpers/SassErrorHelpers.cs index a8358f4..ca39693 100644 --- a/src/LibSassHost/Helpers/SassErrorHelpers.cs +++ b/src/LibSassHost/Helpers/SassErrorHelpers.cs @@ -2,8 +2,9 @@ using System.Globalization; using System.Text; +using AdvancedStringBuilder; + using LibSassHost.Resources; -using LibSassHost.Utilities; namespace LibSassHost.Helpers { @@ -27,7 +28,8 @@ internal static string GenerateCompilerLoadErrorMessage(string description, bool if (!string.IsNullOrWhiteSpace(description)) { - StringBuilder messageBuilder = StringBuilderPool.GetBuilder(); + var stringBuilderPool = StringBuilderPool.Shared; + StringBuilder messageBuilder = stringBuilderPool.Rent(); messageBuilder.Append(compilerNotLoadedPart); messageBuilder.Append(" "); if (quoteDescription) @@ -40,7 +42,7 @@ internal static string GenerateCompilerLoadErrorMessage(string description, bool } message = messageBuilder.ToString(); - StringBuilderPool.ReleaseBuilder(messageBuilder); + stringBuilderPool.Return(messageBuilder); } else { @@ -67,7 +69,8 @@ public static string GenerateErrorDetails(SassException sassException, bool omit throw new ArgumentNullException(nameof(sassException)); } - StringBuilder detailsBuilder = StringBuilderPool.GetBuilder(); + var stringBuilderPool = StringBuilderPool.Shared; + StringBuilder detailsBuilder = stringBuilderPool.Rent(); WriteCommonErrorDetails(detailsBuilder, sassException, omitMessage); var sassСompilationException = sassException as SassСompilationException; @@ -79,7 +82,7 @@ public static string GenerateErrorDetails(SassException sassException, bool omit detailsBuilder.TrimEnd(); string errorDetails = detailsBuilder.ToString(); - StringBuilderPool.ReleaseBuilder(detailsBuilder); + stringBuilderPool.Return(detailsBuilder); return errorDetails; } @@ -98,14 +101,15 @@ public static string GenerateErrorDetails(SassСompilationException sassСompila throw new ArgumentNullException(nameof(sassСompilationException)); } - StringBuilder detailsBuilder = StringBuilderPool.GetBuilder(); + var stringBuilderPool = StringBuilderPool.Shared; + StringBuilder detailsBuilder = stringBuilderPool.Rent(); WriteCommonErrorDetails(detailsBuilder, sassСompilationException, omitMessage); WriteCompilationErrorDetails(detailsBuilder, sassСompilationException); detailsBuilder.TrimEnd(); string errorDetails = detailsBuilder.ToString(); - StringBuilderPool.ReleaseBuilder(detailsBuilder); + stringBuilderPool.Return(detailsBuilder); return errorDetails; } diff --git a/src/LibSassHost/Internal/FileManagerMarshaler.cs b/src/LibSassHost/Internal/FileManagerMarshaler.cs index 13a8683..c8aad32 100644 --- a/src/LibSassHost/Internal/FileManagerMarshaler.cs +++ b/src/LibSassHost/Internal/FileManagerMarshaler.cs @@ -1,12 +1,12 @@ #if NET45 || NET471 || NETSTANDARD using System.Runtime.InteropServices; - #endif -using LibSassHost.Internal.Native; #if NET40 -using LibSassHost.Polyfills.System.Runtime.InteropServices; + +using PolyfillsForOldDotNet.System.Runtime.InteropServices; #endif -using LibSassHost.Utilities; + +using LibSassHost.Internal.Native; namespace LibSassHost.Internal { diff --git a/src/LibSassHost/LibSassHost.csproj b/src/LibSassHost/LibSassHost.csproj index ba06a85..0429b44 100644 --- a/src/LibSassHost/LibSassHost.csproj +++ b/src/LibSassHost/LibSassHost.csproj @@ -29,7 +29,8 @@ This package does not contain the native implementations of LibSass. Therefore, https://github.com/Taritsyn/LibSassHost git LibSass;Sass;SCSS;CSS - An attempt was made to fix a error #26 “"Unable to find an entry point named 'libsass_version' in DLL 'libsass'." on Azure Web App”. + 1. An attempt was made to fix a error #26 “"Unable to find an entry point named 'libsass_version' in DLL 'libsass'." on Azure Web App”; +2. Part of the auxiliary code was moved to external libraries: PolyfillsForOldDotNet and AdvancedStringBuilder. en-US false false @@ -41,6 +42,11 @@ This package does not contain the native implementations of LibSass. Therefore, + + + + + diff --git a/src/LibSassHost/Polyfills/System/Runtime/InteropServices/Architecture.cs b/src/LibSassHost/Polyfills/System/Runtime/InteropServices/Architecture.cs deleted file mode 100644 index bacf48c..0000000 --- a/src/LibSassHost/Polyfills/System/Runtime/InteropServices/Architecture.cs +++ /dev/null @@ -1,12 +0,0 @@ -#if NET40 -namespace LibSassHost.Polyfills.System.Runtime.InteropServices -{ - internal enum Architecture - { - X86, - X64, - Arm, - Arm64 - } -} -#endif \ No newline at end of file diff --git a/src/LibSassHost/Polyfills/System/Runtime/InteropServices/OSPlatform.cs b/src/LibSassHost/Polyfills/System/Runtime/InteropServices/OSPlatform.cs deleted file mode 100644 index a6afb51..0000000 --- a/src/LibSassHost/Polyfills/System/Runtime/InteropServices/OSPlatform.cs +++ /dev/null @@ -1,76 +0,0 @@ -#if NET40 -using System; - -using LibSassHost.Resources; - -namespace LibSassHost.Polyfills.System.Runtime.InteropServices -{ - internal struct OSPlatform : IEquatable - { - private readonly string _osPlatform; - - public static OSPlatform Linux { get; } = new OSPlatform("LINUX"); - - public static OSPlatform OSX { get; } = new OSPlatform("OSX"); - - public static OSPlatform Windows { get; } = new OSPlatform("WINDOWS"); - - - private OSPlatform(string osPlatform) - { - if (osPlatform == null) - { - throw new ArgumentNullException(nameof(osPlatform)); - } - - if (osPlatform.Length == 0) - { - throw new ArgumentException(Strings.Common_ArgumentIsEmpty, nameof(osPlatform)); - } - - _osPlatform = osPlatform; - } - - - public static OSPlatform Create(string osPlatform) - { - return new OSPlatform(osPlatform); - } - - public bool Equals(OSPlatform other) - { - return Equals(other._osPlatform); - } - - internal bool Equals(string other) - { - return string.Equals(_osPlatform, other, StringComparison.Ordinal); - } - - public override bool Equals(object obj) - { - return obj is OSPlatform && Equals((OSPlatform)obj); - } - - public override int GetHashCode() - { - return _osPlatform == null ? 0 : _osPlatform.GetHashCode(); - } - - public override string ToString() - { - return _osPlatform ?? string.Empty; - } - - public static bool operator ==(OSPlatform left, OSPlatform right) - { - return left.Equals(right); - } - - public static bool operator !=(OSPlatform left, OSPlatform right) - { - return !(left == right); - } - } -} -#endif \ No newline at end of file diff --git a/src/LibSassHost/Polyfills/System/Runtime/InteropServices/RuntimeInformation.cs b/src/LibSassHost/Polyfills/System/Runtime/InteropServices/RuntimeInformation.cs deleted file mode 100644 index ff2d853..0000000 --- a/src/LibSassHost/Polyfills/System/Runtime/InteropServices/RuntimeInformation.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if NET40 -using System; - -using LibSassHost.Utilities; - -namespace LibSassHost.Polyfills.System.Runtime.InteropServices -{ - internal static class RuntimeInformation - { - /// - /// Operating system platform - /// - private static OSPlatform _osPlatform; - - /// - /// Operating system architecture - /// - private static Architecture _osArch; - - public static Architecture OSArchitecture - { - get { return _osArch; } - } - - - /// - /// Static constructor - /// - static RuntimeInformation() - { - PlatformID platform = Environment.OSVersion.Platform; - - if (platform == PlatformID.Win32NT || platform == PlatformID.Win32S - || platform == PlatformID.Win32Windows || platform == PlatformID.WinCE) - { - _osPlatform = OSPlatform.Windows; - } - else if (platform == PlatformID.MacOSX) - { - _osPlatform = OSPlatform.OSX; - } - else if (platform == PlatformID.Unix) - { - string unixName = Utils.ReadProcessOutput("uname") ?? string.Empty; - if (unixName.Contains("Darwin")) - { - _osPlatform = OSPlatform.OSX; - } - else - { - _osPlatform = OSPlatform.Linux; - } - } - else - { - _osPlatform = OSPlatform.Create("UNKNOWN"); - } - - _osArch = Environment.Is64BitOperatingSystem ? Architecture.X64 : Architecture.X86; - } - - - public static bool IsOSPlatform(OSPlatform osPlatform) - { - return osPlatform == _osPlatform; - } - } -} -#endif \ No newline at end of file diff --git a/src/LibSassHost/SassCompiler.cs b/src/LibSassHost/SassCompiler.cs index 221307d..157032e 100644 --- a/src/LibSassHost/SassCompiler.cs +++ b/src/LibSassHost/SassCompiler.cs @@ -7,12 +7,14 @@ using System.Text; using System.Threading; +using AdvancedStringBuilder; +#if NET40 +using PolyfillsForOldDotNet.System.Runtime.InteropServices; +#endif + using LibSassHost.Constants; using LibSassHost.Helpers; using LibSassHost.Internal; -#if NET40 -using LibSassHost.Polyfills.System.Runtime.InteropServices; -#endif using LibSassHost.Resources; using LibSassHost.Utilities; @@ -521,7 +523,8 @@ private static SassCompilerLoadException WrapDllNotFoundException( const string manualInstallationInstructionsUrl = "https://github.com/Taritsyn/LibSassHost#{0}"; Architecture osArchitecture = RuntimeInformation.OSArchitecture; - StringBuilder descriptionBuilder = StringBuilderPool.GetBuilder(); + var stringBuilderPool = StringBuilderPool.Shared; + StringBuilder descriptionBuilder = stringBuilderPool.Rent(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { descriptionBuilder.AppendFormat(Strings.Compiler_AssemblyNotFound, DllName.ForWindows); @@ -620,7 +623,7 @@ private static SassCompilerLoadException WrapDllNotFoundException( } description = descriptionBuilder.ToString(); - StringBuilderPool.ReleaseBuilder(descriptionBuilder); + stringBuilderPool.Return(descriptionBuilder); message = SassErrorHelpers.GenerateCompilerLoadErrorMessage(description); } diff --git a/src/LibSassHost/SassException.cs b/src/LibSassHost/SassException.cs index 89e122c..d015583 100644 --- a/src/LibSassHost/SassException.cs +++ b/src/LibSassHost/SassException.cs @@ -5,8 +5,9 @@ #endif using System.Text; +using AdvancedStringBuilder; + using LibSassHost.Helpers; -using LibSassHost.Utilities; namespace LibSassHost { @@ -98,12 +99,14 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont /// A string that represents the current exception public override string ToString() { - StringBuilder resultBuilder = StringBuilderPool.GetBuilder(); + string errorDetails = SassErrorHelpers.GenerateErrorDetails(this, true); + + var stringBuilderPool = StringBuilderPool.Shared; + StringBuilder resultBuilder = stringBuilderPool.Rent(); resultBuilder.Append(this.GetType().FullName); resultBuilder.Append(": "); resultBuilder.Append(this.Message); - string errorDetails = SassErrorHelpers.GenerateErrorDetails(this, true); if (errorDetails.Length > 0) { resultBuilder.AppendLine(); @@ -124,7 +127,7 @@ public override string ToString() } string result = resultBuilder.ToString(); - StringBuilderPool.ReleaseBuilder(resultBuilder); + stringBuilderPool.Return(resultBuilder); return result; } diff --git a/src/LibSassHost/Utilities/SourceCodeNavigator.cs b/src/LibSassHost/Utilities/SourceCodeNavigator.cs index 2a00c46..d436897 100644 --- a/src/LibSassHost/Utilities/SourceCodeNavigator.cs +++ b/src/LibSassHost/Utilities/SourceCodeNavigator.cs @@ -2,6 +2,8 @@ using System.Globalization; using System.Text; +using AdvancedStringBuilder; + namespace LibSassHost.Utilities { internal static class SourceCodeNavigator @@ -313,7 +315,8 @@ public static string GetSourceFragment(string sourceCode, CalculateCutPositions(currentLine, columnNumber, maxFragmentLength, out fragmentStartPosition, out fragmentLength); - StringBuilder sourceFragmentBuilder = StringBuilderPool.GetBuilder(); + var stringBuilderPool = StringBuilderPool.Shared; + StringBuilder sourceFragmentBuilder = stringBuilderPool.Rent(); if (currentLine.Length > 0) { @@ -337,7 +340,7 @@ public static string GetSourceFragment(string sourceCode, } sourceFragment = sourceFragmentBuilder.ToString(); - StringBuilderPool.ReleaseBuilder(sourceFragmentBuilder); + stringBuilderPool.Return(sourceFragmentBuilder); } return sourceFragment; diff --git a/src/LibSassHost/Utilities/StringBuilderPool.cs b/src/LibSassHost/Utilities/StringBuilderPool.cs deleted file mode 100644 index 7503d99..0000000 --- a/src/LibSassHost/Utilities/StringBuilderPool.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System; -using System.Text; -using System.Threading; - -namespace LibSassHost.Utilities -{ - /// - /// Pool of string builders - /// - internal static class StringBuilderPool - { - /// - /// Maximum capacity of builder - /// - const int MAX_BUILDER_CAPACITY = 8 * 1024; - - /// - /// Number of builders per processor - /// - const int BUILDER_COUNT_PER_PROCESSOR = 4; - - /// - /// First builder - /// - /// The first builder is stored in a dedicated field, because we expect - /// to be able to satisfy most requests from it. - private static StringBuilder _firstBuilder; - - /// - /// List of the remaining builders - /// - private static readonly StringBuilder[] _builders; - - - /// - /// Static constructor - /// - static StringBuilderPool() - { - int builderCount = Environment.ProcessorCount * BUILDER_COUNT_PER_PROCESSOR; - if (builderCount < 5) - { - builderCount = 5; - } - - _builders = new StringBuilder[builderCount - 1]; - } - - - /// - /// Gets a instance of string builder from the pool - /// - /// Instance of string builder - public static StringBuilder GetBuilder() - { - // Examine the first builder. - // If that fails, then `GetBuilderSlow` method will look at the remaining builders. - StringBuilder builder = _firstBuilder; - if (builder == null || builder != Interlocked.CompareExchange(ref _firstBuilder, null, builder)) - { - builder = GetBuilderSlow(); - } - - return builder; - } - - /// - /// Gets a instance of string builder with at least the given capacity from the pool - /// - /// If the capacity is less than or equal to our maximum capacity, then return builder from the pool. - /// Otherwise create a new string builder, that will just get discarded when released. - /// Capacity of string builder - /// Instance of string builder - public static StringBuilder GetBuilder(int capacity) - { - if (capacity <= MAX_BUILDER_CAPACITY) - { - return GetBuilder(); - } - - return new StringBuilder(capacity); - } - - private static StringBuilder GetBuilderSlow() - { - StringBuilder[] builders = _builders; - int builderCount = builders.Length; - - for (int builderIndex = 0; builderIndex < builderCount; builderIndex++) - { - StringBuilder builder = builders[builderIndex]; - if (builder != null) - { - if (builder == Interlocked.CompareExchange(ref builders[builderIndex], null, builder)) - { - return builder; - } - } - } - - return new StringBuilder(MAX_BUILDER_CAPACITY); - } - - /// - /// Returns a instance of string builder to the pool - /// - /// Instance of string builder - public static void ReleaseBuilder(StringBuilder builder) - { - if (builder == null || builder.Capacity > MAX_BUILDER_CAPACITY) - { - return; - } - - if (_firstBuilder == null) - { - builder.Clear(); - _firstBuilder = builder; - } - else - { - ReleaseBuilderSlow(builder); - } - } - - private static void ReleaseBuilderSlow(StringBuilder builder) - { - StringBuilder[] builders = _builders; - int builderCount = builders.Length; - - for (int builderIndex = 0; builderIndex < builderCount; builderIndex++) - { - if (builders[builderIndex] == null) - { - builder.Clear(); - builders[builderIndex] = builder; - break; - } - } - } - } -} \ No newline at end of file diff --git a/src/LibSassHost/Utilities/Utils.cs b/src/LibSassHost/Utilities/Utils.cs index 8972ec8..f773ff7 100644 --- a/src/LibSassHost/Utilities/Utils.cs +++ b/src/LibSassHost/Utilities/Utils.cs @@ -1,12 +1,5 @@ using System; -#if NET40 -using System.Diagnostics; -#endif using System.Runtime.CompilerServices; -#if NET40 - -using LibSassHost.Resources; -#endif namespace LibSassHost.Utilities { @@ -51,48 +44,5 @@ public static bool Is64BitProcess() return is64Bit; } -#if NET40 - - public static string ReadProcessOutput(string fileName) - { - return ReadProcessOutput(fileName, string.Empty); - } - - public static string ReadProcessOutput(string fileName, string args) - { - if (fileName == null) - { - throw new ArgumentNullException( - nameof(fileName), - string.Format(Strings.Common_ArgumentIsNull, nameof(fileName)) - ); - } - - if (string.IsNullOrWhiteSpace(fileName)) - { - throw new ArgumentException( - string.Format(Strings.Common_ArgumentIsEmpty, nameof(fileName)), - nameof(fileName) - ); - } - - string output; - var processInfo = new ProcessStartInfo - { - FileName = fileName, - Arguments = args ?? string.Empty, - UseShellExecute = false, - RedirectStandardOutput = true - }; - - using (Process process = Process.Start(processInfo)) - { - output = process.StandardOutput.ReadToEnd(); - process.WaitForExit(); - } - - return output; - } -#endif } } \ No newline at end of file diff --git a/src/LibSassHost/readme.txt b/src/LibSassHost/readme.txt index b65d0fa..75c8447 100644 --- a/src/LibSassHost/readme.txt +++ b/src/LibSassHost/readme.txt @@ -26,8 +26,10 @@ ============= RELEASE NOTES ============= - An attempt was made to fix a error #26 “"Unable to find an entry point named - 'libsass_version' in DLL 'libsass'." on Azure Web App”. + 1. An attempt was made to fix a error #26 “"Unable to find an entry point named + 'libsass_version' in DLL 'libsass'." on Azure Web App”; + 2. Part of the auxiliary code was moved to external libraries: + PolyfillsForOldDotNet and AdvancedStringBuilder. ============ PROJECT SITE