aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--ext/dl/lib/dl/struct.rb32
-rw-r--r--test/dl/test_c_struct_entry.rb46
3 files changed, 64 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ff6bf47d4..ec5fe8161d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Thu May 31 09:27:06 2012 Eric Hodel <drbrain@segment7.net>
+
+ * ext/dl/lib/dl/struct.rb (DL::CStructEntity::size): Refactored ::size
+ to remove unused variables and simplify using newer ruby features.
+ * test/dl/test_c_struct_entry.rb: Test to validate refactoring
+
Thu May 31 08:40:34 2012 Eric Hodel <drbrain@segment7.net>
* ext/dl/lib/dl/struct.rb (DL::CUnionEntity#set_ctypes): Refactored
diff --git a/ext/dl/lib/dl/struct.rb b/ext/dl/lib/dl/struct.rb
index 628adb21c2..e6f7ba710b 100644
--- a/ext/dl/lib/dl/struct.rb
+++ b/ext/dl/lib/dl/struct.rb
@@ -93,26 +93,18 @@ module DL
# => 24
def CStructEntity.size(types)
offset = 0
- max_align = 0
- types.each_with_index{|t,i|
- orig_offset = offset
- if( t.is_a?(Array) )
- align = PackInfo::ALIGN_MAP[t[0]]
- offset = PackInfo.align(orig_offset, align)
- size = offset - orig_offset
- offset += (PackInfo::SIZE_MAP[t[0]] * t[1])
- else
- align = PackInfo::ALIGN_MAP[t]
- offset = PackInfo.align(orig_offset, align)
- size = offset - orig_offset
- offset += PackInfo::SIZE_MAP[t]
- end
- if (max_align < align)
- max_align = align
- end
- }
- offset = PackInfo.align(offset, max_align)
- offset
+
+ max_align = types.map { |type, count = 1|
+ last_offset = offset
+
+ align = PackInfo::ALIGN_MAP[type]
+ offset = PackInfo.align(last_offset, align) +
+ (PackInfo::SIZE_MAP[type] * count)
+
+ align
+ }.max
+
+ PackInfo.align(offset, max_align)
end
# Wraps the C pointer +addr+ as a C struct with the given +types+. The C
diff --git a/test/dl/test_c_struct_entry.rb b/test/dl/test_c_struct_entry.rb
new file mode 100644
index 0000000000..3df6c368b8
--- /dev/null
+++ b/test/dl/test_c_struct_entry.rb
@@ -0,0 +1,46 @@
+require_relative 'test_base'
+
+require 'dl/cparser'
+
+class DL::TestCStructEntity < DL::TestBase
+ def test_class_size
+ types = [DL::TYPE_DOUBLE, DL::TYPE_CHAR]
+
+ size = DL::CStructEntity.size types
+
+ alignments = types.map { |type| DL::PackInfo::ALIGN_MAP[type] }
+
+ expected = DL::PackInfo.align 0, alignments[0]
+ expected += DL::PackInfo::SIZE_MAP[DL::TYPE_DOUBLE]
+
+ expected = DL::PackInfo.align expected, alignments[1]
+ expected += DL::PackInfo::SIZE_MAP[DL::TYPE_CHAR]
+
+ expected = DL::PackInfo.align expected, alignments.max
+
+ assert_equal expected, size
+ end
+
+ def test_class_size_with_count
+ size = DL::CStructEntity.size([[DL::TYPE_DOUBLE, 2], [DL::TYPE_CHAR, 20]])
+
+ assert_equal DL::TYPE_DOUBLE * 2 + DL::SIZEOF_CHAR * 20, size
+ end
+ def test_class_size_with_count
+ size = DL::CStructEntity.size([[DL::TYPE_DOUBLE, 2], [DL::TYPE_CHAR, 20]])
+
+ types = [DL::TYPE_DOUBLE, DL::TYPE_CHAR]
+ alignments = types.map { |type| DL::PackInfo::ALIGN_MAP[type] }
+
+ expected = DL::PackInfo.align 0, alignments[0]
+ expected += DL::PackInfo::SIZE_MAP[DL::TYPE_DOUBLE] * 2
+
+ expected = DL::PackInfo.align expected, alignments[1]
+ expected += DL::PackInfo::SIZE_MAP[DL::TYPE_CHAR] * 20
+
+ expected = DL::PackInfo.align expected, alignments.max
+
+ assert_equal expected, size
+ end
+end
+