Skip to content

[FSKit] Implement this new framework. #21029

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/preview-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,16 @@ We've tentatively set .NET 10 as the release when we'll stop marking CryptoToken

The diagnostic id for CryptoTokenKit is APL0001.

## FSKit (APL0002)

FSKit is a new framework in macOS 15.0 to implement a file system in user space.

At the moment implementing a file system is out of our reach, so we haven't
been able to validate the API, and as such we mark every type in this
framework as preview API for a while.

We've tentatively set .NET 11 as the release when we'll stop marking FSKit as preview API.

The diagnostic id for CryptoTokenKit is APL0001.

[1]: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.experimentalattribute?view=net-8.0
74 changes: 74 additions & 0 deletions src/FSKit/FSBlockDeviceResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#if NET
using Foundation;

#nullable enable

namespace FSKit {
public partial class FSBlockDeviceResource {
public unsafe void Read (byte [] buffer, long offset, nuint length, FSBlockDeviceResourceReadReplyHandler reply)
{
fixed (byte* bufferPtr = buffer) {
Read ((IntPtr) bufferPtr, offset, length, reply);
}
}

public unsafe void SynchronousRead (byte [] buffer, long offset, nuint length, FSBlockDeviceResourceReadReplyHandler reply)
{
fixed (byte* bufferPtr = buffer) {
SynchronousRead ((IntPtr) bufferPtr, offset, length, reply);
}
}

public unsafe void Write (byte [] buffer, long offset, nuint length, FSBlockDeviceResourceWriteReplyHandler reply)
{
fixed (byte* bufferPtr = buffer) {
Write ((IntPtr) bufferPtr, offset, length, reply);
}
}

public unsafe void SynchronousWrite (byte [] buffer, long offset, nuint length, FSBlockDeviceResourceWriteReplyHandler reply)
{
fixed (byte* bufferPtr = buffer) {
SynchronousWrite ((IntPtr) bufferPtr, offset, length, reply);
}
}

public unsafe void SynchronousMetadataRead (byte [] buffer, long offset, nuint length, FSBlockDeviceResourceMetadataReplyHandler reply)
{
fixed (byte* bufferPtr = buffer) {
SynchronousMetadataRead ((IntPtr) bufferPtr, offset, length, reply);
}
}

public unsafe void SynchronousMetadataRead (byte [] buffer, long offset, nuint length, FSMetadataReadahead[] readAheadExtents, FSBlockDeviceResourceMetadataReplyHandler reply)
{
fixed (byte* bufferPtr = buffer) {
fixed (FSMetadataReadahead* readAheadExtentsPtr = readAheadExtents) {
SynchronousMetadataRead ((IntPtr) bufferPtr, offset, length, (IntPtr) readAheadExtentsPtr, readAheadExtents.Length, reply);
}
}
}

public unsafe void MetadataWrite (byte [] buffer, long offset, nuint length, FSBlockDeviceResourceMetadataReplyHandler reply)
{
fixed (byte* bufferPtr = buffer) {
MetadataWrite ((IntPtr) bufferPtr, offset, length, reply);
}
}

public unsafe void SynchronousMetadataWrite (byte [] buffer, long offset, nuint length, FSBlockDeviceResourceMetadataReplyHandler reply)
{
fixed (byte* bufferPtr = buffer) {
SynchronousMetadataWrite ((IntPtr) bufferPtr, offset, length, reply);
}
}

public unsafe void DelayedMetadataWriteFrom (byte [] buffer, long offset, nuint length, FSBlockDeviceResourceMetadataReplyHandler reply)
{
fixed (byte* bufferPtr = buffer) {
DelayedMetadataWriteFrom ((IntPtr) bufferPtr, offset, length, reply);
}
}
}
}
#endif // NET
36 changes: 36 additions & 0 deletions src/FSKit/FSFileName.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#if NET
using System;

using ObjCRuntime;

#nullable enable

