lib/remcached/packet.rb in astro-remcached-0.2.2 vs lib/remcached/packet.rb in astro-remcached-0.3.0

- old
+ new

@@ -1,51 +1,69 @@ require 'remcached/pack_array' module Memcached class Packet + ## + # Initialize with fields def initialize(contents={}) @contents = contents (self.class.fields + self.class.extras).each do |name,fmt,default| self[name] ||= default if default end end + ## + # Get field def [](field) @contents[field] end + ## + # Set field def []=(field, value) @contents[field] = value end - # Define fields for subclasses + ## + # Define a field for subclasses def self.field(name, packed, default=nil) instance_eval do @fields ||= [] @fields << [name, packed, default] end end + ## + # Fields of parent and this class 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 + ## + # Define an extra for subclasses def self.extra(name, packed, default=nil) instance_eval do @extras ||= [] @extras << [name, packed, default] end end + ## + # Extras of this class def self.extras - instance_eval { @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 + ## + # Build a packet by parsing header fields def self.parse_header(buf) pack_fmt = fields.collect { |name,fmt,default| fmt }.join values = PackArray.unpack(buf, pack_fmt) contents = {} @@ -54,11 +72,15 @@ end new contents end - # Return remaining bytes + ## + # 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 def parse_body(buf) buf, rest = buf[0..(self[:total_body_length] - 1)], buf[self[:total_body_length]..-1] if self[:extras_length] > 0 self[:extras] = parse_extras(buf[0..(self[:extras_length]-1)]) @@ -73,10 +95,12 @@ self[:value] = buf[(self[:extras_length]+self[:key_length])..-1] rest end + ## + # Serialize for wire 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 @@ -152,40 +176,64 @@ me[:magic] == 0x80 ? me : nil end class Get < Request def initialize(contents) - super(contents.merge :opcode=>Commands::GET) + super({:opcode=>Commands::GET}.merge(contents)) end + + class Quiet < Get + def initialize(contents) + super({:opcode=>Commands::GETQ}.merge(contents)) + end + end end class Add < Request extra :flags, 'N', 0 extra :expiration, 'N', 0 def initialize(contents) - super(contents.merge :opcode=>Commands::ADD) + super({:opcode=>Commands::ADD}.merge(contents)) end + + class Quiet < Add + def initialize(contents) + super({:opcode=>Commands::ADDQ}.merge(contents)) + end + end end class Set < Request extra :flags, 'N', 0 extra :expiration, 'N', 0 def initialize(contents) - super(contents.merge :opcode=>Commands::SET) + super({:opcode=>Commands::SET}.merge(contents)) end + + class Quiet < Set + def initialize(contents) + super({:opcode=>Commands::SETQ}.merge(contents)) + end + end end class Delete < Request def initialize(contents) - super(contents.merge :opcode=>Commands::DELETE) + super({:opcode=>Commands::DELETE}.merge(contents)) end + + class Quiet < Delete + def initialize(contents) + super({:opcode=>Commands::DELETEQ}.merge(contents)) + end + end end class Stats < Request def initialize(contents) - super(contents.merge :opcode=>Commands::STAT) + super({:opcode=>Commands::STAT}.merge(contents)) end end end ##