Răsfoiți Sursa

Improved PixiParser version handling

CPKreuz 1 an în urmă
părinte
comite
8a56a4939c

+ 1 - 17
src/PixiEditor.AvaloniaUI/Models/Controllers/ClipboardController.cs

@@ -208,23 +208,7 @@ internal static class ClipboardController
                 {
                 {
                     using var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
                     using var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
 
 
-                    try
-                    {
-                        imported = Surface.Load(PixiParser.Deserialize(path).PreviewImage);
-                    }
-                    catch (InvalidFileException e)
-                    {
-                        // Check if it could be a old file
-                        if (!e.Message.StartsWith("Header"))
-                        {
-                            throw;
-                        }
-
-                        stream.Position = 0;
-                        var document = DeprecatedPixiParser.Deserialize(stream);
-
-                        imported = Surface.Load(document.PreviewImage);
-                    }
+                    imported = Surface.Load(PixiParser.ReadPreview(stream));
                 }
                 }
                 else
                 else
                 {
                 {

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/ExceptionHandling/CrashReport.cs

@@ -384,7 +384,7 @@ internal class CrashReport : IDisposable
                     .Replace(':', '_')
                     .Replace(':', '_')
                     .Replace('/', '_');
                     .Replace('/', '_');
 
 
-                byte[] serialized = PixiParser.Serialize(document.ToSerializable());
+                byte[] serialized = PixiParser.V5.Serialize(document.ToSerializable());
 
 
                 using Stream documentStream = archive.CreateEntry($"Documents/{nameInZip}").Open();
                 using Stream documentStream = archive.CreateEntry($"Documents/{nameInZip}").Open();
                 documentStream.Write(serialized);
                 documentStream.Write(serialized);

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/Files/PixiFileType.cs

@@ -20,7 +20,7 @@ internal class PixiFileType : IoFileType
     {
     {
         try
         try
         {
         {
-            await Parser.PixiParser.SerializeAsync(document.ToSerializable(), pathWithExtension);
+            await Parser.PixiParser.V5.SerializeAsync(document.ToSerializable(), pathWithExtension);
         }
         }
         catch (UnauthorizedAccessException e)
         catch (UnauthorizedAccessException e)
         {
         {

+ 44 - 33
src/PixiEditor.AvaloniaUI/Models/IO/Importer.cs

@@ -85,37 +85,34 @@ internal class Importer : ObservableObject
     {
     {
         try
         try
         {
         {
-            var doc = PixiParser.Deserialize(path).ToDocument();
+            using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
+            var pixiDocument = PixiParser.DeserializeUsingCompatible(fileStream);
+
+            var document = pixiDocument switch
+            {
+                Document v5 => v5.ToDocument(),
+                DeprecatedDocument v4 => v4.ToDocument()
+            };
 
 
             if (associatePath)
             if (associatePath)
             {
             {
-                doc.FullFilePath = path;
+                document.FullFilePath = path;
             }
             }
 
 
-            return doc;
+            return document;
         }
         }
         catch (DirectoryNotFoundException)
         catch (DirectoryNotFoundException)
         {
         {
             //TODO: Handle
             //TODO: Handle
             throw new RecoverableException();
             throw new RecoverableException();
         }
         }
-        catch (InvalidFileException)
+        catch (InvalidFileException e)
         {
         {
-            try
-            {
-                var doc = DeprecatedPixiParser.Deserialize(path).ToDocument();
-                
-                if (associatePath)
-                {
-                    doc.FullFilePath = path;
-                }
-
-                return doc;
-            }
-            catch (Exception e)
-            {
-                throw new CorruptedFileException("FAILED_TO_OPEN_FILE", e);
-            }
+            throw new CorruptedFileException("FAILED_TO_OPEN_FILE", e);
+        }
+        catch (OldFileFormatException e)
+        {
+            throw new CorruptedFileException("FAILED_TO_OPEN_FILE", e);
         }
         }
     }
     }
 
 
@@ -123,22 +120,31 @@ internal class Importer : ObservableObject
     {
     {
         try
         try
         {
         {
-            var doc = PixiParser.Deserialize(file).ToDocument();
-            doc.FullFilePath = originalFilePath;
-            return doc;
-        }
-        catch (InvalidFileException)
-        {
-            try
+            if (!PixiParser.TryGetCompatibleVersion(file, out var parser))
             {
             {
-                var doc = DeprecatedPixiParser.Deserialize(file).ToDocument();
-                doc.FullFilePath = originalFilePath;
-                return doc;
+                // TODO: Handle
+                throw new RecoverableException();
             }
             }
-            catch (InvalidFileException e)
+            
+            var pixiDocument = parser.Deserialize(file);
+
+            var document = pixiDocument switch
             {
             {
-                throw new CorruptedFileException("FAILED_TO_OPEN_FILE", e);
-            }
+                Document v5 => v5.ToDocument(),
+                DeprecatedDocument v4 => v4.ToDocument()
+            };
+
+            document.FullFilePath = originalFilePath;
+
+            return document;
+        }
+        catch (InvalidFileException e)
+        {
+            throw new CorruptedFileException("FAILED_TO_OPEN_FILE", e);
+        }
+        catch (OldFileFormatException e)
+        {
+            throw new CorruptedFileException("FAILED_TO_OPEN_FILE", e);
         }
         }
     }
     }
 
 
@@ -148,8 +154,13 @@ internal class Importer : ObservableObject
         {
         {
             throw new InvalidFileTypeException(new LocalizedString("FILE_EXTENSION_NOT_SUPPORTED", Path.GetExtension(path)));
             throw new InvalidFileTypeException(new LocalizedString("FILE_EXTENSION_NOT_SUPPORTED", Path.GetExtension(path)));
         }
         }
+        
+        if (Path.GetExtension(path) != ".pixi")
+            return Surface.Load(path);
+
+        using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
 
 
-        return Path.GetExtension(path) != ".pixi" ? Surface.Load(path) : PixiParser.Deserialize(path).ToDocument().PreviewSurface;
+        return Surface.Load(PixiParser.ReadPreview(fileStream));
     }
     }
 
 
     public static bool IsSupportedFile(string path)
     public static bool IsSupportedFile(string path)

+ 13 - 3
src/PixiEditor.AvaloniaUI/Models/IO/PaletteParsers/PixiPaletteParser.cs

@@ -4,6 +4,7 @@ using System.Threading.Tasks;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Extensions.CommonApi.Palettes.Parsers;
 using PixiEditor.Extensions.CommonApi.Palettes.Parsers;
 using PixiEditor.Parser;
 using PixiEditor.Parser;
+using PixiEditor.Parser.Deprecated;
 
 
 namespace PixiEditor.AvaloniaUI.Models.IO.PaletteParsers;
 namespace PixiEditor.AvaloniaUI.Models.IO.PaletteParsers;
 
 
@@ -25,12 +26,21 @@ internal class PixiPaletteParser : PaletteFileParser
 
 
     private async Task<PaletteFileData> ParseFile(string path)
     private async Task<PaletteFileData> ParseFile(string path)
     {
     {
-        var file = await PixiParser.DeserializeAsync(path);
-        if(file.Palette == null) return PaletteFileData.Corrupted;
+        using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
+        var file = await PixiParser.DeserializeUsingCompatibleAsync(fileStream);
+
+        var palette = file switch
+        {
+            Document v5 => v5.Palette,
+            DeprecatedDocument v4 => v4.Palette,
+            _ => null
+        };
+        
+        if(palette == null) return PaletteFileData.Corrupted;
 
 
         string name = Path.GetFileNameWithoutExtension(path);
         string name = Path.GetFileNameWithoutExtension(path);
 
 
-        return new PaletteFileData(name, file.Palette.Select(x => new PaletteColor(x.R, x.G, x.B)).ToArray());
+        return new PaletteFileData(name, palette.Select(x => new PaletteColor(x.R, x.G, x.B)).ToArray());
     }
     }
 
 
     public override bool CanSave => false;
     public override bool CanSave => false;

+ 3 - 26
src/PixiEditor.AvaloniaUI/Models/UserData/RecentlyOpenedDocument.cs

@@ -4,6 +4,7 @@ using System.Linq;
 using ChunkyImageLib;
 using ChunkyImageLib;
 using CommunityToolkit.Mvvm.ComponentModel;
 using CommunityToolkit.Mvvm.ComponentModel;
 using PixiEditor.AvaloniaUI.Helpers;
 using PixiEditor.AvaloniaUI.Helpers;
+using PixiEditor.AvaloniaUI.Models.IO;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Extensions.Exceptions;
 using PixiEditor.Extensions.Exceptions;
@@ -91,36 +92,12 @@ internal class RecentlyOpenedDocument : ObservableObject
         {
         {
             try
             try
             {
             {
-                var document = PixiParser.Deserialize(filePath);
-
-                if (document.PreviewImage == null || document.PreviewImage.Length == 0)
-                {
-                    return null;
-                }
-
-                return Surface.Load(document.PreviewImage);
+                return Importer.GetPreviewBitmap(FilePath);
             }
             }
             catch
             catch
             {
             {
-
-                try
-                {
-                    var deprecatedDocument = DeprecatedPixiParser.Deserialize(filePath);
-                    
-                    if (deprecatedDocument.PreviewImage == null || deprecatedDocument.PreviewImage.Length == 0)
-                    {
-                        return null;
-                    }
-                    
-                    return Surface.Load(deprecatedDocument.PreviewImage);
-                }
-                catch
-                {
-                    corrupt = true;
-                    return null;
-                }
+                return null;
             }
             }
-
         }
         }
 
 
         if (SupportedFilesHelper.IsExtensionSupported(FileExtension))
         if (SupportedFilesHelper.IsExtensionSupported(FileExtension))

+ 0 - 1
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.cs

@@ -45,7 +45,6 @@ using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Numerics;
 using PixiEditor.Numerics;
-using PixiEditor.Parser;
 using PixiEditor.Parser.Skia;
 using PixiEditor.Parser.Skia;
 using Color = PixiEditor.DrawingApi.Core.ColorsImpl.Color;
 using Color = PixiEditor.DrawingApi.Core.ColorsImpl.Color;
 using Colors = PixiEditor.DrawingApi.Core.ColorsImpl.Colors;
 using Colors = PixiEditor.DrawingApi.Core.ColorsImpl.Colors;

+ 1 - 0
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/ClipboardViewModel.cs

@@ -81,6 +81,7 @@ internal class ClipboardViewModel : SubViewModel<ViewModelMain>
     {
     {
         var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
         var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
 
 
+        // TODO: Exception handling would probably be good
         var bitmap = Importer.GetPreviewBitmap(path);
         var bitmap = Importer.GetPreviewBitmap(path);
         byte[] pixels = bitmap.ToWriteableBitmap().ExtractPixels();
         byte[] pixels = bitmap.ToWriteableBitmap().ExtractPixels();