From 7e2df3dea6623166b64af0c6724d229d7d50fdd0 Mon Sep 17 00:00:00 2001 From: kike-garbo Date: Fri, 13 Oct 2023 15:13:35 +0200 Subject: [PATCH 1/2] Added `PathExtension.IsFullyQualifiedPath` extension method. --- .../Extensions/System.cs | 28 +++++++++++++++++-- .../Settings/AddIns.cs | 3 +- .../Components/Documents/DocumentSave.cs | 2 +- .../Components/Family/New.cs | 2 +- .../Components/Family/Save.cs | 2 +- .../Components/Views/ExportImage.cs | 4 +-- .../Parameters/Document.cs | 1 + .../Convert/Render/RenderMaterialConverter.cs | 6 ++-- 8 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/RhinoInside.Revit.External/Extensions/System.cs b/src/RhinoInside.Revit.External/Extensions/System.cs index 52c9b6dd6..1ec185c7e 100644 --- a/src/RhinoInside.Revit.External/Extensions/System.cs +++ b/src/RhinoInside.Revit.External/Extensions/System.cs @@ -76,6 +76,31 @@ public static string TripleDot(this string sourceString, int maxLength) sourceString.Substring(0, maxLength - 1) + '…' : sourceString; } + } +} + +namespace System.IO +{ + static class PathExtension + { + public static bool IsFullyQualifiedPath(this string path) + { + if (path == null) return false; + if (path.Length < 2) return false; + if (IsDirectorySeparator(path[0])) + return path[1] == '?' || IsDirectorySeparator(path[1]); + + return + ( + (path.Length >= 3) && + (path[1] == Path.VolumeSeparatorChar) && + IsDirectorySeparator(path[2]) && + IsValidDriveChar(path[0]) + ); + + bool IsValidDriveChar(char value) => ('A' <= value && value <= 'Z') || ('a' <= value && value <= 'z'); + bool IsDirectorySeparator(char c) => c == Path.DirectorySeparatorChar || c == Path.AltDirectorySeparatorChar; + } [DllImport("SHLWAPI", CharSet = CharSet.Unicode)] static extern bool PathCompactPathExW([Out] Text.StringBuilder pszOut, string szPath, int cchMax, int dwFlags); @@ -87,10 +112,7 @@ internal static string TripleDotPath(this string path, int maxLength) return builder.ToString(); } } -} -namespace System.IO -{ internal static class FileInfoExtension { public static void MoveTo(this FileInfo source, string destFileName, bool overwrite) diff --git a/src/RhinoInside.Revit.External/Settings/AddIns.cs b/src/RhinoInside.Revit.External/Settings/AddIns.cs index 11ddf0154..6f4f6afd8 100644 --- a/src/RhinoInside.Revit.External/Settings/AddIns.cs +++ b/src/RhinoInside.Revit.External/Settings/AddIns.cs @@ -39,8 +39,7 @@ public class RevitAddIns : List public FileInfo ToFileInfo(string path) { - path = path.Trim(Path.DirectorySeparatorChar); - if (!Path.IsPathRooted(path)) + if (!path.IsFullyQualifiedPath()) path = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(ManifestPath), path)); return new FileInfo(path); diff --git a/src/RhinoInside.Revit.GH/Components/Documents/DocumentSave.cs b/src/RhinoInside.Revit.GH/Components/Documents/DocumentSave.cs index 01c781f9a..e4bd0fd04 100644 --- a/src/RhinoInside.Revit.GH/Components/Documents/DocumentSave.cs +++ b/src/RhinoInside.Revit.GH/Components/Documents/DocumentSave.cs @@ -104,7 +104,7 @@ protected override void TrySolveInstance(IGH_DataAccess DA) if (filePath.Last() == Path.DirectorySeparatorChar) filePath = Path.Combine(filePath, doc.Title); - if (Path.IsPathRooted(filePath) && filePath.Contains(Path.DirectorySeparatorChar)) + if (filePath.IsFullyQualifiedPath()) { if (!Path.HasExtension(filePath)) { diff --git a/src/RhinoInside.Revit.GH/Components/Family/New.cs b/src/RhinoInside.Revit.GH/Components/Family/New.cs index a865b5cdf..058cfa9ac 100644 --- a/src/RhinoInside.Revit.GH/Components/Family/New.cs +++ b/src/RhinoInside.Revit.GH/Components/Family/New.cs @@ -597,7 +597,7 @@ static string GetDefaultTemplatePath(ARDB.Document doc, ARDB.ElementId categoryI static bool FindTemplatePath(ARDB.Document doc, ref string templatePath, out bool pathWasRelative) { - pathWasRelative = !Path.IsPathRooted(templatePath); + pathWasRelative = !templatePath.IsFullyQualifiedPath(); // Validate input foreach (var invalid in Path.GetInvalidPathChars()) diff --git a/src/RhinoInside.Revit.GH/Components/Family/Save.cs b/src/RhinoInside.Revit.GH/Components/Family/Save.cs index d6eea62a8..d2da9b701 100644 --- a/src/RhinoInside.Revit.GH/Components/Family/Save.cs +++ b/src/RhinoInside.Revit.GH/Components/Family/Save.cs @@ -126,7 +126,7 @@ protected override void TrySolveInstance(IGH_DataAccess DA) if (!Path.HasExtension(filePath)) filePath += ".rfa"; - if (!Path.IsPathRooted(filePath)) + if (!filePath.IsFullyQualifiedPath()) { filePath = Path.Combine(Types.Document.FromValue(family.Document).SwapFolder.Directory.FullName, "Families", filePath); Directory.CreateDirectory(Path.GetDirectoryName(filePath)); diff --git a/src/RhinoInside.Revit.GH/Components/Views/ExportImage.cs b/src/RhinoInside.Revit.GH/Components/Views/ExportImage.cs index f539f7d68..4d6c47de0 100644 --- a/src/RhinoInside.Revit.GH/Components/Views/ExportImage.cs +++ b/src/RhinoInside.Revit.GH/Components/Views/ExportImage.cs @@ -274,10 +274,10 @@ protected override void TrySolveInstance(IGH_DataAccess DA) if (!Params.TryGetData(DA, "Folder", out string folder)) return; { - if (folder is object && folder.Any(x => Path.GetInvalidPathChars().Contains(x))) + if (folder?.Any(x => Path.GetInvalidPathChars().Contains(x)) is true) throw new Exceptions.RuntimeArgumentException("Folder", $"'{folder}' is not a valid folder name", folder); - if (folder is object && !Path.IsPathRooted(folder)) + if (folder?.IsFullyQualifiedPath() is false) throw new Exceptions.RuntimeArgumentException("Folder", $"'{folder}' is not a valid absolute path", folder); } diff --git a/src/RhinoInside.Revit.GH/Parameters/Document.cs b/src/RhinoInside.Revit.GH/Parameters/Document.cs index c18f975e0..f35adec55 100644 --- a/src/RhinoInside.Revit.GH/Parameters/Document.cs +++ b/src/RhinoInside.Revit.GH/Parameters/Document.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; diff --git a/src/RhinoInside.Revit/Convert/Render/RenderMaterialConverter.cs b/src/RhinoInside.Revit/Convert/Render/RenderMaterialConverter.cs index e19d0be68..1160055bb 100755 --- a/src/RhinoInside.Revit/Convert/Render/RenderMaterialConverter.cs +++ b/src/RhinoInside.Revit/Convert/Render/RenderMaterialConverter.cs @@ -17,10 +17,10 @@ namespace RhinoInside.Revit.Convert.Render { using Numerical; + using Convert.Geometry; using Convert.System.Drawing; using Convert.Units; using External.DB.Extensions; - using RhinoInside.Revit.Convert.Geometry; using DBXS = External.DB.Schemas; /// @@ -294,7 +294,7 @@ static SimulatedProceduralTexture GetUnifiedBitmapSchemaTexture(Asset asset) { try { - if (Path.IsPathRooted(entry) ? + if (entry.IsFullyQualifiedPath() ? File.Exists(entry) : Rhino.ApplicationSettings.FileSettings.FindFile(entry) is string) { @@ -370,7 +370,7 @@ static SimulatedProceduralTexture GetBumpMapSchemaTexture(Asset asset) { try { - if (Path.IsPathRooted(entry) ? + if (entry.IsFullyQualifiedPath() ? File.Exists(entry) : Rhino.ApplicationSettings.FileSettings.FindFile(entry) is string) { From a636d5c9517c0d285370b210f9eec74fef64ac03 Mon Sep 17 00:00:00 2001 From: kike-garbo Date: Mon, 23 Oct 2023 18:12:20 +0200 Subject: [PATCH 2/2] Null checking. --- src/RhinoInside.Revit.GH/Components/Sheets/SheetRevisions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RhinoInside.Revit.GH/Components/Sheets/SheetRevisions.cs b/src/RhinoInside.Revit.GH/Components/Sheets/SheetRevisions.cs index 8e27adce1..aa687a326 100644 --- a/src/RhinoInside.Revit.GH/Components/Sheets/SheetRevisions.cs +++ b/src/RhinoInside.Revit.GH/Components/Sheets/SheetRevisions.cs @@ -49,11 +49,11 @@ protected override void TrySolveInstance(IGH_DataAccess DA) if (update) { StartTransaction(sheet.Document); - sheet.Value.SetAdditionalRevisionIds(revisions.Select(x => x.Id).ToArray()); + sheet.Value.SetAdditionalRevisionIds(revisions.OfType().Select(x => x.Id).ToArray()); sheet.Document.Regenerate(); } - Params.TrySetData(DA, "Current Revision", () => Types.Element.FromElementId(sheet.Document, sheet.Value.GetCurrentRevision())); + Params.TrySetData(DA, "Current Revision", () => Types.Element.FromElementId(sheet.Document, sheet.Value.GetCurrentRevision()) as Types.Revision); Params.TrySetDataList(DA, "Revisions on Sheet", () => sheet.Value.GetAdditionalRevisionIds().Select(x => Types.Element.FromElementId(sheet.Document, x))); Params.TrySetDataList(DA, "Scheduled Revisions", () => sheet.Value.GetAllRevisionIds().Select(x => Types.Element.FromElementId(sheet.Document, x))); }