digest-stringbuffer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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