kingpong-bitwise_string_ops 0.1.2 → 0.1.3
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.
- data/README.rdoc +1 -2
- data/Rakefile +1 -1
- data/bitwise_string_ops.gemspec +5 -5
- data/ext/bitwise_string_ops.c +29 -13
- data/lib/bitwise_string_ops.rb +0 -4
- data/test/test_perl_equivalence.rb +79 -0
- data/test/test_string_and.rb +31 -0
- data/test/test_string_not.rb +14 -0
- data/test/test_string_or.rb +32 -0
- data/test/test_string_xor.rb +31 -0
- metadata +5 -3
data/README.rdoc
CHANGED
@@ -23,7 +23,7 @@ The operation is applied to each successive byte (not necessarily
|
|
23
23
|
character) in the source strings in parallel. For example, the result
|
24
24
|
of "AB" & "CD" is ("A" & "C") + ("B" & "D").
|
25
25
|
|
26
|
-
If the operands to a binary bitwise op are strings of different sizes,
|
26
|
+
If the operands to a binary bitwise op are strings of different sizes, |
|
27
27
|
and ^ ops act as though the shorter operand had additional zero bits on
|
28
28
|
the right, while the & op acts as though the longer operand were
|
29
29
|
truncated to the length of the shorter. The granularity for such
|
@@ -67,7 +67,6 @@ AND truncates to the shorter of the two:
|
|
67
67
|
|
68
68
|
= Known Issues
|
69
69
|
|
70
|
-
* Largely untested
|
71
70
|
* Completely untested with non-string rhs operands
|
72
71
|
|
73
72
|
= Author
|
data/Rakefile
CHANGED
data/bitwise_string_ops.gemspec
CHANGED
@@ -2,23 +2,23 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{bitwise_string_ops}
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Philip Garrett"]
|
9
|
-
s.date = %q{2009-08-
|
9
|
+
s.date = %q{2009-08-23}
|
10
10
|
s.description = %q{Bitwise operations for Ruby strings}
|
11
11
|
s.email = %q{philip@pastemagazine.com}
|
12
12
|
s.extensions = ["ext/extconf.rb"]
|
13
13
|
s.extra_rdoc_files = ["CHANGELOG", "ext/bitwise.c", "ext/bitwise_string_ops.c", "ext/bitwise_string_ops.h", "ext/extconf.rb", "lib/bitwise_string_ops.rb", "README.rdoc"]
|
14
|
-
s.files = ["bitwise_string_ops.gemspec", "CHANGELOG", "ext/bitwise.c", "ext/bitwise_string_ops.c", "ext/bitwise_string_ops.h", "ext/extconf.rb", "init.rb", "lib/bitwise_string_ops.rb", "Manifest", "Rakefile", "README.rdoc", "setup.rb", "test/test.rb", "test/test_helper.rb", "test/test_string_and.rb", "test/test_string_not.rb", "test/test_string_or.rb", "test/test_string_xor.rb"]
|
14
|
+
s.files = ["bitwise_string_ops.gemspec", "CHANGELOG", "ext/bitwise.c", "ext/bitwise_string_ops.c", "ext/bitwise_string_ops.h", "ext/extconf.rb", "init.rb", "lib/bitwise_string_ops.rb", "Manifest", "Rakefile", "README.rdoc", "setup.rb", "test/test.rb", "test/test_helper.rb", "test/test_string_and.rb", "test/test_string_not.rb", "test/test_string_or.rb", "test/test_string_xor.rb", "test/test_perl_equivalence.rb"]
|
15
15
|
s.homepage = %q{http://github.com/kingpong/bitwise_string_ops}
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bitwise_string_ops", "--main", "README.rdoc"]
|
17
17
|
s.require_paths = ["lib", "ext"]
|
18
18
|
s.rubyforge_project = %q{bitwise_string_ops}
|
19
19
|
s.rubygems_version = %q{1.3.3}
|
20
|
-
s.summary = %q{bitwise_string_ops 0.1.
|
21
|
-
s.test_files = ["test/test_helper.rb", "test/test_string_and.rb", "test/test_string_not.rb", "test/test_string_or.rb", "test/test_string_xor.rb"]
|
20
|
+
s.summary = %q{bitwise_string_ops 0.1.3}
|
21
|
+
s.test_files = ["test/test_helper.rb", "test/test_perl_equivalence.rb", "test/test_string_and.rb", "test/test_string_not.rb", "test/test_string_or.rb", "test/test_string_xor.rb"]
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
24
24
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
data/ext/bitwise_string_ops.c
CHANGED
@@ -29,6 +29,7 @@
|
|
29
29
|
|
30
30
|
// Defining a space for information and references about the module to be stored internally
|
31
31
|
VALUE BitwiseStringOps = Qnil;
|
32
|
+
static ID ToString;
|
32
33
|
|
33
34
|
// Prototype for the initialization method - Ruby calls this, not you
|
34
35
|
void Init_bitwise_string_ops();
|
@@ -39,21 +40,32 @@ VALUE method_bit_xor(VALUE self, VALUE other);
|
|
39
40
|
VALUE method_bit_and(VALUE self, VALUE other);
|
40
41
|
VALUE method_bit_not(VALUE self);
|
41
42
|
|
43
|
+
static VALUE to_s(VALUE o);
|
44
|
+
|
42
45
|
// The initialization method for this module
|
43
46
|
void Init_bitwise_string_ops()
|
44
47
|
{
|
45
48
|
BitwiseStringOps = rb_define_module("BitwiseStringOps");
|
46
|
-
|
47
|
-
rb_define_method(BitwiseStringOps, "
|
48
|
-
rb_define_method(BitwiseStringOps, "
|
49
|
-
rb_define_method(BitwiseStringOps, "
|
49
|
+
ToString = rb_intern("to_s");
|
50
|
+
rb_define_method(BitwiseStringOps, "|", method_bit_or, 1);
|
51
|
+
rb_define_method(BitwiseStringOps, "^", method_bit_xor, 1);
|
52
|
+
rb_define_method(BitwiseStringOps, "&", method_bit_and, 1);
|
53
|
+
rb_define_method(BitwiseStringOps, "~", method_bit_not, 0);
|
54
|
+
}
|
55
|
+
|
56
|
+
static VALUE to_s(VALUE o)
|
57
|
+
{
|
58
|
+
return rb_obj_is_kind_of(o,rb_cString)
|
59
|
+
? o : rb_funcall(o, ToString, 0);
|
50
60
|
}
|
51
61
|
|
52
62
|
VALUE method_bit_or(VALUE self, VALUE other)
|
53
63
|
{
|
54
|
-
|
55
|
-
|
56
|
-
|
64
|
+
VALUE left, right, right_s, dest;
|
65
|
+
left = StringValue(self);
|
66
|
+
right_s = to_s(other);
|
67
|
+
right = StringValue(right_s);
|
68
|
+
dest = rb_str_new(NULL, string_bitwise_or_result_len(RSTRING(left)->len,
|
57
69
|
RSTRING(right)->len));
|
58
70
|
string_bitwise_or(RSTRING(left)->ptr, RSTRING(left)->len,
|
59
71
|
RSTRING(right)->ptr, RSTRING(right)->len,
|
@@ -63,9 +75,11 @@ VALUE method_bit_or(VALUE self, VALUE other)
|
|
63
75
|
|
64
76
|
VALUE method_bit_xor(VALUE self, VALUE other)
|
65
77
|
{
|
66
|
-
|
67
|
-
|
68
|
-
|
78
|
+
VALUE left, right, right_s, dest;
|
79
|
+
left = StringValue(self);
|
80
|
+
right_s = to_s(other);
|
81
|
+
right = StringValue(right_s);
|
82
|
+
dest = rb_str_new(NULL, string_bitwise_xor_result_len(RSTRING(left)->len,
|
69
83
|
RSTRING(right)->len));
|
70
84
|
string_bitwise_xor(RSTRING(left)->ptr, RSTRING(left)->len,
|
71
85
|
RSTRING(right)->ptr, RSTRING(right)->len,
|
@@ -75,9 +89,11 @@ VALUE method_bit_xor(VALUE self, VALUE other)
|
|
75
89
|
|
76
90
|
VALUE method_bit_and(VALUE self, VALUE other)
|
77
91
|
{
|
78
|
-
|
79
|
-
|
80
|
-
|
92
|
+
VALUE left, right, right_s, dest;
|
93
|
+
left = StringValue(self);
|
94
|
+
right_s = to_s(other);
|
95
|
+
right = StringValue(right_s);
|
96
|
+
dest = rb_str_new(NULL, string_bitwise_and_result_len(RSTRING(left)->len,
|
81
97
|
RSTRING(right)->len));
|
82
98
|
string_bitwise_and(RSTRING(left)->ptr, RSTRING(left)->len,
|
83
99
|
RSTRING(right)->ptr, RSTRING(right)->len,
|
data/lib/bitwise_string_ops.rb
CHANGED
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
require 'test/test_helper'
|
4
|
+
require 'bitwise_string_ops'
|
5
|
+
|
6
|
+
class TestPerlEquivalence < Test::Unit::TestCase
|
7
|
+
|
8
|
+
PATH_SEP = RUBY_PLATFORM =~ /mswin/i ? ";" : ":"
|
9
|
+
GENERATOR = File.join(File.dirname(__FILE__),"testcases.pl")
|
10
|
+
|
11
|
+
def test_perl_equivalence
|
12
|
+
return unless perl = find_perl
|
13
|
+
pipe_reader(perl, GENERATOR) do |pipe|
|
14
|
+
while op = read_string(pipe)
|
15
|
+
case op
|
16
|
+
when "|"
|
17
|
+
result, left, right = read_strings(pipe,3)
|
18
|
+
assert_equal left | right, result
|
19
|
+
when "^"
|
20
|
+
result, left, right = read_strings(pipe,3)
|
21
|
+
assert_equal left ^ right, result
|
22
|
+
when "&"
|
23
|
+
result, left, right = read_strings(pipe,3)
|
24
|
+
assert_equal left & right, result
|
25
|
+
when "~"
|
26
|
+
result, operand = read_strings(pipe,2)
|
27
|
+
assert_equal ~operand, result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def find_perl
|
36
|
+
ENV["PATH"].split(PATH_SEP).
|
37
|
+
map {|path| File.join(path,"perl") }.
|
38
|
+
find {|perl| File.executable?(perl) }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Runs a command and yields an IO object opened for reading from the command.
|
42
|
+
# Does *NOT* do any shell expansion (that's the point).
|
43
|
+
# +args+ should be [program,arg1,...]
|
44
|
+
def pipe_reader(*args)
|
45
|
+
# avoid shell expansion using fork/exec
|
46
|
+
reader, writer = IO.pipe
|
47
|
+
pid = fork
|
48
|
+
if pid
|
49
|
+
writer.close
|
50
|
+
yield(reader)
|
51
|
+
Process.waitpid(pid)
|
52
|
+
else
|
53
|
+
begin
|
54
|
+
reader.close
|
55
|
+
STDIN.reopen("/dev/null")
|
56
|
+
STDOUT.reopen(writer)
|
57
|
+
exec(*args)
|
58
|
+
rescue => e
|
59
|
+
# prevent child from jumping out of this scope and continuing main program
|
60
|
+
STDERR.puts(e.to_s)
|
61
|
+
end
|
62
|
+
exit! # will only reach here if exec() failed
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def read_string(io)
|
67
|
+
length = io.read(4).unpack("N").first
|
68
|
+
io.read(length)
|
69
|
+
rescue => e
|
70
|
+
io.eof? ? nil : raise(e)
|
71
|
+
end
|
72
|
+
|
73
|
+
def read_strings(io,n)
|
74
|
+
ret = []
|
75
|
+
n.times { ret << read_string(io) }
|
76
|
+
ret
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
data/test/test_string_and.rb
CHANGED
@@ -5,6 +5,37 @@ require 'bitwise_string_ops'
|
|
5
5
|
|
6
6
|
class TestStringAnd < Test::Unit::TestCase
|
7
7
|
|
8
|
+
def test_empty
|
9
|
+
assert_equal "" & "", ""
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_single
|
13
|
+
assert_equal "0" & "1", "0"
|
14
|
+
assert_equal "a" & "A", "A"
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_multiple
|
18
|
+
assert_equal "01" & "10", "00"
|
19
|
+
assert_equal "aB" & "Ab", "AB"
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_overflow
|
23
|
+
assert_equal "111" & "00", "00"
|
24
|
+
assert_equal "00" & "111", "00"
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_non_string
|
28
|
+
assert_equal "1" & 1, "1" & "1"
|
29
|
+
assert_equal "10" & 1, "10" & "1"
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_truth_table
|
33
|
+
assert_equal "0" & "0", "0"
|
34
|
+
assert_equal "0" & "1", "0"
|
35
|
+
assert_equal "1" & "0", "0"
|
36
|
+
assert_equal "1" & "1", "1"
|
37
|
+
end
|
38
|
+
|
8
39
|
def test_perldoc
|
9
40
|
assert_equal "japh\nJunk" & "_____", "JAPH\n"
|
10
41
|
end
|
data/test/test_string_not.rb
CHANGED
@@ -5,6 +5,20 @@ require 'bitwise_string_ops'
|
|
5
5
|
|
6
6
|
class TestStringNot < Test::Unit::TestCase
|
7
7
|
|
8
|
+
def test_empty
|
9
|
+
assert_equal "" & "", ""
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_single
|
13
|
+
assert_equal ~"1", "\316"
|
14
|
+
assert_equal ~"a", "\236"
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_multiple
|
18
|
+
assert_equal ~"01", "\317\316"
|
19
|
+
assert_equal ~"aB", "\236\275"
|
20
|
+
end
|
21
|
+
|
8
22
|
def test_perldoc
|
9
23
|
assert_equal ~"japh", "\225\236\217\227"
|
10
24
|
end
|
data/test/test_string_or.rb
CHANGED
@@ -5,6 +5,38 @@ require 'bitwise_string_ops'
|
|
5
5
|
|
6
6
|
class TestStringOr < Test::Unit::TestCase
|
7
7
|
|
8
|
+
def test_empty
|
9
|
+
assert_equal "" | "", ""
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_single
|
13
|
+
assert_equal "0" | "1", "1"
|
14
|
+
assert_equal "a" | "A", "a"
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_multiple
|
18
|
+
assert_equal "01" | "10", "11"
|
19
|
+
assert_equal "aB" | "Ab", "ab"
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_overflow
|
23
|
+
assert_equal "111" | "00", "111"
|
24
|
+
assert_equal "00" | "111", "111"
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_non_string
|
28
|
+
assert_equal "1" | 1, "1" | "1"
|
29
|
+
assert_equal "10" | 1, "10" | "1"
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_truth_table
|
33
|
+
assert_equal "0" | "0", "0"
|
34
|
+
assert_equal "0" | "1", "1"
|
35
|
+
assert_equal "1" | "0", "1"
|
36
|
+
assert_equal "1" | "1", "1"
|
37
|
+
end
|
38
|
+
|
39
|
+
# superficial test for perl equivalency
|
8
40
|
def test_perldoc
|
9
41
|
assert_equal "JA" | " ph\n", "japh\n"
|
10
42
|
end
|
data/test/test_string_xor.rb
CHANGED
@@ -5,6 +5,37 @@ require 'bitwise_string_ops'
|
|
5
5
|
|
6
6
|
class TestStringXor < Test::Unit::TestCase
|
7
7
|
|
8
|
+
def test_empty
|
9
|
+
assert_equal "" ^ "", ""
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_single
|
13
|
+
assert_equal "0" ^ "1", "\001"
|
14
|
+
assert_equal "a" ^ "A", " "
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_multiple
|
18
|
+
assert_equal "01" ^ "10", "\001\001"
|
19
|
+
assert_equal "aB" ^ "Ab", " "
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_reversible
|
23
|
+
orig = "abc"
|
24
|
+
mask = "def"
|
25
|
+
assert_not_equal orig ^ mask, orig
|
26
|
+
assert_equal( (orig ^ mask) ^ mask, orig)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_non_string
|
30
|
+
assert_equal "1" ^ 1, "1" ^ "1"
|
31
|
+
assert_equal "10" ^ 1, "10" ^ "1"
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_overflow
|
35
|
+
assert_equal "111" ^ "00", "\001\0011"
|
36
|
+
assert_equal "00" ^ "111", "\001\0011"
|
37
|
+
end
|
38
|
+
|
8
39
|
def test_perldoc
|
9
40
|
assert_equal "j p \n" ^ " a h", "JAPH\n"
|
10
41
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kingpong-bitwise_string_ops
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Philip Garrett
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-23 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -46,6 +46,7 @@ files:
|
|
46
46
|
- test/test_string_not.rb
|
47
47
|
- test/test_string_or.rb
|
48
48
|
- test/test_string_xor.rb
|
49
|
+
- test/test_perl_equivalence.rb
|
49
50
|
has_rdoc: false
|
50
51
|
homepage: http://github.com/kingpong/bitwise_string_ops
|
51
52
|
licenses:
|
@@ -78,9 +79,10 @@ rubyforge_project: bitwise_string_ops
|
|
78
79
|
rubygems_version: 1.3.5
|
79
80
|
signing_key:
|
80
81
|
specification_version: 3
|
81
|
-
summary: bitwise_string_ops 0.1.
|
82
|
+
summary: bitwise_string_ops 0.1.3
|
82
83
|
test_files:
|
83
84
|
- test/test_helper.rb
|
85
|
+
- test/test_perl_equivalence.rb
|
84
86
|
- test/test_string_and.rb
|
85
87
|
- test/test_string_not.rb
|
86
88
|
- test/test_string_or.rb
|