class Riddl::Wrapper::MessageParser

Public Class Methods

new(params,headers) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 4
def initialize(params,headers)
  #{{{
  @mist = params
  @mistp = 0
  @headp = {}
  headers.each do |k,v|
    if v.nil?
      @headp[k.name.upcase.gsub(/\-/,'_')] = k.value
    else
      @headp[k.upcase.gsub(/\-/,'_')] = v
    end
  end

  @numparams = 0
  #}}}
end

Public Instance Methods

check(what,ignore_name=false) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 21
def check(what,ignore_name=false)
  #{{{
  # reset for subsequent calls
  @mistp = 0
  @numparams = 0

  # out not available
  return true if what.nil? && @mist.empty?
  return false if what.nil?

  # do it
  m  = what.content.root

  m.find("des:header").each do |h|
    return false unless header h
  end

  if ignore_name
    # if only one parameter, ignore the name
    @numparams = m.find("count(//des:parameter)").to_i
  end

  m.find("des:*[not(name()='header')]").each do |p|
    return false unless send p.qname.to_s, p
  end

  @mist.count == @mistp
  #}}}
end
choice(a) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 117
def choice(a)
  #{{{
  a.find("des:*").each do |p|
    return true if send p.qname.to_s, p
  end
  false
  #}}}
end
group(a) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 126
def group(a)
  #{{{
  tistp = @mistp
  success = true
  a.find("des:*").each do |p|
    unless send p.qname.to_s, p
      success = false
      break
    end
  end
  if success
    true
  else
    @mistp = tistp
    false
  end
  #}}}
end
oneOrMore(a) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 91
def oneOrMore(a)
  #{{{
  tistp = @mistp
  ncounter = 0
  begin
    counter,length = traverse_simple(a,true)
    ncounter += 1 if counter == length
  end while counter == length && @mistp < @mist.length
  if ncounter > 0
    true
  else
    @mistp = tistp
    false
  end
  #}}}
end
optional(a) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 145
def optional(a)
  #{{{
  return true if @mistp >= @mist.length

  tistp = @mistp
  counter, length = traverse_simple(a,true)

  if counter == 0 || counter == length
    true
  else
    @mistp = tistp
    false
  end
  #}}}
end
traverse_simple(a,single_optional_protection=false) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 172
def traverse_simple(a,single_optional_protection=false)
  #{{{
  tistp = @mistp
  nodes = a.find("des:*")
  counter = 0
  lastname = ''
  nodes.each do |p|
    lastname = p.qname.to_s
    counter += 1 if send lastname, p
  end
  if single_optional_protection && lastname == 'optional' && tistp == @mistp
    [0,-1]
  else
    [counter,nodes.length]
  end
  #}}}
end
zeroOrMore(a) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 108
def zeroOrMore(a)
  #{{{
  begin
    counter,length = traverse_simple(a,true)
  end while counter == length && @mistp < @mist.length
  true
  #}}}
end

Private Instance Methods

header(a) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 161
def header(a)
  #{{{
  name = a.attributes['name'].upcase.sub(/\-/,'_')
  if @headp[name]
    return match_simple(a,@headp[name])
  end
  false
  #}}}
end
match_mimetype(a,b) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 218
def match_mimetype(a,b)
  if (a.attributes['mimetype'] == '*' || b.mimetype == a.attributes['mimetype'])
    true
  else
    ma = a.attributes['mimetype'].split('/')
    mb = b.mimetype.split('/')
    if ma.length == 2 && mb.length == 2 && ((ma[0] == mb[0] && ma[1] == '*') || (ma[1] == mb[1] && ma[0] == '*'))
      true
    else
      false
    end
  end
end
match_simple(a,b) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 190
def match_simple(a,b)
  #{{{
  if a.attributes['fixed']
    a.attributes['fixed'] == b
  else
    value = XML::Smart::string("<check/>")
    value.root.text = b
    if a.find('des:choice').length > 0
      type = XML::Smart::string(CHECK_CHOICE)
      data = type.root
    else
      type = XML::Smart::string(CHECK_DATA)
      data = type.root.children[0]
      data.attributes['type'] = a.attributes['type']
    end
    a.children.each do |e|
      unless e.class == XML::Smart::Dom::Text
        e = e.to_doc.root
        e.namespaces[nil] = 'http://relaxng.org/ns/structure/1.0'
        data.add e
      end
    end
    value.validate_against type
  end
  #}}}
end
parameter(a) click to toggle source
# File lib/ruby/riddl/wrapper/messageparser.rb, line 51
def parameter(a)
  #{{{
  return false if @mistp >= @mist.length
  b = @mist[@mistp]

  if b.class == Riddl::Parameter::Simple && (a.attributes['fixed'] || a.attributes['type'])
    b.name = a.attributes['name'] if @numparams == 1
    if (b.name == a.attributes['name'] || a.attributes['name'] == '*') && match_simple(a,b.value)
      @mistp += 1
      return true
    else
      return false
    end
  end
  if b.class == Riddl::Parameter::Complex && a.attributes['mimetype']
    b.name = a.attributes['name'] if @numparams == 1
    if (b.name == a.attributes['name'] || a.attributes['name'] == '*') && match_mimetype(a,b)
      if a.attributes['handler']
        if Riddl::Handlers::handlers[a.attributes['handler']]
          success = Riddl::Handlers::handlers[a.attributes['handler']].handle(b.value,a.children.map{|e|e.dump}.join)
          b.value.rewind if b.value.respond_to?(:rewind)
          if success
            @mistp += 1
            return true
          end
        else
          # handler not found leads to an error
          return false
        end
      else
        @mistp += 1
        return true
      end
    end
  end
  false
  #}}}
end