module EventMachine::Protocols::Couchbase::Packet
Constants
- CMD_ADD
- CMD_ADDQ
- CMD_APPEND
- CMD_APPENDQ
- CMD_DECREMENT
- CMD_DECREMENTQ
- CMD_DELETE
- CMD_DELETEQ
- CMD_FLUSH
- CMD_FLUSHQ
- CMD_GAT
- CMD_GATQ
- CMD_GET
- CMD_GETK
- CMD_GETKQ
- CMD_GETQ
- CMD_INCREMENT
- CMD_INCREMENTQ
- CMD_NOOP
- CMD_PREPEND
- CMD_PREPENDQ
- CMD_QUIT
- CMD_QUITQ
- CMD_REPLACE
- CMD_REPLACEQ
- CMD_SASL_AUTH
- CMD_SASL_LIST_MECHS
- CMD_SASL_STEP
- CMD_SET
- CMD_SETQ
- CMD_STAT
- CMD_TOUCH
- CMD_VERBOSITY
- CMD_VERSION
- REQUEST_HEADER_FMT
uint8_t magic uint8_t opcode uint16_t keylen uint8_t extlen uint8_t datatype uint16_t vbucket uint32_t bodylen uint32_t opaque uint64_t cas
- REQUEST_HEADER_SIZE
- RESPONSE_HEADER_FMT
Sum of lengths of fields below
uint8_t magic uint8_t opcode uint16_t keylen uint8_t extlen uint8_t datatype uint16_t status uint32_t bodylen uint32_t opaque uint64_t cas
- RESPONSE_HEADER_SIZE
Public Class Methods
build(opaque, vbucket, opcode, *args)
click to toggle source
# File lib/em-couchbase/packet.rb, line 85 def self.build(opaque, vbucket, opcode, *args) case opcode when :set key, value, flags, expiration, cas = args.shift(5) bodylen = key.size + value.size + 8 [ 0x80, # uint8_t magic CMD_SET, # uint8_t opcode key.size, # uint16_t keylen 8, # uint8_t extlen (flags + expiration) 0, # uint8_t datatype vbucket, # uint16_t vbucket bodylen, # uint32_t bodylen opaque || 0, # uint32_t opaque cas || 0, # uint64_t cas flags || 0, # uint32_t flags expiration || 0, # uint32_t expiration key, value ].pack("#{REQUEST_HEADER_FMT}NNa*a*") when :get key = args.shift bodylen = key.size [ 0x80, # uint8_t magic CMD_GET, # uint8_t opcode key.size, # uint16_t keylen 0, # uint8_t extlen 0, # uint8_t datatype vbucket, # uint16_t vbucket bodylen, # uint32_t bodylen opaque || 0, # uint32_t opaque 0, # uint64_t cas key ].pack("#{REQUEST_HEADER_FMT}a*") when :incr, :decr cmd_id = opcode == :incr ? CMD_INCREMENT : CMD_DECREMENT key, delta, initial, expiration, cas = args.shift(5) delta ||= 1 initial ||= 0 bodylen = key.size + 20 [ 0x80, # uint8_t magic cmd_id, # uint8_t opcode key.size, # uint16_t keylen 20, # uint8_t extlen (delta + initial + expiration) 0, # uint8_t datatype vbucket, # uint16_t vbucket bodylen, # uint32_t bodylen opaque || 0, # uint32_t opaque cas || 0, # uint64_t cas delta >> 32, # uint64_t delta & 0xffffffff, # initial >> 32, # uint64_t initial & 0xffffffff, # expiration || 0, # uint32_t key ].pack("#{REQUEST_HEADER_FMT}NNNNNa*") when :sasl_auth mech, username, password = args.shift(3) value = "\0#{username}\0#{password}" bodylen = mech.size + value.size [ 0x80, # uint8_t magic CMD_SASL_AUTH, # uint8_t opcode mech.size, # uint16_t keylen 0, # uint8_t extlen 0, # uint8_t datatype 0, # uint16_t vbucket bodylen, # uint32_t bodylen 0, # uint32_t opaque 0, # uint64_t cas mech, value ].pack("#{REQUEST_HEADER_FMT}a*a*") else raise Couchbase::Error::UnknownCommand, [opcode, *args].inspect end end
parse(data) { |operation, opaque, result| ... }
click to toggle source
# File lib/em-couchbase/packet.rb, line 165 def self.parse(data) while data.length >= RESPONSE_HEADER_SIZE header = data[0...RESPONSE_HEADER_SIZE] ( magic, opcode, keylen, extlen, datatype, status, bodylen, opaque, cas ) = header.unpack(RESPONSE_HEADER_FMT) if magic != 0x81 fail Couchbase::Error::Protocol.new "Broken packet: #{header.inspect}" end if data.size < bodylen + RESPONSE_HEADER_SIZE return # need moar data else data[0...RESPONSE_HEADER_SIZE] = "" end ext = data[0...extlen] data[0...extlen] = "" key = data[0...keylen] data[0...keylen] = "" vallen = bodylen - extlen - keylen body = data[0...vallen] data[0...vallen] = "" result = Result.new(:key => key, :value => body, :status => status, :cas => cas) case opcode when CMD_SET result.operation = :set when CMD_SASL_AUTH result.operation = :sasl_auth when CMD_GET result.operation = :get result.flags, _ = ext.unpack("N") when CMD_INCREMENT result.operation = :incr hi, lo = result.value.unpack("NN") result.value = hi << 32 | lo when CMD_DECREMENT result.operation = :decr hi, lo = result.value.unpack("NN") result.value = hi << 32 | lo else raise Couchbase::Error::UnknownCommand, header.inspect end if error_class = Couchbase::Error.map_error_code(status) result.error = error_class.new(body) result.error.error = status result.error.key = key result.error.cas = cas result.error.operation = result.operation end yield(result.operation, opaque, result) end end