@@ -2,58 +2,93 @@ import Logging
22import NIOCore
33
44extension ByteBuffer {
5+ /// Returns `true` if byte to be read immediately is a GDB RP checksum
6+ /// delimiter. Returns `false` otherwise.
57 var isChecksumDelimiterAtReader : Bool {
68 self . peekInteger ( as: UInt8 . self) == UInt8 ( ascii: " # " )
79 }
810
11+ /// Returns `true` if byte to be read immediately is a GDB RP command arguments
12+ /// delimiter. Returns `false` otherwise.
913 var isArgumentsDelimiterAtReader : Bool {
1014 self . peekInteger ( as: UInt8 . self) == UInt8 ( ascii: " : " )
1115 }
1216}
1317
18+ /// Decoder of GDB RP host commands, that takes raw `ByteBuffer` as an input encoded
19+ /// per https://sourceware.org/gdb/current/onlinedocs/gdb.html/Overview.html#Overview
20+ /// and produces a `GDBPacket<GDBHostCommand>` value as output. This decoder is
21+ /// compatible with NIO channel pipelines, making it easy to integrate with different
22+ /// I/O configurations.
1423package struct GDBHostCommandDecoder : ByteToMessageDecoder {
15- enum Error : Swift . Error {
24+ /// Errors that can be thrown during host command decoding.
25+ package enum Error : Swift . Error {
26+ /// Expected `+` acknowledgement character to be included in the packet, when
27+ /// ``GDBHostCommandDecoder/isNoAckModeActive`` is set to `false`.
1628 case expectedAck
29+
30+ /// Expected command to start with `$` character`.
1731 case expectedCommandStart
18- case unknownCommandKind( String )
32+
33+ /// Expected checksum to be included with the packet was not found.
1934 case expectedChecksum
35+
36+ /// Expected checksum included with the packet did not match the expected value.
2037 case checksumIncorrect( expectedChecksum: Int , receivedChecksum: UInt8 )
38+
39+ /// Unexpected arguments value supplied for a given command.
40+ case unexpectedArgumentsValue
41+
42+ /// Host command kind could not be parsed. See `GDBHostCommand.Kind` for the
43+ /// list of supported commands.
44+ case unknownCommand( kind: String , arguments: String )
2145 }
2246
47+ /// Type of the output value produced by this decoder.
2348 package typealias InboundOut = GDBPacket < GDBHostCommand >
2449
2550 private var accumulatedDelimiter : UInt8 ?
2651
2752 private var accummulatedKind = [ UInt8] ( )
2853 private var accummulatedArguments = [ UInt8] ( )
29-
54+
55+ /// Logger instance used by this decoder.
3056 private let logger : Logger
31-
57+
58+ /// Initializes a new decoder.
59+ /// - Parameter logger: logger instance that consumes messages from the newly
60+ /// initialized decoder.
3261 package init ( logger: Logger ) { self . logger = logger }
33-
62+
63+ /// Sum of the raw character values consumed in the current command so far,
64+ /// used in checksum computation.
3465 private var accummulatedSum = 0
66+
67+ /// Computed checksum for the values consumed in the current command so far.
3568 package var accummulatedChecksum : UInt8 {
3669 UInt8 ( self . accummulatedSum % 256 )
3770 }
3871
3972 private var isNoAckModeRequested = false
4073 private var isNoAckModeActive = false
4174
42- mutating package func decode( buffer: inout ByteBuffer ) throws -> GDBPacket < GDBHostCommand > ? {
75+ package mutating func decode(
76+ buffer: inout ByteBuffer
77+ ) throws ( Error) -> GDBPacket < GDBHostCommand > ? {
4378 guard var startDelimiter = self . accumulatedDelimiter ?? buffer. readInteger ( as: UInt8 . self) else {
4479 // Not enough data to parse.
4580 return nil
4681 }
4782
48- if !isNoAckModeActive {
83+ if !self . isNoAckModeActive {
4984 let firstStartDelimiter = startDelimiter
5085
5186 guard firstStartDelimiter == UInt8 ( ascii: " + " ) else {
5287 logger. error ( " unexpected ack character: \( Character ( UnicodeScalar ( startDelimiter) ) ) " )
5388 throw Error . expectedAck
5489 }
5590
56- if isNoAckModeRequested {
91+ if self . isNoAckModeRequested {
5792 self . isNoAckModeActive = true
5893 }
5994
@@ -70,7 +105,7 @@ package struct GDBHostCommandDecoder: ByteToMessageDecoder {
70105
71106 // Command start delimiters.
72107 guard startDelimiter == UInt8 ( ascii: " $ " ) else {
73- logger. error ( " unexpected delimiter: \( Character ( UnicodeScalar ( startDelimiter) ) ) " )
108+ self . logger. error ( " unexpected delimiter: \( Character ( UnicodeScalar ( startDelimiter) ) ) " )
74109 throw Error . expectedCommandStart
75110 }
76111
@@ -139,7 +174,7 @@ package struct GDBHostCommandDecoder: ByteToMessageDecoder {
139174 mutating package func decode(
140175 context: ChannelHandlerContext ,
141176 buffer: inout ByteBuffer
142- ) throws -> DecodingState {
177+ ) throws ( Error ) -> DecodingState {
143178 logger. trace ( . init( stringLiteral: buffer. peekString ( length: buffer. readableBytes) !) )
144179
145180 guard let command = try self . decode ( buffer: & buffer) else {
0 commit comments