module Transit::Marshaler::Base

@api private

Public Instance Methods

build_handlers(custom_handlers) click to toggle source
# File lib/transit/marshaler/base.rb, line 55
def build_handlers(custom_handlers)
  if HANDLER_CACHE.has_key?(custom_handlers)
    HANDLER_CACHE[custom_handlers]
  else
    handlers = WriteHandlers::DEFAULT_WRITE_HANDLERS.dup
    handlers.merge!(custom_handlers) if custom_handlers
    HANDLER_CACHE[custom_handlers] = handlers
    handlers
  end
end
emit_array(a, cache) click to toggle source
# File lib/transit/marshaler/base.rb, line 104
def emit_array(a, cache)
  emit_array_start(a.size)
  a.each {|e| marshal(e, false, cache)}
  emit_array_end
end
emit_boolean(handler, b, as_map_key, cache) click to toggle source
# File lib/transit/marshaler/base.rb, line 96
def emit_boolean(handler, b, as_map_key, cache)
  as_map_key ? emit_string(ESC, "?", handler.string_rep(b), true, cache) : emit_value(b)
end
emit_double(d, as_map_key, cache) click to toggle source
# File lib/transit/marshaler/base.rb, line 100
def emit_double(d, as_map_key, cache)
  as_map_key ? emit_string(ESC, "d", d, true, cache) : emit_value(d)
end
emit_encoded(handler, tag, obj, as_map_key, cache) click to toggle source
# File lib/transit/marshaler/base.rb, line 126
def emit_encoded(handler, tag, obj, as_map_key, cache)
  if tag.length == 1
    rep = handler.rep(obj)
    if String === rep
      emit_string(ESC, tag, rep, as_map_key, cache)
    elsif as_map_key || @prefer_strings
      if str_rep = handler.string_rep(obj)
        emit_string(ESC, tag, str_rep, as_map_key, cache)
      else
        raise "Cannot be encoded as String: " + {:tag => tag, :rep => rep, :obj => obj}.to_s
      end
    else
      emit_tagged_value(tag, handler.rep(obj), cache)
    end
  elsif as_map_key
    raise "Cannot be used as a map key: " + {:tag => tag, :rep => rep, :obj => obj}.to_s
  else
    emit_tagged_value(tag, handler.rep(obj), cache)
  end
end
emit_map(m, cache) click to toggle source
# File lib/transit/marshaler/base.rb, line 110
def emit_map(m, cache)
  emit_map_start(m.size)
  m.each do |k,v|
    marshal(k, true, cache)
    marshal(v, false, cache)
  end
  emit_map_end
end
emit_nil(as_map_key, cache) click to toggle source
# File lib/transit/marshaler/base.rb, line 83
def emit_nil(as_map_key, cache)
  as_map_key ? emit_string(ESC, "_", nil, true, cache) : emit_value(nil)
end
emit_string(prefix, tag, value, as_map_key, cache) click to toggle source
# File lib/transit/marshaler/base.rb, line 87
def emit_string(prefix, tag, value, as_map_key, cache)
  encoded = "#{prefix}#{tag}#{value}"
  if cache.cacheable?(encoded, as_map_key)
    emit_value(cache.write(encoded), as_map_key)
  else
    emit_value(encoded, as_map_key)
  end
end
emit_tagged_value(tag, rep, cache) click to toggle source
# File lib/transit/marshaler/base.rb, line 119
def emit_tagged_value(tag, rep, cache)
  emit_array_start(2)
  emit_string(ESC, "#", tag, false, cache)
  marshal(rep, false, cache)
  emit_array_end
end
escape(s) click to toggle source
# File lib/transit/marshaler/base.rb, line 75
def escape(s)
  if s.start_with?(SUB,ESC,RES) && s != "#{SUB} "
    "#{ESC}#{s}"
  else
    s
  end
end
find_handler(obj) click to toggle source
# File lib/transit/marshaler/base.rb, line 66
def find_handler(obj)
  obj.class.ancestors.each do |a|
    if handler = @handlers[a]
      return handler
    end
  end
  nil
end
marshal(obj, as_map_key, cache) click to toggle source
# File lib/transit/marshaler/base.rb, line 147
def marshal(obj, as_map_key, cache)
  if handler = find_handler(obj)
    tag = handler.tag(obj)
    case tag
    when "_"
      emit_nil(as_map_key, cache)
    when "?"
      emit_boolean(handler, obj, as_map_key, cache)
    when "s"
      emit_string(nil, nil, escape(handler.rep(obj)), as_map_key, cache)
    when "i"
      emit_int(tag, handler.rep(obj), as_map_key, cache)
    when "d"
      emit_double(handler.rep(obj), as_map_key, cache)
    when "'"
      emit_tagged_value(tag, handler.rep(obj), cache)
    when "array"
      emit_array(handler.rep(obj), cache)
    when "map"
      emit_map(handler.rep(obj), cache)
    else
      emit_encoded(handler, tag, obj, as_map_key, cache)
    end
  else
    raise "Can not find a Write Handler for #{obj.inspect}."
  end
end
marshal_top(obj, cache=RollingCache.new) click to toggle source
# File lib/transit/marshaler/base.rb, line 175
def marshal_top(obj, cache=RollingCache.new)
  if handler = find_handler(obj)
    if tag = handler.tag(obj)
      if tag.length == 1
        marshal(TaggedValue.new(QUOTE, obj), false, cache)
      else
        marshal(obj, false, cache)
      end
      flush
    else
      raise "Handler must provide a non-nil tag: #{handler.inspect}"
    end
  else
    raise "Can not find a Write Handler for #{obj.inspect}."
  end
end
parse_options(opts) click to toggle source
# File lib/transit/marshaler/base.rb, line 48
def parse_options(opts)
  MUTEX.synchronize do
    @handlers = build_handlers(opts[:handlers])
  end
  @handlers.values.each { |h| h.handlers=(@handlers) if h.respond_to?(:handlers=) }
end