diff --git a/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs b/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs index 02be5726e..4da60f745 100644 --- a/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs +++ b/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs @@ -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 a5378e821..54a48b673 100644 --- a/source/Cosmos.System.Plugs/System/IO/FileImpl.cs +++ b/source/Cosmos.System.Plugs/System/IO/FileImpl.cs @@ -9,6 +9,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 { @@ -58,21 +59,37 @@ namespace Cosmos.System.Plugs.System.IO Global.mFileSystemDebugger.SendInternal("Writing bytes"); xFS.Write(xBuff, 0, xBuff.Length); Global.mFileSystemDebugger.SendInternal("Bytes written"); - } } - public static void WriteAllLines(string path, string[] contents) + public static string[] ReadAllLines(string aFile) { - String text = String.Empty; + String text = ReadAllText(aFile); + + Global.mFileSystemDebugger.SendInternal(("Read content"); + Global.mFileSystemDebugger.SendInternal(("\n", text); + + String []result = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + + Global.mFileSystemDebugger.SendInternal(("content as array of lines:"); +#if COSMOSDEBUG + for (int i = 0; i < result.Length; i++) + Global.mFileSystemDebugger.SendInternal((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); } Global.mFileSystemDebugger.SendInternal("Writing contents\n" + text); - WriteAllText(path, text); + WriteAllText(aFile, text); } public static byte[] ReadAllBytes(string aFile) @@ -87,7 +104,7 @@ namespace Cosmos.System.Plugs.System.IO throw new Exception("Couldn't read complete file!"); } Global.mFileSystemDebugger.SendInternal("Bytes read"); - + return xBuff; } } @@ -98,7 +115,7 @@ namespace Cosmos.System.Plugs.System.IO { // This variable is not needed 'aBytes' is already a Byte[] //var xBuff = aBytes; - + xFS.Write(aBytes, 0, aBytes.Length); } } diff --git a/source/Cosmos.System/FileSystem/FAT/FatStream.cs b/source/Cosmos.System/FileSystem/FAT/FatStream.cs index f0ddaf858..d3b61b7df 100644 --- a/source/Cosmos.System/FileSystem/FAT/FatStream.cs +++ b/source/Cosmos.System/FileSystem/FAT/FatStream.cs @@ -15,7 +15,7 @@ namespace Cosmos.System.FileSystem.FAT protected byte[] mReadBuffer; //TODO: In future we might read this in as needed rather than - // all at once. This structure will also consume 2% of file size in RAM + // all at once. This structure will also consume 2% of file size in RAM // (for default cluster size of 2kb, ie 4 bytes per cluster) // so we might consider a way to flush it and only keep parts. // Example, a 100 MB file will require 2MB for this structure. That is @@ -35,9 +35,16 @@ namespace Cosmos.System.FileSystem.FAT mDirectoryEntry = aEntry; mFS = mDirectoryEntry.GetFileSystem(); mSize = mDirectoryEntry.mSize; - if (mDirectoryEntry.mSize > 0) - { + + Global.mFileSystemDebugger.SendInternal("FatStream with mSize", mSize); + + Global.mFileSystemDebugger.SendInternal("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) + { + Global.mFileSystemDebugger.SendInternal("FatTable got but it is null!"); } } @@ -192,6 +199,7 @@ namespace Cosmos.System.FileSystem.FAT protected void Write(byte[] aBuffer, long aOffset, long aCount) { + Global.mFileSystemDebugger.SendInternal("Write() called aCount ", aCount, ", aOffset", aOffset); if (aCount < 0) { throw new ArgumentOutOfRangeException("aCount"); @@ -240,6 +248,7 @@ namespace Cosmos.System.FileSystem.FAT Array.Copy(aBuffer, aOffset, xCluster, (long)xPosInCluster, xWriteSize); mFS.Write(mFatTable[(int)xClusterIdx], xCluster); + Global.mFileSystemDebugger.SendInternal("Data written"); aOffset += xWriteSize; xCount -= (ulong)xWriteSize; @@ -248,4 +257,4 @@ namespace Cosmos.System.FileSystem.FAT mPosition += (ulong)aOffset; } } -} +} \ No newline at end of file