diff options
Diffstat (limited to 'cpp/rubygen/framing.0-10/structs.rb')
-rwxr-xr-x | cpp/rubygen/framing.0-10/structs.rb | 615 |
1 files changed, 0 insertions, 615 deletions
diff --git a/cpp/rubygen/framing.0-10/structs.rb b/cpp/rubygen/framing.0-10/structs.rb deleted file mode 100755 index 62b33ce773..0000000000 --- a/cpp/rubygen/framing.0-10/structs.rb +++ /dev/null @@ -1,615 +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. -# -# 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 <<EOS - typedef #{s.result ? s.result.cpptype.name : 'void'} ResultType; - - template <class T> 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); } - boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*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 "QPID_COMMON_EXTERN void set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname});"; - genl "QPID_COMMON_EXTERN #{f.cpptype.ret} get#{f.name.caps}() const;" - if (f.cpptype.name == "FieldTable") - genl "QPID_COMMON_EXTERN #{f.cpptype.name}& get#{f.name.caps}();" - end - if (f.type_ != "bit") - #extra 'accessors' for packed fields: - genl "QPID_COMMON_EXTERN bool has#{f.name.caps}() const;" - genl "QPID_COMMON_EXTERN 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 - else - public_api("qpid/framing/#{classname}.h") # Non-method structs are public - end - - h_file("qpid/framing/#{classname}.h") { - if (s.kind_of? AmqpMethod) - gen <<EOS -#include "qpid/framing/AMQMethodBody.h" -#include "qpid/framing/AMQP_ServerOperations.h" -#include "qpid/framing/MethodBodyConstVisitor.h" -EOS - end - include "qpid/framing/ModelMethod.h" if (execution_header?(s)) - - s.fields.each { |f| include "qpid/framing/#{f.cpptype.name}" if f.struct?} - - gen <<EOS - -#include <ostream> -#include "qpid/framing/amqp_types_full.h" -#include "qpid/CommonImportExport.h" - -namespace qpid { -namespace framing { - -class QPID_COMMON_CLASS_EXTERN #{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 "QPID_COMMON_EXTERN friend std::ostream& operator<<(std::ostream&, const #{classname}&);" } - end - - gen <<EOS - QPID_COMMON_EXTERN void encode(Buffer&) const; - QPID_COMMON_EXTERN void decode(Buffer&, uint32_t=0); - QPID_COMMON_EXTERN void encodeStructBody(Buffer&) const; - QPID_COMMON_EXTERN void decodeStructBody(Buffer&, uint32_t=0); - QPID_COMMON_EXTERN uint32_t encodedSize() const; - QPID_COMMON_EXTERN uint32_t bodySize() const; - QPID_COMMON_EXTERN void print(std::ostream& out) const; -}; /* class #{classname} */ - -}} -EOS - } - cpp_file("qpid/framing/#{classname}.cpp") { - if (is_packed(s) || s.fields.size > 0 || execution_header?(s)) - buffer = "buffer" - else - buffer = "/*buffer*/" - end - gen <<EOS -#include "qpid/framing/#{classname}.h" -#include "qpid/framing/reply_exceptions.h" - -using namespace qpid::framing; - -EOS - - if (is_packed(s)) - define_packed_accessors(s) - end - gen <<EOS -void #{classname}::encodeStructBody(Buffer& #{buffer}) const -{ -EOS - if (execution_header?(s)) - genl "encodeHeader(buffer);" - end - - if (is_packed(s)) - indent {encode_packed_struct(s)} - else - indent { process_fields(s) { |f, combined| generate_encode(f, combined) } } - end - gen <<EOS -} - -void #{classname}::encode(Buffer& buffer) const -{ -EOS - indent { - if (s.kind_of? AmqpStruct) - if (s.code) - genl "buffer.put#{SizeType[s.size.to_i]}(bodySize() + 2/*typecode*/);" if s.size and s.size.to_i != 0 - genl "buffer.putShort(TYPE);" - else - genl "buffer.put#{SizeType[s.size.to_i]}(bodySize());" if s.size and s.size.to_i != 0 - end - end - genl "encodeStructBody(buffer);" - } - gen <<EOS -} - -void #{classname}::decodeStructBody(Buffer& #{buffer}, uint32_t /*size*/) -{ -EOS - if (execution_header?(s)) - genl "decodeHeader(buffer);" - end - - if (is_packed(s)) - indent {decode_packed_struct(s)} - else - indent { process_fields(s) { |f, combined| generate_decode(f, combined) } } - end - gen <<EOS -} - -void #{classname}::decode(Buffer& buffer, uint32_t /*size*/) -{ -EOS - indent { - if (s.kind_of? AmqpStruct) - genl "buffer.get#{SizeType[s.size.to_i]}();" if s.size and s.size.to_i != 0 - genl "if (TYPE != buffer.getShort()) throw FramingErrorException(\"Bad type code for struct\");" if s.code - end - genl "decodeStructBody(buffer);" - } - gen <<EOS -} - -uint32_t #{classname}::bodySize() const -{ - uint32_t total = 0; -EOS - if (execution_header?(s)) - genl "total += headerSize();" - end - - if (is_packed(s)) - indent {size_packed_struct(s)} - else - indent { process_fields(s) { |f, combined| generate_size(f, combined) } } - end - gen <<EOS - return total; -} - -uint32_t #{classname}::encodedSize() const { - uint32_t total = bodySize(); -EOS - if (s.kind_of? AmqpStruct) - genl "total += #{s.size}/*size field*/;" if s.size - genl "total += 2/*typecode*/;" if s.code - end - gen <<EOS - return total; -} - -void #{classname}::print(std::ostream& out) const -{ - out << "{#{classname}: "; -EOS - if (is_packed(s)) - indent {print_packed_struct(s)} - else - copy = Array.new(s.fields) - f = copy.shift - - indent { - genl "out << \"#{f.name}=\" << #{printable_form(f)};" if f - copy.each { |f| genl "out << \"; #{f.name}=\" << #{printable_form(f)};" } - } - end - gen <<EOS - out << "}"; -} -EOS - - if (s.kind_of? AmqpStruct) - gen <<EOS -namespace qpid{ -namespace framing{ - - std::ostream& operator<<(std::ostream& out, const #{classname}& s) - { - s.print(out); - return out; - } - -} -} -EOS - end -} - end - - def generate() - structs = @amqp.collect_all(AmqpStruct).select { |s| not ["command-fragment"].include?(s.name) } - structs.each { |s| define_struct(s) } - @amqp.methods_.each { |m| define_struct(m) } - #generate a single include file containing the list of structs for convenience - public_api("qpid/framing/amqp_structs.h") - h_file("qpid/framing/amqp_structs.h") { structs.each { |s| genl "#include \"qpid/framing/#{s.cppname}.h\"" } } - end -end - -StructGen.new($outdir, $amqp).generate() - |