namespace FSKit {
public partial class FSFileName {
[DesignatedInitializer]
public FSFileName (byte [] bytes)
{
if (bytes is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (bytes));

unsafe {
fixed (byte* bytesPtr = bytes) {
InitializeHandle (InitWithBytes ((IntPtr) bytesPtr, (nuint) bytes.Length));
}
}
}

public FSFileName Create (byte [] bytes)
{
if (bytes is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (bytes));

unsafe {
fixed (byte* bytesPtr = bytes) {
return _Create ((IntPtr) bytesPtr, (nuint) bytes.Length);
}
}
}
}
}
#endif // NET
59 changes: 59 additions & 0 deletions src/FSKit/FSKitFunctions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#if NET

using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;

using Foundation;
using ObjCRuntime;

#nullable enable

// Let's hope that by .NET 11 we've ironed out all the bugs in the API.
// This can of course be adjusted as needed (until we've released as stable).
#if NET110_0_OR_GREATER
#define STABLE_FSKIT
#endif

namespace FSKit {
#if !STABLE_FSKIT
[Experimental ("APL0002")]
#endif
[SupportedOSPlatform ("macos15.0")]
[UnsupportedOSPlatform ("maccatalyst")]
[UnsupportedOSPlatform ("ios")]
[UnsupportedOSPlatform ("tvos")]
public static class FSKitFunctions {
[DllImport (Constants.FSKitLibrary)]
static extern IntPtr fskit_std_log ();

public static NSObject GetStdLog ()
{
return Runtime.GetNSObject (fskit_std_log ())!;
}

[DllImport (Constants.FSKitLibrary)]
static extern IntPtr fs_errorForPOSIXError (int errorCode);

public static NSError GetErrorForPosixError (int errorCode)
{
return Runtime.GetNSObject<NSError> (fs_errorForPOSIXError (errorCode))!;
}

[DllImport (Constants.FSKitLibrary)]
static extern IntPtr fs_errorForMachError (int errorCode);

public static NSError GetErrorForMachError (int errorCode)
{
return Runtime.GetNSObject<NSError> (fs_errorForMachError (errorCode))!;
}

[DllImport (Constants.FSKitLibrary)]
static extern IntPtr fs_errorForCocoaError (int errorCode);

public static NSError GetErrorForCocoaError (int errorCode)
{
return Runtime.GetNSObject<NSError> (fs_errorForCocoaError (errorCode))!;
}
}
}
#endif // NET
41 changes: 41 additions & 0 deletions src/FSKit/FSMessageConnection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#if NET

using System;

using CoreFoundation;
using Foundation;
using ObjCRuntime;

#nullable enable

namespace FSKit {
public partial class FSMessageConnection {
public NSString GetLocalizedMessage (NSString message, NSString tableName, NSBundle bundle, params NSObject[] arguments)
{
var argumentPtrs = new IntPtr [arguments.Length];
for (var i = 0; i < arguments.Length; i++)
argumentPtrs [i] = arguments [i].GetNonNullHandle ($"{nameof (arguments)} [{i}]");

var rv = Messaging.objc_msgSend_5_vargs (
this.GetNonNullHandle ("this"),
Selector.GetHandle ("localizedMessage:table:bundle:"),
message.GetNonNullHandle (nameof (message)),
tableName.GetNonNullHandle (nameof (message)),
bundle.GetNonNullHandle (nameof (bundle)),
argumentPtrs);

GC.KeepAlive (message);
GC.KeepAlive (tableName);
GC.KeepAlive (bundle);
GC.KeepAlive (arguments);

return Runtime.GetNSObject<NSString> (rv)!;
}

public string GetLocalizedMessage (string message, string tableName, NSBundle bundle, params NSObject[] arguments)
{
return (string) GetLocalizedMessage ((NSString) message, (NSString) tableName, bundle, arguments);
}
}
}
#endif // NET
25 changes: 25 additions & 0 deletions src/FSKit/FSMetaReadahead.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#if NET

using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;

#nullable enable

// Let's hope that by .NET 11 we've ironed out all the bugs in the API.
// This can of course be adjusted as needed (until we've released as stable).
#if NET110_0_OR_GREATER
#define STABLE_FSKIT
#endif

