13
13
import Swift
14
14
import SwiftShims
15
15
16
+ #if os(Windows)
17
+ import MSVCRT
18
+ import WinSDK
19
+ #endif
20
+
21
+ #if os(Windows)
22
+ public struct _FDInputStream {
23
+ public var handle : HANDLE = INVALID_HANDLE_VALUE
24
+ public var isEOF : Bool = false
25
+ public var isClosed : Bool { return handle == INVALID_HANDLE_VALUE }
26
+
27
+ internal var _buffer : ContiguousArray < UInt8 > =
28
+ ContiguousArray < UInt8 > ( repeating: 0 , count: 256 )
29
+ internal var _offset : Int = 0
30
+
31
+ public init ( handle: HANDLE ) {
32
+ self . handle = handle
33
+ }
34
+
35
+ public mutating func getline( ) -> String ? {
36
+ // FIXME(compnerd) Windows uses \r\n for the line delimiter, we should split
37
+ // on that and remove the workaround in the test harness
38
+ if let index =
39
+ _buffer [ 0 ..< _offset] . firstIndex ( of: UInt8 ( Unicode . Scalar ( " \n " ) . value) ) {
40
+ let result = String ( decoding: _buffer [ 0 ..< index] , as: UTF8 . self)
41
+ _buffer. removeSubrange ( 0 ... index)
42
+ _offset -= index + 1
43
+ return result
44
+ }
45
+ if isEOF && _offset > 0 {
46
+ let result = String ( decoding: _buffer [ 0 ..< _offset] , as: UTF8 . self)
47
+ _buffer. removeAll ( )
48
+ _offset = 0
49
+ return result
50
+ }
51
+ return nil
52
+ }
53
+
54
+ public mutating func read( ) {
55
+ var space = _buffer. count - _offset
56
+ if space < 128 {
57
+ let capacity = _buffer. count + ( 128 - space)
58
+ _buffer. reserveCapacity ( capacity)
59
+ for _ in _buffer. count..< capacity {
60
+ _buffer. append ( 0 )
61
+ }
62
+ space = 128
63
+ }
64
+ let read : Int = _buffer. withUnsafeMutableBufferPointer { buffer in
65
+ var read : DWORD = 0
66
+ ReadFile ( handle, buffer. baseAddress! + _offset, DWORD ( space) , & read, nil )
67
+ return Int ( read)
68
+ }
69
+ if read == 0 {
70
+ isEOF = true
71
+ } else {
72
+ _offset += read
73
+ }
74
+ }
75
+
76
+ public mutating func close( ) {
77
+ if isClosed { return }
78
+ CloseHandle ( handle)
79
+ handle = INVALID_HANDLE_VALUE
80
+ }
81
+ }
82
+ #else
16
83
public struct _FDInputStream {
17
84
public let fd : CInt
18
85
public var isClosed : Bool = false
@@ -79,6 +146,7 @@ public struct _FDInputStream {
79
146
isClosed = true
80
147
}
81
148
}
149
+ #endif
82
150
83
151
public struct _Stderr : TextOutputStream {
84
152
public init ( ) { }
@@ -90,6 +158,37 @@ public struct _Stderr : TextOutputStream {
90
158
}
91
159
}
92
160
161
+ #if os(Windows)
162
+ public struct _FDOutputStream : TextOutputStream {
163
+ public var handle : HANDLE
164
+
165
+ public init ( handle: HANDLE ) {
166
+ self . handle = handle
167
+ }
168
+
169
+ public mutating func write( _ string: String ) {
170
+ string. utf8CString. withUnsafeBufferPointer { buffer in
171
+ let dwLength : DWORD = DWORD ( buffer. count - 1 )
172
+ var dwOffset : DWORD = 0
173
+ while dwOffset < dwLength {
174
+ var dwBytesWritten : DWORD = 0
175
+ if WriteFile ( handle,
176
+ UnsafeRawPointer ( buffer. baseAddress! + Int( dwOffset) ) ,
177
+ dwLength - dwOffset, & dwBytesWritten, nil ) == FALSE {
178
+ fatalError ( " WriteFile() failed " )
179
+ }
180
+ dwOffset += dwBytesWritten
181
+ }
182
+ }
183
+ }
184
+
185
+ public mutating func close( ) {
186
+ if handle == INVALID_HANDLE_VALUE { return }
187
+ CloseHandle ( handle)
188
+ handle = INVALID_HANDLE_VALUE
189
+ }
190
+ }
191
+ #else
93
192
public struct _FDOutputStream : TextOutputStream {
94
193
public let fd : CInt
95
194
public var isClosed : Bool = false
@@ -127,3 +226,4 @@ public struct _FDOutputStream : TextOutputStream {
127
226
isClosed = true
128
227
}
129
228
}
229
+ #endif
0 commit comments