Class: Memcached::Packet

Inherits:
Object
  • Object
show all
Defined in:
lib/remcached/packet.rb

Direct Known Subclasses

Request, Response

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(contents = {}) ⇒ Packet

Initialize with fields



7
8
9
10
11
12
13
# File 'lib/remcached/packet.rb', line 7

def initialize(contents={})
  @contents = contents
  (self.class.fields +
   self.class.extras).each do |name,fmt,default|
    self[name] ||= default if default
  end
end

Class Method Details

.extra(name, packed, default = nil) ⇒ Object

Define an extra for subclasses



47
48
49
50
51
52
# File 'lib/remcached/packet.rb', line 47

def self.extra(name, packed, default=nil)
  instance_eval do
    @extras ||= []
    @extras << [name, packed, default]
  end
end

.extrasObject

Extras of this class



56
57
58
59
60
61
# File 'lib/remcached/packet.rb', line 56

def self.extras
  parent_class = ancestors[1]
  parent_extras = parent_class.respond_to?(:extras) ? parent_class.extras : []
  class_extras = instance_eval { @extras || [] }
  parent_extras + class_extras
end

.field(name, packed, default = nil) ⇒ Object

Define a field for subclasses



29
30
31
32
33
34
# File 'lib/remcached/packet.rb', line 29

def self.field(name, packed, default=nil)
  instance_eval do
    @fields ||= []
    @fields << [name, packed, default]
  end
end

.fieldsObject

Fields of parent and this class



38
39
40
41
42
43
# File 'lib/remcached/packet.rb', line 38

def self.fields
  parent_class = ancestors[1]
  parent_fields = parent_class.respond_to?(:fields) ? parent_class.fields : []
  class_fields = instance_eval { @fields || [] }
  parent_fields + class_fields
end

.parse_header(buf) ⇒ Object

Build a packet by parsing header fields



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/remcached/packet.rb', line 65

def self.parse_header(buf)
  pack_fmt = fields.collect { |name,fmt,default| fmt }.join
  values = PackArray.unpack(buf, pack_fmt)

  contents = {}
  fields.each do |name,fmt,default|
    contents[name] = values.shift
  end

  new contents
end

Instance Method Details

#[](field) ⇒ Object

Get field



17
18
19
# File 'lib/remcached/packet.rb', line 17

def [](field)
  @contents[field]
end

#[]=(field, value) ⇒ Object

Set field



23
24
25
# File 'lib/remcached/packet.rb', line 23

def []=(field, value)
  @contents[field] = value
end

#parse_body(buf) ⇒ Object

Parse body of packet when the :total_body_length field is known by header. Pass it at least total_body_length bytes.

return
String

remaining bytes



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/remcached/packet.rb', line 82

def parse_body(buf)
  if self[:total_body_length] < 1
    buf, rest = "", buf
  else
    buf, rest = buf[0..(self[:total_body_length] - 1)], buf[self[:total_body_length]..-1]
  end

  if self[:extras_length] > 0
    self[:extras] = parse_extras(buf[0..(self[:extras_length]-1)])
  else
    self[:extras] = parse_extras("")
  end
  if self[:key_length] > 0
    self[:key] = buf[self[:extras_length]..(self[:extras_length]+self[:key_length]-1)]
  else
    self[:key] = ""
  end
  self[:value] = buf[(self[:extras_length]+self[:key_length])..-1]

  rest
end

#to_sObject

Serialize for wire



106
107
108
109
110
111
112
113
114
# File 'lib/remcached/packet.rb', line 106

def to_s
  extras_s = extras_to_s
  key_s = self[:key].to_s
  value_s = self[:value].to_s
  self[:extras_length] = extras_s.length
  self[:key_length] = key_s.length
  self[:total_body_length] = extras_s.length + key_s.length + value_s.length
  header_to_s + extras_s + key_s + value_s
end