tduehr-libmatty 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ class Range
2
+ module RangeExtensions
3
+ # again, surprised this isn't in the library
4
+ def each_backwards
5
+ max.to_i.downto(min) {|i| yield i}
6
+ end
7
+
8
+ # Take a random number out of a range
9
+ #
10
+ def choice
11
+ rand(self.last - self.first) + self.first
12
+ end
13
+ alias_method :choose, :choice
14
+ end
15
+ include RangeExtensions
16
+ end
@@ -0,0 +1,20 @@
1
+ class Socket
2
+ module SocketExtensions
3
+ module ClassMethods
4
+ def addr(host, port=nil)
5
+ if not port
6
+ raise "bad!" if not host =~ /(.*):(.*)/
7
+ host = $1
8
+ port = $2
9
+ end
10
+ port = port.to_i
11
+ Socket.pack_sockaddr_in(port, host)
12
+ end
13
+ end
14
+
15
+ def self.included(klass)
16
+ klass.extend(ClassMethods)
17
+ end
18
+ end
19
+ include SocketExtensions
20
+ end
@@ -0,0 +1,450 @@
1
+ class String
2
+ module StringExtensions
3
+
4
+ if String.instance_methods.include? :toutf16
5
+ alias_method :to_utf16, :toutf16
6
+ else
7
+ # Convert a string to "Unicode", ie, the way Win32 expects it, including
8
+ # trailing NUL.
9
+ def to_utf16
10
+ require 'iconv'
11
+ Iconv.iconv("utf-16LE", "utf-8", self).first + "\x00\x00"
12
+ end
13
+ alias_method :toutf16, :to_utf16
14
+ end
15
+
16
+ if String.instance_methods.include? :toutf8
17
+ # purely for old code using this library that may otherwise still work in 1.9
18
+ alias_method :to_utf8, :toutf8
19
+ alias_method :to_ascii, :toutf8
20
+ alias_method :from_utf16, :toutf8
21
+ else
22
+ # Convert a "Unicode" (Win32-style) string back to native Ruby UTF-8;
23
+ # get rid of any trailing NUL.
24
+ def from_utf16
25
+ require 'iconv'
26
+ ret = Iconv.iconv("utf-8", "utf-16le", self).first
27
+ if ret[-1] == 0
28
+ ret = ret[0..-2]
29
+ end
30
+ end
31
+ alias_method :to_utf8, :from_utf16
32
+ alias_method :to_ascii, :from_utf16
33
+ alias_method :toutf8, :from_utf16
34
+ end
35
+
36
+ # Convenience for parsing UNICODE strings from a buffer
37
+ # Assumes last char ends in 00, which is not always true but works in English
38
+ def from_utf16_buffer
39
+ self[0..index("\0\0\0")+2].from_utf16
40
+ end
41
+
42
+ # Sometimes string buffers passed through Win32 interfaces come with
43
+ # garbage after the trailing NUL; this method gets rid of that, like
44
+ # String#trim
45
+ def asciiz
46
+ begin
47
+ self[0..self.index("\x00")-1]
48
+ rescue
49
+ self
50
+ end
51
+ end
52
+
53
+ def asciiz!
54
+ replace asciiz
55
+ end
56
+
57
+ # shortcut for hex sanity with regex
58
+ # remember kids, always pratice safe hex
59
+ def is_hex? ; (self =~ /^[a-f0-9]+$/i)? true : false ; end
60
+
61
+ # My entry into the hexdump race. Outputs canonical hexdump, uses
62
+ # StringIO for speed, could be cleaned up with "ljust", and should
63
+ # probably use table lookup instead of to_s(16) method calls.
64
+ def hexdump(capture=false)
65
+ require 'stringio'
66
+ sio = StringIO.new
67
+ rem = size - 1
68
+ off = 0
69
+
70
+ while rem > 0
71
+ pbuf = ""
72
+ pad = (15 - rem) if rem < 16
73
+ pad ||= 0
74
+
75
+ sio.write(("0" * (8 - (x = off.to_s(16)).size)) + x + " ")
76
+
77
+ 0.upto(15-pad) do |i|
78
+ c = self[off]
79
+ x = c.to_s(16)
80
+ sio.write(("0" * (2 - x.size)) + x + " ")
81
+ if c.printable?
82
+ pbuf << c
83
+ else
84
+ pbuf << "."
85
+ end
86
+ off += 1
87
+ rem -= 1
88
+ sio.write(" ") if i == 7
89
+ end
90
+
91
+ sio.write("-- " * pad) if pad > 0
92
+ sio.write(" |#{ pbuf }|\n")
93
+ end
94
+
95
+ sio.rewind()
96
+ if capture
97
+ sio.read()
98
+ else
99
+ puts sio.read()
100
+ end
101
+ end
102
+
103
+ # convert a string to its idiomatic ruby class name
104
+ def class_name
105
+ r = ""
106
+ up = true
107
+ each_byte do |c|
108
+ if c == 95
109
+ if up
110
+ r << "::"
111
+ else
112
+ up = true
113
+ end
114
+ else
115
+ m = up ? :upcase : :to_s
116
+ r << (c.chr.send(m))
117
+ up = false
118
+ end
119
+ end
120
+ r
121
+ end
122
+
123
+ if not String.instance_methods.include?(:starts_with?)
124
+ # Insane that this isn't in the library by default.
125
+ # 1.9 does so we don't add it then
126
+ def starts_with? x
127
+ self[0..x.size-1] == x
128
+ end
129
+ end
130
+
131
+ if not String.instance_methods.include?(:starts_with?)
132
+ def ends_with? x
133
+ self[-(x.size)..-1] == x
134
+ end
135
+ end
136
+
137
+ # Cribbed from Ero Carrera's pefile; a relatively expensive entropy
138
+ # function, gives a float result of random-bits-per-byte.
139
+ def entropy
140
+ e = 0
141
+ 0.upto(255) do |i|
142
+ x = count(i.chr)/size.to_f
143
+ if x > 0
144
+ e += - x * Math.log2(x)
145
+ end
146
+ end
147
+
148
+ return e
149
+ end
150
+
151
+ # The driver function for String#strings below; really, this will
152
+ # run on any Enumerable that contains Fixnums.
153
+ def nextstring(opts={})
154
+ off = opts[:offset] || 0
155
+ sz = opts[:minimum] || 7
156
+ u = opts[:unicode] || false
157
+ l = size
158
+ i = off
159
+ while i < l
160
+ if self[i].printable?
161
+ start = i
162
+ cnt = 1
163
+ i += 1
164
+ lastu = false
165
+ while i < l
166
+ if self[i].printable?
167
+ lastu = false
168
+ cnt += 1
169
+ i += 1
170
+ elsif u and self[i] == 0 and not lastu
171
+ lastu = true
172
+ i += 1
173
+ else
174
+ break
175
+ end
176
+ end
177
+
178
+ return([start, i - start]) if cnt >= sz
179
+ else
180
+ i += 1
181
+ end
182
+ end
183
+
184
+ return false, false
185
+ end
186
+
187
+ # A la Unix strings(1). With a block, yields offset, string length,
188
+ # and contents. Otherwise returns a list. Accepts options:
189
+ # :unicode: superficial but effective Win32 Unicode support, skips NULs
190
+ # :minimum: minimum length of returned strings, ala strings -10
191
+ def strings(opts={})
192
+ ret = []
193
+ opts[:offset] ||= 0
194
+ while 1
195
+ off, size = nextstring(opts)
196
+ break if not off
197
+ opts[:offset] += (off + size)
198
+ if block_given?
199
+ yield off, size, self[off,size]
200
+ else
201
+ ret << [off, size, self[off,size]]
202
+ end
203
+ end
204
+ ret
205
+ end
206
+
207
+ # A hacked up adler16 checksum, a la Andrew Tridgell. This is probably
208
+ # even slower than Ruby's native CRC support. A weak, trivial checksum,
209
+ # part of rsync.
210
+ def adler
211
+ a, b = 0, 0
212
+ 0.upto(size-1) {|i| a += self[i]}
213
+ a %= 65536
214
+ 0.upto(size-1) {|i| b += ((size-i)+1) * self[i]}
215
+ b %= 65536
216
+ return (a|(b<<16))
217
+ end
218
+
219
+ # Convert binary strings back to integers
220
+ def to_l32; unpack("L").first; end
221
+ def to_b32; unpack("N").first; end
222
+ def to_l16; unpack("v").first; end
223
+ def to_b16; unpack("n").first; end
224
+ def to_u8; self[0]; end
225
+ def shift_l32; shift(4).to_l32; end
226
+ def shift_b32; shift(4).to_b32; end
227
+ def shift_l16; shift(2).to_l16; end
228
+ def shift_b16; shift(2).to_b16; end
229
+ def shift_u8; shift(1).to_u8; end
230
+
231
+ # oh, it's exactly what it sounds like.
232
+ def method_name
233
+ r = ""
234
+ scoped = false
235
+ each_byte do |c|
236
+ if c == 58
237
+ if not scoped
238
+ r << "_"
239
+ scoped = true
240
+ else
241
+ scoped = false
242
+ end
243
+ else
244
+ if r.size == 0
245
+ r << c.chr.downcase
246
+ else
247
+ if c.upper?
248
+ r << "_"
249
+ r << c.chr.downcase
250
+ else
251
+ r << c.chr
252
+ end
253
+ end
254
+ end
255
+ end
256
+ return r
257
+ end
258
+
259
+ # I love you String#ljust
260
+ def pad(size, char="\x00")
261
+ ljust(size, char)
262
+ end
263
+
264
+ # Convert a string into hex characters
265
+ def hexify
266
+ l = []
267
+ each_byte{|b| l << "%02x" % b}
268
+ l.join
269
+ end
270
+
271
+ # convert a string to hex characters in place
272
+ def hexify!
273
+ self.replace hexify
274
+ end
275
+
276
+
277
+ # Convert a string of raw hex characters (no %'s or anything) into binary
278
+ def dehexify
279
+ (ret||="") << (me||=clone).shift(2).to_i(16).chr while not (me||=clone).empty?
280
+ return ret
281
+ end
282
+
283
+ # Convert a string of raw hex characters (no %'s or anything) into binary in place
284
+ def dehexify!
285
+ (ret||="") << (me||=clone).shift(2).to_i(16).chr while not (me||=clone).empty?
286
+ self.replace ret
287
+ end
288
+
289
+ # OR two strings together. Slow. Handles mismatched lengths by zero-extending
290
+ def or(str)
291
+ max = size < str.size ? str.size : size
292
+ ret = ""
293
+ 0.upto(max-1) do |i|
294
+ x = self[i] || 0
295
+ y = str[i] || 0
296
+ ret << (x | y).chr
297
+ end
298
+ return ret
299
+ end
300
+
301
+ # XOR two strings. wrapping around if str is shorter than self.
302
+ def xor(str)
303
+ r = []
304
+ size.times do |i|
305
+ r << (self[i] ^ str[i % str.size]).chr
306
+ end
307
+ return r.join
308
+ end
309
+
310
+ def xor!(str)
311
+ size.times do |i|
312
+ self[i] ^= str[i % str.size]
313
+ end
314
+ end
315
+
316
+ # byte rotation cypher (yes it's been useful)
317
+ def rotate_bytes(k=0)
318
+ r = []
319
+ each_byte do |b|
320
+ r << ((b + k) % 256).chr
321
+ end
322
+ return r.join
323
+ end
324
+
325
+ # Insanely useful shorthand: pop bytes off the front of a string
326
+ def shift(count=1)
327
+ return self if count == 0
328
+ slice! 0..(count-1)
329
+ end
330
+
331
+ def underscore
332
+ first = false
333
+ gsub(/[a-z0-9][A-Z]/) do |m|
334
+ "#{ m[0].chr }_#{ m[1].chr.downcase }"
335
+ end
336
+ end
337
+
338
+ # "foo: bar".shift_tok /:\s*/ => "foo" # leaving "bar"
339
+ def shift_tok(rx)
340
+ src = rx.source if rx.kind_of? Regexp
341
+ rx = Regexp.new "(#{ src })"
342
+ idx = (self =~ rx)
343
+ if idx
344
+ ret = shift(idx)
345
+ shift($1.size)
346
+ return ret
347
+ else
348
+ shift(self.size)
349
+ end
350
+ end
351
+
352
+ # Base64 encode
353
+ def b64(len=nil)
354
+ ret = [self].pack("m").gsub("\n", "")
355
+ if len and Numeric === len
356
+ ret.scan(/.{1,#{len}}/).join("\n") + "\n"
357
+ else
358
+ ret
359
+ end
360
+ end
361
+
362
+ # Base64 decode
363
+ def d64; self.unpack("m")[0]; end
364
+
365
+ # Returns a single null-terminated ascii string from beginning of self.
366
+ # This will return the entire string if no null is encountered.
367
+ #
368
+ # Parameters:
369
+ #
370
+ # off = specify an optional beggining offset
371
+ #
372
+ def cstring(off=0)
373
+ self[ off, self.index("\x00") || self.size ]
374
+ end
375
+
376
+ # returns CRC32 checksum for the string object
377
+ def crc32
378
+ ## pure ruby version. slower, but here for reference (found on some forum)
379
+ # r = 0xFFFFFFFF
380
+ # self.each_byte do |b|
381
+ # r ^= b
382
+ # 8.times do
383
+ # r = (r>>1) ^ (0xEDB88320 * (r & 1))
384
+ # end
385
+ # end
386
+ # r ^ 0xFFFFFFFF
387
+ # # or... we can just use:
388
+ require 'zlib'
389
+ Zlib.crc32 self
390
+ end
391
+
392
+ # TODO: this needs to work differently....
393
+ # # Returns a reference to actual constant for a given name in namespace
394
+ # # can be used to lookup classes from enums and such
395
+ # def const_lookup(ns=Object)
396
+ # if c=ns.constants.select {|n| n == self.class_name } and not c.empty?
397
+ # ns.const_get(c.first)
398
+ # end
399
+ # end
400
+
401
+ # Return a self encapsulated in a StringIO object.
402
+ def to_stringio
403
+ require 'stringio'
404
+ StringIO.new(self)
405
+ end
406
+
407
+ # a pbcopy from irb on any String object
408
+ # yes, we're a mac shop.
409
+ def pbcopy
410
+ IO.popen("pbcopy", "w") {|io| io.write self}
411
+ end if Object::RUBY_PLATFORM =~ /darwin/
412
+
413
+ def md5
414
+ require 'digest/md5'
415
+ Digest::MD5.digest(self).hexify
416
+ end
417
+
418
+ def sha1
419
+ require 'digest/sha1'
420
+ Digest::SHA1.digest(self).hexify
421
+ end
422
+
423
+ def sha256
424
+ require 'digest/sha256'
425
+ Digest::SHA256.digest(self).hexify
426
+ end
427
+
428
+ def sha512
429
+ require 'digest/sha512'
430
+ Digest::SHA512.digest(self).hexify
431
+ end
432
+
433
+ # fast 37 hash of a string, for non-security stuff.
434
+ def hashcode
435
+ return 5381 if not ((l = self.size) and l > 0)
436
+ code = 0
437
+ 0.upto(l-1) do |i|
438
+ code = ((code << 5) - code) + self[i]
439
+ end
440
+ code
441
+ end
442
+
443
+ # Returns a Time object for a string representing seconds since epoch
444
+ # fmt: format to be passed to String#to_i (see String#to_i)
445
+ def time_at(fmt=0)
446
+ Time.at(self.to_i(fmt))
447
+ end
448
+ end
449
+ include StringExtensions
450
+ end