From 0e341392e688ff462b71eece47eab04e220823d3 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Tue, 22 Oct 2019 20:58:29 +0200 Subject: [PATCH] Added bitfields --- src/andrew.cr | 6 ++++-- src/views/attribute.ecr | 8 +++---- src/views/attribute_after.ecr | 8 +++---- src/views/bitfield_generator.ecr | 25 +++++++++++++++++++++ src/views/class.ecr | 7 +++++- tests/record.yml | 37 ++++++++++++++++++++++++++++++-- 6 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 src/views/bitfield_generator.ecr diff --git a/src/andrew.cr b/src/andrew.cr index 38d5064..6ae1526 100644 --- a/src/andrew.cr +++ b/src/andrew.cr @@ -70,12 +70,14 @@ class BitfieldGenerator name: String, out_type: String, start: Int32, - size: Int32 + mask: String ) - def initialize(@name : String, @out_type : String, @start : Int32, @size : Int32) + def initialize(@name : String, @out_type : String, @start : Int32, @mask : String) @class_name = "no_class" end + + ECR.def_to_s "src/views/bitfield_generator.ecr" end class AttributeGenerator diff --git a/src/views/attribute.ecr b/src/views/attribute.ecr index f139a8f..7a099ef 100644 --- a/src/views/attribute.ecr +++ b/src/views/attribute.ecr @@ -1,19 +1,19 @@ - <%= @out_type %> get_<%= @name %>(const <%= class_name %>& alter) { + static <%= @out_type %> get_<%= @name %>(const <%= class_name %>& alter) { auto ptr = (char*)&alter; ptr+=<%= @start %>; return *(<%= @out_type %>*)ptr; } - void set_<%= @name %>(<%= class_name %>& alter, const <%= @out_type %>& param) { + static void set_<%= @name %>(<%= class_name %>& alter, const <%= @out_type %>& param) { auto ptr = (char*)&alter; ptr+=<%= @start %>; *(<%= @out_type %>*)ptr = param; } - constexpr size_t <%= @name %>_position() { + static constexpr size_t <%= @name %>_position() { return <%= @start %>; } - constexpr size_t <%= @name %>_end_position() { + static constexpr size_t <%= @name %>_end_position() { return <%= @start %>+sizeof(<%= @out_type %>); } \ No newline at end of file diff --git a/src/views/attribute_after.ecr b/src/views/attribute_after.ecr index 6138f7b..350b681 100644 --- a/src/views/attribute_after.ecr +++ b/src/views/attribute_after.ecr @@ -1,18 +1,18 @@ - size_t <%= @name %>_position() { + static size_t <%= @name %>_position() { return <%= @name %>_end_position(); } - size_t <%= @name %>_end_position() { + static size_t <%= @name %>_end_position() { return <%= @name %>_position()+sizeof(<%= @out_type %>); } - <%= @out_type %> get_<%= @name %>(const <%= class_name %>& alter) { + static <%= @out_type %> get_<%= @name %>(const <%= class_name %>& alter) { auto ptr = (char*)&alter; ptr+=<%= @name %>_position(); return *(<%= @out_type %>*)ptr; } - void set_<%= @name %>(<%= class_name %>& alter, const <%= @out_type %>& param) { + static void set_<%= @name %>(<%= class_name %>& alter, const <%= @out_type %>& param) { auto ptr = (char*)&alter; ptr+=<%= @name %>_position(); *(<%= @out_type %>*)ptr = param; diff --git a/src/views/bitfield_generator.ecr b/src/views/bitfield_generator.ecr new file mode 100644 index 0000000..7b0ed41 --- /dev/null +++ b/src/views/bitfield_generator.ecr @@ -0,0 +1,25 @@ + static <%= @out_type %> get_<%= @name %>(const <%= class_name %>& alter) { + auto ptr = (char*)&alter; + ptr+=<%= @start %>; + return <%= @mask %> & *(<%= @out_type %>*)ptr; + } + + static void set_<%= @name %>(<%= class_name %>& alter) { + auto ptr = (char*)&alter; + ptr+=<%= @start %>; + *(<%= @out_type %>*)ptr = <%= @mask %> | *(<%= @out_type %>*)ptr; + } + + static void unset_<%= @name %>(<%= class_name %>& alter) { + auto ptr = (char*)&alter; + ptr+=<%= @start %>; + *(<%= @out_type %>*)ptr = (<%= @mask %> | *(<%= @out_type %>*)ptr) ^ <%= @mask %>; + } + + static constexpr size_t <%= @name %>_position() { + return <%= @start %>; + } + + static constexpr size_t <%= @name %>_end_position() { + return <%= @start %>+sizeof(<%= @out_type %>); + } \ No newline at end of file diff --git a/src/views/class.ecr b/src/views/class.ecr index cb4d2d9..6a3d14a 100644 --- a/src/views/class.ecr +++ b/src/views/class.ecr @@ -5,7 +5,6 @@ virtual ~<%= @name %>() = 0; <%- @attributes.not_nil!.each do |attr| -%> <%- attr.class_name = @name -%> <%= attr.to_s %> - <%- end -%> <% end %> @@ -13,7 +12,13 @@ virtual ~<%= @name %>() = 0; <%- @attributeafters.not_nil!.each do |attr| -%> <%- attr.class_name = @name -%> <%= attr.to_s %> +<%- end -%> +<% end %> +<% if !(@bitfields.nil?) %> +<%- @bitfields.not_nil!.each do |attr| -%> +<%- attr.class_name = @name -%> +<%= attr.to_s %> <%- end -%> <% end %> }; diff --git a/tests/record.yml b/tests/record.yml index 25636c0..cd61df8 100644 --- a/tests/record.yml +++ b/tests/record.yml @@ -32,7 +32,40 @@ classes: name: offset out_type: uint64_t after_name: timestamp + bitfields: - name: flags - out_type: uint32_t - after_name: offset \ No newline at end of file + out_type: uint16_t + start: 40 + mask: 0b0000000000000111 + - + name: v_flag + out_type: uint16_t + after_name: offset + start: 40 + mask: 0b0000000000000100 + - + name: r_flags + out_type: uint16_t + start: 40 + mask: 0b0000000000000010 + - + name: c_flags + out_type: uint16_t + start: 40 + mask: 0b0000000000000001 + - + name: confirmed + out_type: uint16_t + start: 40 + mask: 0b0000000000000101 + - + name: validated + out_type: uint16_t + start: 40 + mask: 0b0000000000000101 + - + name: removed + out_type: uint16_t + start: 40 + mask: 0b0000000000000010 \ No newline at end of file