rsmaz 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/Manifest.txt +13 -0
- data/PostInstall.txt +6 -0
- data/README.rdoc +70 -0
- data/Rakefile +28 -0
- data/lib/rsmaz.rb +182 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/rsmaz_spec.rb +56 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +14 -0
- data/tasks/rspec.rake +21 -0
- metadata +91 -0
data/History.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
== 0.0.3 2009-04-02
|
2
|
+
|
3
|
+
* Now produces same output as reference smaz implementation
|
4
|
+
* Better compression
|
5
|
+
* Performance tweaks
|
6
|
+
* Initial steps of Rubyizing the algorithm
|
7
|
+
|
8
|
+
== 0.0.2 2009-04-02
|
9
|
+
|
10
|
+
* Ruby 1.9 support added
|
11
|
+
|
12
|
+
== 0.0.1 2009-04-02
|
13
|
+
|
14
|
+
* Initial release
|
data/Manifest.txt
ADDED
data/PostInstall.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
= rsmaz
|
2
|
+
|
3
|
+
* http://github.com/peterc/rsmaz/tree/master
|
4
|
+
* http://github.com/antirez/smaz/tree/master (original C version)
|
5
|
+
|
6
|
+
== DESCRIPTION:
|
7
|
+
|
8
|
+
Short String Compression for Ruby.
|
9
|
+
|
10
|
+
RSmaz is a pure-Ruby port of the Smaz short string compression
|
11
|
+
algorithm by Salvatore Sanfilippo and released as a C library at:
|
12
|
+
http://github.com/antirez/smaz/tree/master
|
13
|
+
|
14
|
+
I've done some initial cleanup of a pure Ruby->C port, but this
|
15
|
+
is not yet complete. It does pass the specs, however! Feel free
|
16
|
+
to clean it up as it's a bit memory inefficient right now... :)
|
17
|
+
|
18
|
+
== REQUIREMENTS:
|
19
|
+
|
20
|
+
* RSpec (if you want to run the specs)
|
21
|
+
* Some strings to compress
|
22
|
+
* A sense of humor
|
23
|
+
|
24
|
+
== USAGE:
|
25
|
+
|
26
|
+
require 'rsmaz'
|
27
|
+
r = RSmaz.compress("whatever")
|
28
|
+
puts RSmaz.decompress(r)
|
29
|
+
|
30
|
+
== RSMAZ LICENSE:
|
31
|
+
|
32
|
+
Copyright (c) 2009 Peter Cooper, Salvatore Sanfilippo
|
33
|
+
|
34
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
35
|
+
a copy of this software and associated documentation files (the
|
36
|
+
'Software'), to deal in the Software without restriction, including
|
37
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
38
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
39
|
+
permit persons to whom the Software is furnished to do so, subject to
|
40
|
+
the following conditions:
|
41
|
+
|
42
|
+
The above copyright notice and this permission notice shall be
|
43
|
+
included in all copies or substantial portions of the Software.
|
44
|
+
|
45
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
46
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
47
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
48
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
49
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
50
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
51
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
52
|
+
|
53
|
+
== SMAZ LICENSE:
|
54
|
+
|
55
|
+
Copyright (c) 2006-2009, Salvatore Sanfilippo
|
56
|
+
All rights reserved.
|
57
|
+
|
58
|
+
Redistribution and use in source and binary forms, with or without
|
59
|
+
modification, are permitted provided that the following conditions are met:
|
60
|
+
|
61
|
+
* Redistributions of source code must retain the above copyright
|
62
|
+
notice, this list of conditions and the following disclaimer.
|
63
|
+
* Redistributions in binary form must reproduce the above copyright
|
64
|
+
notice, this list of conditions and the following disclaimer in the
|
65
|
+
documentation and/or other materials provided with the distribution.
|
66
|
+
* Neither the name of Smaz nor the names of its contributors may be
|
67
|
+
used to endorse or promote products derived from this software without
|
68
|
+
specific prior written permission.
|
69
|
+
|
70
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
2
|
+
require File.dirname(__FILE__) + '/lib/rsmaz'
|
3
|
+
|
4
|
+
# Generate all the Rake tasks
|
5
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
6
|
+
$hoe = Hoe.new('rsmaz', RSmaz::VERSION) do |p|
|
7
|
+
p.developer('Peter Cooper', 'pcooper@petercooper.co.uk')
|
8
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
9
|
+
p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
|
10
|
+
p.rubyforge_name = p.name # TODO this is default value
|
11
|
+
# p.extra_deps = [
|
12
|
+
# ['activesupport','>= 2.0.2'],
|
13
|
+
# ]
|
14
|
+
p.extra_dev_deps = [
|
15
|
+
['newgem', ">= #{::Newgem::VERSION}"]
|
16
|
+
]
|
17
|
+
|
18
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
19
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
20
|
+
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
21
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'newgem/tasks' # load /tasks/*.rake
|
25
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
26
|
+
|
27
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
28
|
+
# task :default => [:spec, :features]
|
data/lib/rsmaz.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'strscan'
|
5
|
+
|
6
|
+
# Silly hack to allow usage of String#ord in Ruby 1.9 without breaking Ruby 1.8
|
7
|
+
if RUBY_VERSION < '1.9.0'
|
8
|
+
class String
|
9
|
+
def ord; self[0]; end;
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# RSmaz is too small to bother splitting into separate files, so I'll be lazy..
|
14
|
+
module RSmaz
|
15
|
+
VERSION = '0.0.3'
|
16
|
+
|
17
|
+
# From http://github.com/antirez/smaz/blob/4b913924e15b7663ee0240af19cedfd266052aab/smaz.c
|
18
|
+
CODEBOOK = ["\002s,\266", "\003had\232\002leW", "\003on \216", "", "\001yS",
|
19
|
+
"\002ma\255\002li\227", "\003or \260", "", "\002ll\230\003s t\277",
|
20
|
+
"\004fromg\002mel", "", "\003its\332", "\001z\333", "\003ingF", "\001>\336",
|
21
|
+
"\001 \000\003 (\002nc\344", "\002nd=\003 on\312",
|
22
|
+
"\002ne\213\003hat\276\003re q", "", "\002ngT\003herz\004have\306\003s o\225",
|
23
|
+
"", "\003ionk\003s a\254\002ly\352", "\003hisL\003 inN\003 be\252", "",
|
24
|
+
"\003 fo\325\003 of \003 ha\311", "", "\002of\005",
|
25
|
+
"\003 co\241\002no\267\003 ma\370", "", "", "\003 cl\356\003enta\003 an7",
|
26
|
+
"\002ns\300\001\"e", "\003n t\217\002ntP\003s, \205",
|
27
|
+
"\002pe\320\003 we\351\002om\223", "\002on\037", "", "\002y G", "\003 wa\271",
|
28
|
+
"\003 re\321\002or*", "", "\002=\"\251\002ot\337", "\003forD\002ou[",
|
29
|
+
"\003 toR", "\003 th\r", "\003 it\366",
|
30
|
+
"\003but\261\002ra\202\003 wi\363\002</\361", "\003 wh\237", "\002 4",
|
31
|
+
"\003nd ?", "\002re!", "", "\003ng c", "",
|
32
|
+
"\003ly \307\003ass\323\001a\004\002rir", "", "", "", "\002se_", "\003of \"",
|
33
|
+
"\003div\364\002ros\003ere\240", "", "\002ta\310\001bZ\002si\324", "",
|
34
|
+
"\003and\a\002rs\335", "\002rt\362", "\002teE", "\003ati\316", "\002so\263",
|
35
|
+
"\002th\021", "\002tiJ\001c\034\003allp", "\003ate\345", "\002ss\246",
|
36
|
+
"\002stM", "", "\002><\346", "\002to\024", "\003arew", "\001d\030",
|
37
|
+
"\002tr\303", "", "\001\n1\003 a \222", "\003f tv\002veo", "\002un\340", "",
|
38
|
+
"\003e o\242", "\002a \243\002wa\326\001e\002", "\002ur\226\003e a\274",
|
39
|
+
"\002us\244\003\n\r\n\247", "\002ut\304\003e c\373", "\002we\221", "", "",
|
40
|
+
"\002wh\302", "\001f,", "", "", "", "\003d t\206", "", "", "\003th \343",
|
41
|
+
"\001g;", "", "", "\001\r9\003e s\265", "\003e t\234", "", "\003to Y",
|
42
|
+
"\003e\r\n\236", "\002d \036\001h\022", "", "\001,Q", "\002 a\031", "\002 b^",
|
43
|
+
"\002\r\n\025\002 cI", "\002 d\245", "\002 e\253", "\002 fh\001i\b\002e \v",
|
44
|
+
"", "\002 hU\001-\314", "\002 i8", "", "", "\002 l\315", "\002 m{",
|
45
|
+
"\002f :\002 n\354", "\002 o\035", "\002 p}\001.n\003\r\n\r\250", "",
|
46
|
+
"\002 r\275", "\002 s>", "\002 t\016", "", "\002g \235\005which+\003whi\367",
|
47
|
+
"\002 w5", "\001/\305", "\003as \214", "\003at \207", "", "\003who\331", "",
|
48
|
+
"\001l\026\002h \212", "", "\002, $", "", "\004withV", "", "", "", "\001m-", "",
|
49
|
+
"", "\002ac\357", "\002ad\350", "\003TheH", "", "", "\004this\233\001n\t",
|
50
|
+
"", "\002. y", "", "\002alX\003e, \365", "\003tio\215\002be\\",
|
51
|
+
"\002an\032\003ver\347", "", "\004that0\003tha\313\001o\006", "\003was2",
|
52
|
+
"\002arO", "\002as.", "\002at'\003the\001\004they\200\005there\322\005theird",
|
53
|
+
"\002ce\210", "\004were]", "", "\002ch\231\002l \264\001p<", "", "",
|
54
|
+
"\003one\256", "", "\003he \023\002dej", "\003ter\270", "\002cou", "",
|
55
|
+
"\002by\177\002di\201\002eax", "", "\002ec\327", "\002edB", "\002ee\353", "",
|
56
|
+
"", "\001r\f\002n )", "", "", "", "\002el\262", "", "\003in i\002en3", "",
|
57
|
+
"\002o `\001s\n", "", "\002er\033", "\003is t\002es6", "", "\002ge\371",
|
58
|
+
"\004.com\375", "\002fo\334\003our\330", "\003ch \301\001t\003", "\002hab", "",
|
59
|
+
"\003men\374", "", "\002he\020", "", "", "\001u&", "\002hif", "",
|
60
|
+
"\003not\204\002ic\203", "\003ed @\002id\355", "", "", "\002ho\273",
|
61
|
+
"\002r K\001vm", "", "", "", "\003t t\257\002il\360", "\002im\342",
|
62
|
+
"\003en \317\002in\017", "\002io\220", "\002s \027\001wA", "", "\003er |",
|
63
|
+
"\003es ~\002is%", "\002it/", "", "\002iv\272", "",
|
64
|
+
"\002t #\ahttp://C\001x\372", "\002la\211", "\001<\341", "\003, a\224"]
|
65
|
+
|
66
|
+
# From http://github.com/antirez/smaz/blob/4b913924e15b7663ee0240af19cedfd266052aab/smaz.c
|
67
|
+
REVERSE_CODEBOOK = [" ", "the", "e", "t", "a", "of", "o", "and", "i", "n", "s", "e ", "r", " th",
|
68
|
+
" t", "in", "he", "th", "h", "he ", "to", "\r\n", "l", "s ", "d", " a", "an",
|
69
|
+
"er", "c", " o", "d ", "on", " of", "re", "of ", "t ", ", ", "is", "u", "at",
|
70
|
+
" ", "n ", "or", "which", "f", "m", "as", "it", "that", "\n", "was", "en",
|
71
|
+
" ", " w", "es", " an", " i", "\r", "f ", "g", "p", "nd", " s", "nd ", "ed ",
|
72
|
+
"w", "ed", "http://", "for", "te", "ing", "y ", "The", " c", "ti", "r ", "his",
|
73
|
+
"st", " in", "ar", "nt", ",", " to", "y", "ng", " h", "with", "le", "al", "to ",
|
74
|
+
"b", "ou", "be", "were", " b", "se", "o ", "ent", "ha", "ng ", "their", "\"",
|
75
|
+
"hi", "from", " f", "in ", "de", "ion", "me", "v", ".", "ve", "all", "re ",
|
76
|
+
"ri", "ro", "is ", "co", "f t", "are", "ea", ". ", "her", " m", "er ", " p",
|
77
|
+
"es ", "by", "they", "di", "ra", "ic", "not", "s, ", "d t", "at ", "ce", "la",
|
78
|
+
"h ", "ne", "as ", "tio", "on ", "n t", "io", "we", " a ", "om", ", a", "s o",
|
79
|
+
"ur", "li", "ll", "ch", "had", "this", "e t", "g ", "e\r\n", " wh", "ere",
|
80
|
+
" co", "e o", "a ", "us", " d", "ss", "\n\r\n", "\r\n\r", "=\"", " be", " e",
|
81
|
+
"s a", "ma", "one", "t t", "or ", "but", "el", "so", "l ", "e s", "s,", "no",
|
82
|
+
"ter", " wa", "iv", "ho", "e a", " r", "hat", "s t", "ns", "ch ", "wh", "tr",
|
83
|
+
"ut", "/", "have", "ly ", "ta", " ha", " on", "tha", "-", " l", "ati", "en ",
|
84
|
+
"pe", " re", "there", "ass", "si", " fo", "wa", "ec", "our", "who", "its", "z",
|
85
|
+
"fo", "rs", ">", "ot", "un", "<", "im", "th ", "nc", "ate", "><", "ver", "ad",
|
86
|
+
" we", "ly", "ee", " n", "id", " cl", "ac", "il", "</", "rt", " wi", "div",
|
87
|
+
"e, ", " it", "whi", " ma", "ge", "x", "e c", "men", ".com"]
|
88
|
+
|
89
|
+
# Compress a string to Smaz encoding
|
90
|
+
def self.compress(input)
|
91
|
+
verb = ""
|
92
|
+
out = ""
|
93
|
+
input = input.dup
|
94
|
+
|
95
|
+
# This algorithm has been ported to Ruby from C and only
|
96
|
+
# slightly Rubyized.. still a lonnnng way to go. Wanna give it a crack?
|
97
|
+
while (input && input.length > 0)
|
98
|
+
h1 = h2 = input.ord << 3
|
99
|
+
h2 += input[1,1].ord if (input.length > 1)
|
100
|
+
h3 = (input.length > 2) ? h2 ^ input[2,1].ord : 0
|
101
|
+
q = []
|
102
|
+
|
103
|
+
[input.length, 7].min.downto(1) do |j|
|
104
|
+
slot = if j == 1
|
105
|
+
CODEBOOK[h1 % 241].dup
|
106
|
+
elsif j == 2
|
107
|
+
CODEBOOK[h2 % 241].dup
|
108
|
+
else
|
109
|
+
CODEBOOK[h3 % 241].dup
|
110
|
+
end
|
111
|
+
|
112
|
+
while (slot && slot[0]) do
|
113
|
+
if (slot.ord == j && (slot[1,j] == input[0,j]))
|
114
|
+
# Match found in hash table
|
115
|
+
|
116
|
+
# Add verbatim data, if any (yes, it's quicker with the check)
|
117
|
+
unless verb.empty?
|
118
|
+
q << verb
|
119
|
+
verb = ""
|
120
|
+
end
|
121
|
+
|
122
|
+
# Add encoded data and ditch unnecessary part of input string
|
123
|
+
q << slot[slot.ord+1,1].ord
|
124
|
+
input.slice!(0..j-1)
|
125
|
+
break
|
126
|
+
else
|
127
|
+
# This in-place hack is quicker than slot = slot[1..-1]
|
128
|
+
|
129
|
+
slot.reverse!.chop!.reverse!
|
130
|
+
#slot.slice!(0)
|
131
|
+
#slot[0] = ''
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# No queue? It means we matched nothing, so add the current byte to the verbatim buffer
|
137
|
+
if q.empty?
|
138
|
+
verb << input[0,1] if input[0]
|
139
|
+
input.slice!(0)
|
140
|
+
end
|
141
|
+
|
142
|
+
# If the verbatim buffer is getting too long or we're at the end of the doc
|
143
|
+
# throw the verbatim buffer to the output queue
|
144
|
+
q << verb if verb.length == 256 || (verb.length > 0 && input.length == 0)
|
145
|
+
|
146
|
+
# Turn the queue into correctly encoded data
|
147
|
+
out << q.collect do |item|
|
148
|
+
if item.class == String && item.length == 1
|
149
|
+
"\376" + item
|
150
|
+
elsif item.class == String && item.length > 1
|
151
|
+
"\377" + (item.length - 1).chr + item
|
152
|
+
elsif item.class == Fixnum
|
153
|
+
item.chr
|
154
|
+
end
|
155
|
+
end.join
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
out
|
160
|
+
end
|
161
|
+
|
162
|
+
# Decompress a Smaz encoded string back to normal plain text
|
163
|
+
def self.decompress(input)
|
164
|
+
out = ""
|
165
|
+
s = StringScanner.new(input)
|
166
|
+
until s.eos?
|
167
|
+
bv = s.get_byte.ord
|
168
|
+
if (bv == 254)
|
169
|
+
out << s.get_byte
|
170
|
+
elsif (bv == 255)
|
171
|
+
len = s.get_byte.ord + 1
|
172
|
+
len.times do
|
173
|
+
out << s.get_byte
|
174
|
+
end
|
175
|
+
else
|
176
|
+
out << REVERSE_CODEBOOK[bv]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
out
|
181
|
+
end
|
182
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/rsmaz.rb'}"
|
9
|
+
puts "Loading rsmaz gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/spec/rsmaz_spec.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe RSmaz do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
# Do some memory leak checking
|
7
|
+
puts "\nMemory used: #{memory_usage}K"
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:each) do
|
11
|
+
puts "\nMemory used: #{memory_usage}K"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should compress 'the' to one byte" do
|
15
|
+
RSmaz.compress("the").length.should == 1
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should compress 'thex' to two bytes" do
|
19
|
+
RSmaz.compress("thex").length.should == 2
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should compress and decompress strings back to the same string" do
|
23
|
+
[
|
24
|
+
"This is a test.",
|
25
|
+
"This is a test",
|
26
|
+
"this is a test",
|
27
|
+
"Let's try a SlIgHtLy Funkie938R str1ng!?!?x",
|
28
|
+
"What about a long one?" * 100
|
29
|
+
].each { |str| RSmaz.decompress(RSmaz.compress(str)).should == str }
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should properly decode a reference compression (so the internal coding doesn't change)" do
|
33
|
+
RSmaz.decompress("\020\230`A\376o\f\026\030").should == "hello world"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should compress to the same extent as the reference smaz implementation" do
|
37
|
+
RSmaz.compress("foobar").length.should == 4
|
38
|
+
RSmaz.compress("Nel mezzo del cammin di nostra vita, mi ritrovai in una selva oscura").length.should == 46
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should compress and decompress lots of random strings without issues" do
|
42
|
+
100.times do
|
43
|
+
str = (1..100).map { |a| (rand(26)+97).chr }.join
|
44
|
+
RSmaz.decompress(RSmaz.compress(str)).length.should == str.length
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should compress and decompress lots of random strings without issues (again)" do
|
49
|
+
100.times do
|
50
|
+
str = (1..100).map { |a| (rand(26)+97).chr }.join
|
51
|
+
RSmaz.decompress(RSmaz.compress(str)).length.should == str.length
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
begin
|
2
|
+
require 'spec'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
gem 'rspec'
|
6
|
+
require 'spec'
|
7
|
+
end
|
8
|
+
|
9
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
10
|
+
require 'rsmaz'
|
11
|
+
|
12
|
+
def memory_usage
|
13
|
+
`ps -Orss #{Process.pid} | tail -1`.scan(/\d+/)[1].to_i rescue 0
|
14
|
+
end
|
data/tasks/rspec.rake
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'spec'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
require 'spec'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'spec/rake/spectask'
|
9
|
+
rescue LoadError
|
10
|
+
puts <<-EOS
|
11
|
+
To use rspec for testing you must install rspec gem:
|
12
|
+
gem install rspec
|
13
|
+
EOS
|
14
|
+
exit(0)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Run the specs under spec/models"
|
18
|
+
Spec::Rake::SpecTask.new do |t|
|
19
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
20
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rsmaz
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Cooper
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-02 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: newgem
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.3.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.8.0
|
34
|
+
version:
|
35
|
+
description: "Short String Compression for Ruby. RSmaz is a pure-Ruby port of the Smaz short string compression algorithm by Salvatore Sanfilippo and released as a C library at: http://github.com/antirez/smaz/tree/master I've done some initial cleanup of a pure Ruby->C port, but this is not yet complete. It does pass the specs, however! Feel free to clean it up as it's a bit memory inefficient right now... :)"
|
36
|
+
email:
|
37
|
+
- pcooper@petercooper.co.uk
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- History.txt
|
44
|
+
- Manifest.txt
|
45
|
+
- PostInstall.txt
|
46
|
+
- README.rdoc
|
47
|
+
files:
|
48
|
+
- History.txt
|
49
|
+
- Manifest.txt
|
50
|
+
- PostInstall.txt
|
51
|
+
- README.rdoc
|
52
|
+
- Rakefile
|
53
|
+
- lib/rsmaz.rb
|
54
|
+
- script/console
|
55
|
+
- script/destroy
|
56
|
+
- script/generate
|
57
|
+
- spec/rsmaz_spec.rb
|
58
|
+
- spec/spec.opts
|
59
|
+
- spec/spec_helper.rb
|
60
|
+
- tasks/rspec.rake
|
61
|
+
has_rdoc: true
|
62
|
+
homepage: http://github.com/peterc/rsmaz/tree/master
|
63
|
+
licenses: []
|
64
|
+
|
65
|
+
post_install_message: PostInstall.txt
|
66
|
+
rdoc_options:
|
67
|
+
- --main
|
68
|
+
- README.rdoc
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: "0"
|
82
|
+
version:
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project: rsmaz
|
86
|
+
rubygems_version: 1.3.5
|
87
|
+
signing_key:
|
88
|
+
specification_version: 2
|
89
|
+
summary: Short String Compression for Ruby
|
90
|
+
test_files: []
|
91
|
+
|