Skip to content

Commit 5603657

Browse files
committed
Intial Implementation of Stream and NSOutputStream
1 parent 1513515 commit 5603657

File tree

2 files changed

+135
-14
lines changed

2 files changed

+135
-14
lines changed

Foundation/NSStream.swift

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,34 +163,58 @@ public class InputStream: Stream {
163163
// Subclassers are required to implement these methods.
164164
// 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)
165165
public class NSOutputStream : Stream {
166+
167+
private var _stream: CFWriteStream!
168+
166169
// writes the bytes from the specified buffer to the stream up to len bytes. Returns the number of bytes actually written.
167170
public func write(_ buffer: UnsafePointer<UInt8>, maxLength len: Int) -> Int {
168-
NSUnimplemented()
171+
return CFWriteStreamWrite(_stream, buffer, len)
169172
}
170173

171174
// returns YES if the stream can be written to or if it is impossible to tell without actually doing the write.
172175
public var hasSpaceAvailable: Bool {
173-
NSUnimplemented()
176+
return CFWriteStreamCanAcceptBytes(_stream)
174177
}
175178

176-
public init(toMemory: ()) {
177-
NSUnimplemented()
179+
required public init(toMemory: ()) {
180+
_stream = CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, kCFAllocatorDefault)
178181
}
179182

180183
public init(toBuffer buffer: UnsafeMutablePointer<UInt8>, capacity: Int) {
181-
NSUnimplemented()
184+
_stream = CFWriteStreamCreateWithBuffer(kCFAllocatorSystemDefault, buffer, capacity)
182185
}
183-
186+
184187
public init?(url: URL, append shouldAppend: Bool) {
185-
NSUnimplemented()
188+
_stream = CFWriteStreamCreateWithFile(kCFAllocatorSystemDefault, url._cfObject)
189+
CFWriteStreamSetProperty(_stream, kCFStreamPropertyAppendToFile, shouldAppend._cfObject)
186190
}
187191

188192
public convenience init?(toFileAtPath path: String, append shouldAppend: Bool) {
189-
NSUnimplemented()
193+
self.init(url: URL(fileURLWithPath: path), append: shouldAppend)
194+
}
195+
196+
public override func open() {
197+
CFWriteStreamOpen(_stream)
198+
}
199+
200+
public override func close() {
201+
CFWriteStreamClose(_stream)
202+
}
203+
204+
public override var streamStatus: Status {
205+
return Stream.Status(rawValue: UInt(CFWriteStreamGetStatus(_stream)))!
190206
}
191207

192208
public class func outputStreamToMemory() -> Self {
193-
NSUnimplemented()
209+
return self.init(toMemory: ())
210+
}
211+
212+
public override func propertyForKey(_ key: String) -> AnyObject? {
213+
return CFWriteStreamCopyProperty(_stream, key._cfObject)
214+
}
215+
216+
public override func setProperty(_ property: AnyObject?, forKey key: String) -> Bool {
217+
return CFWriteStreamSetProperty(_stream, key._cfObject, property)
194218
}
195219
}
196220

TestFoundation/TestNSStream.swift

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ 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_outputStreamCreationToMemory", test_outputStreamCreationToMemory),
30+
("test_outputStreamHasSpaceAvailable", test_outputStreamHasSpaceAvailable),
31+
("test_ouputStreamWithInvalidPath", test_ouputStreamWithInvalidPath),
2632
]
2733
}
2834

@@ -118,19 +124,111 @@ class TestNSStream : XCTestCase {
118124
XCTAssertEqual(Stream.Status.error, fileStream.streamStatus)
119125
}
120126

