mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 12:30:32 +00:00
During the test and plugging of DirectoryInfo I've benn hit by a lot of stack overflows / stack corruptions. I do this PR because I've not the necessary competency to find where the issue his, executing the Cosmos.Kernel.Tests.Fat.Kernel you will be soon hit by a stack overflow.
148 lines
6.6 KiB
C#
148 lines
6.6 KiB
C#
//#define COSMOSDEBUG
|
|
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using Cosmos.Debug.Kernel;
|
|
using Cosmos.IL2CPU.API;
|
|
using Cosmos.IL2CPU.API.Attribs;
|
|
using Cosmos.System;
|
|
using Cosmos.System.FileSystem;
|
|
using Cosmos.System.FileSystem.Listing;
|
|
using Cosmos.System.FileSystem.VFS;
|
|
|
|
namespace Cosmos.System_Plugs.System.IO
|
|
{
|
|
//[Plug(TargetName = "System.IO.Win32FileSystem")]
|
|
[Plug(TargetName = "System.IO.Win32FileSystem, System.IO.FileSystem") ]
|
|
public static class CosmosFileSystem
|
|
{
|
|
public static void CreateDirectory(object aThis, string fullPath)
|
|
{
|
|
// TODO check if 'fullPath' exists already and return in this case
|
|
|
|
// XXX If the Directory 'aPath' already exits this method must not do nothing
|
|
var xEntry = VFSManager.CreateDirectory(fullPath);
|
|
|
|
if (xEntry == null)
|
|
{
|
|
throw new IOException("VFSManager.CreateDirectory() returns null");
|
|
}
|
|
}
|
|
|
|
// Never called? Cosmos goes in StackOverflow... ILCPU gets lost and do not find this native method
|
|
public static bool DirectoryExists(object aThis, string fullPath)
|
|
{
|
|
if (fullPath == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Global.mFileSystemDebugger.SendInternal($"DirectoryExists : fullPath = {fullPath}");
|
|
return VFSManager.DirectoryExists(fullPath);
|
|
}
|
|
|
|
public static void RemoveDirectory(object aThis, string fullPath, bool recursive)
|
|
{
|
|
Global.mFileSystemDebugger.SendInternal($"RemoveDirectory : fullPath = {fullPath}");
|
|
VFSManager.DeleteDirectory(fullPath, recursive);
|
|
}
|
|
|
|
public static object /* FileStreamBase */ Open(object aThis, string fullPath, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, FileStream parent)
|
|
{
|
|
Global.mFileSystemDebugger.SendInternal("In FileStream.InitializeStream");
|
|
if (fullPath == null)
|
|
{
|
|
Global.mFileSystemDebugger.SendInternal("In FileStream.Ctor: Path == null is true");
|
|
throw new ArgumentNullException("The file path cannot be null.");
|
|
}
|
|
if (fullPath.Length == 0)
|
|
{
|
|
Global.mFileSystemDebugger.SendInternal("In FileStream.Ctor: Path.Length == 0 is true");
|
|
throw new ArgumentException("The file path cannot be empty.");
|
|
}
|
|
|
|
// Naive, but working implementation of FileMode. Probably is better to do this at lower level...
|
|
|
|
// Before let's see if aPath already exists
|
|
bool aPathExists = File.Exists(fullPath);
|
|
|
|
Stream aStream = null;
|
|
|
|
switch (mode)
|
|
{
|
|
case FileMode.Append:
|
|
// TODO it seems that GetFileStream effectively Creates the file if not exist
|
|
aStream = aPathExists ? VFSManager.GetFileStream(fullPath) : File.Create(fullPath);
|
|
|
|
if (aPathExists)
|
|
{
|
|
Global.mFileSystemDebugger.SendInternal("Append mode with aPath already existing let's seek to end of the file");
|
|
Global.mFileSystemDebugger.SendInternal("Actual aStream Lenght: " + aStream.Length);
|
|
aStream.Seek(0, SeekOrigin.End);
|
|
}
|
|
else
|
|
{
|
|
Global.mFileSystemDebugger.SendInternal("Append mode with aPath not existing let's create a new the file");
|
|
}
|
|
break;
|
|
|
|
case FileMode.Create:
|
|
Global.mFileSystemDebugger.SendInternal("Create Mode aPath will be overwritten if existing");
|
|
// TODO it seems that GetFileStream effectively Creates the file if not exist
|
|
aStream = File.Create(fullPath);
|
|
break;
|
|
|
|
case FileMode.CreateNew:
|
|
if (aPathExists)
|
|
{
|
|
Global.mFileSystemDebugger.SendInternal("CreateNew Mode with aPath already existing");
|
|
throw new IOException("File already existing but CreateNew Requested");
|
|
}
|
|
|
|
Global.mFileSystemDebugger.SendInternal("CreateNew Mode with aPath not existing new file created");
|
|
// TODO it seems that GetFileStream effectively Creates the file if it does not exist
|
|
aStream = File.Create(fullPath);
|
|
break;
|
|
|
|
case FileMode.Open:
|
|
if (!aPathExists)
|
|
{
|
|
Global.mFileSystemDebugger.SendInternal("Open Mode with aPath not existing");
|
|
#warning TODO: Change IOException to FileNotFoundException, it asks for a plug
|
|
throw new IOException("File not existing but Open Requested");
|
|
}
|
|
|
|
Global.mFileSystemDebugger.SendInternal("Open Mode with aPath existing opening file");
|
|
// TODO it seems that GetFileStream effectively Creates the file if it does not exist
|
|
aStream = VFSManager.GetFileStream(fullPath);
|
|
aStream.Position = 0;
|
|
break;
|
|
|
|
case FileMode.OpenOrCreate:
|
|
Global.mFileSystemDebugger.SendInternal("OpenOrCreate Mode with aPath not existing new file created");
|
|
// TODO it seems that GetFileStream effectively Creates the file if it does not exist
|
|
aStream = aPathExists ? VFSManager.GetFileStream(fullPath) : File.Create(fullPath);
|
|
break;
|
|
|
|
case FileMode.Truncate:
|
|
if (!aPathExists)
|
|
{
|
|
Global.mFileSystemDebugger.SendInternal("Truncate Mode with aPath not existing");
|
|
throw new IOException("File not existing but Truncate Requested");
|
|
}
|
|
|
|
Global.mFileSystemDebugger.SendInternal("Truncate Mode with aPath existing change its lenght to 0 bytes");
|
|
// TODO it seems that GetFileStream effectively Creates the file if it does not exist
|
|
aStream = VFSManager.GetFileStream(fullPath);
|
|
aStream.SetLength(0);
|
|
break;
|
|
|
|
default:
|
|
Global.mFileSystemDebugger.SendInternal("The mode " + mode + "is out of range");
|
|
throw new ArgumentOutOfRangeException("The file mode is invalid");
|
|
}
|
|
|
|
return aStream;
|
|
}
|
|
}
|
|
}
|