class PHPSession::Decoder

Attributes

array[RW]
buffer[RW]
encoding[R]
encoding_option[R]
stack[RW]
state[RW]

Public Class Methods

decode(string, encoding = nil, encoding_option = {}) click to toggle source
# File lib/php_session/decoder.rb, line 6
def self.decode(string, encoding = nil, encoding_option = {})
  if string.nil?
    string = ""
  end
  string.chomp!
  self.new(string, encoding, encoding_option).decode
end
new(string, encoding, encoding_option) click to toggle source
# File lib/php_session/decoder.rb, line 14
def initialize(string, encoding, encoding_option)
  @encoding = encoding
  @encoding_option = encoding_option
  @buffer = string
  @data = {}
  @state = State::VarName
  @stack = []
  @array = [] # array of array
end

Public Instance Methods

consume_array() click to toggle source
# File lib/php_session/decoder.rb, line 46
def consume_array
  @array[0][:consumed_count] += 1
end
decode() click to toggle source
# File lib/php_session/decoder.rb, line 24
def decode
  loop do
    break if @buffer.size == 0
    @state.parse(self)
  end
  @data
end
elements_count() click to toggle source
# File lib/php_session/decoder.rb, line 40
def elements_count
  @array[0][:length]
end
extract_stack(count) click to toggle source
# File lib/php_session/decoder.rb, line 53
def extract_stack(count)
  poped = @stack[(@stack.size - count) .. -1]
  @stack = @stack.slice(0, @stack.size - count)
  poped
end
finished_array() click to toggle source
# File lib/php_session/decoder.rb, line 49
def finished_array
  @array[0][:length] * 2 == @array[0][:consumed_count]
end
in_array() click to toggle source
# File lib/php_session/decoder.rb, line 43
def in_array
  @array.size > 0
end
process_empty_array_value() click to toggle source
# File lib/php_session/decoder.rb, line 59
def process_empty_array_value
  array_which_finished  = @array.shift

  klass  = array_which_finished[:klass];
  if klass
    struct = define_or_find_struct(klass, [])
    process_value(struct.new)
  else
    process_value({})
  end
  @state = State::ArrayEnd
end
process_value(value) click to toggle source
# File lib/php_session/decoder.rb, line 71
def process_value(value)
  if in_array
    @stack.push(value)
    consume_array

    if finished_array
      array_which_finished  = @array.shift
      key_values_array = extract_stack(array_which_finished[:length] * 2)
      key_values = key_values_array.group_by.with_index{|el, i| i%2 == 0 ? :key : :value}

      klass  = array_which_finished[:klass];
      if klass
        struct = define_or_find_struct(klass, key_values[:key])
        process_value(struct.new(*key_values[:value]))
        @state = State::ArrayEnd
        @state.parse(self)
      else
        hash = {}
        key_values_array.each_slice(2) do |kv|
          hash[kv[0]] = kv[1]
        end
        process_value(hash)

        @state = State::ArrayEnd
        @state.parse(self)
      end
    else
      @state = State::VarType
    end
  else
    varname = @stack.pop;
    @data[varname] = value;
    @state = State::VarName
  end
end
start_array(length, klass = nil) click to toggle source
# File lib/php_session/decoder.rb, line 32
def start_array(length, klass = nil)
  # [length, comsumed?, class]
  @array.unshift({
    :length => length,
    :consumed_count => 0,
    :klass => klass
  })
end

Private Instance Methods

define_or_find_struct(name, properties) click to toggle source
# File lib/php_session/decoder.rb, line 109
def define_or_find_struct(name, properties)
  if Struct.const_defined?(name)
    struct = Struct.const_get(name)
    if struct.members.sort != properties.map(&:to_sym).sort
      raise Errors::ParseError, "objects properties don't match with the other object which has same class"
    end
  else
    struct = Struct.new(name, *properties)
  end
  struct
end