tduehr-libmatty 0.9.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.
- data/History.txt +3 -0
- data/README.txt +28 -0
- data/Rakefile +35 -0
- data/bin/libmatty +8 -0
- data/lib/libmatty.rb +49 -0
- data/lib/libmatty/array.rb +42 -0
- data/lib/libmatty/class.rb +167 -0
- data/lib/libmatty/dir.rb +23 -0
- data/lib/libmatty/duplicable.rb +39 -0
- data/lib/libmatty/enumerable.rb +16 -0
- data/lib/libmatty/file.rb +32 -0
- data/lib/libmatty/fixnum.rb +25 -0
- data/lib/libmatty/hash.rb +47 -0
- data/lib/libmatty/integer.rb +120 -0
- data/lib/libmatty/ipaddr.rb +113 -0
- data/lib/libmatty/irb.rb +29 -0
- data/lib/libmatty/math.rb +6 -0
- data/lib/libmatty/module.rb +67 -0
- data/lib/libmatty/numeric.rb +12 -0
- data/lib/libmatty/object.rb +33 -0
- data/lib/libmatty/range.rb +16 -0
- data/lib/libmatty/socket.rb +20 -0
- data/lib/libmatty/string.rb +450 -0
- data/lib/libmatty/symbol.rb +15 -0
- data/spec/libmatty_spec.rb +8 -0
- data/spec/spec_helper.rb +16 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/test_libmatty.rb +0 -0
- metadata +108 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
class Fixnum
|
2
|
+
module FixnumExtensions
|
3
|
+
# Ridiculous that this isn't in the library.
|
4
|
+
def printable?; self >= 0x20 and self <= 0x7e; end
|
5
|
+
|
6
|
+
# Like Numeric#Step, but yields the length of each span along with
|
7
|
+
# the offset. Useful for stepping through data in increments:
|
8
|
+
# 0.stepwith(buffer.size, 4096) {|off,len| pp buffer[off,len]}
|
9
|
+
# The "len" parameter accounts for the inevitable short final block.
|
10
|
+
def stepwith(limit, stepv, &block)
|
11
|
+
step(limit, stepv) do |i|
|
12
|
+
remt = limit - i
|
13
|
+
yield i, remt.cap(stepv)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# you can't clone a fixnum? Why?
|
18
|
+
def clone; self; end
|
19
|
+
|
20
|
+
def upper?; self >= 0x41 and self <= 0x5a; end
|
21
|
+
def lower?; self >= 0x61 and self <= 0x7a; end
|
22
|
+
end
|
23
|
+
include FixnumExtensions
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Hash
|
2
|
+
module HashExtensions
|
3
|
+
# XXX does the same thing as Hash#invert i think?
|
4
|
+
def flip
|
5
|
+
map {|k,v| [v,k]}.to_hash
|
6
|
+
end
|
7
|
+
|
8
|
+
# Model.create(params.deny_keys(:password, :isadmin))
|
9
|
+
##
|
10
|
+
def allow_keys(*keys)
|
11
|
+
tmp = self.clone
|
12
|
+
tmp.delete_if {|k,v| ! keys.include?(k) }
|
13
|
+
tmp
|
14
|
+
end
|
15
|
+
|
16
|
+
def allow_keys!(*keys)
|
17
|
+
delete_if{|k,v| ! keys.include?(k) }
|
18
|
+
end
|
19
|
+
|
20
|
+
# Filter a list of keys, rejecting the ones we don't
|
21
|
+
# want to allow through.
|
22
|
+
def deny_keys(*keys)
|
23
|
+
tmp = self.clone
|
24
|
+
tmp.delete_if {|k,v| keys.include?(k) }
|
25
|
+
tmp
|
26
|
+
end
|
27
|
+
|
28
|
+
# {:foo=>"bar"}.xfrm(:foo => :meep) ==> {:meep=>"bar"}
|
29
|
+
def xfrm(opts={})
|
30
|
+
self.map do |k,v|
|
31
|
+
x = [opts.fetch(k, k), v]
|
32
|
+
pp x
|
33
|
+
x
|
34
|
+
end.to_h
|
35
|
+
end
|
36
|
+
class KeyRequired < RuntimeError; end
|
37
|
+
|
38
|
+
def demand(*args)
|
39
|
+
args.each do |a|
|
40
|
+
if not self.has_key? a
|
41
|
+
raise KeyRequired, "option #{ a } required"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
include HashExtensions
|
47
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
class Integer
|
2
|
+
module IntegerExtensions
|
3
|
+
# Convert integers to binary strings
|
4
|
+
def to_l32; [self].pack "L"; end
|
5
|
+
def to_b32; [self].pack "N"; end
|
6
|
+
def to_l16; [self].pack "v"; end
|
7
|
+
def to_b16; [self].pack "n"; end
|
8
|
+
def to_u8; [self].pack "C"; end
|
9
|
+
|
10
|
+
# sign extend
|
11
|
+
def sx8; ([self].pack "c").unpack("C").first; end
|
12
|
+
def sx16; ([self].pack "s").unpack("S").first; end
|
13
|
+
def sx32; ([self].pack "l").unpack("L").first; end
|
14
|
+
|
15
|
+
# Print a number in hex
|
16
|
+
def to_hex(pre="0x"); pre + to_s(16); end
|
17
|
+
|
18
|
+
# Print a number in binary
|
19
|
+
def to_b(pre=""); pre + to_s(2); end
|
20
|
+
|
21
|
+
def clear_bits(c); (self ^ (self & c)); end
|
22
|
+
|
23
|
+
def ffs
|
24
|
+
i = 0
|
25
|
+
v = self
|
26
|
+
while((v >>= 1) != 0)
|
27
|
+
i += 1
|
28
|
+
end
|
29
|
+
return i
|
30
|
+
end
|
31
|
+
module ClassMethods
|
32
|
+
# Make a bitmask with m-many bits, as an Integer
|
33
|
+
def mask_for(m)
|
34
|
+
# This is just table lookup for values less than 65
|
35
|
+
|
36
|
+
@@mask ||= {
|
37
|
+
1 => 0x1,
|
38
|
+
2 => 0x3,
|
39
|
+
3 => 0x7,
|
40
|
+
4 => 0xf,
|
41
|
+
5 => 0x1f,
|
42
|
+
6 => 0x3f,
|
43
|
+
7 => 0x7f,
|
44
|
+
8 => 0xff,
|
45
|
+
9 => 0x1ff,
|
46
|
+
10 => 0x3ff,
|
47
|
+
11 => 0x7ff,
|
48
|
+
12 => 0xfff,
|
49
|
+
13 => 0x1fff,
|
50
|
+
14 => 0x3fff,
|
51
|
+
15 => 0x7fff,
|
52
|
+
16 => 0xffff,
|
53
|
+
17 => 0x1ffff,
|
54
|
+
18 => 0x3ffff,
|
55
|
+
19 => 0x7ffff,
|
56
|
+
20 => 0xfffff,
|
57
|
+
21 => 0x1fffff,
|
58
|
+
22 => 0x3fffff,
|
59
|
+
23 => 0x7fffff,
|
60
|
+
24 => 0xffffff,
|
61
|
+
25 => 0x1ffffff,
|
62
|
+
26 => 0x3ffffff,
|
63
|
+
27 => 0x7ffffff,
|
64
|
+
28 => 0xfffffff,
|
65
|
+
29 => 0x1fffffff,
|
66
|
+
30 => 0x3fffffff,
|
67
|
+
31 => 0x7fffffff,
|
68
|
+
32 => 0xffffffff,
|
69
|
+
33 => 0x1ffffffff,
|
70
|
+
34 => 0x3ffffffff,
|
71
|
+
35 => 0x7ffffffff,
|
72
|
+
36 => 0xfffffffff,
|
73
|
+
37 => 0x1fffffffff,
|
74
|
+
38 => 0x3fffffffff,
|
75
|
+
39 => 0x7fffffffff,
|
76
|
+
40 => 0xffffffffff,
|
77
|
+
41 => 0x1ffffffffff,
|
78
|
+
42 => 0x3ffffffffff,
|
79
|
+
43 => 0x7ffffffffff,
|
80
|
+
44 => 0xfffffffffff,
|
81
|
+
45 => 0x1fffffffffff,
|
82
|
+
46 => 0x3fffffffffff,
|
83
|
+
47 => 0x7fffffffffff,
|
84
|
+
48 => 0xffffffffffff,
|
85
|
+
49 => 0x1ffffffffffff,
|
86
|
+
50 => 0x3ffffffffffff,
|
87
|
+
51 => 0x7ffffffffffff,
|
88
|
+
52 => 0xfffffffffffff,
|
89
|
+
53 => 0x1fffffffffffff,
|
90
|
+
54 => 0x3fffffffffffff,
|
91
|
+
55 => 0x7fffffffffffff,
|
92
|
+
56 => 0xffffffffffffff,
|
93
|
+
57 => 0x1ffffffffffffff,
|
94
|
+
58 => 0x3ffffffffffffff,
|
95
|
+
59 => 0x7ffffffffffffff,
|
96
|
+
60 => 0xfffffffffffffff,
|
97
|
+
61 => 0x1fffffffffffffff,
|
98
|
+
62 => 0x3fffffffffffffff,
|
99
|
+
63 => 0x7fffffffffffffff,
|
100
|
+
64 => 0xffffffffffffffff
|
101
|
+
}
|
102
|
+
|
103
|
+
if (v = @@mask[m])
|
104
|
+
return v
|
105
|
+
end
|
106
|
+
|
107
|
+
# Compute it for crazy values.
|
108
|
+
|
109
|
+
r = 0
|
110
|
+
0.upto(m-1) {|q| r |= (1 << q)}
|
111
|
+
return r
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.included(klass)
|
116
|
+
klass.extend(ClassMethods)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
include IntegerExtensions
|
120
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
class IPAddr
|
4
|
+
attr_reader :mask_addr
|
5
|
+
|
6
|
+
module IPAddrExtensions
|
7
|
+
|
8
|
+
# make an IP address take the int32 value provided
|
9
|
+
def set_int(ip)
|
10
|
+
set(ip, Socket::AF_INET)
|
11
|
+
end
|
12
|
+
|
13
|
+
# randomize the "host" part of the IP address (destructive)
|
14
|
+
def random(mask=0xFFFFFFFF)
|
15
|
+
r = rand(0xFFFFFFFF) & mask
|
16
|
+
i = self.to_i & (~mask)
|
17
|
+
self.set_int(i | r)
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :random!, :random
|
21
|
+
|
22
|
+
# convert a string to IP
|
23
|
+
def inet_addr(str)
|
24
|
+
in_addr(str)
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
# construct an IPAddr from a dotted quad string or integer
|
29
|
+
def inet_addr(str)
|
30
|
+
if str.kind_of? String
|
31
|
+
IPAddr.lite(str).to_i
|
32
|
+
else
|
33
|
+
i = IPAddr.new(0, Socket::AF_INET)
|
34
|
+
i.set_int(str)
|
35
|
+
return i
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# construct an IPAddr from a dotted quad string without
|
40
|
+
# incurring a reverse lookup.
|
41
|
+
def lite(str)
|
42
|
+
ip = IPAddr.new(0, Socket::AF_INET)
|
43
|
+
|
44
|
+
parts = str.split "/"
|
45
|
+
|
46
|
+
ip.set_int(ip.inet_addr(parts[0]))
|
47
|
+
ip = ip.mask parts[1] if parts[1]
|
48
|
+
return ip
|
49
|
+
end
|
50
|
+
|
51
|
+
# Convert 255.255.255.0 to 24
|
52
|
+
def mask2mlen(mask)
|
53
|
+
len = 0
|
54
|
+
while len < 32 && mask & 0x80000000 != 0
|
55
|
+
mask <<= 1
|
56
|
+
mask &= 0xFFFFFFFF
|
57
|
+
len += 1
|
58
|
+
end
|
59
|
+
return len
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.included(klass)
|
64
|
+
klass.extend(ClassMethods)
|
65
|
+
end
|
66
|
+
|
67
|
+
# to_s with a cidr prefix at the end
|
68
|
+
def to_cidr_s
|
69
|
+
"#{ to_s }/#{ self.class.mask2mlen(@mask_addr) }"
|
70
|
+
end
|
71
|
+
|
72
|
+
# get the mask length
|
73
|
+
def to_mlen
|
74
|
+
mask = self.to_i
|
75
|
+
self.class.mask2mlen(mask)
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
# get the highest address in the range defined by the netmask
|
80
|
+
def top
|
81
|
+
IPAddr.inet_addr(self.to_i | (0xFFFFFFFF & (~self.mask_addr)))
|
82
|
+
end
|
83
|
+
|
84
|
+
# get the lowest address in the range defined by the netmask
|
85
|
+
def bottom
|
86
|
+
IPAddr.inet_addr(self.to_i & self.mask_addr)
|
87
|
+
end
|
88
|
+
|
89
|
+
# get a random address from within the range defined by the
|
90
|
+
# netmask.
|
91
|
+
def choice
|
92
|
+
return self.clone if self.mask_addr == 0xFFFFFFFF
|
93
|
+
|
94
|
+
span = self.top.to_i - self.bottom.to_i
|
95
|
+
x = self.clone
|
96
|
+
x.set_int(self.bottom.to_i + rand(span))
|
97
|
+
return x
|
98
|
+
end
|
99
|
+
|
100
|
+
# test if the address provided is in the range defined by the
|
101
|
+
# netmask
|
102
|
+
def contains(i)
|
103
|
+
if not i.kind_of? IPAddr
|
104
|
+
i = IPAddr.inet_addr i
|
105
|
+
end
|
106
|
+
|
107
|
+
i.to_i >= self.bottom.to_i and i.to_i <= self.top.to_i
|
108
|
+
end
|
109
|
+
|
110
|
+
alias_method :contains?, :contains
|
111
|
+
end
|
112
|
+
include IPAddrExtensions
|
113
|
+
end
|
data/lib/libmatty/irb.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'irb'
|
2
|
+
|
3
|
+
module IRB
|
4
|
+
# Lifted from http://errtheblog.com/posts/9-drop-to-irb
|
5
|
+
# Starts an IRB session with a specific binding. To use type:
|
6
|
+
# IRB.start_session(binding)
|
7
|
+
def self.start_session(binding)
|
8
|
+
IRB.setup(nil)
|
9
|
+
|
10
|
+
workspace = WorkSpace.new(binding)
|
11
|
+
|
12
|
+
if @CONF[:SCRIPT]
|
13
|
+
irb = Irb.new(workspace, @CONF[:SCRIPT])
|
14
|
+
else
|
15
|
+
irb = Irb.new(workspace)
|
16
|
+
end
|
17
|
+
|
18
|
+
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
19
|
+
@CONF[:MAIN_CONTEXT] = irb.context
|
20
|
+
|
21
|
+
trap("SIGINT") do
|
22
|
+
irb.signal_handle
|
23
|
+
end
|
24
|
+
|
25
|
+
catch(:IRB_EXIT) do
|
26
|
+
irb.eval_input
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class Module
|
2
|
+
module ModuleExtensions
|
3
|
+
def to_name_hash
|
4
|
+
@name_hash ||= constants.map {|k| [k.intern, const_get(k.intern)]}.to_hash
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_key_hash
|
8
|
+
@key_hash ||= constants.map {|k| [const_get(k.intern), k.intern]}.to_hash
|
9
|
+
end
|
10
|
+
|
11
|
+
def flag_dump(i)
|
12
|
+
@bit_map ||= constants.map do |k|
|
13
|
+
[k, const_get(k.intern).ffs]
|
14
|
+
end.sort {|x, y| x[1] <=> y[1]}
|
15
|
+
|
16
|
+
last = 0
|
17
|
+
r = ""
|
18
|
+
@bit_map.each do |tup|
|
19
|
+
if((v = (tup[1] - last)) > 1)
|
20
|
+
r << ("." * (v-1))
|
21
|
+
end
|
22
|
+
|
23
|
+
if((i & (1 << tup[1])) != 0)
|
24
|
+
r << tup[0][0].chr
|
25
|
+
else
|
26
|
+
r << tup[0][0].chr.downcase
|
27
|
+
end
|
28
|
+
last = tup[1]
|
29
|
+
end
|
30
|
+
return r.reverse
|
31
|
+
end
|
32
|
+
|
33
|
+
# When the base class method just returns nil
|
34
|
+
def stub(*args)
|
35
|
+
opts = {}
|
36
|
+
if args[-1].kind_of? Hash
|
37
|
+
opts = args[-1]
|
38
|
+
args = args[0..-2]
|
39
|
+
end
|
40
|
+
|
41
|
+
args.each do |meth|
|
42
|
+
class_def(meth) do |*a|; nil; end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Dynamically create instance methods
|
47
|
+
def class_def(name, &blk)
|
48
|
+
class_eval { define_method name, &blk }
|
49
|
+
end
|
50
|
+
|
51
|
+
module ClassMethods
|
52
|
+
# like const_get, but doesn't raise exception if sym not found.
|
53
|
+
def const_find(sym)
|
54
|
+
begin
|
55
|
+
const_get(sym)
|
56
|
+
rescue
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.included(klass)
|
63
|
+
klass.extend ClassMethods
|
64
|
+
end
|
65
|
+
end
|
66
|
+
include ModuleExtensions
|
67
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Numeric
|
2
|
+
module NumericExtensions
|
3
|
+
# This HAS TO BE in the library somewhere already, but: give a fixnum,
|
4
|
+
# cap it at some number (ie, max(x, y) -> x). 10.cap(9) => 9.
|
5
|
+
def cap(limit); self > limit ? limit : self; end
|
6
|
+
|
7
|
+
# shortcut for packing a single number...
|
8
|
+
def pack(arg) ; [self].pack(arg) ; end
|
9
|
+
|
10
|
+
end
|
11
|
+
include NumericExtensions
|
12
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Object
|
2
|
+
module ObjectExtensions
|
3
|
+
# don't need these if we're using 1.9
|
4
|
+
if not Object::RUBY_FRAMEWORK_VERSION == "1.9"
|
5
|
+
# Every object has a "singleton" class, which you can think
|
6
|
+
# of as the class (ie, 1.metaclass =~ Fixnum) --- but that you
|
7
|
+
# can modify and extend without fucking up the actual class.
|
8
|
+
|
9
|
+
def metaclass; class << self; self; end; end
|
10
|
+
def meta_eval(&blk) metaclass.instance_eval &blk; end
|
11
|
+
def meta_def(name, &blk) meta_eval { define_method name, &blk }; end
|
12
|
+
def try(meth, *args); send(meth, *args) if respond_to? meth; end
|
13
|
+
|
14
|
+
def through(meth, *args)
|
15
|
+
if respond_to? meth
|
16
|
+
send(meth, *args)
|
17
|
+
else
|
18
|
+
self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def pbpaste
|
24
|
+
`pbpaste`
|
25
|
+
end if RUBY_PLATFORM =~ /darwin/
|
26
|
+
|
27
|
+
## This is from Topher Cyll's Stupd IRB tricks
|
28
|
+
def mymethods
|
29
|
+
(self.methods - self.class.superclass.methods).sort
|
30
|
+
end
|
31
|
+
end
|
32
|
+
include ObjectExtensions
|
33
|
+
end
|