1+ //
2+ // STPath+Metadata.swift
3+ //
4+ //
5+ // Created by linhey on 2025/8/1.
6+ //
7+
8+ import Foundation
9+
10+ public extension STPathProtocol {
11+
12+ /// [en] Sets the permissions for the file or folder.
13+ /// [zh] 设置文件或文件夹的权限。
14+ /// - Parameter permissions: The permissions to set.
15+ /// - Throws: An error if the permissions cannot be set.
16+ func set( permissions: STPathPermission . Posix ) throws {
17+ try FileManager . default. setAttributes ( [ . posixPermissions: permissions. rawValue] , ofItemAtPath: url. path)
18+ }
19+
20+ /// [en] Returns the permissions for the file or folder.
21+ /// [zh] 返回文件或文件夹的权限。
22+ /// - Returns: The permissions.
23+ /// - Throws: An error if the permissions cannot be retrieved.
24+ func permissions( ) throws -> STPathPermission . Posix {
25+ let attributes = try FileManager . default. attributesOfItem ( atPath: url. path)
26+ if let permissions = attributes [ . posixPermissions] as? UInt16 {
27+ return STPathPermission . Posix ( rawValue: permissions)
28+ }
29+ throw STPathError ( message: " [en] Failed to get permissions. \n [zh] 获取权限失败。 " , code: 0 )
30+ }
31+
32+
33+ }
34+
35+ extension STPathProtocol {
36+
37+ /// [en] Returns the extended attributes of the file or folder.
38+ /// [zh] 返回文件或文件夹的扩展属性。
39+ /// - Returns: An instance of `ExtendedAttributes`.
40+ var extendedAttributes : STExtendedAttributes {
41+ STExtendedAttributes ( url: url)
42+ }
43+
44+ }
45+
46+
47+ struct STExtendedAttributes {
48+
49+ let url : URL
50+
51+ /// [en] Sets an extended attribute for the file or folder.
52+ /// [zh] 为文件或文件夹设置扩展属性。
53+ /// - Parameters:
54+ /// - value: The value of the attribute.
55+ /// - forName: The name of the attribute.
56+ /// - Throws: An error if the attribute cannot be set.
57+ func set( name: String , value: Data ) throws {
58+ try url. path. withCString { fileSystemPath in
59+ let status = setxattr ( fileSystemPath, name, value. withUnsafeBytes { $0. baseAddress! } , value. count, 0 , 0 )
60+ if status == - 1 {
61+ throw STPathError ( message: " [en] Failed to set extended attribute \( name) . \n [zh] 设置扩展属性 \( name) 失败。 " , code: Int ( errno) )
62+ }
63+ }
64+ }
65+
66+ /// [en] Returns the value of an extended attribute.
67+ /// [zh] 返回扩展属性的值。
68+ /// - Parameter forName: The name of the attribute.
69+ /// - Returns: The value of the attribute.
70+ /// - Throws: An error if the attribute cannot be retrieved.
71+ func value( of name: String ) throws -> Data {
72+ try url. path. withCString { fileSystemPath in
73+ let length = getxattr ( fileSystemPath, name, nil , 0 , 0 , 0 )
74+ if length == - 1 {
75+ throw STPathError ( message: " [en] Failed to get extended attribute \( name) . \n [zh] 获取扩展属性 \( name) 失败。 " , code: Int ( errno) )
76+ }
77+ var data = Data ( count: length)
78+ let result = data. withUnsafeMutableBytes { buffer in
79+ getxattr ( fileSystemPath, name, buffer. baseAddress, length, 0 , 0 )
80+ }
81+ if result == - 1 {
82+ throw STPathError ( message: " [en] Failed to get extended attribute \( name) . \n [zh] 获取扩展属性 \( name) 失败。 " , code: Int ( errno) )
83+ }
84+ return data
85+ }
86+ }
87+
88+ /// [en] Removes an extended attribute from the file or folder.
89+ /// [zh] 从文件或文件夹中删除扩展属性。
90+ /// - Parameter forName: The name of the attribute to remove.
91+ /// - Throws: An error if the attribute cannot be removed.
92+ func remove( of name: String ) throws {
93+ try url. path. withCString { fileSystemPath in
94+ let status = removexattr ( fileSystemPath, name, 0 )
95+ if status == - 1 {
96+ throw STPathError ( message: " [en] Failed to remove extended attribute \( name) . \n [zh] 删除扩展属性 \( name) 失败。 " , code: Int ( errno) )
97+ }
98+ }
99+ }
100+
101+ /// [en] Returns a list of all extended attributes.
102+ /// [zh] 返回所有扩展属性的列表。
103+ /// - Returns: A list of attribute names.
104+ /// - Throws: An error if the attributes cannot be retrieved.
105+ func list( ) throws -> [ String ] {
106+ try url. path. withCString { fileSystemPath in
107+ let length = listxattr ( fileSystemPath, nil , 0 , 0 )
108+ if length == - 1 {
109+ throw STPathError ( message: " [en] Failed to list extended attributes. \n [zh] 列出扩展属性失败。 " , code: Int ( errno) )
110+ }
111+ var buffer = [ CChar] ( repeating: 0 , count: length)
112+ let result = listxattr ( fileSystemPath, & buffer, length, 0 )
113+ if result == - 1 {
114+ throw STPathError ( message: " [en] Failed to list extended attributes. \n [zh] 列出扩展属性失败。 " , code: Int ( errno) )
115+ }
116+ return buffer. split ( separator: 0 ) . compactMap { String ( cString: Array ( $0) , encoding: . utf8) }
117+ }
118+ }
119+ }
0 commit comments