summaryrefslogtreecommitdiff
path: root/trunk/qpid/ruby/lib/qpid/spec010.rb
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/qpid/ruby/lib/qpid/spec010.rb')
-rw-r--r--trunk/qpid/ruby/lib/qpid/spec010.rb485
1 files changed, 0 insertions, 485 deletions
diff --git a/trunk/qpid/ruby/lib/qpid/spec010.rb b/trunk/qpid/ruby/lib/qpid/spec010.rb
deleted file mode 100644
index 3e54115087..0000000000
--- a/trunk/qpid/ruby/lib/qpid/spec010.rb
+++ /dev/null
@@ -1,485 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-require "qpid/spec"
-require 'pathname'
-require 'fileutils'
-
-module Qpid::Spec010
-
- include Qpid::Spec
-
- # XXX: workaround for ruby bug/missfeature
- Reference = Reference
- Loader = Loader
-
- class Spec
-
- ENCODINGS = {
- String => "str16",
- Fixnum => "int64",
- Bignum => "int64",
- Float => "float",
- NilClass => "void",
- Array => "list",
- Hash => "map"
- }
-
- fields(:major, :minor, :port, :children)
-
- def init()
- @controls = {}
- @commands = {}
- @structs = {}
- @types = {}
- children.each {|c|
- case c
- when Control
- @controls[c.code] = c
- when Command
- @commands[c.code] = c
- when Struct
- @structs[c.code] = c
- when Type
- @types[c.code] = c unless c.code.nil?
- end
- }
- end
-
- attr_reader :controls, :commands, :structs, :types
-
- def [](key)
- return @children[key]
- end
-
- def encoding(klass)
- if ENCODINGS.has_key?(klass)
- return self[ENCODINGS[klass]]
- end
- for base in klass.__bases__
- result = encoding(base)
- return result unless result.nil?
- end
- end
-
- def inspect; "spec"; end
- end
-
- class Constant
-
- fields(:name, :value)
-
- attr :parent, true
-
- end
-
- class Type
-
- fields(:name, :code, :fixed, :variable)
-
- attr :parent, true
-
- def present?(value)
- if @fixed == 0
- return value
- else
- return !value.nil?
- end
- end
-
- def encode(codec, value)
- codec.send("write_#{name}", value)
- end
-
- def decode(codec)
- return codec.send("read_#{name}")
- end
-
- def inspect; name; end
-
- end
-
- class Domain < Type
-
- fields(:name, :type, :enum)
-
- attr :parent, true
-
- def encode(codec, value)
- @type.encode(codec, value)
- end
-
- def decode(codec)
- return @type.decode(codec)
- end
-
- end
-
- class Enum
- fields(:choices)
-
- def [](choice)
- case choice
- when String
- choice = choice.to_sym
- return choices.find { |c| c.name == choice }
- when Symbol
- return choices.find { |c| c.name == choice }
- else
- return choices.find { |c| c.value == choice }
- end
- end
-
- def method_missing(name, *args)
- raise ArgumentError.new("wrong number of arguments") unless args.empty?
- return self[name].value
- end
-
- end
-
- class Choice
- fields(:name, :value)
- end
-
- class Composite
-
- fields(:name, :code, :size, :pack, :fields)
-
- attr :parent, true
-
- # Python calls this 'new', but that has special meaning in Ruby
- def create(*args)
- return Qpid::struct(self, *args)
- end
-
- def decode(codec)
- codec.read_size(@size)
- codec.read_uint16() unless @code.nil?
- return Qpid::struct(self, self.decode_fields(codec))
- end
-
- def decode_fields(codec)
- flags = 0
- pack.times {|i| flags |= (codec.read_uint8() << 8*i)}
-
- result = {}
-
- fields.each_index {|i|
- f = @fields[i]
- if flags & (0x1 << i) != 0
- result[f.name] = f.type.decode(codec)
- else
- result[f.name] = nil
- end
- }
-
- return result
- end
-
- def encode(codec, value)
- sc = Qpid::StringCodec.new(@spec)
- sc.write_uint16(@code) unless @code.nil?
- encode_fields(sc, value)
- codec.write_size(@size, sc.encoded.size)
- codec.write(sc.encoded)
- end
-
- def encode_fields(codec, values)
- # FIXME: This could be written cleaner using select
- # instead of flags
- flags = 0
- fields.each_index do |i|
- f = fields[i]
- flags |= (0x1 << i) if f.type.present?(values[f.name])
- end
-
- pack.times { |i| codec.write_uint8((flags >> 8*i) & 0xFF) }
-
- fields.each_index do |i|
- f = fields[i]
- f.type.encode(codec, values[f.name]) if flags & (0x1 << i) != 0
- end
- end
-
- def inspect; name; end
-
- end
-
- class Field
-
- fields(:name, :type, :exceptions)
-
- def default()
- return nil
- end
-
- end
-
- class Struct < Composite
-
- def present?(value)
- return !value.nil?
- end
-
- end
-
- class Action < Composite; end
-
- class Control < Action
-
- def segment_type
- @parent[:segment_type].enum[:control].value
- end
-
- def track
- @parent[:track].enum[:control].value
- end
-
- end
-
- class Command < Action
-
- attr_accessor :payload, :result
-
- def segment_type
- @parent["segment_type"].enum["command"].value
- end
-
- def track
- @parent["track"].enum["command"].value
- end
-
- end
-
- class Doc
- fields(:type, :title, :text)
- end
-
- class Loader010 < Loader
-
- def initialize()
- super()
- end
-
- def klass
- cls = element
- until cls.nil?
- break if cls.name == "class"
- cls = cls.parent
- end
- return cls
- end
-
- def scope
- if element.name == "struct"
- return nil
- else
- return class_name
- end
- end
-
- def class_name
- cls = klass
- if cls.nil?
- return nil
- else
- return parse_name(cls.attributes["name"].strip)
- end
- end
-
- def class_code
- cls = klass
- if cls.nil?
- return 0
- else
- return parse_int(cls.attributes["code"].strip)
- end
- end
-
- def parse_decl(value)
- name = parse_name(value)
-
- s = scope
- if s.nil?
- return name
- else
- return :"#{s}_#{name}"
- end
- end
-
- def parse_code(value)
- c = parse_int(value)
- if c.nil?
- return nil
- else
- return c | (class_code << 8)
- end
- end
-
- def parse_type(value)
- name = parse_name(value.sub(".", "_"))
- cls = class_name
- return Reference.new {|spec|
- candidates = [name]
- candidates << :"#{cls}_#{name}" unless cls.nil?
- for c in candidates
- child = spec[c]
- break unless child.nil?
- end
- if child.nil?
- raise Exception.new("unresolved type: #{name}")
- else
- child
- end
-}
- end
-
- def load_amqp()
- children = nil
-
- for s in ["constant", "type", "domain", "struct", "control",
- "command"]
- ch = load(s)
- if children.nil?
- children = ch
- else
- children += ch
- end
- children += load("class/#{s}")
- end
- children += load("class/command/result/struct")
- Spec.new(attr("major", :int), attr("minor", :int), attr("port", :int),
- children)
- end
-
- def load_constant()
- Constant.new(attr("name", :decl), attr("value", :int))
- end
-
- def load_type()
- Type.new(attr("name", :decl), attr("code", :code),
- attr("fixed-width", :int), attr("variable-width", :int))
- end
-
- def load_domain()
- Domain.new(attr("name", :decl), attr("type", :type), load("enum").first)
- end
-
- def load_enum()
- Enum.new(load("choice"))
- end
-
- def load_choice()
- Choice.new(attr("name", :name), attr("value", :int))
- end
-
- def load_field()
- Field.new(attr("name", :name), attr("type", :type))
- end
-
- def load_struct()
- Struct.new(attr("name", :decl), attr("code", :code), attr("size", :int),
- attr("pack", :int), load("field"))
- end
-
- def load_action(cls)
- cls.new(attr("name", :decl), attr("code", :code), 0, 2, load("field"))
- end
-
- def load_control()
- load_action(Control)
- end
-
- def load_command()
- result = attr("type", :type, nil, "result")
- result = attr("name", :type, nil, "result/struct") if result.nil?
- segs = load("segments")
- cmd = load_action(Command)
- cmd.result = result
- cmd.payload = !segs.empty?
- return cmd
- end
-
- def load_result()
- true
- end
-
- def load_segments()
- true
- end
-
- end
-
- def self.spec_cache(specfile)
- File::join(File::dirname(__FILE__), "spec_cache",
- File::basename(specfile, ".xml") + ".rb_marshal")
- end
-
- # XXX: could be shared
- def self.load(spec = nil)
- return spec if spec.is_a?(Qpid::Spec010::Spec)
- if spec.nil?
- # FIXME: Need to add a packaging setup in here so we know where
- # the installed spec is going to be.
- specfile = nil
- if ENV['AMQP_SPEC']
- specfile = ENV['AMQP_SPEC']
- else
- require "qpid/config"
- specfile = Qpid::Config.amqp_spec
- end
- else
- specfile = spec
- end
-
- specfile_cache = spec_cache(specfile)
- # FIXME: Check that cache is newer than specfile
- if File::exist?(specfile_cache)
- begin
- spec = File::open(specfile_cache, "r") do |f|
- Marshal::load(f)
- end
- return spec
- rescue
- # Ignore, will load from XML
- end
- end
-
- doc = File::open(specfile, "r") { |f| Document.new(f) }
- spec = Loader010.new().load(doc.root)
- spec.traverse! do |o|
- if o.is_a?(Reference)
- o.resolve(spec)
- else
- o
- end
- end
-
- spec.children.each { |c| c.parent = spec }
-
- begin
- FileUtils::mkdir_p(File::dirname(specfile_cache))
- File::open(specfile_cache, "w") { |f| Marshal::dump(spec, f) }
- rescue
- # Ignore, we are fine without the cached spec
- end
- return spec
- end
-
-end