ipconverter 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cf2a5bcd16c2e1debc4e76243f377950e2e29886
4
- data.tar.gz: e23960bd3f703c5a0e61eed15256ae7ac069cf79
3
+ metadata.gz: a5c6788e7c3fc69744f0dc2f24403f73eca1ca1f
4
+ data.tar.gz: 2698334ced4e0b518741dc61ab0920e79476ab0a
5
5
  SHA512:
6
- metadata.gz: 68b2fb9ad042f6c2dbca75ef28eae042d2df7a4a34371637e94b6e71ceae060157a8a0c3706d44fcbced43db9bb2ca3efcda03d95716fdcee693b49371dc3f11
7
- data.tar.gz: 58f602f002d910d26c07563a82c4d10a95b06cc2be2fc05f0fac13a1c23cfb4030f499321652ec8d2a09489c8465e0859cb1f6495b9070f7a1ebaae05d7df216
6
+ metadata.gz: ae82161f4019c9223c3d1daca44cede206c70a2909503c7d077bbff8be044e081fb9e48209ce387ad8ad6ec13f5d6732a6b9963b3fbacd13c9023fba19d1cd4f
7
+ data.tar.gz: 740c071a89938af5001e5a62a27161c7859352cd6184b168595e8209b65928f8c348ab1e8b8f7c13bc3c376bd0ca2788c93b497aa732cc619f12add4fed50b07
@@ -0,0 +1,23 @@
1
+ require 'benchmark'
2
+ require 'ipaddr'
3
+ require 'ipconverter'
4
+
5
+ def ruby_shift(ip)
6
+ [
7
+ (ip >> 24) & 255,
8
+ (ip >> 16) & 255,
9
+ (ip >> 8) & 255,
10
+ (ip >> 0) & 255
11
+ ].join('.')
12
+ end
13
+
14
+ ips = 0..999999
15
+
16
+ puts 'iterations: 1,000,000'
17
+
18
+ Benchmark.bmbm do |x|
19
+ x.report('IPAddr#to_s') { ips.each { |ip| IPAddr.new(ip, Socket::AF_INET).to_s } }
20
+ x.report('Ruby shifts') { ips.each { |ip| ruby_shift(ip) } }
21
+ x.report('C shifts') { ips.each { |ip| IpConverter.int_to_str(ip) } }
22
+ x.report('noop') { ips.each { |ip| ip } }
23
+ end
@@ -29,7 +29,7 @@ ips = []
29
29
  end
30
30
  end
31
31
 
32
- puts 'iterations: ' + ips.length
32
+ puts 'iterations: 1,000,000'
33
33
 
34
34
  Benchmark.bmbm do |x|
35
35
  x.report('IPAddr#to_i') { ips.each { |ip| IPAddr.new(ip).to_i } }
@@ -1,12 +1,15 @@
1
1
  #include <ruby.h>
2
2
  #include "ipconverter.h"
3
3
 
4
+ #define MAX_IP_INT 4294967295
5
+
4
6
  // Module name
5
7
  VALUE IpConverter = Qnil;
6
8
 
7
9
  void Init_ipconverter() {
8
10
  IpConverter = rb_define_module("IpConverter");
9
11
  rb_define_method(IpConverter, "str_to_int", method_str_to_int, 1);
12
+ rb_define_method(IpConverter, "int_to_str", method_int_to_str, 1);
10
13
  }
11
14
 
