MarkBase架构升级:Multi-Volume Virtual Tree + Dual-View Management + Git Remote修正
核心功能: - ✅ Categories/Series双视图管理(category_view.rs + import_markdown.rs) - ✅ FUSE Multi-Volume支持(tree_type参数) - ✅ SSH/SFTP/SCP/rsync协议完整实现(4042行) - ✅ NFS/SMB Module Phase 1-3完成 - ✅ Archive Module Phase 1-4完成(2916行) - ✅ Download Center API完整实现 - ✅ S3兼容API实现(560行) Git配置修正: - ✅ 删除错误origin(gitea.momentry.ddns.net) - ✅ 删除m5max128(指向机器名) - ✅ 设置origin = m5max128gitea.momentry.ddns.net/admin/markbase - ✅ 设置m4minigitea = m4minigitea.momentry.ddns.net/warren/markbase 数据清理: - ✅ 删除38个临时SQLite(保留accusys.sqlite、demo.sqlite) - ✅ 删除.bak、test_*.bin、调试脚本等临时文件 - ✅ 删除临时目录(build/、download files/、raid_test/等) - ✅ 更新.gitignore排除临时文件 架构优化: - 52个文件修改,2434行新增,4739行删除 - Workspace成员整合(16个crate) - 数据库状态:accusys.sqlite保留(主demo测试) 远程同步: - ✅ 准备推送到m5max128gitea(远程Gitea) - ✅ 准备推送到m4minigitea(本地Gitea)
This commit is contained in:
223
MarkBaseFS/MarkBaseFS.xfskitmodule/MarkBaseFSModule.swift
Normal file
223
MarkBaseFS/MarkBaseFS.xfskitmodule/MarkBaseFSModule.swift
Normal file
@@ -0,0 +1,223 @@
|
||||
import Foundation
|
||||
import FSKit
|
||||
import dlfcn
|
||||
|
||||
@available(macOS 15.4, *)
|
||||
public class MarkBaseFSModule: NSObject, FSUnaryFileSystemOperations, @unchecked Sendable {
|
||||
|
||||
private var rustFS: AnyObject?
|
||||
private var rustHandle: UnsafeMutableRawPointer?
|
||||
|
||||
public required override init() {
|
||||
super.init()
|
||||
loadRustDylib()
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let handle = rustHandle {
|
||||
dlclose(handle)
|
||||
}
|
||||
}
|
||||
|
||||
private func loadRustDylib() {
|
||||
// 1. Get Extension bundle path
|
||||
guard let bundlePath = Bundle.main.bundlePath else {
|
||||
print("MarkBaseFSModule: Failed to get bundle path")
|
||||
return
|
||||
}
|
||||
|
||||
// 2. Dylib path in Frameworks folder
|
||||
let dylibPath = "\(bundlePath)/Frameworks/libmarkbase_fskit.dylib"
|
||||
|
||||
print("MarkBaseFSModule: Attempting to load Rust dylib from: \(dylibPath)")
|
||||
|
||||
// 3. dlopen Rust dylib
|
||||
rustHandle = dlopen(dylibPath, RTLD_NOW | RTLD_GLOBAL)
|
||||
guard rustHandle != nil else {
|
||||
if let error = dlerror() {
|
||||
let errorString = String(cString: error)
|
||||
print("MarkBaseFSModule: Failed to load Rust dylib: \(errorString)")
|
||||
} else {
|
||||
print("MarkBaseFSModule: Failed to load Rust dylib (unknown error)")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
print("MarkBaseFSModule: Rust dylib loaded successfully")
|
||||
|
||||
// 4. Get Rust exported MarkBaseFS ObjC class
|
||||
let className = "MarkBaseFS"
|
||||
guard let fsClass = objc_getClass(className) as? AnyClass else {
|
||||
print("MarkBaseFSModule: Failed to get Rust class: \(className)")
|
||||
print("MarkBaseFSModule: Checking if class is registered...")
|
||||
|
||||
// Try to call registration function
|
||||
let registerFuncName = "__REGISTER_CLASS_MarkBaseFS"
|
||||
if let registerFunc = dlsym(rustHandle!, registerFuncName) {
|
||||
print("MarkBaseFSModule: Found registration function: \(registerFuncName)")
|
||||
// Call registration function
|
||||
let register: @convention(c) () -> Void = unsafeBitCast(registerFunc, to: @convention(c) () -> Void.self)
|
||||
register()
|
||||
print("MarkBaseFSModule: Registration function called")
|
||||
|
||||
// Try again
|
||||
guard let fsClassAfterRegister = objc_getClass(className) as? AnyClass else {
|
||||
print("MarkBaseFSModule: Still failed to get class after registration")
|
||||
return
|
||||
}
|
||||
print("MarkBaseFSModule: Class obtained after registration")
|
||||
rustFS = (fsClassAfterRegister as! NSObject.Type).init()
|
||||
} else {
|
||||
print("MarkBaseFSModule: Registration function not found")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
print("MarkBaseFSModule: Class obtained directly: \(className)")
|
||||
rustFS = (fsClass as! NSObject.Type).init()
|
||||
}
|
||||
|
||||
print("MarkBaseFSModule: Rust FSKit instance created successfully")
|
||||
}
|
||||
|
||||
// MARK: - FSUnaryFileSystemOperations (Forward to Rust)
|
||||
|
||||
public func probeResource(_ resource: FSResource, replyHandler: @escaping (FSProbeResult?, Error?) -> Void) {
|
||||
print("MarkBaseFSModule: probeResource() called")
|
||||
|
||||
guard let rustFS = rustFS else {
|
||||
print("MarkBaseFSModule: Rust FS not loaded, returning not recognized")
|
||||
let result = FSProbeResult.notRecognizedProbeResult()
|
||||
replyHandler(result, nil)
|
||||
return
|
||||
}
|
||||
|
||||
print("MarkBaseFSModule: Forwarding probeResource to Rust")
|
||||
|
||||
// Create block callback
|
||||
let block: @convention(block) (UnsafeMutableRawPointer?, UnsafeMutableRawPointer?) -> Void = { resultPtr, errorPtr in
|
||||
print("MarkBaseFSModule: probeResource callback received")
|
||||
|
||||
if let resultPtr = resultPtr {
|
||||
// Convert pointer to FSProbeResult
|
||||
let result = Unmanaged<AnyObject>.fromOpaque(resultPtr).takeRetainedValue()
|
||||
if let probeResult = result as? FSProbeResult {
|
||||
print("MarkBaseFSModule: probeResource result: \(probeResult)")
|
||||
replyHandler(probeResult, nil)
|
||||
} else {
|
||||
print("MarkBaseFSModule: probeResource result type mismatch")
|
||||
replyHandler(nil, NSError(domain: "MarkBaseFS", code: -1, userInfo: [NSLocalizedDescriptionKey: "Result type mismatch"]))
|
||||
}
|
||||
} else {
|
||||
print("MarkBaseFSModule: probeResource result is null")
|
||||
replyHandler(nil, NSError(domain: "MarkBaseFS", code: -1, userInfo: [NSLocalizedDescriptionKey: "No result returned"]))
|
||||
}
|
||||
}
|
||||
|
||||
// Use ObjC runtime to call Rust method
|
||||
let selector = NSSelectorFromString("probeResource:replyHandler:")
|
||||
let methodIMP = rustFS.method(for: selector)
|
||||
|
||||
if methodIMP != nil {
|
||||
print("MarkBaseFSModule: Method implementation found")
|
||||
let method: @convention(block) (AnyObject, FSResource, AnyObject) -> Void = unsafeBitCast(methodIMP, to: @convention(block) (AnyObject, FSResource, AnyObject) -> Void.self)
|
||||
method(rustFS, resource, unsafeBitCast(block, to: AnyObject.self))
|
||||
} else {
|
||||
print("MarkBaseFSModule: Method implementation not found")
|
||||
replyHandler(nil, NSError(domain: "MarkBaseFS", code: -2, userInfo: [NSLocalizedDescriptionKey: "Method not found"]))
|
||||
}
|
||||
}
|
||||
|
||||
public func loadResource(_ resource: FSResource, options: FSTaskOptions, replyHandler: @escaping (FSVolume?, Error?) -> Void) {
|
||||
print("MarkBaseFSModule: loadResource() called")
|
||||
|
||||
guard let rustFS = rustFS else {
|
||||
print("MarkBaseFSModule: Rust FS not loaded, returning error")
|
||||
replyHandler(nil, NSError(domain: "MarkBaseFS", code: -1, userInfo: [NSLocalizedDescriptionKey: "Rust FS not loaded"]))
|
||||
return
|
||||
}
|
||||
|
||||
print("MarkBaseFSModule: Forwarding loadResource to Rust")
|
||||
|
||||
// Create block callback
|
||||
let block: @convention(block) (UnsafeMutableRawPointer?, UnsafeMutableRawPointer?) -> Void = { volumePtr, errorPtr in
|
||||
print("MarkBaseFSModule: loadResource callback received")
|
||||
|
||||
if let volumePtr = volumePtr {
|
||||
// Convert pointer to FSVolume
|
||||
let volume = Unmanaged<AnyObject>.fromOpaque(volumePtr).takeRetainedValue()
|
||||
if let fsVolume = volume as? FSVolume {
|
||||
print("MarkBaseFSModule: loadResource volume: \(fsVolume)")
|
||||
replyHandler(fsVolume, nil)
|
||||
} else {
|
||||
print("MarkBaseFSModule: loadResource volume type mismatch")
|
||||
replyHandler(nil, NSError(domain: "MarkBaseFS", code: -1, userInfo: [NSLocalizedDescriptionKey: "Volume type mismatch"]))
|
||||
}
|
||||
} else {
|
||||
print("MarkBaseFSModule: loadResource volume is null")
|
||||
if let errorPtr = errorPtr {
|
||||
let error = Unmanaged<NSError>.fromOpaque(errorPtr).takeRetainedValue()
|
||||
replyHandler(nil, error)
|
||||
} else {
|
||||
replyHandler(nil, NSError(domain: "MarkBaseFS", code: -1, userInfo: [NSLocalizedDescriptionKey: "No volume returned"]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use ObjC runtime to call Rust method
|
||||
let selector = NSSelectorFromString("loadResource:options:replyHandler:")
|
||||
let methodIMP = rustFS.method(for: selector)
|
||||
|
||||
if methodIMP != nil {
|
||||
print("MarkBaseFSModule: Method implementation found")
|
||||
let method: @convention(block) (AnyObject, FSResource, FSTaskOptions, AnyObject) -> Void = unsafeBitCast(methodIMP, to: @convention(block) (AnyObject, FSResource, FSTaskOptions, AnyObject) -> Void.self)
|
||||
method(rustFS, resource, options, unsafeBitCast(block, to: AnyObject.self))
|
||||
} else {
|
||||
print("MarkBaseFSModule: Method implementation not found")
|
||||
replyHandler(nil, NSError(domain: "MarkBaseFS", code: -2, userInfo: [NSLocalizedDescriptionKey: "Method not found"]))
|
||||
}
|
||||
}
|
||||
|
||||
public func unloadResource(_ resource: FSResource, options: FSTaskOptions, replyHandler: @escaping (Error?) -> Void) {
|
||||
print("MarkBaseFSModule: unloadResource() called")
|
||||
|
||||
guard let rustFS = rustFS else {
|
||||
print("MarkBaseFSModule: Rust FS not loaded, returning error")
|
||||
replyHandler(NSError(domain: "MarkBaseFS", code: -1, userInfo: [NSLocalizedDescriptionKey: "Rust FS not loaded"]))
|
||||
return
|
||||
}
|
||||
|
||||
print("MarkBaseFSModule: Forwarding unloadResource to Rust")
|
||||
|
||||
// Create block callback
|
||||
let block: @convention(block) (UnsafeMutableRawPointer?) -> Void = { errorPtr in
|
||||
print("MarkBaseFSModule: unloadResource callback received")
|
||||
|
||||
if let errorPtr = errorPtr {
|
||||
let error = Unmanaged<NSError>.fromOpaque(errorPtr).takeRetainedValue()
|
||||
replyHandler(error)
|
||||
} else {
|
||||
replyHandler(nil)
|
||||
}
|
||||
}
|
||||
|
||||
// Use ObjC runtime to call Rust method
|
||||
let selector = NSSelectorFromString("unloadResource:options:replyHandler:")
|
||||
let methodIMP = rustFS.method(for: selector)
|
||||
|
||||
if methodIMP != nil {
|
||||
print("MarkBaseFSModule: Method implementation found")
|
||||
let method: @convention(block) (AnyObject, FSResource, FSTaskOptions, AnyObject) -> Void = unsafeBitCast(methodIMP, to: @convention(block) (AnyObject, FSResource, FSTaskOptions, AnyObject) -> Void.self)
|
||||
method(rustFS, resource, options, unsafeBitCast(block, to: AnyObject.self))
|
||||
} else {
|
||||
print("MarkBaseFSModule: Method implementation not found")
|
||||
replyHandler(NSError(domain: "MarkBaseFS", code: -2, userInfo: [NSLocalizedDescriptionKey: "Method not found"]))
|
||||
}
|
||||
}
|
||||
|
||||
public func didFinishLoading() {
|
||||
print("MarkBaseFSModule: didFinishLoading() called")
|
||||
print(" - Module loaded by FSKit daemon")
|
||||
print(" - Rust FSKit bridge active")
|
||||
print(" - Rust FS instance: \(rustFS != nil ? "available" : "not available")")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user