class Xdrgen::Generators::Csharp
Public Instance Methods
decl_string(decl)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 522 def decl_string(decl) case decl when AST::Declarations::Opaque 'byte[]' when AST::Declarations::String 'String' when AST::Declarations::Array "#{type_string decl.type}[]" when AST::Declarations::Optional type_string(decl.type).to_s when AST::Declarations::Simple type_string(decl.type) else raise "Unknown declaration type: #{decl.class.name}" end end
decode_innervalue_member(value, member, out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 413 def decode_innervalue_member(value, member, out) case member.declaration when AST::Declarations::Void return end if member.type.sub_type == :optional out.puts <<-EOS.strip_heredoc int #{member.name.camelize}Present = stream.ReadInt(); if (#{member.name.camelize}Present != 0) { EOS end case member.declaration when AST::Declarations::Opaque if member.declaration.fixed? out.puts "int #{member.name}size = #{member.declaration.size};" else out.puts "int #{member.name}size = stream.ReadInt();" end out.puts <<-EOS.strip_heredoc #{value}.InnerValue = new byte[#{member.name}size]; stream.Read(#{value}.InnerValue, 0, #{member.name}size); EOS when AST::Declarations::Array if member.declaration.fixed? out.puts "int #{member.name}size = #{member.declaration.size};" else out.puts "int #{member.name}size = stream.ReadInt();" end out.puts <<-EOS.strip_heredoc #{value}.InnerValue = new #{type_string member.type}[#{member.name}size]; for (int i = 0; i < #{member.name}size; i++) { #{value}.InnerValue[i] = #{decode_type member.declaration.type}; } EOS else out.puts "#{value}.InnerValue = #{decode_type member.declaration.type};" end out.puts '}' if member.type.sub_type == :optional end
decode_member(value, member, out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 453 def decode_member(value, member, out) case member.declaration when AST::Declarations::Void return end if member.type.sub_type == :optional out.puts <<-EOS.strip_heredoc int #{member.name.camelize}Present = stream.ReadInt(); if (#{member.name.camelize}Present != 0) { EOS end case member.declaration when AST::Declarations::Opaque if member.declaration.fixed? out.puts "int #{member.name}size = #{member.declaration.size};" else out.puts "int #{member.name}size = stream.ReadInt();" end out.puts <<-EOS.strip_heredoc #{value}.#{member.name.camelize} = new byte[#{member.name}size]; stream.Read(#{value}.#{member.name.camelize},0,#{member.name}size); EOS when AST::Declarations::Array if member.declaration.fixed? out.puts "int #{member.name}size = #{member.declaration.size};" else out.puts "int #{member.name}size = stream.ReadInt();" end out.puts <<-EOS.strip_heredoc #{value}.#{member.name.camelize} = new #{type_string member.type}[#{member.name}size]; for (int i = 0; i < #{member.name}size; i++) { #{value}.#{member.name.camelize}[i] = #{decode_type member.declaration.type}; } EOS else out.puts "#{value}.#{member.name.camelize} = #{decode_type member.declaration.type};" end out.puts '}' if member.type.sub_type == :optional end
decode_type(type)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 493 def decode_type(type) case type when AST::Typespecs::Int 'stream.ReadInt()' when AST::Typespecs::UnsignedInt 'stream.ReadInt()' when AST::Typespecs::Hyper 'stream.ReadLong()' when AST::Typespecs::UnsignedHyper 'stream.ReadLong()' when AST::Typespecs::Float 'stream.ReadFloat()' when AST::Typespecs::Double 'stream.ReadDouble()' when AST::Typespecs::Quadruple raise 'cannot render quadruple in c#' when AST::Typespecs::Bool 'stream.ReadInt() == 1 ? true : false' when AST::Typespecs::String 'stream.ReadString()' when AST::Typespecs::Simple "#{name type.resolved_type}.Decode(stream)" when AST::Concerns::NestedDefinition "#{name type}.Decode(stream)" else raise "Unknown typespec: #{type.class.name}" end end
encode_innervalue_member(value, member, out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 305 def encode_innervalue_member(value, member, out) case member.declaration when AST::Declarations::Void return end if member.type.sub_type == :optional out.puts "if (#{value}.InnerValue != null) {" out.puts 'stream.WriteInt(1);' end case member.declaration when AST::Declarations::Opaque out.puts "int #{member.name}size = #{value}.InnerValue.Length;" unless member.declaration.fixed? out.puts "stream.WriteInt(#{member.name.camelize}size);" end out.puts <<-EOS.strip_heredoc stream.Write(#{value}.InnerValue, 0, #{member.name}size); EOS when AST::Declarations::Array out.puts "int #{member.name}size = #{value}.InnerValue.Length;" unless member.declaration.fixed? out.puts "stream.WriteInt(#{member.name}size);" end out.puts <<-EOS.strip_heredoc for (int i = 0; i < #{member.name}size; i++) { #{encode_type member.declaration.type, "#{value}.InnerValue[i]"}; } EOS else out.puts "#{encode_type member.declaration.type, "#{value}.InnerValue"};" end if member.type.sub_type == :optional out.puts '} else {' out.puts 'stream.WriteInt(0);' out.puts '}' end end
encode_member(value, member, out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 345 def encode_member(value, member, out) case member.declaration when AST::Declarations::Void return end if member.type.sub_type == :optional out.puts "if (#{value}.#{member.name.camelize} != null) {" out.puts 'stream.WriteInt(1);' end case member.declaration when AST::Declarations::Opaque out.puts "int #{member.name}size = #{value}.#{member.name.camelize}.Length;" unless member.declaration.fixed? out.puts "stream.WriteInt(#{member.name.camelize}size);" end out.puts <<-EOS.strip_heredoc stream.Write(#{value}.#{member.name.camelize}, 0, #{member.name}size); EOS when AST::Declarations::Array out.puts "int #{member.name}size = #{value}.#{member.name.camelize}.Length;" unless member.declaration.fixed? out.puts "stream.WriteInt(#{member.name}size);" end out.puts <<-EOS.strip_heredoc for (int i = 0; i < #{member.name}size; i++) { #{encode_type member.declaration.type, "#{value}.#{member.name.camelize}[i]"}; } EOS else out.puts "#{encode_type member.declaration.type, "#{value}.#{member.name.camelize}"};" end if member.type.sub_type == :optional out.puts '} else {' out.puts 'stream.WriteInt(0);' out.puts '}' end end
encode_type(type, value)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 384 def encode_type(type, value) case type when AST::Typespecs::Int "stream.WriteInt(#{value})" when AST::Typespecs::UnsignedInt "stream.WriteInt(#{value})" when AST::Typespecs::Hyper "stream.WriteLong(#{value})" when AST::Typespecs::UnsignedHyper "stream.WriteLong(#{value})" when AST::Typespecs::Float "stream.WriteFloat(#{value})" when AST::Typespecs::Double "stream.WriteDouble(#{value})" when AST::Typespecs::Quadruple raise 'cannot render quadruple in c#' when AST::Typespecs::Bool "stream.WriteInt(#{value} ? 1 : 0)" when AST::Typespecs::String "stream.WriteString(#{value})" when AST::Typespecs::Simple "#{name type.resolved_type}.Encode(stream, #{value})" when AST::Concerns::NestedDefinition "#{name type}.Encode(stream, #{value})" else raise "Unknown typespec: #{type.class.name}" end end
generate()
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 4 def generate render_lib render_definitions(@top) end
name(named)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 568 def name(named) parent = name named.parent_defn if named.is_a?(AST::Concerns::NestedDefinition) result = named.name.camelize "#{parent}#{result}" end
name_string(name)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 575 def name_string(name) name.camelize end
render_definition(defn)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 16 def render_definition(defn) case defn when AST::Definitions::Struct render_element 'public class', defn do |out| render_struct defn, out render_nested_definitions defn, out end when AST::Definitions::Enum render_element 'public class', defn do |out| render_enum defn, out end when AST::Definitions::Union render_element 'public class', defn do |out| render_union defn, out render_nested_definitions defn, out end when AST::Definitions::Typedef render_element 'public class', defn do |out| render_typedef defn, out end end end
render_definitions(node)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 11 def render_definitions(node) node.namespaces.each { |n| render_definitions n } node.definitions.each(&method(:render_definition)) end
render_element(type, element, post_name = '') { |out| ... }
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 77 def render_element(type, element, post_name = '') path = element.name.camelize + '.cs' name = name_string element.name out = @output.open(path) render_top_matter out render_source_comment out, element out.puts "#{type} #{name} #{post_name} {" out.indent do yield out out.unbreak end out.puts '}' out.puts '}' end
render_enum(enum, out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 93 def render_enum(enum, out) enumname = enum.name + 'Enum' out.puts "public enum #{enumname} {" out.balance_after /,[\s]*/ do enum.members.each do |em| out.puts "#{em.name} = #{em.value}," end end out.puts "}\n" out.puts <<-EOS.strip_heredoc public #{enumname} InnerValue {get; set;} = default(#{enumname}); public static #{enum.name} Create(#{enumname} v) { return new #{enum.name} { InnerValue = v }; } public static #{name_string enum.name} Decode(XdrDataInputStream stream) { int value = stream.ReadInt(); switch (value) { EOS out.indent 2 do enum.members.each do |em| out.puts "case #{em.value}: return Create(#{enumname}.#{em.name});" end end out.puts <<-EOS.strip_heredoc default: throw new Exception("Unknown enum value: " + value); } } public static void Encode(XdrDataOutputStream stream, #{name_string enum.name} value) { stream.WriteInt((int)value.InnerValue); } EOS out.break end
render_lib()
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 9 def render_lib; end
render_nested_definitions(defn, out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 39 def render_nested_definitions(defn, out) return unless defn.respond_to? :nested_definitions defn.nested_definitions.each do |ndefn| case ndefn when AST::Definitions::Struct name = name ndefn out.puts "public class #{name} {" out.indent do render_struct ndefn, out render_nested_definitions ndefn, out end out.puts '}' when AST::Definitions::Enum name = name ndefn out.puts "public class #{name} {" out.indent do render_enum ndefn, out end out.puts '}' when AST::Definitions::Union name = name ndefn out.puts "public class #{name} {" out.indent do render_union ndefn, out render_nested_definitions ndefn, out end out.puts '}' when AST::Definitions::Typedef name = name ndefn out.puts "public class #{name} {" out.indent do render_typedef ndefn, out end out.puts '}' end end end
render_source_comment(out, defn)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 289 def render_source_comment(out, defn) return if defn.is_a?(AST::Definitions::Namespace) out.puts <<-EOS.strip_heredoc // === xdr source ============================================================ EOS out.puts '// ' + defn.text_value.split("\n").join("\n// ") out.puts <<-EOS.strip_heredoc // =========================================================================== EOS end
render_struct(struct, out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 135 def render_struct(struct, out) out.puts "public #{name struct} () {}" struct.members.each do |m| out.puts <<-EOS.strip_heredoc public #{decl_string(m.declaration)} #{m.name.camelize} {get; set;} EOS end out.puts "\n" out.puts "public static void Encode(XdrDataOutputStream stream, #{name struct} encoded#{name struct}) {" struct.members.each do |m| out.indent do encode_member "encoded#{name struct}", m, out end end out.puts '}' out.puts <<-EOS.strip_heredoc public static #{name struct} Decode(XdrDataInputStream stream) { #{name struct} decoded#{name struct} = new #{name struct}(); EOS struct.members.each do |m| out.indent do decode_member "decoded#{name struct}", m, out end end out.indent do out.puts "return decoded#{name struct};" end out.puts '}' out.break end
render_top_matter(out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 278 def render_top_matter(out) out.puts <<-EOS.strip_heredoc // Automatically generated by xdrgen // DO NOT EDIT or your changes may be overwritten using System; namespace #{@namespace} { EOS out.break end
render_typedef(typedef, out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 168 def render_typedef(typedef, out) out.puts <<-EOS.strip_heredoc public #{decl_string typedef.declaration} InnerValue {get; set;} = default(#{decl_string typedef.declaration}); public #{typedef.name.camelize}() {} public #{typedef.name.camelize}(#{decl_string typedef.declaration} value) { InnerValue = value; } EOS out.puts "public static void Encode(XdrDataOutputStream stream, #{name typedef} encoded#{name typedef}) {" encode_innervalue_member "encoded#{name typedef}", typedef, out out.puts '}' out.puts <<-EOS.strip_heredoc public static #{name typedef} Decode(XdrDataInputStream stream) { #{name typedef} decoded#{name typedef} = new #{name typedef}(); EOS decode_innervalue_member "decoded#{name typedef}", typedef, out out.indent do out.puts "return decoded#{name typedef};" end out.puts '}' end
render_union(union, out)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 195 def render_union(union, out) has_inner_value = false out.puts "public #{name union} () {}" out.puts <<-EOS.strip_heredoc public #{type_string union.discriminant.type} Discriminant { get; set; } = new #{type_string union.discriminant.type}(); EOS union.arms.each do |arm| next if arm.void? out.puts <<-EOS.strip_heredoc public #{decl_string(arm.declaration)} #{arm.name.camelize} {get; set;} EOS end out.puts "public static void Encode(XdrDataOutputStream stream, #{name union} encoded#{name union}) {" if union.discriminant.type.is_a?(AST::Typespecs::Int) out.puts "stream.WriteInt((int)encoded#{name union}.Discriminant);" out.puts "switch (encoded#{name union}.Discriminant) {" # elsif [discriminant is AST::Definitions::Typedef] # out.puts "stream.writeInt(encoded#{name union}.getDiscriminant().get#{name union.discriminant.type}());" else has_inner_value = true out.puts "stream.WriteInt((int)encoded#{name union}.Discriminant.InnerValue);" out.puts "switch (encoded#{name union}.Discriminant.InnerValue) {" end union.arms.each do |arm| case arm when AST::Definitions::UnionDefaultArm out.puts 'default:' else arm.cases.each do |kase| if kase.value.is_a?(AST::Identifier) out.puts "case #{type_string union.discriminant.type}.#{type_string union.discriminant.type}Enum.#{kase.value.name}:" else out.puts "case #{kase.value.value}:" end end end encode_member "encoded#{name union}", arm, out out.puts 'break;' end out.puts "}\n}" out.puts "public static #{name union} Decode(XdrDataInputStream stream) {" out.puts "#{name union} decoded#{name union} = new #{name union}();" if union.discriminant.type.is_a?(AST::Typespecs::Int) out.puts 'int discriminant = stream.ReadInt();' out.puts "decoded#{name union}.Discriminant = discriminant;" out.puts "switch (decoded#{name union}.Discriminant) {" else out.puts "#{name union.discriminant.type} discriminant = #{name union.discriminant.type}.Decode(stream);" out.puts "decoded#{name union}.Discriminant = discriminant;" out.puts "switch (decoded#{name union}.Discriminant.InnerValue) {" end union.arms.each do |arm| case arm when AST::Definitions::UnionDefaultArm out.puts 'default:' else arm.cases.each do |kase| if kase.value.is_a?(AST::Identifier) out.puts "case #{type_string union.discriminant.type}.#{type_string union.discriminant.type}Enum.#{kase.value.name}:" else out.puts "case #{kase.value.value}:" end end end decode_member "decoded#{name union}", arm, out out.puts 'break;' end out.puts "}\n" out.indent do out.puts "return decoded#{name union};" end out.puts '}' out.break end
type_string(type)
click to toggle source
# File lib/xdrgen/generators/csharp.rb, line 539 def type_string(type) case type when AST::Typespecs::Int 'int' when AST::Typespecs::UnsignedInt 'int' when AST::Typespecs::Hyper 'long' when AST::Typespecs::UnsignedHyper 'long' when AST::Typespecs::Float 'float' when AST::Typespecs::Double 'double' when AST::Typespecs::Quadruple 'Tuple' when AST::Typespecs::Bool 'bool' when AST::Typespecs::Opaque "Byte[#{type.size}]" when AST::Typespecs::Simple name type.resolved_type when AST::Concerns::NestedDefinition name type else raise "Unknown typespec: #{type.class.name}" end end