From 38cde902ffe68eac8ffb0884bcc9c7bfa98c02ac Mon Sep 17 00:00:00 2001 From: Rajith Muditha Attapattu Date: Fri, 19 Dec 2008 19:34:45 +0000 Subject: Tagging RC5 for M4 release git-svn-id: https://svn.apache.org/repos/asf/qpid/tags/M4@728121 13f79535-47bb-0310-9956-ffa450edef68 --- RC5/cpp/rubygen/framing.0-10/structs.rb | 611 ++++++++++++++++++++++++++++++++ 1 file changed, 611 insertions(+) create mode 100644 RC5/cpp/rubygen/framing.0-10/structs.rb (limited to 'RC5/cpp/rubygen/framing.0-10/structs.rb') diff --git a/RC5/cpp/rubygen/framing.0-10/structs.rb b/RC5/cpp/rubygen/framing.0-10/structs.rb new file mode 100644 index 0000000000..eb935d06b4 --- /dev/null +++ b/RC5/cpp/rubygen/framing.0-10/structs.rb @@ -0,0 +1,611 @@ +#!/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. +# +# Usage: output_directory xml_spec_file [xml_spec_file...] +# +$: << '..' +require 'cppgen' + +class StructGen < CppGen + + def initialize(outdir, amqp) + super(outdir, amqp) + end + + SizeMap={ + "Octet"=>1, + "Short"=>2, + "Long"=>4, + "LongLong"=>8, + "int8"=>1, + "int16"=>2, + "int32"=>4, + "int64"=>8, + "uint8"=>1, + "uint16"=>2, + "uint32"=>4, + "uint64"=>8, + "timestamp"=>8 + } + + StringSizeMap={ + "LongString"=>4, + "MediumString"=>2, + "ShortString"=>1 + } + + SizeType={ + 1=>"Octet", + 2=>"Short", + 4=>"Long", + 8=>"LongLong" + } + + ValueTypes=["uint8_t", "uint16_t", "uint32_t", "uint64_t"] + + def is_packed(s) s.pack and s.pack != "0" end + + def execution_header?(s) + s.is_a? AmqpMethod and not s.parent.control? + # s.kind_of? AmqpMethod and s.parent.name.include?("010") and not s.parent.control? + end + + def has_bitfields_only(s) + s.fields.select {|f| f.type_ != "bit"}.empty? + end + + def default_initialisation(s) + params = s.fields.select {|f| ValueTypes.include?(f.cpptype.name) || (!is_packed(s) && f.type_ == "bit")} + strings = params.collect {|f| "#{f.cppname}(#{f.default_value})"} + strings << "flags(0)" if (is_packed(s)) + if strings.empty? + return "" + else + return " : " + strings.join(", ") + end + end + + def printable_form(f) + if (f.cpptype.name == "uint8_t") + return "(int) " + f.cppname + elsif (f.type_ == "bit") + return "get#{f.name.caps}()" + else + return f.cppname + end + end + + def flag_mask(s, i) + pos = s.pack.to_i*8 - 8 - (i/8)*8 + (i % 8) + return "(1 << #{pos})" + end + + def encode_packed_struct(s) + genl s.cpp_pack_type.encode('flags', 'buffer') + process_packed_fields(s) { |f, i| encode_packed_field(s, f, i) unless f.type_ == "bit" } + end + + def decode_packed_struct(s) + genl "#{s.cpp_pack_type.decode('flags', 'buffer')}" + process_packed_fields(s) { |f, i| decode_packed_field(s, f, i) unless f.type_ == "bit" } + end + + def size_packed_struct(s) + genl "total += #{s.pack};" + process_packed_fields(s) { |f, i| size_packed_field(s, f, i) unless f.type_ == "bit" } + end + + def print_packed_struct(s) + process_packed_fields(s) { |f, i| print_packed_field(s, f, i) } + end + + def encode_packed_field(s, f, i) + genl "if (flags & #{flag_mask(s, i)})" + indent { genl f.cpptype.encode(f.cppname,"buffer") } + end + + def decode_packed_field(s, f, i) + genl "if (flags & #{flag_mask(s, i)})" + indent { genl f.cpptype.decode(f.cppname,"buffer") } + end + + def size_packed_field(s, f, i) + genl "if (flags & #{flag_mask(s, i)})" + indent { generate_size(f, []) } + end + + def print_packed_field(s, f, i) + classname = s.cppname + if (s.kind_of? AmqpMethod) + classname = s.body_name + end + genl "if (flags & #{flag_mask(s, i)})" + indent { + unless (classname == "ConnectionStartOkBody" && f.name == "response") + genl "out << \"#{f.name}=\" << #{printable_form(f)} << \"; \";" + else + genl "out << \"response=\" << \"xxxxxx\" << \"; \";" + end + } + end + + def generate_encode(f, combined) + if (f.type_ == "bit") + genl "uint8_t #{f.cppname}_bits = #{f.cppname};" + count = 0 + combined.each { |c| genl "#{f.cppname}_bits |= #{c.cppname} << #{count += 1};" } + genl "buffer.putOctet(#{f.cppname}_bits);" + else + genl f.cpptype.encode(f.cppname,"buffer") + end + end + + def generate_decode(f, combined) + if (f.type_ == "bit") + genl "uint8_t #{f.cppname}_bits = buffer.getOctet();" + genl "#{f.cppname} = 1 & #{f.cppname}_bits;" + count = 0 + combined.each { |c| genl "#{c.cppname} = (1 << #{count += 1}) & #{f.cppname}_bits;" } + else + genl f.cpptype.decode(f.cppname,"buffer") + end + end + + def generate_size(f, combined) + if (f.type_ == "bit") + names = ([f] + combined).collect {|g| g.cppname} + genl "total += 1;//#{names.join(", ")}" + else + size = SizeMap[f.cpptype.encoded] + if (size) + genl "total += #{size};//#{f.cppname}" + elsif (f.cpptype.name == "SequenceNumberSet") + genl "total += #{f.cppname}.encodedSize();" + elsif (size = StringSizeMap[f.cpptype.encoded]) + genl "total += #{size} + #{f.cppname}.size();" + else + genl "total += #{f.cppname}.encodedSize();" + end + end + end + + def process_packed_fields(s) + s.fields.each { |f| yield f, s.fields.index(f) } + end + + def process_fields(s) + last = nil + count = 0 + bits = [] + s.fields.each { + |f| if (last and last.bit? and f.bit? and count < 7) + count += 1 + bits << f + else + if (last and last.bit?) + yield last, bits + count = 0 + bits = [] + end + if (not f.bit?) + yield f + end + last = f + end + } + if (last and last.bit?) + yield last, bits + end + end + + def all_fields_via_accessors(s) + s.fields.collect { |f| "get#{f.name.caps}()" }.join(", ") + end + + def methodbody_extra_defs(s) + if (s.parent.control?) + genl "virtual uint8_t type() const { return 0;/*control segment*/ }" + end + + + gen < ResultType invoke(T& invocable) const { + return invocable.#{s.cppname}(#{all_fields_via_accessors(s)}); + } + + using AMQMethodBody::accept; + void accept(MethodBodyConstVisitor& v) const { v.visit(*this); } + + ClassId amqpClassId() const { return CLASS_ID; } + MethodId amqpMethodId() const { return METHOD_ID; } + bool isContentBearing() const { return #{s.content ? "true" : "false" }; } + bool resultExpected() const { return #{s.result ? "true" : "false"}; } + bool responseExpected() const { return #{s.responses().empty? ? "false" : "true"}; } +EOS + end + + def define_constructor(name, s) + if (s.fields.size > 0) + genl "#{name}(" + if (s.kind_of? AmqpMethod) + indent {gen "ProtocolVersion, "} + end + indent { gen s.fields.collect { |f| "#{f.cpptype.param} _#{f.cppname}" }.join(",\n") } + genl ") : " + if (is_packed(s)) + initialisers = s.fields.select { |f| f.type_ != "bit"}.collect { |f| "#{f.cppname}(_#{f.cppname})"} + + initialisers << "flags(0)" + indent { gen initialisers.join(",\n") } + genl "{" + indent { + process_packed_fields(s) { |f, i| genl "set#{f.name.caps}(_#{f.cppname});" if f.type_ == "bit"} + process_packed_fields(s) { |f, i| genl "flags |= #{flag_mask(s, i)};" unless f.type_ == "bit"} + } + genl "}" + else + indent { gen s.fields.collect { |f| " #{f.cppname}(_#{f.cppname})" }.join(",\n") } + genl "{}" + end + end + #default constructors: + if (s.kind_of? AmqpMethod) + genl "#{name}(ProtocolVersion=ProtocolVersion()) #{default_initialisation(s)} {}" + end + if (s.kind_of? AmqpStruct) + genl "#{name}() #{default_initialisation(s)} {}" + end + end + + def define_packed_field_accessors(s, f, i) + if (s.kind_of? AmqpMethod) + define_packed_field_accessors_for_method(s, f, i) + else + define_packed_field_accessors_for_struct(s, f, i) + end + end + + def define_packed_field_accessors_for_struct(s, f, i) + if (f.type_ == "bit") + genl "void #{s.cppname}::set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname}) {" + indent { + genl "if (_#{f.cppname}) flags |= #{flag_mask(s, i)};" + genl "else flags &= ~#{flag_mask(s, i)};" + } + genl "}" + genl "#{f.cpptype.ret} #{s.cppname}::get#{f.name.caps}() const { return flags & #{flag_mask(s, i)}; }" + else + genl "void #{s.cppname}::set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname}) {" + indent { + genl "#{f.cppname} = _#{f.cppname};" + genl "flags |= #{flag_mask(s, i)};" + } + genl "}" + genl "#{f.cpptype.ret} #{s.cppname}::get#{f.name.caps}() const { return #{f.cppname}; }" + if (f.cpptype.name == "FieldTable") + genl "#{f.cpptype.name}& #{s.cppname}::get#{f.name.caps}() {" + indent { + genl "flags |= #{flag_mask(s, i)};"#treat the field table as having been 'set' + genl "return #{f.cppname};" + } + genl "}" + end + genl "bool #{s.cppname}::has#{f.name.caps}() const { return flags & #{flag_mask(s, i)}; }" + genl "void #{s.cppname}::clear#{f.name.caps}Flag() { flags &= ~#{flag_mask(s, i)}; }" + end + genl "" + end + + def define_packed_field_accessors_for_method(s, f, i) + if (f.type_ == "bit") + genl "void #{s.body_name}::set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname}) {" + indent { + genl "if (_#{f.cppname}) flags |= #{flag_mask(s, i)};" + genl "else flags &= ~#{flag_mask(s, i)};" + } + genl "}" + genl "#{f.cpptype.ret} #{s.body_name}::get#{f.name.caps}() const { return flags & #{flag_mask(s, i)}; }" + else + genl "void #{s.body_name}::set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname}) {" + indent { + genl "#{f.cppname} = _#{f.cppname};" + genl "flags |= #{flag_mask(s, i)};" + } + genl "}" + genl "#{f.cpptype.ret} #{s.body_name}::get#{f.name.caps}() const { return #{f.cppname}; }" + if (f.cpptype.name == "FieldTable") + genl "#{f.cpptype.name}& #{s.body_name}::get#{f.name.caps}() {" + indent { + genl "flags |= #{flag_mask(s, i)};"#treat the field table as having been 'set' + genl "return #{f.cppname};" + } + genl "}" + end + genl "bool #{s.body_name}::has#{f.name.caps}() const { return flags & #{flag_mask(s, i)}; }" + genl "void #{s.body_name}::clear#{f.name.caps}Flag() { flags &= ~#{flag_mask(s, i)}; }" + end + genl "" + end + + def define_packed_accessors(s) + process_packed_fields(s) { |f, i| define_packed_field_accessors(s, f, i) } + end + + def declare_packed_accessors(f) + genl "void set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname});"; + genl "#{f.cpptype.ret} get#{f.name.caps}() const;" + if (f.cpptype.name == "FieldTable") + genl "#{f.cpptype.name}& get#{f.name.caps}();" + end + if (f.type_ != "bit") + #extra 'accessors' for packed fields: + genl "bool has#{f.name.caps}() const;" + genl "void clear#{f.name.caps}Flag();" + end + end + + def define_accessors(f) + genl "void set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname}) { #{f.cppname} = _#{f.cppname}; }" + genl "#{f.cpptype.ret} get#{f.name.caps}() const { return #{f.cppname}; }" + if (f.cpptype.name == "FieldTable") + genl "#{f.cpptype.name}& get#{f.name.caps}() { return #{f.cppname}; }" + end + end + + def define_struct(s) + classname = s.cppname + inheritance = "" + if (s.kind_of? AmqpMethod) + classname = s.body_name + if (execution_header?(s)) + inheritance = ": public ModelMethod" + else + inheritance = ": public AMQMethodBody" + end + end + + h_file("qpid/framing/#{classname}.h") { + if (s.kind_of? AmqpMethod) + gen < +#include "qpid/framing/amqp_types_full.h" + +namespace qpid { +namespace framing { + +class #{classname} #{inheritance} { +EOS + if (is_packed(s)) + indent { s.fields.each { |f| genl "#{f.cpptype.name} #{f.cppname};" unless f.type_ == "bit"} } + indent { + genl "#{s.cpp_pack_type.name} flags;" + } + else + indent { s.fields.each { |f| genl "#{f.cpptype.name} #{f.cppname};" } } + end + genl "public:" + if (s.kind_of? AmqpMethod) + indent { genl "static const ClassId CLASS_ID = #{s.parent.code};" } + indent { genl "static const MethodId METHOD_ID = #{s.code};" } + end + + if (s.kind_of? AmqpStruct) + if (s.code) + indent { genl "static const uint16_t TYPE = #{s.full_code};" } + end + end + + indent { + define_constructor(classname, s) + genl "" + if (is_packed(s)) + s.fields.each { |f| declare_packed_accessors(f) } + else + s.fields.each { |f| define_accessors(f) } + end + } + if (s.kind_of? AmqpMethod) + methodbody_extra_defs(s) + end + if (s.kind_of? AmqpStruct) + indent {genl "friend std::ostream& operator<<(std::ostream&, const #{classname}&);" } + end + + gen < 0 || execution_header?(s)) + buffer = "buffer" + else + buffer = "/*buffer*/" + end + gen <