Skip to content

Commit 3948314

Browse files
committed
Intial Implementation of Stream and NSOutputStream
1 parent 0d9628a commit 3948314

File tree

2 files changed

+101
-11
lines changed

2 files changed

+101
-11
lines changed

Foundation/NSStream.swift

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,35 +155,50 @@ public class InputStream: Stream {
155155
// Subclassers are required to implement these methods.
156156
// Currently this is left as named NSOutputStream due to conflicts with the standard library's text streaming target protocol named OutputStream (which ideally should be renamed)
157157
public class NSOutputStream : Stream {
158+
159+
private var _stream: CFWriteStream!
160+
158161
// writes the bytes from the specified buffer to the stream up to len bytes. Returns the number of bytes actually written.
159162
public func write(_ buffer: UnsafePointer<UInt8>, maxLength len: Int) -> Int {
160-
NSUnimplemented()
163+
return CFWriteStreamWrite(_stream, buffer, len)
161164
}
162165

163166
// returns YES if the stream can be written to or if it is impossible to tell without actually doing the write.
164167
public var hasSpaceAvailable: Bool {
165-
NSUnimplemented()
168+
return CFWriteStreamCanAcceptBytes(_stream)
166169
}
167170

168171
public init(toMemory: ()) {
169172
NSUnimplemented()
170173
}
171174

172175
public init(toBuffer buffer: UnsafeMutablePointer<UInt8>, capacity: Int) {
173-
NSUnimplemented()
176+
_stream = CFWriteStreamCreateWithBuffer(kCFAllocatorSystemDefault, buffer, capacity)
174177
}
175-
178+
176179
public init?(url: URL, append shouldAppend: Bool) {
177-
NSUnimplemented()
180+
_stream = CFWriteStreamCreateWithFile(kCFAllocatorSystemDefault, url._cfObject)
178181
}
179182

180183
public convenience init?(toFileAtPath path: String, append shouldAppend: Bool) {
181-
NSUnimplemented()
184+
self.init(url: URL(fileURLWithPath: path), append: true)
182185
}
183186

184187
public class func outputStreamToMemory() -> Self {
185188
NSUnimplemented()
186189
}
190+
191+
public override func open() {
192+
CFWriteStreamOpen(_stream)
193+
}
194+
195+
public override func close() {
196+
CFWriteStreamClose(_stream)
197+
}
198+
199+
public override var streamStatus: Status {
200+
return Stream.Status(rawValue: UInt(CFWriteStreamGetStatus(_stream)))!
201+
}
187202
}
188203

189204
// Discussion of this API is ongoing for its usage of AutoreleasingUnsafeMutablePointer

TestFoundation/TestNSStream.swift

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ class TestNSStream : XCTestCase {
2323
("test_InputStreamWithFile", test_InputStreamWithFile),
2424
("test_InputStreamHasBytesAvailable", test_InputStreamHasBytesAvailable),
2525
("test_InputStreamInvalidPath", test_InputStreamInvalidPath),
26+
("test_outputStreamCreationToFile", test_outputStreamCreationToFile),
27+
("test_outputStreamCreationToBuffer", test_outputStreamCreationToBuffer),
28+
("test_outputStreamCreationWithUrl", test_outputStreamCreationWithUrl),
29+
("test_outputStreamHasSpaceAvailable", test_outputStreamHasSpaceAvailable),
30+
("test_ouputStreamWithInvalidPath", test_ouputStreamWithInvalidPath),
2631
]
2732
}
2833

@@ -118,19 +123,90 @@ class TestNSStream : XCTestCase {
118123
XCTAssertEqual(Stream.Status.error, fileStream.streamStatus)
119124
}
120125

