class Cassandra::DynamicComposite

Attributes

types[RW]

Public Class Methods

new(*parts) click to toggle source
   # File lib/cassandra/dynamic_composite.rb
 5 def initialize(*parts)
 6   return if parts.empty?
 7 
 8   options = {}
 9   if parts.last.is_a?(Hash)
10     options = parts.pop
11   end
12   @column_slice = options[:slice]
13   raise ArgumentError if @column_slice != nil && ![:before, :after].include?(@column_slice)
14 
15   if parts.length == 1 && parts[0].instance_of?(self.class)
16     @column_slice = parts[0].column_slice
17     @parts = parts[0].parts
18     @types = parts[0].types
19   elsif parts.length == 1 && parts[0].instance_of?(String) && @column_slice.nil? && try_packed_composite(parts[0])
20     @hash = parts[0].hash
21   else
22     @types, @parts = parts.transpose
23   end
24 end

Public Instance Methods

fast_unpack(packed_string) click to toggle source
   # File lib/cassandra/dynamic_composite.rb
47 def fast_unpack(packed_string)
48   @hash = packed_string.hash
49 
50   @types = []
51   @parts = []
52 
53   offset = 0
54   length = nil
55   while offset < packed_string.length
56     if packed_string[offset].ord & 0x80 != 0
57       @types << packed_string[offset+1]
58       offset += 2
59     else
60       length = packed_string.slice(offset, 2).unpack('n')[0]
61       offset += 2
62       @types << packed_string.slice(offset, length)
63       offset += length
64     end
65     length = packed_string.slice(offset, 2).unpack('n')[0]
66     offset += 2
67     @parts << packed_string.slice(offset, length)
68     offset += length + 1
69   end
70 
71   @column_slice = :after if packed_string[-1] == "\x01"
72   @column_slice = :before if packed_string[-1] == "\xFF"
73 end
pack() click to toggle source
   # File lib/cassandra/dynamic_composite.rb
26 def pack
27   packed_parts = @parts.map do |part|
28     [part.length].pack('n') + part + "\x00"
29   end
30 
31   if @column_slice
32     part = @parts[-1]
33     packed_parts[-1] = [part.length].pack('n') + part + slice_end_of_component
34   end
35 
36   packed_types = @types.map do |type|
37     if type.length == 1
38       [0x8000 | type[0].ord].pack('n')
39     else
40       [type.length].pack('n') + type
41     end
42   end
43 
44   return packed_types.zip(packed_parts).flatten.join('')
45 end

Private Instance Methods

try_packed_composite(packed_string) click to toggle source
    # File lib/cassandra/dynamic_composite.rb
 76 def try_packed_composite(packed_string)
 77   types = []
 78   parts = []
 79   end_of_component = nil
 80   offset = 0
 81 
 82   read_bytes = proc do |length|
 83     return false if offset + length > packed_string.length
 84     out = packed_string.slice(offset, length)
 85     offset += length
 86     out
 87   end
 88 
 89   while offset < packed_string.length
 90     header = read_bytes.call(2).unpack('n')[0]
 91     is_alias = header & 0x8000 != 0
 92     if is_alias
 93       alias_char = (header & 0xFF).chr
 94       types << alias_char
 95     else
 96       length = header
 97       return false if length.nil? || length + offset > packed_string.length
 98       type = read_bytes.call(length)
 99       types << type
100     end
101     length = read_bytes.call(2).unpack('n')[0]
102     return false if length.nil? || length + offset > packed_string.length
103     parts << read_bytes.call(length)
104     end_of_component = read_bytes.call(1)
105     if offset < packed_string.length
106       return false if end_of_component != "\x00"
107     end
108   end
109   @column_slice = :after if end_of_component == "\x01"
110   @column_slice = :before if end_of_component == "\xFF"
111   @types = types
112   @parts = parts
113   @hash = packed_string.hash
114 
115   return true
116 end