Swift 3 beta6. Doesn't work, something in websocket.swift is segfaulting the compiler

This commit is contained in:
Erik 2016-08-15 18:52:25 -04:00
parent d2cb8f2d9a
commit 3bf7a09f98
No known key found for this signature in database
GPG Key ID: 4930B7C5FBC1A69D
11 changed files with 58 additions and 62 deletions

View File

@ -116,7 +116,7 @@ public class SSLSecurity : NSObject {
} }
return certificates return certificates
} }
self.certificates = certificates self.certificates = certificates as [NSData]
self.isReady = true self.isReady = true
} }
} }
@ -141,7 +141,7 @@ public class SSLSecurity : NSObject {
} }
var policy: SecPolicy var policy: SecPolicy
if self.validatedDN { if self.validatedDN {
policy = SecPolicyCreateSSL(true, domain) policy = SecPolicyCreateSSL(true, domain as CFString?)
} else { } else {
policy = SecPolicyCreateBasicX509() policy = SecPolicyCreateBasicX509()
} }
@ -163,7 +163,7 @@ public class SSLSecurity : NSObject {
for cert in certs { for cert in certs {
collect.append(SecCertificateCreateWithData(nil,cert)!) collect.append(SecCertificateCreateWithData(nil,cert)!)
} }
SecTrustSetAnchorCertificates(trust,collect) SecTrustSetAnchorCertificates(trust,collect as CFArray)
var result = SecTrustResultType(rawValue: 0)! var result = SecTrustResultType(rawValue: 0)!
SecTrustEvaluate(trust,&result) SecTrustEvaluate(trust,&result)
let r = Int(result.rawValue) let r = Int(result.rawValue)
@ -171,7 +171,7 @@ public class SSLSecurity : NSObject {
var trustedCount = 0 var trustedCount = 0
for serverCert in serverCerts { for serverCert in serverCerts {
for cert in certs { for cert in certs {
if cert == serverCert { if cert as Data == serverCert {
trustedCount += 1 trustedCount += 1
break break
} }
@ -193,7 +193,7 @@ public class SSLSecurity : NSObject {
- returns: a public key - returns: a public key
*/ */
func extractPublicKey(_ data: Data) -> SecKey? { func extractPublicKey(_ data: Data) -> SecKey? {
guard let cert = SecCertificateCreateWithData(nil, data) else { return nil } guard let cert = SecCertificateCreateWithData(nil, data as CFData) else { return nil }
return extractPublicKeyFromCert(cert, policy: SecPolicyCreateBasicX509()) return extractPublicKeyFromCert(cert, policy: SecPolicyCreateBasicX509())
} }

View File

@ -67,6 +67,6 @@ struct SocketAckManager {
mutating func timeoutAck(_ ack: Int, onQueue: DispatchQueue) { mutating func timeoutAck(_ ack: Int, onQueue: DispatchQueue) {
let ack = acks.remove(SocketAck(ack: ack)) let ack = acks.remove(SocketAck(ack: ack))
onQueue.async() { ack?.callback(["NO ACK"]) } onQueue.async() { ack?.callback?(["NO ACK" as AnyObject]) }
} }
} }

View File

@ -244,7 +244,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
} }
private func createWebsocketAndConnect() { private func createWebsocketAndConnect() {
ws = WebSocket(url: urlWebSocketWithSid) ws = WebSocket(url: urlWebSocketWithSid as NSURL)
if cookies != nil { if cookies != nil {
let headers = HTTPCookie.requestHeaderFields(with: cookies!) let headers = HTTPCookie.requestHeaderFields(with: cookies!)

View File

@ -100,7 +100,7 @@ extension SocketEnginePollable {
doLongPoll(for: req ) doLongPoll(for: req )
} }
func doRequest(for req: URLRequest, callbackWith callback: (Data?, URLResponse?, Error?) -> Void) { func doRequest(for req: URLRequest, callbackWith callback: @escaping (Data?, URLResponse?, Error?) -> Void) {
if !polling || closed || invalidated || fastUpgrade { if !polling || closed || invalidated || fastUpgrade {
return return
} }

View File

@ -100,7 +100,7 @@ extension NSDictionary {
var options = [] as SocketIOClientConfiguration var options = [] as SocketIOClientConfiguration
for (rawKey, value) in self { for (rawKey, value) in self {
if let key = rawKey as? String, let opt = NSDictionary.keyValueToSocketIOClientOption(key: key, value: value) { if let key = rawKey as? String, let opt = NSDictionary.keyValueToSocketIOClientOption(key: key, value: value as AnyObject) {
options.insert(opt) options.insert(opt)
} }
} }

View File

@ -242,7 +242,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
private func _emit(_ data: [AnyObject], ack: Int? = nil) { private func _emit(_ data: [AnyObject], ack: Int? = nil) {
emitQueue.async { emitQueue.async {
guard self.status == .connected else { guard self.status == .connected else {
self.handleEvent("error", data: ["Tried emitting when not connected"], isInternalMessage: true) self.handleEvent("error", data: ["Tried emitting when not connected" as AnyObject], isInternalMessage: true)
return return
} }
@ -259,7 +259,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
func emitAck(_ ack: Int, with items: [AnyObject]) { func emitAck(_ ack: Int, with items: [AnyObject]) {
emitQueue.async { emitQueue.async {
if self.status == .connected { if self.status == .connected {
let packet = SocketPacket.packetFromEmit(items, id: ack ?? -1, nsp: self.nsp, ack: true) let packet = SocketPacket.packetFromEmit(items, id: ack, nsp: self.nsp, ack: true)
let str = packet.packetString let str = packet.packetString
DefaultSocketLogger.Logger.log("Emitting Ack: %@", type: self.logType, args: str) DefaultSocketLogger.Logger.log("Emitting Ack: %@", type: self.logType, args: str)
@ -310,7 +310,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
public func handleEvent(_ event: String, data: [AnyObject], isInternalMessage: Bool, withAck ack: Int = -1) { public func handleEvent(_ event: String, data: [AnyObject], isInternalMessage: Bool, withAck ack: Int = -1) {
guard status == .connected || isInternalMessage else { return } guard status == .connected || isInternalMessage else { return }
DefaultSocketLogger.Logger.log("Handling event: %@ with data: %@", type: logType, args: event, data ?? "") DefaultSocketLogger.Logger.log("Handling event: %@ with data: %@", type: logType, args: event, data)
handleQueue.async { handleQueue.async {
self.anyHandler?(SocketAnyEvent(event: event, items: data)) self.anyHandler?(SocketAnyEvent(event: event, items: data))
@ -385,7 +385,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
} }
/// Adds a handler that will be called on every event. /// Adds a handler that will be called on every event.
public func onAny(_ handler: (SocketAnyEvent) -> Void) { public func onAny(_ handler: @escaping (SocketAnyEvent) -> Void) {
anyHandler = handler anyHandler = handler
} }
@ -416,7 +416,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
guard reconnecting else { return } guard reconnecting else { return }
DefaultSocketLogger.Logger.log("Starting reconnect", type: logType) DefaultSocketLogger.Logger.log("Starting reconnect", type: logType)
handleEvent("reconnect", data: [reason], isInternalMessage: true) handleEvent("reconnect", data: [reason as AnyObject], isInternalMessage: true)
_tryReconnect() _tryReconnect()
} }
@ -439,23 +439,22 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
DispatchQueue.main.asyncAfter(deadline: deadline, execute: _tryReconnect) DispatchQueue.main.asyncAfter(deadline: deadline, execute: _tryReconnect)
} }
}
// Test properties
// Test extensions
extension SocketIOClient {
var testHandlers: [SocketEventHandler] { var testHandlers: [SocketEventHandler] {
return handlers return handlers
} }
func setTestable() { func setTestable() {
status = .connected status = .connected
} }
func setTestEngine(_ engine: SocketEngineSpec?) { func setTestEngine(_ engine: SocketEngineSpec?) {
self.engine = engine self.engine = engine
} }
func emitTest(event: String, _ data: AnyObject...) { func emitTest(event: String, _ data: AnyObject...) {
_emit([event] + data) _emit([event as AnyObject] + data)
} }
} }

View File

@ -47,8 +47,8 @@ public extension SocketLogger {
private func abstractLog(_ logType: String, message: String, type: String, args: [Any]) { private func abstractLog(_ logType: String, message: String, type: String, args: [Any]) {
guard log else { return } guard log else { return }
let newArgs = args.map({arg -> CVarArg in String(arg)}) let newArgs = args.map({arg -> CVarArg in String(describing: arg)})
let messageFormat = String(format: message, arguments: newArgs) ?? "" let messageFormat = String(format: message, arguments: newArgs)
NSLog("\(logType) \(type): %@", messageFormat) NSLog("\(logType) \(type): %@", messageFormat)
} }

View File

@ -51,11 +51,11 @@ struct SocketPacket {
var description: String { var description: String {
return "SocketPacket {type: \(String(type.rawValue)); data: " + return "SocketPacket {type: \(String(type.rawValue)); data: " +
"\(String(data)); id: \(id); placeholders: \(placeholders); nsp: \(nsp)}" "\(String(describing: data)); id: \(id); placeholders: \(placeholders); nsp: \(nsp)}"
} }
var event: String { var event: String {
return String(data[0]) return String(describing: data[0])
} }
var packetString: String { var packetString: String {
@ -136,10 +136,10 @@ struct SocketPacket {
switch object { switch object {
case let dict as NSDictionary: case let dict as NSDictionary:
if dict["_placeholder"] as? Bool ?? false { if dict["_placeholder"] as? Bool ?? false {
return binary[dict["num"] as! Int] return binary[dict["num"] as! Int] as AnyObject
} else { } else {
return dict.reduce(NSMutableDictionary(), {cur, keyValue in return dict.reduce(NSMutableDictionary(), {cur, keyValue in
cur[keyValue.0 as! NSCopying] = _fillInPlaceholders(keyValue.1) cur[keyValue.0 as! NSCopying] = _fillInPlaceholders(keyValue.1 as AnyObject)
return cur return cur
}) })
} }
@ -179,7 +179,7 @@ extension SocketPacket {
private extension SocketPacket { private extension SocketPacket {
// Recursive function that looks for NSData in collections // Recursive function that looks for NSData in collections
static func shred(_ data: AnyObject, binary: inout [Data]) -> AnyObject { static func shred(_ data: AnyObject, binary: inout [Data]) -> AnyObject {
let placeholder = ["_placeholder": true, "num": binary.count as AnyObject] let placeholder = ["_placeholder": true, "num": binary.count as AnyObject] as [String : Any]
switch data { switch data {
case let bin as Data: case let bin as Data:
@ -189,7 +189,7 @@ private extension SocketPacket {
return arr.map({shred($0, binary: &binary)}) as AnyObject return arr.map({shred($0, binary: &binary)}) as AnyObject
case let dict as NSDictionary: case let dict as NSDictionary:
return dict.reduce(NSMutableDictionary(), {cur, keyValue in return dict.reduce(NSMutableDictionary(), {cur, keyValue in
cur[keyValue.0 as! NSCopying] = shred(keyValue.1, binary: &binary) cur[keyValue.0 as! NSCopying] = shred(keyValue.1 as AnyObject, binary: &binary)
return cur return cur
}) })
default: default:

View File

@ -85,7 +85,7 @@ extension SocketParsable {
} }
if reader.currentCharacter == "/" { if reader.currentCharacter == "/" {
namespace = reader.readUntilOccurence(of: ",") ?? reader.readUntilEnd() namespace = reader.readUntilOccurence(of: ",")
} }
if !reader.hasNext { if !reader.hasNext {
@ -160,8 +160,7 @@ extension SocketParsable {
let packet = waitingPackets.removeLast() let packet = waitingPackets.removeLast()
if packet.type != .binaryAck { if packet.type != .binaryAck {
handleEvent(packet.event, data: packet.args ?? [], handleEvent(packet.event, data: packet.args, isInternalMessage: false, withAck: packet.id)
isInternalMessage: false, withAck: packet.id)
} else { } else {
handleAck(packet.id, data: packet.args) handleAck(packet.id, data: packet.args)
} }

View File

@ -41,7 +41,7 @@ extension String : SocketData {}
public typealias AckCallback = ([AnyObject]) -> Void public typealias AckCallback = ([AnyObject]) -> Void
public typealias NormalCallback = ([AnyObject], SocketAckEmitter) -> Void public typealias NormalCallback = ([AnyObject], SocketAckEmitter) -> Void
public typealias OnAckCallback = (timeoutAfter: UInt64, callback: AckCallback) -> Void public typealias OnAckCallback = (_ timeoutAfter: UInt64, _ callback: AckCallback) -> Void
typealias Probe = (msg: String, type: SocketEnginePacketType, data: [Data]) typealias Probe = (msg: String, type: SocketEnginePacketType, data: [Data])
typealias ProbeWaitQueue = [Probe] typealias ProbeWaitQueue = [Probe]

View File

@ -142,7 +142,7 @@ public class WebSocket: NSObject, StreamDelegate {
private var url: NSURL private var url: NSURL
private var inputStream: InputStream? private var inputStream: InputStream?
private var outputStream: NSOutputStream? private var outputStream: OutputStream?
private var connected = false private var connected = false
private var isConnecting = false private var isConnecting = false
private var writeQueue = OperationQueue() private var writeQueue = OperationQueue()
@ -216,7 +216,7 @@ public class WebSocket: NSObject, StreamDelegate {
*/ */
public func writeString(_ str: String, completion: (() -> ())? = nil) { public func writeString(_ str: String, completion: (() -> ())? = nil) {
guard isConnected else { return } guard isConnected else { return }
dequeueWrite(data: str.data(using: String.Encoding.utf8)!, code: .textFrame, writeCompletion: completion) dequeueWrite(data: str.data(using: String.Encoding.utf8)! as NSData, code: .textFrame, writeCompletion: completion)
} }
/** /**
@ -229,7 +229,7 @@ public class WebSocket: NSObject, StreamDelegate {
*/ */
public func writeData(_ data: Data, completion: (() -> ())? = nil) { public func writeData(_ data: Data, completion: (() -> ())? = nil) {
guard isConnected else { return } guard isConnected else { return }
dequeueWrite(data: data, code: .binaryFrame, writeCompletion: completion) dequeueWrite(data: data as NSData, code: .binaryFrame, writeCompletion: completion)
} }
// Write a ping to the websocket. This sends it as a control frame. // Write a ping to the websocket. This sends it as a control frame.
@ -242,7 +242,7 @@ public class WebSocket: NSObject, StreamDelegate {
/// Private method that starts the connection. /// Private method that starts the connection.
private func createHTTPRequest() { private func createHTTPRequest() {
let urlRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, "GET", let urlRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, "GET" as CFString,
url, kCFHTTPVersion1_1).takeRetainedValue() url, kCFHTTPVersion1_1).takeRetainedValue()
var port = url.port var port = url.port
@ -269,7 +269,7 @@ public class WebSocket: NSObject, StreamDelegate {
} }
if let cfHTTPMessage = CFHTTPMessageCopySerializedMessage(urlRequest) { if let cfHTTPMessage = CFHTTPMessageCopySerializedMessage(urlRequest) {
let serializedRequest = cfHTTPMessage.takeRetainedValue() let serializedRequest = cfHTTPMessage.takeRetainedValue()
initStreamsWithData(data: serializedRequest as Data, Int(port!)) initStreamsWithData(data: serializedRequest as NSData, Int(port!))
} }
} }
@ -284,7 +284,7 @@ public class WebSocket: NSObject, StreamDelegate {
let seed = 16 let seed = 16
for _ in 0..<seed { for _ in 0..<seed {
let uni = UnicodeScalar(UInt32(97 + arc4random_uniform(25))) let uni = UnicodeScalar(UInt32(97 + arc4random_uniform(25)))
key += "\(Character(uni))" key += "\(Character(uni!))"
} }
let data = key.data(using: String.Encoding.utf8) let data = key.data(using: String.Encoding.utf8)
let baseKey = data?.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0)) let baseKey = data?.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
@ -346,7 +346,7 @@ public class WebSocket: NSObject, StreamDelegate {
self.readyToWrite = true self.readyToWrite = true
self.mutex.unlock() self.mutex.unlock()
let bytes = UnsafePointer<UInt8>(data.bytes) let bytes = UnsafeRawPointer(data.bytes).assumingMemoryBound(to: UInt8.self)
var out = timeout * 1000000 // wait 5 seconds before giving up var out = timeout * 1000000 // wait 5 seconds before giving up
writeQueue.addOperation { [weak self] in writeQueue.addOperation { [weak self] in
while !outStream.hasSpaceAvailable { while !outStream.hasSpaceAvailable {
@ -368,24 +368,22 @@ public class WebSocket: NSObject, StreamDelegate {
public func stream(aStream: Stream, handleEvent eventCode: Stream.Event) { public func stream(aStream: Stream, handleEvent eventCode: Stream.Event) {
if let sec = security , !certValidated && [.hasBytesAvailable, .hasSpaceAvailable].contains(eventCode) { if let sec = security , !certValidated && [.hasBytesAvailable, .hasSpaceAvailable].contains(eventCode) {
let possibleTrust: AnyObject? = aStream.property(forKey: kCFStreamPropertySSLPeerTrust as Stream.PropertyKey) let possibleTrust = aStream.property(forKey: kCFStreamPropertySSLPeerTrust as Stream.PropertyKey) as AnyObject
if let trust: AnyObject = possibleTrust { let domain = aStream.property(forKey: kCFStreamSSLPeerName as Stream.PropertyKey) as? String
let domain: AnyObject? = aStream.property(forKey: kCFStreamSSLPeerName as Stream.PropertyKey) if sec.isValid(possibleTrust as! SecTrust, domain: domain) {
if sec.isValid(trust as! SecTrust, domain: domain as! String?) {
certValidated = true certValidated = true
} else { } else {
let error = errorWithDetail(detail: "Invalid SSL certificate", code: 1) let error = errorWithDetail(detail: "Invalid SSL certificate", code: 1)
disconnectStream(error: error) disconnectStream(error: error)
return return
} }
}
} }
if eventCode == .hasBytesAvailable { if eventCode == .hasBytesAvailable {
if aStream == inputStream { if aStream == inputStream {
processInputStream() processInputStream()
} }
} else if eventCode == .errorOccurred { } else if eventCode == .errorOccurred {
disconnectStream(error: aStream.streamError) disconnectStream(error: aStream.streamError as NSError?)
} else if eventCode == .endEncountered { } else if eventCode == .endEncountered {
disconnectStream(error: nil) disconnectStream(error: nil)
} }
@ -420,7 +418,7 @@ public class WebSocket: NSObject, StreamDelegate {
/// Handles the incoming bytes and sending them to the proper processing method. /// Handles the incoming bytes and sending them to the proper processing method.
private func processInputStream() { private func processInputStream() {
let buf = NSMutableData(capacity: BUFFER_MAX) let buf = NSMutableData(capacity: BUFFER_MAX)
let buffer = UnsafeMutablePointer<UInt8>(buf!.bytes) let buffer = UnsafeMutableRawPointer(mutating: buf!.bytes).assumingMemoryBound(to: UInt8.self)
let length = inputStream!.read(buffer, maxLength: BUFFER_MAX) let length = inputStream!.read(buffer, maxLength: BUFFER_MAX)
guard length > 0 else { return } guard length > 0 else { return }
@ -445,7 +443,7 @@ public class WebSocket: NSObject, StreamDelegate {
work = combine as Data work = combine as Data
self.fragBuffer = nil self.fragBuffer = nil
} }
let buffer = UnsafePointer<UInt8>((work as NSData).bytes) let buffer = UnsafeRawPointer((work as NSData).bytes).assumingMemoryBound(to: UInt8.self)
let length = work.count let length = work.count
if !connected { if !connected {
processTCPHandshake(buffer: buffer, bufferLen: length) processTCPHandshake(buffer: buffer, bufferLen: length)
@ -635,10 +633,10 @@ public class WebSocket: NSObject, StreamDelegate {
var dataLength = UInt64(payloadLen) var dataLength = UInt64(payloadLen)
if dataLength == 127 { if dataLength == 127 {
dataLength = WebSocket.readUint64(buffer: baseAddress, offset: offset) dataLength = WebSocket.readUint64(buffer: baseAddress, offset: offset)
offset += sizeof(UInt64.self) offset += MemoryLayout<UInt64>.size
} else if dataLength == 126 { } else if dataLength == 126 {
dataLength = UInt64(WebSocket.readUint16(buffer: baseAddress, offset: offset)) dataLength = UInt64(WebSocket.readUint16(buffer: baseAddress, offset: offset))
offset += sizeof(UInt16.self) offset += MemoryLayout<UInt16>.size
} }
if bufferLen < offset || UInt64(bufferLen - offset) < dataLength { if bufferLen < offset || UInt64(bufferLen - offset) < dataLength {
fragBuffer = Data(bytes: baseAddress, count: bufferLen) fragBuffer = Data(bytes: baseAddress, count: bufferLen)
@ -776,10 +774,10 @@ public class WebSocket: NSObject, StreamDelegate {
/// Write a an error to the socket. /// Write a an error to the socket.
private func writeError(code: UInt16) { private func writeError(code: UInt16) {
let buf = NSMutableData(capacity: sizeof(UInt16.self)) let buf = NSMutableData(capacity: MemoryLayout<UInt16>.size)
let buffer = UnsafeMutablePointer<UInt8>(buf!.bytes) let buffer = UnsafeMutableRawPointer(mutating: buf!.bytes).assumingMemoryBound(to: UInt8.self)
WebSocket.writeUint16(buffer: buffer, offset: 0, value: code) WebSocket.writeUint16(buffer: buffer, offset: 0, value: code)
dequeueWrite(data: Data(bytes: buffer, count: sizeof(UInt16.self)), code: .connectionClose) dequeueWrite(data: Data(bytes: buffer, count: MemoryLayout<UInt16>.size) as NSData, code: .connectionClose)
} }
/// Used to write things to the stream. /// Used to write things to the stream.
@ -788,35 +786,35 @@ public class WebSocket: NSObject, StreamDelegate {
//stream isn't ready, let's wait //stream isn't ready, let's wait
guard let s = self else { return } guard let s = self else { return }
var offset = 2 var offset = 2
let bytes = UnsafeMutablePointer<UInt8>((data as NSData).bytes) let bytes = UnsafeMutableRawPointer(mutating: (data as NSData).bytes).assumingMemoryBound(to: UInt8.self)
let dataLength = data.length let dataLength = data.length
let frame = NSMutableData(capacity: dataLength + s.MaxFrameSize) let frame = NSMutableData(capacity: dataLength + s.MaxFrameSize)
let buffer = UnsafeMutablePointer<UInt8>(frame!.mutableBytes) let buffer = UnsafeMutableRawPointer(frame!.mutableBytes).assumingMemoryBound(to: UInt8.self)
buffer[0] = s.FinMask | code.rawValue buffer[0] = s.FinMask | code.rawValue
if dataLength < 126 { if dataLength < 126 {
buffer[1] = CUnsignedChar(dataLength) buffer[1] = CUnsignedChar(dataLength)
} else if dataLength <= Int(UInt16.max) { } else if dataLength <= Int(UInt16.max) {
buffer[1] = 126 buffer[1] = 126
WebSocket.writeUint16(buffer: buffer, offset: offset, value: UInt16(dataLength)) WebSocket.writeUint16(buffer: buffer, offset: offset, value: UInt16(dataLength))
offset += sizeof(UInt16.self) offset += MemoryLayout<UInt16>.size
} else { } else {
buffer[1] = 127 buffer[1] = 127
WebSocket.writeUint64(buffer: buffer, offset: offset, value: UInt64(dataLength)) WebSocket.writeUint64(buffer: buffer, offset: offset, value: UInt64(dataLength))
offset += sizeof(UInt64.self) offset += MemoryLayout<UInt64>.size
} }
buffer[1] |= s.MaskMask buffer[1] |= s.MaskMask
let maskKey = UnsafeMutablePointer<UInt8>(buffer + offset) let maskKey = UnsafeMutablePointer<UInt8>(buffer + offset)
_ = SecRandomCopyBytes(kSecRandomDefault, Int(sizeof(UInt32.self)), maskKey) _ = SecRandomCopyBytes(kSecRandomDefault, Int(MemoryLayout<UInt32>.size), maskKey)
offset += sizeof(UInt32.self) offset += MemoryLayout<UInt32>.size
for i in 0..<dataLength { for i in 0..<dataLength {
buffer[offset] = bytes[i] ^ maskKey[i % sizeof(UInt32.self)] buffer[offset] = bytes[i] ^ maskKey[i % MemoryLayout<UInt32>.size]
offset += 1 offset += 1
} }
var total = 0 var total = 0
while true { while true {
guard let outStream = s.outputStream else { break } guard let outStream = s.outputStream else { break }
let writeBuffer = UnsafePointer<UInt8>(frame!.bytes+total) let writeBuffer = UnsafeRawPointer(frame!.bytes+total).assumingMemoryBound(to: UInt8.self)
let len = outStream.write(writeBuffer, maxLength: offset-total) let len = outStream.write(writeBuffer, maxLength: offset-total)
if len < 0 { if len < 0 {
var error: NSError? var error: NSError?