12
15
  /*
@@ -68,3 +71,40 @@ ip_string_to_long(char c_string[], uint32_t *result) {
68
71
  return 1;
69
72
  }
70
73
 
74
+ /*
75
+ * call-seq:
76
+ * IpConverter.int_to_str(ip_addr_integer) -> String
77
+ *
78
+ * Converts the passed integer into an IPv4 address string.
79
+ *
80
+ * Raises ArugmentError if number is negative, or greater than the maximum
81
+ * possible value for an IPv4 address (4294967295)
82
+ *
83
+ * Example:
84
+ * IpConverter.int_to_str(3232236033)
85
+ * => "192.168.2.1"
86
+ *
87
+ */
88
+ VALUE
89
+ method_int_to_str(VALUE _module_, VALUE ip_fixnum) {
90
+ char c_string[16];
91
+ int64_t ip = NUM2LL(ip_fixnum);
92
+ if (ip > MAX_IP_INT || ip < 0) {
93
+ rb_raise(rb_eArgError, "IP address integer out of range");
94
+ }
95
+ ip_long_to_string((uint32_t)ip, c_string);
96
+ return rb_str_new2(c_string);
97
+ }
98
+
99
+ // This one is a void because the bounds checking is done with the uint32_t
100
+ // type already.
101
+ static void
102
+ ip_long_to_string(uint32_t ip, char c_string[]) {
103
+ uint8_t bytes[4];
104
+ bytes[0] = ip & 0xFF;
105
+ bytes[1] = (ip >> 8) & 0xFF;
106
+ bytes[2] = (ip >> 16) & 0xFF;
107
+ bytes[3] = (ip >> 24) & 0xFF;
108
+
109
+ sprintf(c_string, "%d.%d.%d.%d", bytes[3], bytes[2], bytes[1], bytes[0]);
110
+ }
@@ -1,3 +1,7 @@
1
1
  VALUE method_str_to_int(VALUE, VALUE);
2
2
  static int ip_string_to_long(char[], uint32_t*);
3
+
4
+ VALUE method_int_to_str(VALUE, VALUE);
5
+ static void ip_long_to_string(uint32_t, char[]);
6
+
3
7
  void Init_ipconverter();
@@ -8,4 +8,5 @@ require 'ipconverter/ipconverter'
8
8
  #
9
9
  module IpConverter
10
10
  module_function :str_to_int
11
+ module_function :int_to_str
11
12
  end
@@ -1,3 +1,3 @@
1
1
  module IpConverter
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -2,6 +2,7 @@ require 'ipconverter'
2
2
  require 'minitest/autorun'
3
3
 
4
4
  class TestIpConverter < MiniTest::Test
5
+ MAX_IP_INT = 4294967295
5
6
  def setup
6
7
  end
7
8
 
@@ -13,7 +14,7 @@ class TestIpConverter < MiniTest::Test
13
14
  def test_largest_ip
14
15
  int = IpConverter.str_to_int '255.255.255.255'
15
16
  # maximum 32-bit integer
16
- assert_equal int, 256 * 256 * 256 * 256 - 1
17
+ assert_equal int, MAX_IP_INT
17
18
  end
18
19
 
19
20
  def test_handles_spaces
@@ -36,4 +37,20 @@ class TestIpConverter < MiniTest::Test
36
37
  def test_junk
37
38
  assert_raises(ArgumentError) { IpConverter.str_to_int 'junk' }
38
39
  end
40
+
41
+ def test_int_to_str_0
42
+ assert_equal "0.0.0.0", IpConverter.int_to_str(0)
43
+ end
44
+
45
+ def test_int_to_str_max
46
+ assert_equal "255.255.255.255", IpConverter.int_to_str(MAX_IP_INT)
47
+ end
48
+
49
+ def test_int_to_str_negative
50
+ assert_raises(ArgumentError) { IpConverter.int_to_str -1 }
51
+ end
52
+
53
+ def test_int_to_str_too_big
54
+ assert_raises(ArgumentError) { IpConverter.int_to_str(MAX_IP_INT + 1) }
55
+ end
39
56
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ipconverter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Scott
@@ -81,7 +81,8 @@ files:
81
81
  - LICENSE.txt
82
82
  - README.md
83
83
  - Rakefile
84
- - bench.rb
84
+ - benchmark/int_to_str.rb
85
+ - benchmark/str_to_int.rb
85
86
  - ext/ipconverter/extconf.rb
86
87
  - ext/ipconverter/ipconverter.c
87
88
  - ext/ipconverter/ipconverter.h