ipconverter 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/benchmark/int_to_str.rb +23 -0
- data/{bench.rb → benchmark/str_to_int.rb} +1 -1
- data/ext/ipconverter/ipconverter.c +40 -0
- data/ext/ipconverter/ipconverter.h +4 -0
- data/lib/ipconverter.rb +1 -0
- data/lib/ipconverter/version.rb +1 -1
- data/test/test_ipconverter.rb +18 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5c6788e7c3fc69744f0dc2f24403f73eca1ca1f
|
4
|
+
data.tar.gz: 2698334ced4e0b518741dc61ab0920e79476ab0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
@@ -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
|
+
}
|
data/lib/ipconverter.rb
CHANGED
data/lib/ipconverter/version.rb
CHANGED
data/test/test_ipconverter.rb
CHANGED
@@ -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,
|
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.
|
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
|
-
-
|
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
|