Exemplo n.º 1
0
	    public void ClearState() 
	    {
		    Type = RedisValueType.None;
		    _bulkLengthExpected = null;
		    _valueBufferLen = 0;
		    _skip = 0;
		    _valueBuffer = new byte[4096];
	    }	
Exemplo n.º 2
0
	    public void Update(byte[] inbound, int start, int length) 
	    {
		    for (int i=start, count = 0; count < length; i++, count++) 
		    {
			    if (_skip > 0) 
			    {
				    _skip--;
				    continue;
			    }

			    var typeBefore = Type;

			    if (Type == RedisValueType.None) 
			    {
				    switch (inbound[i]) {
					    case DOLLAR: Type = RedisValueType.Bulk;      break;
					    case STAR:   Type = RedisValueType.MultiBulk; break;
					    case COLON:  Type = RedisValueType.Integer;   break;
					    case PLUS:   Type = RedisValueType.Inline;    break;
					    case MINUS:  Type = RedisValueType.Error;     break;
				    }
			    }

			    // Just a state transition on '*', '+', etc.?  

			    if (typeBefore != Type)
				    continue;

			    switch (inbound[i]) {
			    case CR:
				    switch (Type) {
					    case RedisValueType.Inline:
					    case RedisValueType.Error:
						    // CR denotes end of the inline/error value.  
						    // +OK\r\n
						    //    ^

						    var inlineBuf = new byte[_valueBufferLen];
						    Array.Copy(_valueBuffer, inlineBuf, _valueBufferLen);
				            var val = new RedisValue
				                          {
                                            Data = inlineBuf,
                                            Type = Type
				                          };
						    MaybeCallbackWithReply(val);
						    break;

					    case RedisValueType.Integer:
						    // CR denotes the end of the integer value.  
						    // :42\r\n
						    //    ^
						    var n = ParseInt(_valueBuffer, _valueBufferLen);
						    MaybeCallbackWithReply( n );
						    break;

					    case RedisValueType.Bulk:
						    if (_bulkLengthExpected == null) {
							    // CR denotes end of first line of a bulk reply,
							    // which is the length of the bulk reply value.
							    // $5\r\nhello\r\n
							    //   ^

                                var lengthExpected = ParseInt(_valueBuffer, _valueBufferLen);

							    if (lengthExpected <= 0) {
								    MaybeCallbackWithReply( RedisValue.Empty );
							    } else {
								    ClearState();

								    _bulkLengthExpected = lengthExpected;
								    Type = RedisValueType.Bulk;
								    _skip = 1;  // _skip LF
							    }
						    } else if (_valueBufferLen == _bulkLengthExpected) {
							    // CR denotes end of the bulk reply value.
							    // $5\r\nhello\r\n
							    //            ^

							    var bulkBuf = new Byte[_valueBufferLen];
                                Array.Copy(_valueBuffer, bulkBuf, _valueBufferLen);
							    MaybeCallbackWithReply(bulkBuf);
						    } else {
							    // CR is just an embedded CR and has nothing to do
							    // with the reply specification.
							    // $11\r\nhello\rworld\r\n
							    //             ^	
							    _valueBuffer[_valueBufferLen++] = inbound[i];
						    }
						    break;

					    case RedisValueType.MultiBulk:
						    // Parse the count which is the number of expected replies
						    // in the multi-bulk reply.
						    // *2\r\n$5\r\nhello\r\n$5\r\nworld\r\n
						    //   ^

						    var repliesExpected = ParseInt(_valueBuffer, _valueBufferLen);

						    if (repliesExpected <= 0) {
							    MaybeCallbackWithReply( RedisValue.Empty );
						    } else {
							    ClearState();
							    _skip = 1;    // _skip LF
							    _multibulkReplies = new byte[repliesExpected][];
							    _multibulkRepliesExpected = repliesExpected;
							    _multibulkIndex = 0;
						    }
						    break;
				    }
				    break;

			    default:
				    _valueBuffer[_valueBufferLen++] = inbound[i];
				    break;
			    }

			    // If the current value buffer is too big, create a new buffer, copy in
			    // the old buffer, and replace the old buffer with the new buffer.
    	 
			    if (_valueBufferLen == _valueBuffer.Length) 
			    {
				    var newBuffer = new byte[_valueBuffer.Length * 2];
				    _valueBuffer.CopyTo(newBuffer, 0);
				    _valueBuffer = newBuffer;
			    }
		    }
	    }