121-
private func createTestFile(_ path: String,_contents: Data) -> String? {
126+
func test_outputStreamCreationToFile() {
127+
let filePath = createTestFile("TestFileOut.txt", _contents: Data(capacity: 256)!)
128+
if filePath != nil {
129+
let outputStream = NSOutputStream(toFileAtPath: filePath!, append: true)
130+
XCTAssertEqual(Stream.Status.notOpen, outputStream!.streamStatus)
131+
var myString = "Hello world!"
132+
let encodedData = [UInt8](myString.utf8)
133+
outputStream?.open()
134+
XCTAssertEqual(Stream.Status.open, outputStream!.streamStatus)
135+
let result: Int? = outputStream?.write(encodedData, maxLength: encodedData.count)
136+
outputStream?.close()
137+
XCTAssertEqual(myString.characters.count, result)
138+
XCTAssertEqual(Stream.Status.closed, outputStream!.streamStatus)
139+
removeTestFile(filePath!)
140+
} else {
141+
XCTFail("Unable to create temp file");
142+
}
143+
}
144+
145+
func test_outputStreamCreationToBuffer() {
146+
var buffer = Array<UInt8>(repeating: 0, count: 12)
147+
var myString = "Hello world!"
148+
let encodedData = [UInt8](myString.utf8)
149+
let outputStream = NSOutputStream(toBuffer: UnsafeMutablePointer<UInt8>(buffer), capacity: 12)
150+
XCTAssertEqual(Stream.Status.notOpen, outputStream.streamStatus)
151+
outputStream.open()
152+
XCTAssertEqual(Stream.Status.open, outputStream.streamStatus)
153+
let result: Int? = outputStream.write(encodedData, maxLength: encodedData.count)
154+
outputStream.close()
155+
XCTAssertEqual(Stream.Status.closed, outputStream.streamStatus)
156+
XCTAssertEqual(myString.characters.count, result)
157+
XCTAssertEqual(NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.utf8.rawValue),myString._bridgeToObject())
158+
}
159+
160+
func test_outputStreamCreationWithUrl() {
161+
let filePath = createTestFile("TestFileOut.txt", _contents: Data(capacity: 256)!)
162+
if filePath != nil {
163+
let outputStream = NSOutputStream(url: URL(fileURLWithPath: filePath!), append: true)
164+
XCTAssertEqual(Stream.Status.notOpen, outputStream!.streamStatus)
165+
var myString = "Hello world!"
166+
let encodedData = [UInt8](myString.utf8)
167+
outputStream!.open()
168+
XCTAssertEqual(Stream.Status.open, outputStream!.streamStatus)
169+
let result: Int? = outputStream?.write(encodedData, maxLength: encodedData.count)
170+
outputStream?.close()
171+
XCTAssertEqual(myString.characters.count, result)
172+
XCTAssertEqual(Stream.Status.closed, outputStream!.streamStatus)
173+
removeTestFile(filePath!)
174+
} else {
175+
XCTFail("Unable to create temp file");
176+
}
177+
}
178+
179+
func test_outputStreamHasSpaceAvailable() {
180+
let buffer = Array<UInt8>(repeating: 0, count: 12)
181+
var myString = "Welcome To Hello world !"
182+
let encodedData = [UInt8](myString.utf8)
183+
let outputStream = NSOutputStream(toBuffer: UnsafeMutablePointer<UInt8>(buffer), capacity: 12)
184+
outputStream.open()
185+
XCTAssertTrue(outputStream.hasSpaceAvailable)
186+
_ = outputStream.write(encodedData, maxLength: encodedData.count)
187+
XCTAssertFalse(outputStream.hasSpaceAvailable)
188+
}
189+
190+
func test_ouputStreamWithInvalidPath(){
191+
let outputStream = NSOutputStream(toFileAtPath: "http:///home/sdsfsdfd", append: true)
192+
XCTAssertEqual(Stream.Status.notOpen, outputStream!.streamStatus)
193+
outputStream?.open()
194+
XCTAssertEqual(Stream.Status.error, outputStream!.streamStatus)
195+
}
196+
197+
private func createTestFile(_ path: String, _contents: Data) -> String? {
122198
let tempDir = "/tmp/TestFoundation_Playground_" + NSUUID().UUIDString + "/"
123199
do {
124200
try FileManager.default().createDirectory(atPath: tempDir, withIntermediateDirectories: false, attributes: nil)
125-
if FileManager.default().createFile(atPath: tempDir + "/" + path, contents: _contents, attributes: nil) {
126-
return tempDir + path
201+
if FileManager.default().createFile(atPath: tempDir + "/" + path, contents: _contents,
202+
attributes: nil) {
203+
return tempDir + path
127204
} else {
128205
return nil
129206
}
130207
} catch _ {
131208
return nil
132209
}
133-
134210
}
135211

136212
private func removeTestFile(_ location: String) {
@@ -142,4 +218,3 @@ class TestNSStream : XCTestCase {
142218
}
143219
}
144220

145-

0 commit comments

Comments
 (0)