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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +93 -0
- data/Rakefile +21 -0
- data/digest-stringbuffer.gemspec +26 -0
- data/ext/digest/stringbuffer/extconf.rb +5 -0
- data/ext/digest/stringbuffer/init.c +336 -0
- data/lib/digest/stringbuffer.rb +6 -0
- data/lib/digest/stringbuffer/version.rb +5 -0
- data/spec/bench.rb +58 -0
- data/spec/buffer_spec.rb +47 -0
- data/spec/exception_spec.rb +15 -0
- data/spec/mem_spec.rb +15 -0
- data/spec/spec_helper.rb +15 -0
- metadata +121 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# Digest::StringBuffer
|
2
|
+
|
3
|
+
[](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
|
data/Rakefile
ADDED
@@ -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,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
|
+
}
|
data/spec/bench.rb
ADDED
@@ -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
|
data/spec/buffer_spec.rb
ADDED
@@ -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
|
+
|
data/spec/mem_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
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
|