1414
1515import NIO
1616
17- final class RedisChannelHandler : ChannelInboundHandler ,
18- ChannelOutboundHandler
17+ open class RedisChannelHandler : ChannelInboundHandler ,
18+ ChannelOutboundHandler
1919{
2020
21- typealias InboundErr = RESPParserError
21+ public typealias InboundErr = RESPParserError
2222
23- typealias InboundIn = ByteBuffer
24- typealias InboundOut = RESPValue
23+ public typealias InboundIn = ByteBuffer
24+ public typealias InboundOut = RESPValue
2525
26- typealias OutboundIn = RESPEncodable
27- typealias OutboundOut = ByteBuffer
26+ public typealias OutboundIn = RESPEncodable
27+ public typealias OutboundOut = ByteBuffer
2828
29- let nilStringBuffer = ConstantBuffers . nilStringBuffer
30- let nilArrayBuffer = ConstantBuffers . nilArrayBuffer
29+ private final let nilStringBuffer = ConstantBuffers . nilStringBuffer
30+ private final let nilArrayBuffer = ConstantBuffers . nilArrayBuffer
3131
32- private final var parser = RESPParser ( )
32+ public final var parser = RESPParser ( )
3333
3434 // MARK: - Channel Open/Close
3535
36- func channelActive( ctx: ChannelHandlerContext ) {
36+ public func channelActive( ctx: ChannelHandlerContext ) {
3737 ctx. fireChannelActive ( )
3838 }
39- func channelInactive( ctx: ChannelHandlerContext ) {
40- switch state {
41- case . protocolError, . start: break // all good
42- default :
43- ctx. fireErrorCaught ( InboundErr . ProtocolError)
44- }
45-
46- overflowBuffer = nil
47-
39+ public func channelInactive( ctx: ChannelHandlerContext ) {
40+ #if false // this doesn't gain us anything?
41+ switch parser. state {
42+ case . protocolError, . start: break // all good
43+ default :
44+ ctx. fireErrorCaught ( InboundErr . ProtocolError)
45+ }
46+ #endif
4847 ctx. fireChannelInactive ( )
4948 }
50-
49+
5150
5251 // MARK: - Reading
5352
5453 public func channelRead( ctx: ChannelHandlerContext , data: NIOAny ) {
5554 do {
5655 let buffer = self . unwrapInboundIn ( data)
5756 try parser. feed ( buffer) { respValue in
58- ctx . fireChannelRead ( self . wrapInboundOut ( respValue) )
57+ self . channelRead ( ctx : ctx , value : respValue)
5958 }
6059 }
6160 catch {
@@ -64,84 +63,28 @@ final class RedisChannelHandler : ChannelInboundHandler,
6463 return
6564 }
6665 }
67-
66+
67+ open func channelRead( ctx: ChannelHandlerContext , value: RESPValue ) {
68+ ctx. fireChannelRead ( self . wrapInboundOut ( value) )
69+ }
70+
6871 public func errorCaught( ctx: ChannelHandlerContext , error: Error ) {
6972 ctx. fireErrorCaught ( InboundErr . TransportError ( error) )
7073 }
7174
7275
73- // MARK: - Parsing
76+ // MARK: - Writing
7477
75- private enum ParserState {
76- case protocolError
77- case start
78- case error
79- case integer
80- case bulkStringLen
81- case bulkStringValue
82- case simpleString
83- case arrayCount
84- case telnet
85- }
86-
87- @inline ( __always)
88- private func makeArrayParseContext( _ parent: ArrayParseContext ? = nil ,
89- _ count: Int ) -> ArrayParseContext
78+ public func write( ctx: ChannelHandlerContext , data: NIOAny ,
79+ promise: EventLoopPromise < Void > ? )
9080 {
91- if parent == nil && cachedParseContext != nil {
92- let ctx = cachedParseContext!
93- cachedParseContext = nil
94- ctx. count = count
95- ctx. values. reserveCapacity ( count)
96- return ctx
97- }
98- else {
99- return ArrayParseContext ( parent, count)
100- }
101- }
102- private final var cachedParseContext : ArrayParseContext ? = nil
103-
104- final private class ArrayParseContext {
105-
106- let parent : ArrayParseContext ?
107- var values = ContiguousArray < RESPValue > ( )
108- var count : Int
109-
110- init ( _ parent: ArrayParseContext ? , _ count: Int ) {
111- self . parent = parent
112- self . count = count
113- }
114-
115- var isDone : Bool { return count <= values. count }
116- var isNested : Bool { return parent != nil }
117-
118- @inline ( __always)
119- func append( value v: InboundOut ) -> Bool {
120- assert ( !isNested || !isDone,
121- " attempt to add to a context which is not TL or done " )
122- values. append ( v)
123- return isDone
124- }
81+ let data : RESPEncodable = self . unwrapOutboundIn ( data)
82+ write ( ctx: ctx, value: data. toRESPValue ( ) , promise: promise)
12583 }
12684
127- private var state = ParserState . start
128- private var overflowSkipNL = false
129- private var hadMinus = false
130-
131- private var countValue = 0
132- private var overflowBuffer : ByteBuffer ?
133-
134- private var arrayContext : ArrayParseContext ?
135-
136-
137- // MARK: - Writing
138-
139- func write( ctx: ChannelHandlerContext , data: NIOAny ,
140- promise: EventLoopPromise < Void > ? )
85+ public final func write( ctx: ChannelHandlerContext , value: RESPValue ,
86+ promise: EventLoopPromise < Void > ? )
14187 {
142- let data : RESPEncodable = self . unwrapOutboundIn ( data)
143- let value = data. toRESPValue ( )
144-
14588 var out : ByteBuffer
14689 switch value {
14790 case . simpleString( var s) : // +
@@ -190,8 +133,8 @@ final class RedisChannelHandler : ChannelInboundHandler,
190133 }
191134
192135 @inline ( __always)
193- func encode< S: ContiguousCollection > ( simpleString bytes: S ,
194- out: inout ByteBuffer )
136+ final func encode< S: ContiguousCollection > ( simpleString bytes: S ,
137+ out: inout ByteBuffer )
195138 where S. Element == UInt8
196139 {
197140 out. write ( integer : UInt8 ( 43 ) ) // +
@@ -200,15 +143,15 @@ final class RedisChannelHandler : ChannelInboundHandler,
200143 }
201144
202145 @inline ( __always)
203- func encode( simpleString bytes: ByteBuffer , out: inout ByteBuffer ) {
146+ final func encode( simpleString bytes: ByteBuffer , out: inout ByteBuffer ) {
204147 var s = bytes
205148 out. write ( integer : UInt8 ( 43 ) ) // +
206149 out. write ( buffer : & s)
207150 out. write ( bytes : eol)
208151 }
209152
210153 @inline ( __always)
211- func encode( bulkString bytes: ByteBuffer ? , out: inout ByteBuffer ) {
154+ final func encode( bulkString bytes: ByteBuffer ? , out: inout ByteBuffer ) {
212155 if var s = bytes {
213156 out. write ( integer : UInt8 ( 36 ) ) // $
214157 out. write ( integerAsString : s. readableBytes)
@@ -222,8 +165,8 @@ final class RedisChannelHandler : ChannelInboundHandler,
222165 }
223166
224167 @inline ( __always)
225- func encode< S: ContiguousCollection > ( bulkString bytes: S ? ,
226- out: inout ByteBuffer )
168+ final func encode< S: ContiguousCollection > ( bulkString bytes: S ? ,
169+ out: inout ByteBuffer )
227170 where S. Element == UInt8
228171 {
229172 if let s = bytes {
@@ -239,32 +182,32 @@ final class RedisChannelHandler : ChannelInboundHandler,
239182 }
240183
241184 @inline ( __always)
242- func encode( integer i: Int , out: inout ByteBuffer ) {
185+ final func encode( integer i: Int , out: inout ByteBuffer ) {
243186 out. write ( integer : UInt8 ( 58 ) ) // :
244187 out. write ( integerAsString : i)
245188 out. write ( bytes : eol)
246189 }
247190
248191 @inline ( __always)
249- func encode( error: RESPError , out: inout ByteBuffer ) {
192+ final func encode( error: RESPError , out: inout ByteBuffer ) {
250193 out. write ( integer : UInt8 ( 45 ) ) // -
251194 out. write ( string : error. code)
252195 out. write ( integer : UInt8 ( 32 ) ) // ' '
253196 out. write ( string : error. message)
254197 out. write ( bytes : eol)
255198 }
256199
257- func encode( ctx : ChannelHandlerContext ,
258- data : RESPValue ,
259- out : inout ByteBuffer )
200+ final func encode( ctx : ChannelHandlerContext ,
201+ data : RESPValue ,
202+ out : inout ByteBuffer )
260203 {
261204 encode ( ctx: ctx, data: data, level: 0 , out: & out)
262205 }
263206
264- func encode( ctx : ChannelHandlerContext ,
265- data : RESPValue ,
266- level : Int ,
267- out : inout ByteBuffer )
207+ final func encode( ctx : ChannelHandlerContext ,
208+ data : RESPValue ,
209+ level : Int ,
210+ out : inout ByteBuffer )
268211 {
269212 // FIXME: Creating a String for an Int is expensive, there is something
270213 // something better in the HTTP-API async imp.
0 commit comments