namespace FSKit {
#if !STABLE_FSKIT
[Experimental ("APL0002")]
#endif
[StructLayout (LayoutKind.Sequential)]
public struct FSMetadataReadahead
{
public long Offset;
public nuint Length;
}
}
#endif
1 change: 1 addition & 0 deletions src/Foundation/NSObject.mac.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public partial class NSObject {
static IntPtr sm = Dlfcn.dlopen (Constants.ServiceManagementLibrary, 1);
static IntPtr sa = Dlfcn.dlopen (Constants.SafetyKitLibrary, 1);
static IntPtr cr = Dlfcn.dlopen (Constants.CryptoTokenKitLibrary, 1);
static IntPtr fk = Dlfcn.dlopen (Constants.FSKitLibrary, 1);

#if !NET
[Obsolete ("Use PlatformAssembly for easier code sharing across platforms.")]
Expand Down
1 change: 1 addition & 0 deletions src/ObjCRuntime/Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2783,6 +2783,7 @@ static IntPtr LookupUnmanagedFunction (IntPtr assembly, IntPtr symbol, int id)
}
}


internal class IntPtrEqualityComparer : IEqualityComparer<IntPtr> {
public bool Equals (IntPtr x, IntPtr y)
{
Expand Down
Empty file added src/ObjCRuntime/Timespec.cs
Empty file.
1 change: 1 addition & 0 deletions src/bgen/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1807,6 +1807,7 @@ void GenerateStrongDictionaryTypes ()
print ("namespace {0} {{", dictType.Namespace);
indent++;
PrintPlatformAttributes (dictType);
PrintExperimentalAttribute (dictType);
print ("public partial class {0} : DictionaryContainer {{", typeName);
indent++;
sw.WriteLine ("#if !COREBUILD");
Expand Down
3 changes: 3 additions & 0 deletions src/build/generator-frameworks.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ partial class Frameworks {
"FileProviderUI",
"FinderSync",
"Foundation",
"FSKit",
"GameController",
"GameKit",
"GameplayKit",
Expand Down Expand Up @@ -627,6 +628,7 @@ partial class Frameworks {
bool? _FileProviderUI;
bool? _FinderSync;
bool? _Foundation;
bool? _FSKit;
bool? _GameController;
bool? _GameKit;
bool? _GameplayKit;
Expand Down Expand Up @@ -797,6 +799,7 @@ partial class Frameworks {
public bool HaveFileProviderUI { get { if (!_FileProviderUI.HasValue) _FileProviderUI = GetValue ("FileProviderUI"); return _FileProviderUI.Value; } }
public bool HaveFinderSync { get { if (!_FinderSync.HasValue) _FinderSync = GetValue ("FinderSync"); return _FinderSync.Value; } }
public bool HaveFoundation { get { if (!_Foundation.HasValue) _Foundation = GetValue ("Foundation"); return _Foundation.Value; } }
public bool HaveFSKit { get { if (!_FSKit.HasValue) _FSKit = GetValue ("FSKit"); return _FSKit.Value; } }
public bool HaveGameController { get { if (!_GameController.HasValue) _GameController = GetValue ("GameController"); return _GameController.Value; } }
public bool HaveGameKit { get { if (!_GameKit.HasValue) _GameKit = GetValue ("GameKit"); return _GameKit.Value; } }
public bool HaveGameplayKit { get { if (!_GameplayKit.HasValue) _GameplayKit = GetValue ("GameplayKit"); return _GameplayKit.Value; } }
Expand Down
12 changes: 12 additions & 0 deletions src/frameworks.sources
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,17 @@ FOUNDATION_SOURCES = \
Foundation/ToString.cs \
Foundation/NSItemProvider.cs \

# FSKit

FSKIT_CORE_SOURCES = \
FSKit/FSMetaReadahead.cs \

FSKIT_SOURCES = \
FSKit/FSBlockDeviceResource.cs \
FSKit/FSFileName.cs \
FSKit/FSKitFunctions.cs \
FSKit/FSMessageConnection.cs \

# GameController

GAMECONTROLLER_API_SOURCES = \
Expand Down Expand Up @@ -2116,6 +2127,7 @@ MACOS_FRAMEWORKS = \
FileProvider \
FileProviderUI \
FinderSync \
FSKit \
GameController \
GameplayKit \
GLKit \
Expand Down
Loading