lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nightowl...@apache.org
Subject [4/8] lucenenet git commit: Lucene.Net.Support.IO.FileSupport: Added GetCanonicalPath() method + tests
Date Mon, 25 Sep 2017 11:52:28 GMT
Lucene.Net.Support.IO.FileSupport: Added GetCanonicalPath() method + tests


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/8b7b9cb6
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/8b7b9cb6
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/8b7b9cb6

Branch: refs/heads/master
Commit: 8b7b9cb6d02292e6d31330c0153ae1b975ecbae0
Parents: 5065f10
Author: Shad Storhaug <shad@shadstorhaug.com>
Authored: Mon Sep 25 00:25:44 2017 +0700
Committer: Shad Storhaug <shad@shadstorhaug.com>
Committed: Mon Sep 25 00:25:44 2017 +0700

----------------------------------------------------------------------
 .../Support/IO/TestFileSupport.cs               | 216 +++++++++++++++++++
 src/Lucene.Net/Support/IO/FileSupport.cs        | 124 +++++++++++
 2 files changed, 340 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8b7b9cb6/src/Lucene.Net.Tests/Support/IO/TestFileSupport.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Support/IO/TestFileSupport.cs b/src/Lucene.Net.Tests/Support/IO/TestFileSupport.cs
new file mode 100644
index 0000000..b5ce877
--- /dev/null
+++ b/src/Lucene.Net.Tests/Support/IO/TestFileSupport.cs
@@ -0,0 +1,216 @@
+´╗┐using Lucene.Net.Attributes;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using System;
+using System.Globalization;
+using System.IO;
+
+namespace Lucene.Net.Support.IO
+{
+    /*
+     * Licensed to the Apache Software Foundation (ASF) under one or more
+     * contributor license agreements.  See the NOTICE file distributed with
+     * this work for additional information regarding copyright ownership.
+     * The ASF licenses this file to You under the Apache License, Version 2.0
+     * (the "License"); you may not use this file except in compliance with
+     * the License.  You may obtain a copy of the License at
+     *
+     *     http://www.apache.org/licenses/LICENSE-2.0
+     *
+     * Unless required by applicable law or agreed to in writing, software
+     * distributed under the License is distributed on an "AS IS" BASIS,
+     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     * See the License for the specific language governing permissions and
+     * limitations under the License.
+     */
+
+    public class TestFileSupport : LuceneTestCase
+    {
+        private static String platformId = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.Replace('.',
'-');
+
+        /** Location to store tests in */
+        private DirectoryInfo tempDirectory;
+
+        public override void SetUp()
+        {
+            base.SetUp();
+            tempDirectory = CreateTempDir(this.GetType().Name);
+        }
+
+        public override void TearDown()
+        {
+            if (tempDirectory != null)
+            {
+                Directory.Delete(tempDirectory.FullName, true);
+                tempDirectory = null;
+            }
+            base.TearDown();
+        }
+
+        [Test, LuceneNetSpecific]
+        public void TestCreateRandomFile()
+        {
+            var dir = new DirectoryInfo(Path.Combine(Path.GetTempPath(), "testrandomfile"));
+
+            var file1 = FileSupport.CreateTempFile("foo", "bar", dir);
+            var file2 = FileSupport.CreateTempFile("foo", "bar", dir);
+
+            Assert.AreNotEqual(file1.FullName, file2.FullName);
+        }
+
+        [Test, LuceneNetSpecific]
+        public void TestGetCanonicalPath()
+        {
+            // Should work for Unix/Windows.
+            String dots = "..";
+            String @base = tempDirectory.GetCanonicalPath();
+            @base = addTrailingSlash(@base);
+            FileInfo f = new FileInfo(Path.Combine(@base, "temp.tst"));
+
+            assertEquals("Test 1: Incorrect Path Returned.", @base + "temp.tst", f
+                    .GetCanonicalPath());
+            f = new FileInfo(@base + "Temp" + Path.DirectorySeparatorChar + dots + Path.DirectorySeparatorChar
+ "temp.tst");
+            assertEquals("Test 2: Incorrect Path Returned.", @base + "temp.tst", f
+                    .GetCanonicalPath());
+
+
+            // Finding a non-existent directory for tests 3 and 4
+            // This is necessary because getCanonicalPath is case sensitive and
+            // could cause a failure in the test if the directory exists but with
+            // different case letters (e.g "Temp" and "temp")
+            int dirNumber = 1;
+            bool dirExists = true;
+            DirectoryInfo dir1 = new DirectoryInfo(Path.Combine(@base, dirNumber.ToString(CultureInfo.InvariantCulture)));
+            while (dirExists)
+            {
+                if (dir1.Exists)
+                {
+                    dirNumber++;
+                    dir1 = new DirectoryInfo(Path.Combine(@base, dirNumber.ToString(CultureInfo.InvariantCulture)));
+                }
+                else
+                {
+                    dirExists = false;
+                }
+            }
+            f = new FileInfo(@base + dirNumber + Path.DirectorySeparatorChar + dots + Path.DirectorySeparatorChar
+ dirNumber
+                    + Path.DirectorySeparatorChar + "temp.tst");
+            assertEquals("Test 3: Incorrect Path Returned.", @base + dirNumber
+                    + Path.DirectorySeparatorChar + "temp.tst", f.GetCanonicalPath());
+            f = new FileInfo(@base + dirNumber + Path.DirectorySeparatorChar + "Temp" + Path.DirectorySeparatorChar
+ dots + Path.DirectorySeparatorChar
+                    + "Test" + Path.DirectorySeparatorChar + "temp.tst");
+            assertEquals("Test 4: Incorrect Path Returned.", @base + dirNumber
+                    + Path.DirectorySeparatorChar + "Test" + Path.DirectorySeparatorChar
+ "temp.tst", f.GetCanonicalPath());
+
+            f = new FileInfo(@base + "1234.567");
+            assertEquals("Test 5: Incorrect Path Returned.", @base + "1234.567", f
+                    .GetCanonicalPath());
+
+            // Test for long file names on Windows
+            bool onWindows = (Path.DirectorySeparatorChar == '\\');
+            if (onWindows)
+            {
+                DirectoryInfo testdir = new DirectoryInfo(Path.Combine(@base, "long-" + platformId));
+                testdir.Create();
+                FileInfo f1 = new FileInfo(Path.Combine(testdir.FullName, "longfilename"
+ platformId + ".tst"));
+                using (FileStream fos = new FileStream(f1.FullName, FileMode.CreateNew, FileAccess.Write))
+                { }
+                FileInfo f2 = null, f3 = null;
+                DirectoryInfo dir2 = null;
+                try
+                {
+                    String dirName1 = f1.GetCanonicalPath();
+                    FileInfo f4 = new FileInfo(Path.Combine(testdir.FullName, "longfi~1.tst"));
+                    /*
+                     * If the "short file name" doesn't exist, then assume that the
+                     * 8.3 file name compatibility is disabled.
+                     */
+                    if (f4.Exists)
+                    {
+                        String dirName2 = f4.GetCanonicalPath();
+                        assertEquals("Test 6: Incorrect Path Returned.", dirName1,
+                                dirName2);
+                        dir2 = new DirectoryInfo(Path.Combine(testdir.FullName, "longdirectory"
+ platformId));
+                        if (!dir2.Exists)
+                        {
+                            try
+                            {
+                                dir2.Create();
+                            }
+                            catch
+                            {
+                            }
+                            finally
+                            {
+                                if (!Directory.Exists(dir2.FullName))
+                                    fail("Could not create dir: " + dir2);
+                            }
+
+                        }
+                        f2 = new FileInfo(testdir.FullName + Path.DirectorySeparatorChar
+ "longdirectory"
+                                + platformId + Path.DirectorySeparatorChar + "Test" + Path.DirectorySeparatorChar
+ dots
+                                + Path.DirectorySeparatorChar + "longfilename.tst");
+                        using (FileStream fos2 = new FileStream(f2.FullName, FileMode.CreateNew,
FileAccess.Write))
+                        { }
+                        dirName1 = f2.GetCanonicalPath();
+                        f3 = new FileInfo(testdir.FullName + Path.DirectorySeparatorChar
+ "longdi~1"
+                                + Path.DirectorySeparatorChar + "Test" + Path.DirectorySeparatorChar
+ dots + Path.DirectorySeparatorChar
+                                + "longfi~1.tst");
+                        dirName2 = f3.GetCanonicalPath();
+                        assertEquals("Test 7: Incorrect Path Returned.", dirName1,
+                                dirName2);
+                    }
+                }
+                finally
+                {
+                    f1.Delete();
+                    if (f2 != null)
+                    {
+                        f2.Delete();
+                    }
+                    if (dir2 != null)
+                    {
+                        dir2.Delete();
+                    }
+                    testdir.Delete();
+                }
+            }
+        }
+
+        private static String addTrailingSlash(String path)
+        {
+            if (Path.DirectorySeparatorChar == path[path.Length - 1])
+            {
+                return path;
+            }
+            return path + Path.DirectorySeparatorChar;
+        }
+
+        [Test, LuceneNetSpecific]
+        public void TestGetCanonicalPathDriveLetterNormalization()
+        {
+            bool onWindows = (Path.DirectorySeparatorChar == '\\');
+            if (onWindows)
+            {
+                var path = @"f:\testing\on\Windows";
+                var expected = @"F:\testing\on\Windows";
+
+                var dir = new DirectoryInfo(path);
+
+                assertEquals(expected, dir.GetCanonicalPath());
+            }
+        }
+
+        [Test, LuceneNetSpecific]
+        public void TestGetCanonicalPathDriveLetter()
+        {
+            bool onWindows = (Path.DirectorySeparatorChar == '\\');
+            if (onWindows)
+            {
+                var path = new FileInfo(@"c:\").GetCanonicalPath();
+                if (path.Length > 3)
+                    fail("Drive letter incorrectly represented");
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8b7b9cb6/src/Lucene.Net/Support/IO/FileSupport.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/IO/FileSupport.cs b/src/Lucene.Net/Support/IO/FileSupport.cs
index 99ac644..db64b87 100644
--- a/src/Lucene.Net/Support/IO/FileSupport.cs
+++ b/src/Lucene.Net/Support/IO/FileSupport.cs
@@ -1,5 +1,6 @@
 using Lucene.Net.Util;
 using System;
+using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Text;
@@ -177,5 +178,128 @@ namespace Lucene.Net.Support.IO
 
             return Path.Combine(directory.FullName, string.Concat(prefix, randomFileName));
         }
+
+        private static readonly IDictionary<string, string> fileCanonPathCache = new
Dictionary<string, string>();
+
+        /// <summary>
+        /// Returns the absolute path of this <see cref="FileSystemInfo"/> with all
references resolved and
+        /// any drive letters normalized to upper case on Windows. An
+        /// <em>absolute</em> path is one that begins at the root of the file
+        /// system. The canonical path is one in which all references have been
+        /// resolved. For the cases of '..' and '.', where the file system supports
+        /// parent and working directory respectively, these are removed and replaced
+        /// with a direct directory reference. 
+        /// </summary>
+        /// <param name="path">This <see cref="FileSystemInfo"/> instance.</param>
+        /// <returns>The canonical path of this file.</returns>
+        // LUCENENET NOTE: Implementation ported mostly from Apache Harmony
+        public static string GetCanonicalPath(this FileSystemInfo path)
+        {
+            string absPath = path.FullName; // LUCENENET NOTE: This internally calls GetFullPath(),
which resolves relative paths
+            byte[] result = Encoding.UTF8.GetBytes(absPath);
+
+            string canonPath;
+            if (fileCanonPathCache.TryGetValue(absPath, out canonPath) && canonPath
!= null)
+            {
+                return canonPath;
+            }
+
+            // LUCENENET TODO: On Unix, this resolves symbolic links. Not sure
+            // if it is safe to assume Path.GetFullPath() does that for us.
+            //if (Path.DirectorySeparatorChar == '/')
+            //{
+            //    //// resolve the full path first
+            //    //result = resolveLink(result, result.Length, false);
+            //    //// resolve the parent directories
+            //    //result = resolve(result);
+            //}
+            int numSeparators = 1;
+            for (int i = 0; i < result.Length; i++)
+            {
+                if (result[i] == Path.DirectorySeparatorChar)
+                {
+                    numSeparators++;
+                }
+            }
+            int[] sepLocations = new int[numSeparators];
+            int rootLoc = 0;
+            if (Path.DirectorySeparatorChar == '\\')
+            {
+                if (result[0] == '\\')
+                {
+                    rootLoc = (result.Length > 1 && result[1] == '\\') ? 1 : 0;
+                }
+                else
+                {
+                    rootLoc = 2; // skip drive i.e. c:
+                }
+            }
+            byte[] newResult = new byte[result.Length + 1];
+            int newLength = 0, lastSlash = 0, foundDots = 0;
+            sepLocations[lastSlash] = rootLoc;
+            for (int i = 0; i <= result.Length; i++)
+            {
+                if (i < rootLoc)
+                {
+                    // Normalize case of Windows drive letter to upper
+                    newResult[newLength++] = (byte)char.ToUpperInvariant((char)result[i]);
+                }
+                else
+                {
+                    if (i == result.Length || result[i] == Path.DirectorySeparatorChar)
+                    {
+                        if (i == result.Length && foundDots == 0)
+                        {
+                            break;
+                        }
+                        if (foundDots == 1)
+                        {
+                            /* Don't write anything, just reset and continue */
+                            foundDots = 0;
+                            continue;
+                        }
+                        if (foundDots > 1)
+                        {
+                            /* Go back N levels */
+                            lastSlash = lastSlash > (foundDots - 1) ? lastSlash
+                                    - (foundDots - 1) : 0;
+                            newLength = sepLocations[lastSlash] + 1;
+                            foundDots = 0;
+                            continue;
+                        }
+                        sepLocations[++lastSlash] = newLength;
+                        newResult[newLength++] = (byte)Path.DirectorySeparatorChar;
+                        continue;
+                    }
+                    if (result[i] == '.')
+                    {
+                        foundDots++;
+                        continue;
+                    }
+                    /* Found some dots within text, write them out */
+                    if (foundDots > 0)
+                    {
+                        for (int j = 0; j < foundDots; j++)
+                        {
+                            newResult[newLength++] = (byte)'.';
+                        }
+                    }
+                    newResult[newLength++] = result[i];
+                    foundDots = 0;
+                }
+            }
+            // remove trailing slash
+            if (newLength > (rootLoc + 1)
+                    && newResult[newLength - 1] == Path.DirectorySeparatorChar)
+            {
+                newLength--;
+            }
+            newResult[newLength] = 0;
+            //newResult = getCanonImpl(newResult);
+            newLength = newResult.Length;
+            canonPath = Encoding.UTF8.GetString(newResult, 0, newLength).TrimEnd('\0'); //
LUCENENET: Eliminate null terminator char
+            fileCanonPathCache[absPath] = canonPath;
+            return canonPath;
+        }
     }
 }
\ No newline at end of file


Mime
View raw message