From 06649f47a8b1d65590ee8a8f78668d064e92f56b Mon Sep 17 00:00:00 2001 From: Navan Chauhan Date: Sun, 28 Jul 2024 14:55:56 -0600 Subject: rename and capitalize --- .../gopherRequestResponseHandler.swift | 113 +++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 Sources/SwiftGopherClient/gopherRequestResponseHandler.swift (limited to 'Sources/SwiftGopherClient/gopherRequestResponseHandler.swift') diff --git a/Sources/SwiftGopherClient/gopherRequestResponseHandler.swift b/Sources/SwiftGopherClient/gopherRequestResponseHandler.swift new file mode 100644 index 0000000..10da67e --- /dev/null +++ b/Sources/SwiftGopherClient/gopherRequestResponseHandler.swift @@ -0,0 +1,113 @@ +// +// gopherRequestResponseHandler.swift +// +// +// Created by Navan Chauhan on 12/12/23. +// + +import Foundation +import GopherHelpers +import NIO + +final class GopherRequestResponseHandler: ChannelInboundHandler { + typealias InboundIn = ByteBuffer + typealias OutboundOut = ByteBuffer + + private var accumulatedData: ByteBuffer + private let message: String + private let completion: (Result<[gopherItem], Error>) -> Void + + init(message: String, completion: @escaping (Result<[gopherItem], 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) + } + + func channelInactive(context: ChannelHandlerContext) { + if let dataCopy = accumulatedData.getSlice(at: 0, length: accumulatedData.readableBytes) { + parseGopherServerResponse( + response: accumulatedData.readString(length: accumulatedData.readableBytes) ?? "", + originalBytes: dataCopy) + } + } + + func errorCaught(context: ChannelHandlerContext, error: Error) { + print("Error: ", error) + context.close(promise: nil) + } + + func createGopherItem(rawLine: String, itemType: gopherItemType = .info, rawData: ByteBuffer) + -> gopherItem + { + var item = gopherItem(rawLine: rawLine) + item.parsedItemType = itemType + item.rawData = rawData + + 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, originalBytes: ByteBuffer) { + 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)" + ) + + if newlineCarriageReturnCount == 0 { + for line in response.split(separator: "\n") { + let lineItemType = getGopherFileType(item: "\(line.first ?? " ")") + let item = createGopherItem( + rawLine: String(line), itemType: lineItemType, rawData: originalBytes) + gopherServerResponse.append(item) + + } + } else { + for line in response.split(separator: "\r\n") { + let lineItemType = getGopherFileType(item: "\(line.first ?? " ")") + let item = createGopherItem( + rawLine: String(line), itemType: lineItemType, rawData: originalBytes) + gopherServerResponse.append(item) + + } + } + + print("done parsing") + + completion(.success(gopherServerResponse)) + } +} -- cgit v1.2.3