From bfc3934be0384ccf3f1d70e7f0db30619a42188b Mon Sep 17 00:00:00 2001 From: fanoI Date: Wed, 6 Jan 2016 22:21:52 +0100 Subject: [PATCH 1/2] FATStream Constructor Fixed: FatTable generated for empty files too - FATStream Constructor Fixed: FatTable generated for empty files too - Corrected method WriteAllLines() - Added new method ReadAllLines() - In FatTestKernel added utility method StringArrayAreEquals() - In FatTestKernel fixed assertions on file existence - In FatTestKernel used ReadAllLines() to check that WriteAllLines() succeeded - In FatTestKernel moved AppendAllText() test as last of File as - for now - is always failing --- Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs | 87 ++++++++++++++----- .../Cosmos.System.Plugs/System/IO/FileImpl.cs | 41 +++++++-- .../FileSystem/FAT/FatFileSystem.cs | 1 + .../Cosmos.System/FileSystem/FAT/FatStream.cs | 17 ++-- 4 files changed, 115 insertions(+), 31 deletions(-) diff --git a/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs b/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs index 02be5726e..0aabe61cc 100644 --- a/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs +++ b/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs @@ -28,10 +28,10 @@ namespace Cosmos.Kernel.Tests.Fat { mDebugger.Send("Run"); - TestPath(); - TestDirectory(); + //TestPath(); + //TestDirectory(); TestFile(); - TestFileStream(); + //TestFileStream(); TestController.Completed(); } @@ -49,7 +49,7 @@ namespace Cosmos.Kernel.Tests.Fat { if (ReferenceEquals(a1, a2)) { - mDebugger.Send("byte Array a1 and a2 are the same Object"); + mDebugger.Send("a1 and a2 are the same Object"); return true; } @@ -76,6 +76,39 @@ namespace Cosmos.Kernel.Tests.Fat return true; } + // Utility method to test String Array equality if Generics would have worked it could have been done universal + public bool StringArrayAreEquals(String[] a1, String[] a2) + { + if (ReferenceEquals(a1, a2)) + { + mDebugger.Send("a1 and a2 are the same Object"); + return true; + } + + if (a1 == null || a2 == null) + { + mDebugger.Send("a1 or a2 is null so are different"); + return false; + } + + if (a1.Length != a2.Length) + { + mDebugger.Send("a1.Length != a2.Length so are different"); + return false; + } + + for (int i = 0; i < a1.Length; i++) + { + if (a1[i] != a2[i]) + { + mDebugger.Send("In position " + i + " a String is different"); + return false; + } + } + + return true; + } + public void TestPath() { string xMessage; @@ -390,11 +423,12 @@ namespace Cosmos.Kernel.Tests.Fat // mDebugger.Send("START TEST: Create file:"); // Attention! File.Create() returns a FileStream that should be Closed / Disposed on Windows trying to write to the file next gives "File in Use" exception! + using (var xFile = File.Create(@"0:\test2.txt")) { Assert.IsTrue(xFile != null, "Failed to create a new file."); bool xFileExists = File.Exists(@"0:\test2.txt"); - Assert.IsTrue(xFileExists, "Failed to create a new file."); + Assert.IsTrue(xFileExists, "Failed to check existence of the new file."); mDebugger.Send("END TEST"); mDebugger.Send(""); } @@ -410,25 +444,37 @@ namespace Cosmos.Kernel.Tests.Fat mDebugger.Send("END TEST"); mDebugger.Send(""); - // Now we write in test2.txt using WriteAllLines() + // Now we write in test3.txt using WriteAllLines() mDebugger.Send("START TEST: WriteAllLines:"); using (var xFile = File.Create(@"0:\test3.txt")) { Assert.IsTrue(xFile != null, "Failed to create a new file."); bool xFileExists = File.Exists(@"0:\test3.txt"); - Assert.IsTrue(xFileExists, "Failed to create a new file."); + Assert.IsTrue(xFileExists, "Failed to check existence of the new file."); mDebugger.Send("END TEST"); mDebugger.Send(""); } + String[] contents = { "One", "Two", "Three" }; File.WriteAllLines(@"0:\test3.txt", contents); mDebugger.Send("Text written"); + mDebugger.Send("Now reading with ReadAllLines()"); + String[] readLines = File.ReadAllLines(@"0:\test3.txt"); + mDebugger.Send("Contents retrieved after writing"); + for (int i = 0; i < readLines.Length; i++) { + mDebugger.Send(readLines[i]); + } + Assert.IsTrue(StringArrayAreEquals(contents, readLines), "Contents of test3.txt was written incorrectly!"); +#if false // TODO maybe the more correct test is to implement ReadAllLines and then check that two arrays are equals - xContents = File.ReadAllText(@"0:\test3.txt"); + var xContents = File.ReadAllText(@"0:\test3.txt"); mDebugger.Send("Contents retrieved after writing"); mDebugger.Send(xContents); - Assert.IsTrue(xContents == "One\nTwo\nThree", "Contents of test3.txt was written incorrectly!"); + String expectedResult = String.Concat("One", Environment.NewLine, "Two", Environment.NewLine, "Three"); + mDebugger.Send("expectedResult: " + expectedResult); + Assert.IsTrue(xContents == expectedResult, "Contents of test3.txt was written incorrectly!"); +#endif mDebugger.Send("END TEST"); mDebugger.Send(""); @@ -446,17 +492,6 @@ namespace Cosmos.Kernel.Tests.Fat mDebugger.Send("END TEST"); mDebugger.Send(""); - mDebugger.Send("START TEST: Append text to file:"); - string appendedText = "Yet other text."; - File.AppendAllText(@"0:\Kudzu.txt", appendedText); - mDebugger.Send("Text appended"); - xContents = File.ReadAllText(@"0:\Kudzu.txt"); - mDebugger.Send("Contents retrieved after writing"); - mDebugger.Send(xContents); - Assert.IsTrue(xContents == "Test FAT write.\nYet other text.", "Contents of Kudzu.txt was appended incorrectly!"); - mDebugger.Send("END TEST"); - mDebugger.Send(""); - // This creates a loop? Nothing is printed when VFSManager.CreateStream() method is reached... mDebugger.Send("START TEST: Create a new directory with a file inside (filestream):"); var xDirectory = Directory.CreateDirectory(@"0:\testdir"); @@ -487,6 +522,18 @@ namespace Cosmos.Kernel.Tests.Fat xContents = File.ReadAllText(@"0:\testdir\file.txt"); mDebugger.Send("Contents retrieved"); Assert.IsTrue(xContents == WrittenText, "Failed to read from file"); + + mDebugger.Send("START TEST: Append text to file:"); + string appendedText = "Yet other text."; + File.AppendAllText(@"0:\Kudzu.txt", appendedText); + mDebugger.Send("Text appended"); + xContents = File.ReadAllText(@"0:\Kudzu.txt"); + mDebugger.Send("Contents retrieved after writing"); + mDebugger.Send(xContents); + // XXX Use String.Concat() with Enviroment.NewLine this not Linux there are is '\n'! + Assert.IsTrue(xContents == "Test FAT write.\nYet other text.", "Contents of Kudzu.txt was appended incorrectly!"); + mDebugger.Send("END TEST"); + mDebugger.Send(""); } private void TestDirectory() diff --git a/source/Cosmos.System.Plugs/System/IO/FileImpl.cs b/source/Cosmos.System.Plugs/System/IO/FileImpl.cs index 0c1101136..48eb51bf2 100644 --- a/source/Cosmos.System.Plugs/System/IO/FileImpl.cs +++ b/source/Cosmos.System.Plugs/System/IO/FileImpl.cs @@ -8,6 +8,7 @@ using Cosmos.System.FileSystem.VFS; namespace Cosmos.System.Plugs.System.IO { + // TODO A lot of these methods should be implemented using StreamReader / StreamWriter [Plug(Target = typeof(File))] public static class FileImpl { @@ -41,6 +42,14 @@ namespace Cosmos.System.Plugs.System.IO { FileSystemHelpers.Debug("Converting " + aText + " to UFT8"); var xBuff = aText.GetUtf8Bytes(0, (uint)aText.Length); + +#if COSMOSDEBUG + for (int i = 0; i < xBuff.Length; i++) + { + FileSystemHelpers.Debug("xBuff is", xBuff[i].ToString("0:x2")); + } +#endif + FileSystemHelpers.Debug("Writing bytes"); xFS.Write(xBuff, 0, xBuff.Length); FileSystemHelpers.Debug("Bytes written"); @@ -56,22 +65,42 @@ namespace Cosmos.System.Plugs.System.IO var xBuff = aText.GetUtf8Bytes(0, (uint)aText.Length); FileSystemHelpers.Debug("Writing bytes"); xFS.Write(xBuff, 0, xBuff.Length); + FileSystemHelpers.Debug("Bytes written"); } } - public static void WriteAllLines(string path, string[] contents) + public static string[] ReadAllLines(string aFile) { - String text = String.Empty; + String text = ReadAllText(aFile); + + FileSystemHelpers.Debug("Read content"); + FileSystemHelpers.Debug("\n", text); + + String []result = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + + FileSystemHelpers.Debug("content as array of lines:"); +#if COSMOSDEBUG + for (int i = 0; i < result.Length; i++) + FileSystemHelpers.Debug(result[i]); +#endif + + return result; + } + + public static void WriteAllLines(string aFile, string[] contents) + { + String text = null; for (int i = 0; i < contents.Length; i++) { - text += contents[i]; - text += '\n'; + text = String.Concat(text, contents[i], Environment.NewLine); } - FileSystemHelpers.Debug("Writing contents\n" + text); - WriteAllText(path, text); + FileSystemHelpers.Debug("Writing contents"); + FileSystemHelpers.Debug("\n" + text); + + WriteAllText(aFile, text); } public static byte[] ReadAllBytes(string aFile) diff --git a/source/Cosmos.System/FileSystem/FAT/FatFileSystem.cs b/source/Cosmos.System/FileSystem/FAT/FatFileSystem.cs index 4e1e4c591..4b173dab0 100644 --- a/source/Cosmos.System/FileSystem/FAT/FatFileSystem.cs +++ b/source/Cosmos.System/FileSystem/FAT/FatFileSystem.cs @@ -413,6 +413,7 @@ namespace Cosmos.System.FileSystem.FAT internal void Write(ulong aFirstCluster, byte[] aData, ulong aSize = 0, ulong aOffset = 0) { + FileSystemHelpers.Debug("low level Write() called"); if (aSize == 0) { aSize = BytesPerCluster; diff --git a/source/Cosmos.System/FileSystem/FAT/FatStream.cs b/source/Cosmos.System/FileSystem/FAT/FatStream.cs index b0199c456..64d51f6d2 100644 --- a/source/Cosmos.System/FileSystem/FAT/FatStream.cs +++ b/source/Cosmos.System/FileSystem/FAT/FatStream.cs @@ -29,15 +29,20 @@ namespace Cosmos.System.FileSystem.FAT public FatStream(FatDirectoryEntry aEntry) { - FileSystemHelpers.Debug("FatStream with entry " + aEntry); + FileSystemHelpers.Debug("FatStream Ctor"); mDirectoryEntry = aEntry; mFS = mDirectoryEntry.GetFileSystem(); mSize = mDirectoryEntry.mSize; - if (mDirectoryEntry.mSize > 0) - { - mFatTable = mDirectoryEntry.GetFatTable(); - } + + FileSystemHelpers.Debug("FatStream with mSize", mSize); + + FileSystemHelpers.Debug("Getting FatTable"); + // We get always the FatTable if the file is empty too + mFatTable = mDirectoryEntry.GetFatTable(); + // What to do if this should happen? Throw exception? + if (mFatTable == null) + FileSystemHelpers.Debug("FatTable got but it is null!"); } public override bool CanSeek @@ -191,6 +196,7 @@ namespace Cosmos.System.FileSystem.FAT protected void Write(byte[] aBuffer, long aOffset, long aCount) { + FileSystemHelpers.Debug("Write() called aCount ", aCount, ", aOffset", aOffset); if (aCount < 0) { throw new ArgumentOutOfRangeException("aCount"); @@ -239,6 +245,7 @@ namespace Cosmos.System.FileSystem.FAT Array.Copy(aBuffer, aOffset, xCluster, (long)xPosInCluster, xWriteSize); mFS.Write(mFatTable[(int)xClusterIdx], xCluster); + FileSystemHelpers.Debug("Data written"); aOffset += xWriteSize; xCount -= (ulong)xWriteSize; From 41d6aaf2c076ae8ee84d35b6fa5b6e544367ff67 Mon Sep 17 00:00:00 2001 From: fanoI Date: Wed, 6 Jan 2016 22:24:19 +0100 Subject: [PATCH 2/2] Re-enabled all tests - TestPath, TestDirectory and TestFileStream was commented --- Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs b/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs index 0aabe61cc..4da60f745 100644 --- a/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs +++ b/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs @@ -28,10 +28,10 @@ namespace Cosmos.Kernel.Tests.Fat { mDebugger.Send("Run"); - //TestPath(); - //TestDirectory(); + TestPath(); + TestDirectory(); TestFile(); - //TestFileStream(); + TestFileStream(); TestController.Completed(); }