aboutsummaryrefslogtreecommitdiff
path: root/Sources/swiftGopherClient/gopherRequestResponseHandler.swift
diff options
context:
space:
mode:
authorNavan Chauhan <navanchauhan@gmail.com>2023-12-12 22:51:56 -0700
committerNavan Chauhan <navanchauhan@gmail.com>2023-12-12 22:51:56 -0700
commit3916948004dadc045739c786236ccda82590a130 (patch)
tree70bee6110898b2a31f80b5e048df5577dfc1f5da /Sources/swiftGopherClient/gopherRequestResponseHandler.swift
parent315e2510d577b7303f4b8204a4555aad26bc41a3 (diff)
add initial swiftGopherClient1.0.0
Diffstat (limited to 'Sources/swiftGopherClient/gopherRequestResponseHandler.swift')
-rw-r--r--Sources/swiftGopherClient/gopherRequestResponseHandler.swift111
1 files changed, 111 insertions, 0 deletions
diff --git a/Sources/swiftGopherClient/gopherRequestResponseHandler.swift b/Sources/swiftGopherClient/gopherRequestResponseHandler.swift
new file mode 100644
index 0000000..0cd040a
--- /dev/null
+++ b/Sources/swiftGopherClient/gopherRequestResponseHandler.swift
@@ -0,0 +1,111 @@
+//
+// gopherRequestResponseHandler.swift
+//
+//
+// Created by Navan Chauhan on 12/12/23.
+//
+
+import Foundation
+import NIO
+
+final class GopherRequestResponseHandler: ChannelInboundHandler {
+ typealias InboundIn = ByteBuffer
+ typealias OutboundOut = ByteBuffer
+
+ private var accumulatedData: ByteBuffer
+ private let message: String
+ private let completion: (Result<String, Error>) -> Void
+
+ init(message: String, completion: @escaping (Result<String, Error>) -> Void) {
+ self.message = message
+ self.completion = completion
+ self.accumulatedData = ByteBuffer()
+ }
+
+ func channelActive(context: ChannelHandlerContext) {
+ var buffer = context.channel.allocator.buffer(capacity: message.utf8.count)
+ buffer.writeString(message)
+ context.writeAndFlush(self.wrapOutboundOut(buffer), promise: nil)
+ }
+
+ func channelRead(context: ChannelHandlerContext, data: NIOAny) {
+ var buffer = unwrapInboundIn(data)
+ accumulatedData.writeBuffer(&buffer)
+ if let receivedString = buffer.getString(at: 0, length: buffer.readableBytes) {
+ print("Received from server: \(receivedString)")
+ }
+ //completion(.success(receivedString))
+ //context.close(promise: nil)
+ }
+
+ func channelInactive(context: ChannelHandlerContext) {
+ // Parse GopherServerResponse
+ parseGopherServerResponse(response: accumulatedData.readString(length: accumulatedData.readableBytes) ?? "")
+ //completion(.success(accumulatedData.readString(length: accumulatedData.readableBytes) ?? ""))
+ }
+
+ func errorCaught(context: ChannelHandlerContext, error: Error) {
+ print("Error: ", error)
+ context.close(promise: nil)
+ }
+
+ func createGopherItem(rawLine: String, itemType: gopherItemType = .info) -> gopherItem {
+ var item = gopherItem(rawLine: rawLine)
+ item.parsedItemType = itemType
+
+ if rawLine.isEmpty {
+ item.valid = false
+ } else {
+ let components = rawLine.components(separatedBy: "\t")
+
+ // Handle cases where rawLine does not have any itemType in the first character
+ item.message = String(components[0].dropFirst())
+
+ if components.indices.contains(1) {
+ item.selector = String(components[1])
+ }
+
+ if components.indices.contains(2) {
+ item.host = String(components[2])
+ }
+
+ if components.indices.contains(3) {
+ item.port = Int(String(components[3])) ?? 70
+ }
+ }
+
+ return item
+ }
+
+ func parseGopherServerResponse(response: String) {
+ var gopherServerResponse: [gopherItem] = []
+
+ print("parsing")
+ let carriageReturnCount = response.filter({ $0 == "\r" }).count
+ let newlineCarriageReturnCount = response.filter({ $0 == "\r\n" }).count
+ print("Carriage Returns: \(carriageReturnCount), Newline + Carriage Returns: \(newlineCarriageReturnCount)")
+
+ for line in response.split(separator: "\r\n") {
+ let lineItemType = getGopherFileType(item: "\(line.first ?? " ")")
+ let item = createGopherItem(rawLine: String(line), itemType: lineItemType)
+ print(item.message)
+ gopherServerResponse.append(item)
+
+ }
+
+ print("done parsing")
+
+ completion(.success(response))
+ }
+}
+
+struct gopherItem {
+ var rawLine: String
+ var message: String = ""
+ var parsedItemType: gopherItemType = .info
+ var host: String = "error.host"
+ var port: Int = 1
+ var selector: String = ""
+ var valid: Bool = true
+}
+