121-
private func createTestFile(_ path: String,_contents: Data) -> String? {
127+
func test_outputStreamCreationToFile() {
128+
let filePath = createTestFile("TestFileOut.txt", _contents: Data(capacity: 256)!)
129+
if filePath != nil {
130+
let outputStream = NSOutputStream(toFileAtPath: filePath!, append: true)
131+
XCTAssertEqual(Stream.Status.notOpen, outputStream!.streamStatus)
132+
var myString = "Hello world!"
133+
let encodedData = [UInt8](myString.utf8)
134+
outputStream?.open()
135+
XCTAssertEqual(Stream.Status.open, outputStream!.streamStatus)
136+
let result: Int? = outputStream?.write(encodedData, maxLength: encodedData.count)
137+
outputStream?.close()
138+
XCTAssertEqual(myString.characters.count, result)
139+
XCTAssertEqual(Stream.Status.closed, outputStream!.streamStatus)
140+
removeTestFile(filePath!)
141+
} else {
142+
XCTFail("Unable to create temp file");
143+
}
144+
}
145+
146+
func test_outputStreamCreationToBuffer() {
147+
var buffer = Array<UInt8>(repeating: 0, count: 12)
148+
var myString = "Hello world!"
149+
let encodedData = [UInt8](myString.utf8)
150+
let outputStream = NSOutputStream(toBuffer: UnsafeMutablePointer<UInt8>(buffer), capacity: 12)
151+
XCTAssertEqual(Stream.Status.notOpen, outputStream.streamStatus)
152+
outputStream.open()
153+
XCTAssertEqual(Stream.Status.open, outputStream.streamStatus)
154+
let result: Int? = outputStream.write(encodedData, maxLength: encodedData.count)
155+
outputStream.close()
156+
XCTAssertEqual(Stream.Status.closed, outputStream.streamStatus)
157+
XCTAssertEqual(myString.characters.count, result)
158+
XCTAssertEqual(NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.utf8.rawValue),myString._bridgeToObject())
159+
}
160+
161+
func test_outputStreamCreationWithUrl() {
162+
let filePath = createTestFile("TestFileOut.txt", _contents: Data(capacity: 256)!)
163+
if filePath != nil {
164+
let outputStream = NSOutputStream(url: URL(fileURLWithPath: filePath!), append: true)
165+
XCTAssertEqual(Stream.Status.notOpen, outputStream!.streamStatus)
166+
var myString = "Hello world!"
167+
let encodedData = [UInt8](myString.utf8)
168+
outputStream!.open()
169+
XCTAssertEqual(Stream.Status.open, outputStream!.streamStatus)
170+
let result: Int? = outputStream?.write(encodedData, maxLength: encodedData.count)
171+
outputStream?.close()
172+
XCTAssertEqual(myString.characters.count, result)
173+
XCTAssertEqual(Stream.Status.closed, outputStream!.streamStatus)
174+
removeTestFile(filePath!)
175+
} else {
176+
XCTFail("Unable to create temp file");
177+
}
178+
}
179+
180+
func test_outputStreamCreationToMemory(){
181+
var buffer = Array<UInt8>(repeating: 0, count: 12)
182+
var myString = "Hello world!"
183+
let encodedData = [UInt8](myString.utf8)
184+
let outputStream = NSOutputStream.outputStreamToMemory()
185+
XCTAssertEqual(Stream.Status.notOpen, outputStream.streamStatus)
186+
outputStream.open()
187+
XCTAssertEqual(Stream.Status.open, outputStream.streamStatus)
188+
let result: Int? = outputStream.write(encodedData, maxLength: encodedData.count)
189+
XCTAssertEqual(myString.characters.count, result)
190+
//verify the data written
191+
let dataWritten = outputStream.propertyForKey(NSStreamDataWrittenToMemoryStreamKey)
192+
if let nsdataWritten = dataWritten as? NSData {
193+
nsdataWritten.getBytes(UnsafeMutablePointer<UInt8>(buffer), length: result!)
194+
XCTAssertEqual(NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.utf8.rawValue), myString._bridgeToObject())
195+
outputStream.close()
196+
} else {
197+
XCTFail("Unable to get data from memeory.")
198+
}
199+
}
200+
201+
func test_outputStreamHasSpaceAvailable() {
202+
let buffer = Array<UInt8>(repeating: 0, count: 12)
203+
var myString = "Welcome To Hello world !"
204+
let encodedData = [UInt8](myString.utf8)
205+
let outputStream = NSOutputStream(toBuffer: UnsafeMutablePointer<UInt8>(buffer), capacity: 12)
206+
outputStream.open()
207+
XCTAssertTrue(outputStream.hasSpaceAvailable)
208+
_ = outputStream.write(encodedData, maxLength: encodedData.count)
209+
XCTAssertFalse(outputStream.hasSpaceAvailable)
210+
}
211+
212+
func test_ouputStreamWithInvalidPath(){
213+
let outputStream = NSOutputStream(toFileAtPath: "http:///home/sdsfsdfd", append: true)
214+
XCTAssertEqual(Stream.Status.notOpen, outputStream!.streamStatus)
215+
outputStream?.open()
216+
XCTAssertEqual(Stream.Status.error, outputStream!.streamStatus)
217+
}
218+
219+
private func createTestFile(_ path: String, _contents: Data) -> String? {
122220
let tempDir = "/tmp/TestFoundation_Playground_" + NSUUID().UUIDString + "/"
123221
do {
124222
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
223+
if FileManager.default().createFile(atPath: tempDir + "/" + path, contents: _contents,
224+
attributes: nil) {
225+
return tempDir + path
127226
} else {
128227
return nil
129228
}
130229
} catch _ {
131230
return nil
132231
}
133-
134232
}
135233

136234
private func removeTestFile(_ location: String) {
@@ -142,4 +240,3 @@ class TestNSStream : XCTestCase {
142240
}
143241
}
144242

145-

0 commit comments

Comments
 (0)