diff options
author | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
---|---|---|
committer | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
commit | 66765100f4257159622cefe57bed50125a5ad017 (patch) | |
tree | a88ee23bb194eb91f0ebb2d9b23ff423e3ea8e37 /cpp/rubygen/0-10/specification.rb | |
parent | 1aeaa7b16e5ce54f10c901d75c4d40f9f88b9db6 (diff) | |
parent | 88b98b2f4152ef59a671fad55a0d08338b6b78ca (diff) | |
download | qpid-python-rajith_jms_client.tar.gz |
Creating a branch for experimenting with some ideas for JMS client.rajith_jms_client
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/rajith_jms_client@1128369 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/rubygen/0-10/specification.rb')
-rwxr-xr-x | cpp/rubygen/0-10/specification.rb | 389 |
1 files changed, 0 insertions, 389 deletions
diff --git a/cpp/rubygen/0-10/specification.rb b/cpp/rubygen/0-10/specification.rb deleted file mode 100755 index ef193f5fd0..0000000000 --- a/cpp/rubygen/0-10/specification.rb +++ /dev/null @@ -1,389 +0,0 @@ -#!/usr/bin/env ruby -# -# 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. -# -$: << ".." # Include .. in load path -require 'cppgen' - - -# Dummy element representing an unknown struct type. -class UnknownStruct - def visitable?() true end - def fqclassname() "UnknownStruct" end -end - -# Dummy element representing a session.header field -class SessionHeaderField - def amqp2cpp() "session::Header" end - def cppname() "sessionHeader" end - def name() "session-header" end -end - -class Specification < CppGen - def initialize(outdir, amqp) - super(outdir, amqp) - @ns="qpid::amqp_#{@amqp.version.bars}" - @dir="qpid/amqp_#{@amqp.version.bars}" - end - - # domains - - def domain_h(d) - genl - typename=d.name.typename - if d.enum - scope("enum #{typename} {", "};") { - genl d.enum.choices.map { |c| - "#{c.name.constname} = #{c.value}" }.join(",\n") - } - scope("inline SerializeAs<#{typename}, uint8_t> serializable(#{typename}& e) {") { - genl "return SerializeAs<#{typename}, uint8_t>(e);" - } - else - genl "typedef #{d.amqp2cpp} #{typename};" - end - end - - def visitable?(x) x.code and x.size=="4" end - - # Used by structs, commands and controls. - def action_struct_h(x, base, consts, &block) - genl - base = visitable?(x) ? ["public #{base}"] : [] - struct(x.classname, *base) { - x.fields.each { |f| genl "#{f.amqp2cpp} #{f.cppname};" } - genl - genl "static const char* NAME;" - consts.each { - |c| genl "static const uint8_t #{c.upcase}=#{(x.send c) or 0};" - } - genl "static const uint8_t CLASS_CODE=#{x.containing_class.nsname}::CODE;" - genl "static const char* CLASS_NAME;" - ctor_decl("explicit #{x.classname}", x.parameters(true)) - - if visitable? x - genl "void accept(Visitor&);" - genl "void accept(ConstVisitor&) const;" - end - - if (x.fields.empty?) - genl "template <class S> void serialize(S&) {}" - else - scope("template <class S> void serialize(S& s) {") { - gen "s"; x.fields.each { |f| gen "(#{f.cppname})"}; genl ";" - } - end - genl - yield if block - } - case x - when AmqpCommand then packer = "CommandPacker" - when AmqpControl then packer = "Packer" - when AmqpStruct then packer = "SizedPacker" - end - genl "inline #{packer}<#{x.classname}> serializable(#{x.classname}& x) { return #{packer}<#{x.classname}>(x); }" unless x.respond_to? :pack and x.pack == "0" - genl "std::ostream& operator << (std::ostream&, const #{x.classname}&);" - genl "bool operator==(const #{x.classname}&, const #{x.classname}&);" - end - - def action_struct_cpp(x, &block) - genl - genl "const char* #{x.classname}::NAME=\"#{x.fqname}\";" - genl "const char* #{x.classname}::CLASS_NAME=#{x.containing_class.nsname}::NAME;" - genl - ctor=x.classname+"::"+x.classname - ctor_defn(ctor, x.parameters, x.initializers) {} - - if visitable? x - genl "void #{x.classname}::accept(Visitor& v) { v.visit(*this); }" - genl "void #{x.classname}::accept(ConstVisitor& v) const { v.visit(*this); }" - end - genl - scope("std::ostream& operator << (std::ostream& o, const #{x.classname}&#{"x" unless x.fields.empty?}) {") { - genl "o << \"#{x.fqname}[\";"; - x.fields.each{ |f| genl "o << \" #{f.name}=\" << x.#{f.cppname};" } - genl "o << \"]\";" - genl "return o;" - } - yield if block - end - - # structs - - def struct_h(s) action_struct_h(s, "Struct", ["size","pack","code"]); end - def struct_cpp(s) action_struct_cpp(s) end - - # command and control - - def action_h(a) - action_struct_h(a, a.base, ["code"]) { - struct("Handler") { - scope("void #{a.funcname}(", ");") { - genl a.parameters.join(",\n") - } - } - function_defn("template <class T> void invoke", ["T& target"], "const") { - genl "target.#{a.funcname}(#{a.values.join(', ')} );" - } - } - end - - def action_cpp(a) - action_struct_cpp(a) { - scope("void #{a.classname}::Handler::#{a.funcname}(", ")") { - genl a.unused_parameters.join(",\n") - } - scope { - genl "assert(0);" - genl "throw NotImplementedException(QPID_MSG(\"#{a.fqname} not implemented.\"));" - } - } - end - - # Types that must be generated early because they are used by other types. - def pregenerate?(x) not @amqp.used_by[x.fqname].empty?; end - - def pregenerate_class?(c) - c.children.select{ |t| (t.is_a? AmqpStruct or t.is_a? AmqpDomain) and pregenerate? t} - end - - # Typedefs, enums and forward declarations for classes. - def gen_specification_fwd() - h_file("#{@dir}/specification_fwd") { - include "#{@dir}/built_in_types" - namespace(@ns) { - # Top level - @amqp.domains.each { |d| - # segment-type and track are are built in - domain_h d unless ["track","segment-type"].include?(d.name) - } - each_class_ns { |c| - genl "const uint8_t CODE=#{c.code};" # class code - genl "extern const char* NAME;" - c.each_descendant { |x| - case x - when AmqpDomain then domain_h x - when AmqpStruct then genl "class #{x.classname};" - when AmqpAction then genl "class #{x.classname};" - end - } - } - } - } - end - - # Generate struct definitions into a separate header file so the - # can be included by StructHolder.h without circularity. - def gen_structs() - h_file("#{@dir}/structs") { - include "#{@dir}/specification_fwd" - include "#{@dir}/Map.h" - include "#{@dir}/Array.h" - include "#{@dir}/Struct.h" - include "#{@dir}/UnknownStruct.h" - include "#{@dir}/Packer.h" - namespace(@ns) { - each_class_ns { |c| - c.collect_all(AmqpStruct).each { |s| struct_h s } - } - } - } - - cpp_file("#{@dir}/structs") { - include "#{@dir}/structs" - include "#{@dir}/StructHolder" - namespace(@ns) { - each_class_ns { |c| - c.collect_all(AmqpStruct).each { |s| struct_cpp(s) } - } - } - } - end - - # Generate the specification files - def gen_specification() - h_file("#{@dir}/specification") { - include "#{@dir}/specification_fwd.h" - include "#{@dir}/Map.h" - include "#{@dir}/Array.h" - include "#{@dir}/UnknownType.h" - include "#{@dir}/Struct32" - include "#{@dir}/Control.h" - include "#{@dir}/Command.h" - include "#{@dir}/Packer.h" - include "<iosfwd>" - namespace(@ns) { - each_class_ns { |c| - c.collect_all(AmqpAction).each { |a| action_h a } - } - }} - - cpp_file("#{@dir}/specification") { - include "#{@dir}/specification" - include "#{@dir}/exceptions" - include "<iostream>" - ["Command","Control", "Struct"].each { |x| include "#{@dir}/Apply#{x}" } - namespace(@ns) { - each_class_ns { |c| - genl "const char* NAME=\"#{c.fqname}\";" - c.actions.each { |a| action_cpp a} - } - } - } - end - - def gen_proxy() - h_file("#{@dir}/ProxyTemplate.h") { - include "#{@dir}/specification" - namespace(@ns) { - genl "template <class F, class R=typename F::result_type>" - cpp_extern_class("QPID_COMMON_CLASS_EXTERN", "ProxyTemplate") { - public - genl "ProxyTemplate(F f=F()) : functor(f) {}" - @amqp.classes.each { |c| - c.actions.each { |a| - genl - function_defn("R #{a.funcname}", a.parameters) { - var=a.name.funcname - args = a.arguments.empty? ? "" : "("+a.arguments.join(", ")+")" - genl("#{a.fqclassname} #{var}#{args};") - genl "return functor(#{var});" - } - } - } - private - genl "F functor;" - } - } - } - end - - def visitor_interface_h(base, subs, is_const) - name="#{is_const ? 'Const' : ''}#{base}Visitor" - const=is_const ? "const " : "" - struct(name) { - genl "virtual ~#{name}() {}" - genl "typedef #{const}#{base} BaseType;" - subs.each{ |s| - genl "virtual void visit(#{const}#{s.fqclassname}&) = 0;" - }} - end - - def visitor_impl(base, subs, is_const) - name="#{is_const ? 'Const' : ''}#{base}Visitor" - const=is_const ? "const " : "" - genl "template <class F>" - struct("ApplyVisitor<#{name}, F>", "public ApplyVisitorBase<#{name}, F>") { - subs.each{ |s| - genl "virtual void visit(#{const}#{s.fqclassname}& x) { this->invoke(x); }" - }} - end - - def gen_visitor(base, subs) - h_file("#{@dir}/#{base}Visitor.h") { - include base=="Struct" ? "#{@dir}/structs" : "#{@dir}/specification" - namespace("#{@ns}") { - visitor_interface_h(base, subs, false) - visitor_interface_h(base, subs, true) - }} - - h_file("#{@dir}/Apply#{base}.h") { - include "#{@dir}/#{base}Visitor.h" - include "#{@dir}/apply.h" - namespace("#{@ns}") { - visitor_impl(base, subs, false) - visitor_impl(base, subs, true) - } - } - end - - def gen_holder(base, subs) - name=base+"Holder" - h_file("#{@dir}/#{name}") { - include "#{@dir}/Apply#{base}" - include "#{@dir}/Holder" - include base=="Struct" ? "#{@dir}/structs" : "#{@dir}/specification" - namespace(@ns){ - namespace("#{base.downcase}_max") { - genl "static const size_t MAX000=0;" - last="MAX000" - subs.each { |s| - sizeof="sizeof(#{s.fqclassname})" - genl "static const size_t #{last.succ} = #{sizeof} > #{last} ? #{sizeof} : #{last};" - last.succ! - } - genl "static const int MAX=#{last};" - } - holder_base="amqp_0_10::Holder<#{name}, #{base}, #{base.downcase}_max::MAX>" - struct("#{name}", "public #{holder_base}") { - genl "#{name}() {}" - genl "template <class T> explicit #{name}(const T& t) : #{holder_base}(t) {}" - genl "using #{holder_base}::operator=;" - genl "void set(uint8_t classCode, uint8_t code);" - } - genl - genl "std::ostream& operator<<(std::ostream& o, const #{name}& h);" - } - } - - cpp_file("#{@dir}/#{name}") { - include "#{@dir}/#{name}" - include "#{@dir}/exceptions.h" - namespace(@ns) { - genl "using framing::in_place;" - genl - scope("void #{name}::set(uint8_t classCode, uint8_t code) {") { - genl "uint16_t key=(classCode<<8)+code;" - scope ("switch(key) {") { - subs.each { |s| - genl "case 0x#{s.full_code.to_s(16)}: *this=in_place<#{s.fqclassname}>(); break;" unless (s.is_a? UnknownStruct) - } - genl "default: " - indent { - if (base=="Struct") - genl "*this=in_place<UnknownStruct>(classCode, code);" - else - genl "throw CommandInvalidException(QPID_MSG(\"Invalid class-#{base.downcase} key \" << std::hex << key));" - end - } - } - } - genl - genl "std::ostream& operator<<(std::ostream& o, const #{name}& h) { return h.get() ? (o << *h.get()) : (o << \"<empty #{name}>\"); }" - } - } - end - - def gen_visitable(base, subs) - subs << UnknownStruct.new if base=="Struct" # Extra case for unknown structs. - gen_holder(base, subs) - gen_visitor(base, subs) - end - - def generate - gen_specification_fwd - gen_specification - gen_proxy - gen_structs - gen_visitable("Command", @amqp.collect_all(AmqpCommand)) - gen_visitable("Control", @amqp.collect_all(AmqpControl)) - gen_visitable("Struct", @amqp.collect_all(AmqpStruct).select { |s| s.code}) - end -end - -Specification.new($outdir, $amqp).generate(); |