digest-stringbuffer 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e170734bb2055e267955391de34165d1af9cc5d4
4
+ data.tar.gz: c984f2440dd44c3719273f6defd693ee5014ae23
5
+ SHA512:
6
+ metadata.gz: 233b13755506b9d932fb9455edc9992fcd256299e2dc872b3c9ba5e20e6a9a9f95d840af59e9b7e280958c938a6c43a5f5b47c0b1902f97eadd9600e6c6573fa
7
+ data.tar.gz: 4dd16f861e12e782e93ac5355c9cb9e4dbaa6228706dd130424f777f0df5c96752773a47ca27592cd54467fbcc7688eb7aaf01da3a8e09d5f4f92c80ad70d1d2
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.bundle
4
+ *.so
5
+ *.o
6
+ .bundle
7
+ .config
8
+ .yardoc
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 ksss
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,93 @@
1
+ # Digest::StringBuffer
2
+
3
+ [![Build Status](https://travis-ci.org/ksss/digest-stringbuffer.png?branch=master)](https://travis-ci.org/ksss/digest-stringbuffer)
4
+
5
+ **Digest::StringBuffer** is a class that just only to string buffering for message digest.
6
+
7
+ **Digest::StringBuffer** increase speed by limiting function.
8
+
9
+ **Digest::StringBuffer** more fast than **Digest::Class** when calculate hash meny times.
10
+
11
+ ## Usage
12
+
13
+ Digest::StringBuffer depends only one method `finish`.
14
+
15
+ ```ruby
16
+ module Digest
17
+ class Prime31
18
+ def initialize
19
+ @prime = 31
20
+ end
21
+
22
+ def finish
23
+ result = 0
24
+ buffer.unpack("C*").each do |c|
25
+ result += (c * @prime)
26
+ end
27
+ [result & 0xffffffff].pack("N")
28
+ end
29
+ end
30
+ end
31
+
32
+ p Digest::Prime.hexdigest("abc" * 1000) #=> "008b1190"
33
+ ```
34
+
35
+ ## APIs
36
+
37
+ ### Class methods
38
+
39
+ `digest`: make self instance and execute `update` and `digest`
40
+
41
+ `hexdigest`: make self instance and execute `update` and `hexdigest`
42
+
43
+ ### Instance methods
44
+
45
+ `update`: add string in buffer.
46
+
47
+ `<<`: alias of `update`.
48
+
49
+ `finish`: should be overriden subclasses.
50
+
51
+ `reset`: initialize instance
52
+
53
+ `digest`: execute `finish`. it's should be return string.
54
+
55
+ `digest!`: execute `digest` and `reset`
56
+
57
+ `hexdigest`: execute `digest` and change to hex string.
58
+
59
+ `hexdigest!`: execute `hexdigest` and `reset`
60
+
61
+ `digest_length`: byte size of `digest`
62
+
63
+ `length`: and `size` alias of `digest`
64
+
65
+ `==`: check same string when execute `digest`
66
+
67
+ `initialize_copy`: run when `dup` and `clone`
68
+
69
+ `to_s`: same mean `hexdigest` when no arguments
70
+
71
+ `buffer`: string of all buffering now.
72
+
73
+ ## Installation
74
+
75
+ Add this line to your application's Gemfile:
76
+
77
+ gem 'digest-stringbuffer'
78
+
79
+ And then execute:
80
+
81
+ $ bundle
82
+
83
+ Or install it yourself as:
84
+
85
+ $ gem install digest-stringbuffer
86
+
87
+ ## Contributing
88
+
89
+ 1. Fork it
90
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
91
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
92
+ 4. Push to the branch (`git push origin my-new-feature`)
93
+ 5. Create new Pull Request
@@ -0,0 +1,21 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.rspec_opts = ["-c", "-f progress", "-Ilib"]
8
+ t.pattern = "spec/**/*_spec.rb"
9
+ t.verbose = true
10
+ end
11
+ task :spec => :compile
12
+
13
+ require 'rake/extensiontask'
14
+ spec = Bundler::GemHelper.gemspec
15
+ Rake::ExtensionTask.new('stringbuffer', spec) do |ext|
16
+ ext.ext_dir = 'ext/digest/stringbuffer'
17
+ ext.lib_dir = 'lib/digest/stringbuffer'
18
+ end
19
+
20
+
21
+ task :default => [:spec]
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'digest/stringbuffer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "digest-stringbuffer"
8
+ spec.version = Digest::StringBuffer::VERSION
9
+ spec.author = "ksss"
10
+ spec.email = "co000ri@gmail.com"
11
+ spec.description = %q{Digest::StringBuffer is a class that subset of Digest::Instance.}
12
+ spec.summary = %q{Digest::StringBuffer is a class that subset of Digest::Instance.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+ spec.extensions = ["ext/digest/stringbuffer/extconf.rb"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec", ['~> 2.11']
25
+ spec.add_development_dependency "rake-compiler", ["~> 0.8.3"]
26
+ end
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ $preload = %w[digest]
4
+
5
+ create_makefile('digest/stringbuffer')
@@ -0,0 +1,336 @@
1
+ #include "ruby.h"
2
+
3
+ /*
4
+ * digest module from https://github.com/ruby/ruby/blob/trunk/ext/digest/digest.c
5
+ * Copyright (C) 1995-2001 Yukihiro Matsumoto
6
+ * Copyright (C) 2001-2006 Akinori MUSHA
7
+ */
8
+
9
+ #define BUFFER_INIT 64
10
+
11
+ typedef struct {
12
+ char* buffer;
13
+ char* p;
14
+ size_t memsize;
15
+ } buffer_t;
16
+
17
+ static void
18
+ buffer_init(buffer_t* ptr)
19
+ {
20
+ ptr->buffer = (char*) xmalloc(sizeof(char) * BUFFER_INIT);
21
+ ptr->p = ptr->buffer;
22
+ ptr->memsize = BUFFER_INIT;
23
+ }
24
+
25
+ static void
26
+ buffer_realloc(buffer_t* ptr, size_t size)
27
+ {
28
+ char* buffer;
29
+
30
+ buffer = (char*) xrealloc(ptr->buffer, size);
31
+ if (buffer == NULL)
32
+ rb_raise(rb_eNoMemError, "failed to realloc");
33
+
34
+ ptr->buffer = buffer;
35
+ }
36
+
37
+ static void
38
+ buffer_free(buffer_t* ptr)
39
+ {
40
+ xfree(ptr->buffer);
41
+ }
42
+
43
+ static size_t
44
+ buffer_buffer_length(buffer_t* ptr)
45
+ {
46
+ return ptr->p - ptr->buffer;
47
+ }
48
+
49
+ static VALUE
50
+ buffer_alloc(VALUE self)
51
+ {
52
+ buffer_t* ptr = ALLOC(buffer_t);
53
+ buffer_init(ptr);
54
+ return Data_Wrap_Struct(self, 0, buffer_free, ptr);
55
+ }
56
+
57
+ static VALUE
58
+ hexencode_str_new(VALUE str_digest)
59
+ {
60
+ char *digest;
61
+ size_t digest_len;
62
+ size_t i;
63
+ VALUE str;
64
+ char *p;
65
+ static const char hex[] = {
66
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
67
+ 'a', 'b', 'c', 'd', 'e', 'f'
68
+ };
69
+
70
+ StringValue(str_digest);
71
+ digest = RSTRING_PTR(str_digest);
72
+ digest_len = RSTRING_LEN(str_digest);
73
+
74
+ if (LONG_MAX / 2 < digest_len) {
75
+ rb_raise(rb_eRuntimeError, "digest string too long");
76
+ }
77
+
78
+ str = rb_usascii_str_new(0, digest_len * 2);
79
+
80
+ for (i = 0, p = RSTRING_PTR(str); i < digest_len; i++) {
81
+ unsigned char byte = digest[i];
82
+
83
+ p[i + i] = hex[byte >> 4];
84
+ p[i + i + 1] = hex[byte & 0x0f];
85
+ }
86
+
87
+ return str;
88
+ }
89
+
90
+ static VALUE
91
+ buffer_initialize_copy(VALUE copy, VALUE origin)
92
+ {
93
+ buffer_t *ptr_copy, *ptr_origin;
94
+ size_t buffer_len;
95
+
96
+ if (copy == origin) return copy;
97
+
98
+ rb_check_frozen(copy);
99
+
100
+ Data_Get_Struct(copy, buffer_t, ptr_copy);
101
+ Data_Get_Struct(origin, buffer_t, ptr_origin);
102
+
103
+ buffer_len = buffer_buffer_length(ptr_origin);
104
+
105
+ if (ptr_copy->memsize < ptr_origin->memsize) {
106
+ buffer_realloc(ptr_copy, sizeof(char) * ptr_origin->memsize);
107
+ ptr_copy->memsize = ptr_origin->memsize;
108
+ }
109
+
110
+ memcpy(ptr_copy->buffer, ptr_origin->buffer, buffer_len);
111
+ ptr_copy->p = ptr_copy->buffer + buffer_len;
112
+
113
+ return copy;
114
+ }
115
+
116
+ static VALUE
117
+ buffer_reset(VALUE self)
118
+ {
119
+ buffer_t *ptr;
120
+ Data_Get_Struct(self, buffer_t, ptr);
121
+ ptr->p = ptr->buffer;
122
+ return self;
123
+ }
124
+
125
+ static VALUE
126
+ buffer_update(VALUE self, VALUE str)
127
+ {
128
+ size_t buffer_len, str_len, require, newsize;
129
+ const char* str_p;
130
+ buffer_t *ptr;
131
+ Data_Get_Struct(self, buffer_t, ptr);
132
+
133
+ StringValue(str);
134
+ str_p = RSTRING_PTR(str);
135
+ str_len = RSTRING_LEN(str);
136
+ buffer_len = buffer_buffer_length(ptr);
137
+ require = buffer_len + str_len;
138
+ if (ptr->memsize < require) {
139
+ newsize = ptr->memsize;
140
+ while (newsize < require) {
141
+ newsize *= 2;
142
+ }
143
+ buffer_realloc(ptr, sizeof(char) * newsize);
144
+ ptr->p = ptr->buffer + buffer_len;
145
+ ptr->memsize = newsize;
146
+ }
147
+ memcpy(ptr->p, str_p, str_len);
148
+ ptr->p += str_len;
149
+
150
+ return self;
151
+ }
152
+
153
+ static VALUE
154
+ buffer_finish(VALUE self)
155
+ {
156
+ rb_raise(rb_eRuntimeError, "%s does not implement finish()",
157
+ rb_obj_classname(self));
158
+ }
159
+
160
+ static VALUE
161
+ buffer_digest(int argc, VALUE *argv, VALUE self)
162
+ {
163
+ VALUE str, value;
164
+
165
+ if (0 < rb_scan_args(argc, argv, "01", &str)) {
166
+ buffer_reset(self);
167
+ buffer_update(self, str);
168
+ value = rb_funcall(self, rb_intern("finish"), 0);
169
+ buffer_reset(self);
170
+ } else {
171
+ value = rb_funcall(self, rb_intern("finish"), 0);
172
+ }
173
+
174
+ return value;
175
+ }
176
+
177
+ static VALUE
178
+ buffer_digest_bang(VALUE self)
179
+ {
180
+ VALUE value = rb_funcall(self, rb_intern("finish"), 0);
181
+ buffer_reset(self);
182
+
183
+ return value;
184
+ }
185
+
186
+ static VALUE
187
+ buffer_hexdigest(int argc, VALUE *argv, VALUE self)
188
+ {
189
+ return hexencode_str_new(buffer_digest(argc, argv, self));
190
+ }
191
+
192
+ static VALUE
193
+ buffer_hexdigest_bang(VALUE self)
194
+ {
195
+ return hexencode_str_new(buffer_digest_bang(self));
196
+ }
197
+
198
+ static VALUE
199
+ buffer_to_s(VALUE self)
200
+ {
201
+ return hexencode_str_new(buffer_digest(0, 0, self));
202
+ }
203
+
204
+ static VALUE
205
+ buffer_digest_length(VALUE self)
206
+ {
207
+ /* subclasses really should redefine this method */
208
+ VALUE digest = buffer_digest(0, 0, self);
209
+
210
+ /* never blindly assume that #digest() returns a string */
211
+ StringValue(digest);
212
+ return UINT2NUM(RSTRING_LEN(digest));
213
+ }
214
+
215
+ static VALUE
216
+ buffer_equal(VALUE self, VALUE other)
217
+ {
218
+ VALUE str1, str2;
219
+ str1 = buffer_digest(0, 0, self);
220
+ str2 = buffer_digest(0, 0, other);
221
+
222
+ StringValue(str1);
223
+ StringValue(str2);
224
+
225
+ if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&
226
+ rb_str_cmp(str1, str2) == 0) {
227
+ return Qtrue;
228
+ } else {
229
+ return Qfalse;
230
+ }
231
+ }
232
+
233
+ static VALUE
234
+ buffer_inspect(VALUE self)
235
+ {
236
+ VALUE str;
237
+ size_t digest_len = 32; /* about this size at least */
238
+ const char *cname;
239
+
240
+ cname = rb_obj_classname(self);
241
+
242
+ /* #<Digest::ClassName: xxxxx...xxxx> */
243
+ str = rb_str_buf_new(2 + strlen(cname) + 2 + digest_len * 2 + 1);
244
+ rb_str_buf_cat2(str, "#<");
245
+ rb_str_buf_cat2(str, cname);
246
+ rb_str_buf_cat2(str, ": ");
247
+ rb_str_buf_append(str, buffer_hexdigest(0, 0, self));
248
+ rb_str_buf_cat2(str, ">");
249
+ return str;
250
+ }
251
+
252
+ static VALUE
253
+ buffer_get(VALUE self)
254
+ {
255
+ buffer_t *ptr;
256
+ Data_Get_Struct(self, buffer_t, ptr);
257
+ return rb_str_new(ptr->buffer, buffer_buffer_length(ptr));
258
+ }
259
+
260
+ static VALUE
261
+ buffer_s_digest(int argc, VALUE *argv, VALUE klass)
262
+ {
263
+ VALUE str;
264
+ volatile VALUE obj;
265
+
266
+ if (argc < 1) {
267
+ rb_raise(rb_eArgError, "no data given");
268
+ }
269
+
270
+ str = *argv++;
271
+ argc--;
272
+
273
+ StringValue(str);
274
+
275
+ obj = rb_obj_alloc(klass);
276
+ rb_obj_call_init(obj, argc, argv);
277
+
278
+ return buffer_digest(1, &str, obj);
279
+ }
280
+
281
+ static VALUE
282
+ buffer_s_hexdigest(int argc, VALUE *argv, VALUE klass)
283
+ {
284
+ VALUE str;
285
+ volatile VALUE obj;
286
+
287
+ if (argc < 1) {
288
+ rb_raise(rb_eArgError, "no data given");
289
+ }
290
+
291
+ str = *argv++;
292
+ argc--;
293
+
294
+ StringValue(str);
295
+
296
+ obj = rb_obj_alloc(klass);
297
+ rb_obj_call_init(obj, argc, argv);
298
+
299
+ return hexencode_str_new(buffer_digest(1, &str, obj));
300
+ }
301
+
302
+ void
303
+ Init_stringbuffer(void)
304
+ {
305
+ VALUE mDigest, cDigest_Class, cDigest_StringBuffer;
306
+
307
+ /* Digest::Buffer is require that Digest module and Digest::Class class of CRuby built-in */
308
+ rb_require("digest");
309
+ mDigest = rb_path2class("Digest");
310
+
311
+ /* class Digest::Buffer < Digest::Class */
312
+ cDigest_StringBuffer = rb_define_class_under(mDigest, "StringBuffer", rb_cObject);
313
+
314
+ rb_define_alloc_func(cDigest_StringBuffer, buffer_alloc);
315
+
316
+ rb_define_singleton_method(cDigest_StringBuffer, "digest", buffer_s_digest, -1);
317
+ rb_define_singleton_method(cDigest_StringBuffer, "hexdigest", buffer_s_hexdigest, -1);
318
+
319
+ rb_define_method(cDigest_StringBuffer, "update", buffer_update, 1);
320
+ rb_define_alias(cDigest_StringBuffer, "<<", "update");
321
+ rb_define_private_method(cDigest_StringBuffer, "finish", buffer_finish, 0);
322
+ rb_define_method(cDigest_StringBuffer, "reset", buffer_reset, 0);
323
+ rb_define_method(cDigest_StringBuffer, "digest_length", buffer_digest_length, 0);
324
+ rb_define_alias(cDigest_StringBuffer, "length", "digest_length");
325
+ rb_define_alias(cDigest_StringBuffer, "size", "digest_length");
326
+ rb_define_method(cDigest_StringBuffer, "==", buffer_equal, 1);
327
+ rb_define_method(cDigest_StringBuffer, "initialize_copy", buffer_initialize_copy, 1);
328
+
329
+ rb_define_method(cDigest_StringBuffer, "digest", buffer_digest, -1);
330
+ rb_define_method(cDigest_StringBuffer, "digest!", buffer_digest_bang, 0);
331
+ rb_define_method(cDigest_StringBuffer, "hexdigest", buffer_hexdigest, -1);
332
+ rb_define_method(cDigest_StringBuffer, "hexdigest!", buffer_hexdigest_bang, 0);
333
+ rb_define_method(cDigest_StringBuffer, "to_s", buffer_to_s, 0);
334
+
335
+ rb_define_method(cDigest_StringBuffer, "buffer", buffer_get, 0);
336
+ }
@@ -0,0 +1,6 @@
1
+ begin
2
+ require "digest/stringbuffer/#{RUBY_VERSION[/\d+.\d+/]}/stringbuffer"
3
+ rescue LoadError
4
+ require "digest/stringbuffer/stringbuffer"
5
+ end
6
+ require "digest/stringbuffer/version"
@@ -0,0 +1,5 @@
1
+ module Digest
2
+ class StringBuffer
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,58 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'digest/stringbuffer'
7
+ require 'benchmark'
8
+
9
+ module Digest
10
+ class BenchClass < Digest::Class
11
+ def initialize(*arg)
12
+ super
13
+ @buf = []
14
+ end
15
+
16
+ def update (arg)
17
+ @buf << arg
18
+ self
19
+ end
20
+
21
+ def finish
22
+ (@buf.join('').length % 256).chr
23
+ end
24
+
25
+ def reset
26
+ @buf.clear
27
+ self
28
+ end
29
+ end
30
+
31
+ class BenchBuffer < Digest::StringBuffer
32
+ def finish
33
+ (buffer.length % 256).chr
34
+ end
35
+ end
36
+ end
37
+
38
+ Benchmark.bm do |x|
39
+ x.report("Digest::Class long string") do
40
+ Digest::BenchClass.digest("abc" * 1_000_000)
41
+ end
42
+
43
+ x.report("Digest::Buffer long string") do
44
+ Digest::BenchBuffer.digest("abc" * 1_000_000)
45
+ end
46
+
47
+ x.report("Digest::Class meny times") do
48
+ 1000_000.times {
49
+ Digest::BenchClass.digest("abc")
50
+ }
51
+ end
52
+
53
+ x.report("Digest::Buffer meny times") do
54
+ 1000_000.times {
55
+ Digest::BenchBuffer.digest("abc")
56
+ }
57
+ end
58
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Digest::StringBuffer do
4
+ it "initialize" do
5
+ expect(Digest::StringBuffer.new).to be_a_kind_of(Digest::StringBuffer)
6
+ expect(Test.new).to be_a_kind_of(Digest::StringBuffer)
7
+ end
8
+
9
+ it "digest" do
10
+ expect(Test.digest("abc" * 1000)).to eq("\x00\x8B\x11\x90".force_encoding("ASCII-8BIT"))
11
+ end
12
+
13
+ it "hexdigest" do
14
+ expect(Test.hexdigest("abc" * 1000)).to eq("008b1190")
15
+ end
16
+
17
+ it "update and reset and hexdigest" do
18
+ test = Test.new
19
+ test.update("b").update("u").update("ff")
20
+ test << "er"
21
+ expect(test.hexdigest).to eq("00004cc6");
22
+ expect(test.hexdigest).to eq("00004cc6");
23
+ expect(test.hexdigest!).to eq("00004cc6");
24
+ expect(test.hexdigest).to eq("00000000");
25
+ end
26
+
27
+ it "==" do
28
+ test1 = Test.new.update("test")
29
+ test2 = Test.new.update("test")
30
+ expect(test1).to eq(test2)
31
+ end
32
+
33
+ it "dup" do
34
+ test1 = Test.new.update("buff")
35
+ test2 = test1.dup.update("er")
36
+ expect(test2.hexdigest).to eq("00004cc6");
37
+ end
38
+
39
+ it "length" do
40
+ expect(Test.new.length).to eq(4);
41
+ end
42
+
43
+ it "buffer" do
44
+ expect(Digest::StringBuffer.new.update("a").buffer).to eq("a")
45
+ expect(Test.new.update("a").buffer).to eq("a")
46
+ end
47
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Digest::StringBuffer do
4
+ it "update nil" do
5
+ expect{ Digest::StringBuffer.new.update }.to raise_error(ArgumentError)
6
+ expect{ Test.new.update }.to raise_error(ArgumentError)
7
+ end
8
+
9
+ it "no override digest" do
10
+ expect{ Digest::StringBuffer.digest("a") }.to raise_error(RuntimeError)
11
+ end
12
+ end
13
+
14
+
15
+
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Digest::StringBuffer do
4
+ it "gc safe" do
5
+ test = Test.new
6
+ GC.start
7
+ test.update("buff")
8
+ GC.start
9
+ expect(test.update("er").to_s).to eq("00004cc6");
10
+ end
11
+ end
12
+
13
+
14
+
15
+
@@ -0,0 +1,15 @@
1
+ require 'digest/stringbuffer'
2
+
3
+ class Test < Digest::StringBuffer
4
+ def initialize
5
+ @prime = 31
6
+ end
7
+
8
+ def finish
9
+ result = 0
10
+ buffer.unpack("C*").each do |c|
11
+ result += (c * @prime)
12
+ end
13
+ [result & 0xffffffff].pack("N")
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: digest-stringbuffer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - ksss
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.11'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.11'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake-compiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.3
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.8.3
69
+ description: Digest::StringBuffer is a class that subset of Digest::Instance.
70
+ email: co000ri@gmail.com
71
+ executables: []
72
+ extensions:
73
+ - ext/digest/stringbuffer/extconf.rb
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .travis.yml
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - digest-stringbuffer.gemspec
83
+ - ext/digest/stringbuffer/extconf.rb
84
+ - ext/digest/stringbuffer/init.c
85
+ - lib/digest/stringbuffer.rb
86
+ - lib/digest/stringbuffer/version.rb
87
+ - spec/bench.rb
88
+ - spec/buffer_spec.rb
89
+ - spec/exception_spec.rb
90
+ - spec/mem_spec.rb
91
+ - spec/spec_helper.rb
92
+ homepage: ''
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.1.6
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Digest::StringBuffer is a class that subset of Digest::Instance.
116
+ test_files:
117
+ - spec/bench.rb
118
+ - spec/buffer_spec.rb
119
+ - spec/exception_spec.rb
120
+ - spec/mem_spec.rb
121
+ - spec/spec_helper.rb