Skip to content

Commit 07ee880

Browse files
committed
Add FileSystem related code from swift-tools-support-core
1 parent e89f45b commit 07ee880

7 files changed

Lines changed: 3056 additions & 0 deletions

File tree

Tool/Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ let package = Package(
1515
.library(name: "Logger", targets: ["Logger"]),
1616
.library(name: "OpenAIService", targets: ["OpenAIService"]),
1717
.library(name: "ChatTab", targets: ["ChatTab"]),
18+
.library(name: "FileSystem", targets: ["FileSystem"]),
1819
.library(
1920
name: "ChatContextCollector",
2021
targets: ["ChatContextCollector", "ActiveDocumentChatContextCollector"]
@@ -89,6 +90,8 @@ let package = Package(
8990

9091
.target(name: "Logger"),
9192

93+
.target(name: "FileSystem"),
94+
9295
.target(name: "ObjectiveCExceptionHandling"),
9396

9497
.target(
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
13+
/// A `ByteString` represents a sequence of bytes.
14+
///
15+
/// This struct provides useful operations for working with buffers of
16+
/// bytes. Conceptually it is just a contiguous array of bytes (UInt8), but it
17+
/// contains methods and default behavior suitable for common operations done
18+
/// using bytes strings.
19+
///
20+
/// This struct *is not* intended to be used for significant mutation of byte
21+
/// strings, we wish to retain the flexibility to micro-optimize the memory
22+
/// allocation of the storage (for example, by inlining the storage for small
23+
/// strings or and by eliminating wasted space in growable arrays). For
24+
/// construction of byte arrays, clients should use the `WritableByteStream` class
25+
/// and then convert to a `ByteString` when complete.
26+
public struct ByteString: ExpressibleByArrayLiteral, Hashable, Sendable {
27+
/// The buffer contents.
28+
@usableFromInline
29+
internal var _bytes: [UInt8]
30+
31+
/// Create an empty byte string.
32+
@inlinable
33+
public init() {
34+
_bytes = []
35+
}
36+
37+
/// Create a byte string from a byte array literal.
38+
@inlinable
39+
public init(arrayLiteral contents: UInt8...) {
40+
_bytes = contents
41+
}
42+
43+
/// Create a byte string from an array of bytes.
44+
@inlinable
45+
public init(_ contents: [UInt8]) {
46+
_bytes = contents
47+
}
48+
49+
/// Create a byte string from an array slice.
50+
@inlinable
51+
public init(_ contents: ArraySlice<UInt8>) {
52+
_bytes = Array(contents)
53+
}
54+
55+
/// Create a byte string from an byte buffer.
56+
@inlinable
57+
public init<S: Sequence> (_ contents: S) where S.Iterator.Element == UInt8 {
58+
_bytes = [UInt8](contents)
59+
}
60+
61+
/// Create a byte string from the UTF8 encoding of a string.
62+
@inlinable
63+
public init(encodingAsUTF8 string: String) {
64+
_bytes = [UInt8](string.utf8)
65+
}
66+
67+
/// Access the byte string contents as an array.
68+
@inlinable
69+
public var contents: [UInt8] {
70+
return _bytes
71+
}
72+
73+
/// Return the byte string size.
74+
@inlinable
75+
public var count: Int {
76+
return _bytes.count
77+
}
78+
79+
/// Gives a non-escaping closure temporary access to an immutable `Data` instance wrapping the `ByteString` without
80+
/// copying any memory around.
81+
///
82+
/// - Parameters:
83+
/// - closure: The closure that will have access to a `Data` instance for the duration of its lifetime.
84+
@inlinable
85+
public func withData<T>(_ closure: (Data) throws -> T) rethrows -> T {
86+
return try _bytes.withUnsafeBytes { pointer -> T in
87+
let mutatingPointer = UnsafeMutableRawPointer(mutating: pointer.baseAddress!)
88+
let data = Data(bytesNoCopy: mutatingPointer, count: pointer.count, deallocator: .none)
89+
return try closure(data)
90+
}
91+
}
92+
93+
/// Returns a `String` lowercase hexadecimal representation of the contents of the `ByteString`.
94+
@inlinable
95+
public var hexadecimalRepresentation: String {
96+
_bytes.reduce("") {
97+
var str = String($1, radix: 16)
98+
// The above method does not do zero padding.
99+
if str.count == 1 {
100+
str = "0" + str
101+
}
102+
return $0 + str
103+
}
104+
}
105+
}
106+
107+
/// Conform to CustomDebugStringConvertible.
108+
extension ByteString: CustomStringConvertible {
109+
/// Return the string decoded as a UTF8 sequence, or traps if not possible.
110+
public var description: String {
111+
return cString
112+
}
113+
114+
/// Return the string decoded as a UTF8 sequence, if possible.
115+
@inlinable
116+
public var validDescription: String? {
117+
// FIXME: This is very inefficient, we need a way to pass a buffer. It
118+
// is also wrong if the string contains embedded '\0' characters.
119+
let tmp = _bytes + [UInt8(0)]
120+
return tmp.withUnsafeBufferPointer { ptr in
121+
return String(validatingUTF8: unsafeBitCast(ptr.baseAddress, to: UnsafePointer<CChar>.self))
122+
}
123+
}
124+
125+
/// Return the string decoded as a UTF8 sequence, substituting replacement
126+
/// characters for ill-formed UTF8 sequences.
127+
@inlinable
128+
public var cString: String {
129+
return String(decoding: _bytes, as: Unicode.UTF8.self)
130+
}
131+
132+
@available(*, deprecated, message: "use description or validDescription instead")
133+
public var asString: String? {
134+
return validDescription
135+
}
136+
}
137+
138+
/// ByteStreamable conformance for a ByteString.
139+
extension ByteString: ByteStreamable {
140+
@inlinable
141+
public func write(to stream: WritableByteStream) {
142+
stream.write(_bytes)
143+
}
144+
}
145+
146+
/// StringLiteralConvertable conformance for a ByteString.
147+
extension ByteString: ExpressibleByStringLiteral {
148+
public typealias UnicodeScalarLiteralType = StringLiteralType
149+
public typealias ExtendedGraphemeClusterLiteralType = StringLiteralType
150+
151+
public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
152+
_bytes = [UInt8](value.utf8)
153+
}
154+
public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
155+
_bytes = [UInt8](value.utf8)
156+
}
157+
public init(stringLiteral value: StringLiteralType) {
158+
_bytes = [UInt8](value.utf8)
159+
}
160+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
13+
#if swift(<5.6)
14+
extension FileAttributeType: UnsafeSendable {}
15+
extension Date: UnsafeSendable {}
16+
#endif
17+
18+
/// File system information for a particular file.
19+
public struct FileInfo: Equatable, Codable, Sendable {
20+
21+
/// The device number.
22+
public let device: UInt64
23+
24+
/// The inode number.
25+
public let inode: UInt64
26+
27+
/// The size of the file.
28+
public let size: UInt64
29+
30+
/// The modification time of the file.
31+
public let modTime: Date
32+
33+
/// Kind of file system entity.
34+
public let posixPermissions: Int16
35+
36+
/// Kind of file system entity.
37+
public let fileType: FileAttributeType
38+
39+
public init(_ attrs: [FileAttributeKey : Any]) {
40+
let device = (attrs[.systemNumber] as? NSNumber)?.uint64Value
41+
assert(device != nil)
42+
self.device = device!
43+
44+
let inode = attrs[.systemFileNumber] as? UInt64
45+
assert(inode != nil)
46+
self.inode = inode!
47+
48+
let posixPermissions = (attrs[.posixPermissions] as? NSNumber)?.int16Value
49+
assert(posixPermissions != nil)
50+
self.posixPermissions = posixPermissions!
51+
52+
let fileType = attrs[.type] as? FileAttributeType
53+
assert(fileType != nil)
54+
self.fileType = fileType!
55+
56+
let size = attrs[.size] as? UInt64
57+
assert(size != nil)
58+
self.size = size!
59+
60+
let modTime = attrs[.modificationDate] as? Date
61+
assert(modTime != nil)
62+
self.modTime = modTime!
63+
}
64+
}
65+
66+
extension FileAttributeType: Codable {}

0 commit comments

Comments
 (0)