-
Notifications
You must be signed in to change notification settings - Fork 554
Expand file tree
/
Copy pathSocket+File.swift
More file actions
57 lines (50 loc) · 1.82 KB
/
Socket+File.swift
File metadata and controls
57 lines (50 loc) · 1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//
// Socket+File.swift
// Swifter
//
// Created by Damian Kolakowski on 13/07/16.
//
import Foundation
#if os(iOS) || os(tvOS) || os (Linux)
// swiftlint:disable type_name function_parameter_count
struct sf_hdtr { }
private func sendfileImpl(_ source: UnsafeMutablePointer<FILE>, _ target: Int32, _: off_t, _: UnsafeMutablePointer<off_t>, _: UnsafeMutablePointer<sf_hdtr>, _: Int32) -> Int32 {
var buffer = [UInt8](repeating: 0, count: 1024)
while true {
let readResult = fread(&buffer, 1, buffer.count, source)
guard readResult > 0 else {
return Int32(readResult)
}
var writeCounter = 0
while writeCounter < readResult {
let writeResult = buffer.withUnsafeBytes { (ptr) -> Int in
let start = ptr.baseAddress! + writeCounter
let len = readResult - writeCounter
#if os(Linux)
return send(target, start, len, Int32(MSG_NOSIGNAL))
#else
return write(target, start, len)
#endif
}
guard writeResult > 0 else {
return Int32(writeResult)
}
writeCounter += writeResult
}
}
}
#endif
extension Socket {
public func writeFile(_ file: String.File) throws {
var offset: off_t = 0
var sf: sf_hdtr = sf_hdtr()
#if os(iOS) || os(tvOS) || os (Linux)
let result = sendfileImpl(file.pointer, self.socketFileDescriptor, 0, &offset, &sf, 0)
#else
let result = sendfile(fileno(file.pointer), self.socketFileDescriptor, 0, &offset, &sf, 0)
#endif
if result == -1 {
throw SocketError.writeFailed("sendfile: " + Errno.description())
}
}
}