All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.finagle.redis.protocol.Parsers.scala Maven / Gradle / Ivy

There is a newer version: 21.2.0
Show newest version
package com.twitter.finagle.redis.protocol

import com.twitter.finagle.redis.naggati.{NextStep, ProtocolError}
import com.twitter.finagle.redis.naggati.Stages._
import com.twitter.finagle.redis.protocol.RedisCodec._
import com.twitter.finagle.redis.util._

trait UnifiedProtocolCodec {

  type ByteArrays = List[Array[Byte]]

  def decodeUnifiedFormat[T <: AnyRef](argCount: Long, doneFn: ByteArrays => T) =
    argCount match {
      case n if n < 0 => throw new ProtocolError("Invalid argument count specified")
      case n => decodeRequestLines(n, Nil, { lines => doneFn(lines) } )
    }

  def decodeRequestLines[T <: AnyRef](
    i: Long,
    lines: ByteArrays,
    doneFn: ByteArrays => T): NextStep =
  {
    if (i <= 0) {
      emit(doneFn(lines.reverse))
    } else {
      readLine { line =>
        val header = line(0)
        header match {
          case ARG_SIZE_MARKER =>
            val size = NumberFormat.toInt(line.drop(1))
            if (size < 1) {
              decodeRequestLines(i - 1, lines.+:(RedisCodec.NIL_VALUE_BA.array), doneFn)
            } else {
              readBytes(size) { byteArray =>
                readBytes(2) { eol =>
                  if (eol(0) != '\r' || eol(1) != '\n') {
                    throw new ProtocolError("Expected EOL after line data and didn't find it")
                  }
                  decodeRequestLines(i - 1, lines.+:(byteArray), doneFn)
                }
              }
            }
          case STATUS_REPLY =>
            decodeRequestLines(i - 1, lines.+:(line.drop(1).getBytes), doneFn)
          case ARG_COUNT_MARKER =>
            decodeRequestLines(line.drop(1).toLong, lines, doneFn)
          case INTEGER_REPLY =>
            decodeRequestLines(i - 1, lines.+:(line.drop(1).getBytes), doneFn)
          case ERROR_REPLY =>
            decodeRequestLines(i - 1, lines.+:(line.drop(1).getBytes), doneFn)
          case b: Char =>
            throw new ProtocolError("Expected size marker $, got " + b)
        } // header match
      } // readLine
    } // else
  } // decodeRequestLines
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy