Pārlūkot izejas kodu

QpdfNativeDependencyCompatibilityChecker: lazy compatibility evaluation

Marcin Ziąbek 1 gadu atpakaļ
vecāks
revīzija
293c7c1b9f

+ 1 - 2
Source/QuestPDF/Drawing/DocumentGenerator.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 using QuestPDF.Companion;
 using QuestPDF.Drawing.Exceptions;
@@ -18,7 +17,7 @@ namespace QuestPDF.Drawing
     {
         static DocumentGenerator()
         {
-            NativeDependencyCompatibilityChecker.Test();
+            SkNativeDependencyCompatibilityChecker.Test();
         }
         
         internal static void GeneratePdf(SkWriteStream stream, IDocument document)

+ 1 - 2
Source/QuestPDF/Drawing/FontManager.cs

@@ -3,7 +3,6 @@ using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Reflection;
-using QuestPDF.Helpers;
 using QuestPDF.Infrastructure;
 using QuestPDF.Skia;
 using QuestPDF.Skia.Text;
@@ -22,7 +21,7 @@ namespace QuestPDF.Drawing
 
         static FontManager()
         {
-            NativeDependencyCompatibilityChecker.Test();
+            SkNativeDependencyCompatibilityChecker.Test();
             RegisterLibraryDefaultFonts();
         }
         

+ 3 - 2
Source/QuestPDF/Fluent/ElementExtensions.cs

@@ -1,9 +1,10 @@
 using System;
+using System.Net.Mime;
 using System.Runtime.CompilerServices;
 using QuestPDF.Drawing.Exceptions;
 using QuestPDF.Elements;
-using QuestPDF.Helpers;
 using QuestPDF.Infrastructure;
+using QuestPDF.Skia;
 
 namespace QuestPDF.Fluent
 {
@@ -11,7 +12,7 @@ namespace QuestPDF.Fluent
     {
         static ElementExtensions()
         {
-            NativeDependencyCompatibilityChecker.Test();
+            SkNativeDependencyCompatibilityChecker.Test();
         }
         
         internal static Container Create(Action<IContainer> factory)

+ 2 - 2
Source/QuestPDF/Fluent/MinimalApi.cs

@@ -1,7 +1,7 @@
 using System;
 using System.Collections.Generic;
-using QuestPDF.Helpers;
 using QuestPDF.Infrastructure;
+using QuestPDF.Skia;
 
 namespace QuestPDF.Fluent
 {
@@ -9,7 +9,7 @@ namespace QuestPDF.Fluent
     {
         static Document()
         {
-            NativeDependencyCompatibilityChecker.Test();
+            SkNativeDependencyCompatibilityChecker.Test();
         }
         
         private Action<IDocumentContainer> ContentSource { get; }

+ 1 - 1
Source/QuestPDF/Helpers/Helpers.cs

@@ -15,7 +15,7 @@ namespace QuestPDF.Helpers
     {
         static Helpers()
         {
-            NativeDependencyCompatibilityChecker.Test();
+            SkNativeDependencyCompatibilityChecker.Test();
         }
         
         internal static byte[] LoadEmbeddedResource(string resourceName)

+ 5 - 18
Source/QuestPDF/Helpers/NativeDependencyCompatibilityChecker.cs

@@ -7,25 +7,17 @@ namespace QuestPDF.Helpers
 {
     internal static class NativeDependencyCompatibilityChecker
     {
-        private static bool IsCompatibilityChecked = false;
-            
-        public static void Test()
+        public static void Test(Action executeNativeCode)
         {
             const string exceptionBaseMessage = "The QuestPDF library has encountered an issue while loading one of its dependencies.";
             const string paragraph = "\n\n";
-            
-            if (IsCompatibilityChecked)
-                return;
                 
             // test with dotnet-based mechanism where native files are provided
             // in the "runtimes/{rid}/native" folder on Core, or by the targets file on .NET Framework
-            var innerException = CheckIfExceptionIsThrownWhenLoadingNativeDependencies();
+            var innerException = CheckIfExceptionIsThrownWhenLoadingNativeDependencies(executeNativeCode);
 
             if (innerException == null)
-            {
-                IsCompatibilityChecked = true;
                 return;
-            }
 
             if (!NativeDependencyProvider.IsCurrentPlatformSupported())
                 ThrowCompatibilityException(innerException);
@@ -33,13 +25,10 @@ namespace QuestPDF.Helpers
             // detect platform, copy appropriate native files and test compatibility again
             NativeDependencyProvider.EnsureNativeFileAvailability();
             
-            innerException = CheckIfExceptionIsThrownWhenLoadingNativeDependencies();
+            innerException = CheckIfExceptionIsThrownWhenLoadingNativeDependencies(executeNativeCode);
 
             if (innerException == null)
-            {
-                IsCompatibilityChecked = true;
                 return;
-            }
 
             ThrowCompatibilityException(innerException);
             
@@ -72,13 +61,11 @@ namespace QuestPDF.Helpers
             }
         }
     
-        private static Exception? CheckIfExceptionIsThrownWhenLoadingNativeDependencies()
+        private static Exception? CheckIfExceptionIsThrownWhenLoadingNativeDependencies(Action executeNativeCode)
         {
             try
             {
-                SkNativeDependencyCompatibilityChecker.CheckIfExceptionIsThrownWhenLoadingNativeDependencies();
-                QpdfNativeDependencyCompatibilityChecker.CheckIfExceptionIsThrownWhenLoadingNativeDependencies();
-
+                executeNativeCode();
                 return null;
             }
             catch (Exception exception)

+ 1 - 1
Source/QuestPDF/Helpers/Placeholders.cs

@@ -9,7 +9,7 @@ namespace QuestPDF.Helpers
     {
         static Placeholders()
         {
-            NativeDependencyCompatibilityChecker.Test();
+            SkNativeDependencyCompatibilityChecker.Test();
         }
         
         public static readonly Random Random = new Random();

+ 1 - 1
Source/QuestPDF/Infrastructure/Image.cs

@@ -26,7 +26,7 @@ namespace QuestPDF.Infrastructure
     {
         static Image()
         {
-            NativeDependencyCompatibilityChecker.Test();
+            SkNativeDependencyCompatibilityChecker.Test();
         }
         
         internal SkImage SkImage { get; }

+ 2 - 8
Source/QuestPDF/Qpdf/QpdfAPI.cs

@@ -6,11 +6,6 @@ namespace QuestPDF.Qpdf;
 
 class QpdfAPI
 {
-    public static void Initialize()
-    {
-        API.qpdf_init();
-    }
-    
     public static string? GetQpdfVersion()
     {
         var ptr = API.qpdf_get_qpdf_version();
@@ -19,6 +14,8 @@ class QpdfAPI
     
     public static void ExecuteJob(string jobJson)
     {
+        QpdfNativeDependencyCompatibilityChecker.Test();
+        
         // create StringBuilder that will store the error message
         var error = new StringBuilder();
         var errorHandle = GCHandle.Alloc(error);
@@ -71,9 +68,6 @@ class QpdfAPI
         
         /* GENERAL */
         
-        [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
-        public static extern IntPtr qpdf_init();
-    
         [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
         public static extern IntPtr qpdf_get_qpdf_version();
     

+ 16 - 7
Source/QuestPDF/Qpdf/QpdfNativeDependencyCompatibilityChecker.cs

@@ -1,17 +1,26 @@
 using System;
-using QuestPDF.Qpdf;
+using QuestPDF.Helpers;
 
-namespace QuestPDF.Skia;
+namespace QuestPDF.Qpdf;
 
 internal static class QpdfNativeDependencyCompatibilityChecker
 {
-    public static void CheckIfExceptionIsThrownWhenLoadingNativeDependencies()
+    private static bool IsCompatibilityChecked = false;
+    
+    public static void Test()
     {
-        QpdfAPI.Initialize();
+        if (IsCompatibilityChecked)
+            return;
         
-        var qpdfVersion = QpdfAPI.GetQpdfVersion();
+        NativeDependencyCompatibilityChecker.Test(ExecuteNativeCode);
+        IsCompatibilityChecked = true;
+
+        void ExecuteNativeCode()
+        {
+            var qpdfVersion = QpdfAPI.GetQpdfVersion();
         
-        if (string.IsNullOrEmpty(qpdfVersion))
-            throw new Exception();
+            if (string.IsNullOrEmpty(qpdfVersion))
+                throw new Exception();
+        }
     }
 }

+ 2 - 2
Source/QuestPDF/Settings.cs

@@ -1,7 +1,7 @@
 using System;
 using System.Collections.Generic;
-using QuestPDF.Helpers;
 using QuestPDF.Infrastructure;
+using QuestPDF.Skia;
 
 namespace QuestPDF
 {
@@ -65,7 +65,7 @@ namespace QuestPDF
         
         static Settings()
         {
-            NativeDependencyCompatibilityChecker.Test();
+            SkNativeDependencyCompatibilityChecker.Test();
         }
     }
 }

+ 19 - 8
Source/QuestPDF/Skia/SkNativeDependencyCompatibilityChecker.cs

@@ -7,18 +7,29 @@ namespace QuestPDF.Skia;
 
 internal static class SkNativeDependencyCompatibilityChecker
 {
-    public static void CheckIfExceptionIsThrownWhenLoadingNativeDependencies()
+    private static bool IsCompatibilityChecked = false;
+    
+    public static void Test()
     {
-        var random = new Random();
+        if (IsCompatibilityChecked)
+            return;
+        
+        NativeDependencyCompatibilityChecker.Test(ExecuteNativeCode);
+        IsCompatibilityChecked = true;
+
+        void ExecuteNativeCode()
+        {
+            var random = new Random();
             
-        var a = random.Next();
-        var b = random.Next();
+            var a = random.Next();
+            var b = random.Next();
         
-        var expected = a + b;
-        var returned = API.check_compatibility_by_calculating_sum(a, b);
+            var expected = a + b;
+            var returned = API.check_compatibility_by_calculating_sum(a, b);
         
-        if (expected != returned)
-            throw new Exception();
+            if (expected != returned)
+                throw new Exception();
+        }
     }
     
     private static class API