Skip to content

Commit

Permalink
Initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr. Brandon Wiley committed Sep 1, 2020
1 parent c59d226 commit 0f7363e
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 15 deletions.
10 changes: 7 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import PackageDescription

let package = Package(
name: "Transmission",
platforms: [.macOS(.v10_15)],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
Expand All @@ -14,15 +15,18 @@ let package = Package(
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/OperatorFoundation/Chord", from: "0.0.5"),
.package(url: "https://github.com/OperatorFoundation/Datable", from: "3.0.2"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "Transmission",
dependencies: []),
dependencies: ["Chord"]),
.testTarget(
name: "TransmissionTests",
dependencies: ["Transmission"]),
]
dependencies: ["Transmission", "Datable"]),
],
swiftLanguageVersions: [.v5]
)
118 changes: 118 additions & 0 deletions Sources/Transmission/Connection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import Foundation
import Network
import Datable

public class Connection
{
var connection: NWConnection
var connectLock = DispatchGroup()
var readLock = DispatchGroup()
var writeLock = DispatchGroup()

public convenience init?(host: String, port: Int)
{
let nwhost = NWEndpoint.Host(host)

let port16 = UInt16(port)
let nwport = NWEndpoint.Port(integerLiteral: port16)

let nwconnection = NWConnection(host: nwhost, port: nwport, using: .tcp)

self.init(connection: nwconnection)
}

init?(connection: NWConnection)
{
self.connection = connection

var success = false

self.connectLock.enter()
self.connection.stateUpdateHandler =
{
(state) in

switch state
{
case .ready:
success = true
self.connectLock.leave()
return
case .cancelled:
self.connectLock.leave()
return
case .failed(_):
self.connectLock.leave()
return
default:
return
}
}

self.connection.start(queue: .global())

connectLock.wait()

guard success else {return nil}
}

public func read(size: Int) -> Data?
{
var result: Data?

self.readLock.enter()
self.connection.receive(minimumIncompleteLength: size, maximumLength: size)
{
(maybeData, maybeContext, isComplete, maybeError) in

guard maybeError == nil else
{
self.readLock.leave()
return
}

if let data = maybeData
{
result = data
}

self.readLock.leave()
}

readLock.wait()

return result
}

public func write(string: String) -> Bool
{
let data = string.data
return write(data: data)
}

public func write(data: Data) -> Bool
{
var success = false

self.writeLock.enter()
self.connection.send(content: data, completion: NWConnection.SendCompletion.contentProcessed(
{
(maybeError) in

guard maybeError == nil else
{
success = false
self.writeLock.leave()
return
}

success = true
self.writeLock.leave()
return
}))

self.writeLock.wait()

return success
}
}
42 changes: 42 additions & 0 deletions Sources/Transmission/Listener.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Listener.swift
//
//
// Created by Dr. Brandon Wiley on 8/31/20.
//

import Foundation
import Network
import Chord

public class Listener
{
let listener: NWListener
let queue: BlockingQueue<Connection> = BlockingQueue<Connection>()
let lock: DispatchGroup = DispatchGroup()

public init?(port: Int)
{
let port16 = UInt16(port)
let nwport = NWEndpoint.Port(integerLiteral: port16)

guard let listener = try? NWListener(using: .tcp, on: nwport) else {return nil}
self.listener = listener

self.listener.newConnectionHandler =
{
nwconnection in

guard let connection = Connection(connection: nwconnection) else {return}

self.queue.enqueue(element: connection)
}

self.listener.start(queue: .global())
}

public func accept() -> Connection
{
return self.queue.dequeue()
}
}
3 changes: 0 additions & 3 deletions Sources/Transmission/Transmission.swift

This file was deleted.

50 changes: 41 additions & 9 deletions Tests/TransmissionTests/TransmissionTests.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,47 @@
import XCTest
import Foundation
@testable import Transmission

final class TransmissionTests: XCTestCase {
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
XCTAssertEqual(Transmission().text, "Hello, World!")
final class TransmissionTests: XCTestCase
{
public func testConnection()
{
let lock = DispatchGroup()
let queue = DispatchQueue(label: "testing")

lock.enter()

queue.async
{
self.runServer(lock)
}

lock.wait()

runClient()
}

func runServer(_ lock: DispatchGroup)
{
guard let listener = Listener(port: 1234) else {return}
lock.leave()

static var allTests = [
("testExample", testExample),
]
let connection = listener.accept()
let _ = connection.read(size: 4)
let _ = connection.write(string: "back")
}

func runClient()
{
let connection = Connection(host: "127.0.0.1", port: 1234)
XCTAssertNotNil(connection)

let writeResult = connection!.write(string: "test")
XCTAssertTrue(writeResult)

let result = connection!.read(size: 4)
XCTAssertNotNil(result)

XCTAssertEqual(result!, "back")
}
}

0 comments on commit 0f7363e

Please sign in to comment.