digest-xxhash 0.0.3 → 0.2.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 +5 -5
- data/LICENSE +1 -1
- data/README.md +46 -10
- data/Rakefile +15 -1
- data/digest-xxhash.gemspec +8 -4
- data/ext/digest/xxhash/ext.c +581 -152
- data/ext/digest/xxhash/extconf.rb +20 -0
- data/ext/digest/xxhash/utils.h +15 -4
- data/ext/digest/xxhash/xxhash.h +5306 -157
- data/lib/digest/xxhash/version.rb +4 -2
- data/test/produce-vectors-with-ruby-xxhash.rb +5 -4
- data/test/produce-vectors-with-xxhsum.rb +112 -0
- data/test/test.rb +58 -33
- data/test/test.vectors +960 -462
- data/test/xxhsum.c.c0e86bc0.diff +424 -0
- metadata +15 -10
- data/ext/digest/xxhash/xxhash.c +0 -888
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 67c1180d8629bae85bc269796cdae0b67e1fb1942dd5048906c5b785b94b878b
|
4
|
+
data.tar.gz: 0f35b3b820f91b12e0439e91dac4bf45a390dfc901d20c730d746886c132ca5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7177998d433255ccb0e222257f9161c2e9514418052cf757621b3b13fbdb348dc6a47bd460b94398466496b28ebc7c06b845fc44329156a46309aef749c3bd5
|
7
|
+
data.tar.gz: af71a1e091b287e7d2ff9a41f74fc1adb2af73f625a66c9a5f1d64d3001c99034ec00e5b88085d93362b0820e0a33e2ad1f5f70df8b19551247d9a8d84d757da
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
# digest-xxhash
|
1
|
+
# digest-xxhash
|
2
2
|
|
3
|
-
This gem
|
4
|
-
|
5
|
-
Digest::Instance.
|
3
|
+
This gem provides XXH32, XXH64, XXH3_64bits and XXH3_128bits
|
4
|
+
functionalities for Ruby. It inherits Digest::Class and complies
|
5
|
+
with Digest::Instance's functional design.
|
6
6
|
|
7
|
-
Its core implementation
|
8
|
-
|
7
|
+
Its core implementation comes from the official source, which is in
|
8
|
+
https://github.com/Cyan4973/xxHash.
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
12
|
-
Add this line to
|
12
|
+
Add this line to the application's Gemfile:
|
13
13
|
|
14
14
|
gem 'digest-xxhash'
|
15
15
|
|
@@ -17,10 +17,21 @@ And then execute:
|
|
17
17
|
|
18
18
|
$ bundle
|
19
19
|
|
20
|
-
|
20
|
+
It can also be installed manually with:
|
21
21
|
|
22
22
|
$ gem install digest-xxhash
|
23
23
|
|
24
|
+
The library can also be installed in Gentoo system-wide using 'layman':
|
25
|
+
|
26
|
+
# Fetch remote list of overlays, and add 'konsolebox' overlay
|
27
|
+
layman -f && layman -a konsolebox
|
28
|
+
|
29
|
+
# Unmask unstable keyword
|
30
|
+
echo 'dev-ruby/digest-xxhash' > /etc/portage/package.keywords/dev-ruby.digest-xxhash
|
31
|
+
|
32
|
+
# Merge package
|
33
|
+
emerge dev-ruby/digest-xxhash
|
34
|
+
|
24
35
|
## Example Usage
|
25
36
|
|
26
37
|
require 'digest/xxhash'
|
@@ -52,10 +63,35 @@ Or install it yourself as:
|
|
52
63
|
Digest::XXH64.new.reset("0123456789abcdef").update("12").update("34").hexdigest
|
53
64
|
=> "d7544504de216507"
|
54
65
|
|
66
|
+
Digest::XXH3_64bits.hexdigest("1234", "0123456789abcdef")
|
67
|
+
=> "4156724c7605b1be"
|
68
|
+
|
69
|
+
Digest::XXH3_64bits.new.reset_with_secret("abcd" * 34).update("1234").hexdigest
|
70
|
+
=> "f7bbdbf9ec8c6394"
|
71
|
+
|
72
|
+
Digest::XXH3_128bits.hexdigest("1234", "0123456789abcdef") # XXH3_128bits() only allows 64-bit seeds
|
73
|
+
=> "ad6108fb0b9a6b51b7f80d053c76c0fd"
|
74
|
+
|
75
|
+
Digest::XXH3_128bits.new.reset_with_secret("abcd" * 34).update("1234").hexdigest
|
76
|
+
=> "0d44dd7fde8ea2b4ba961e1a26f71f21"
|
77
|
+
|
78
|
+
## API Documentation
|
79
|
+
|
80
|
+
RubyGems.org provides autogenerated API documentation of the library in
|
81
|
+
https://www.rubydoc.info/gems/digest-xxhash/.
|
82
|
+
|
83
|
+
## Homepage
|
84
|
+
|
85
|
+
https://rubygems.org/gems/digest-xxhash
|
86
|
+
|
55
87
|
## Contributing
|
56
88
|
|
57
89
|
1. Fork it ( https://github.com/konsolebox/digest-xxhash-ruby/fork ).
|
58
|
-
2. Create
|
59
|
-
3. Commit
|
90
|
+
2. Create feature branch (`git checkout -b my-new-feature`).
|
91
|
+
3. Commit changes (`git commit -am 'Add some feature'`).
|
60
92
|
4. Push to the branch (`git push origin my-new-feature`).
|
61
93
|
5. Create a new Pull Request.
|
94
|
+
|
95
|
+
[](https://travis-ci.org/konsolebox/digest-xxhash-ruby)
|
96
|
+
[](https://ci.appveyor.com/project/konsolebox/digest-xxhash-ruby)
|
97
|
+
[](https://github.com/konsolebox/digest-xxhash-ruby/actions/workflows/ruby.yml)
|
data/Rakefile
CHANGED
@@ -1,10 +1,21 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/extensiontask'
|
2
3
|
require 'rake/testtask'
|
3
4
|
|
4
5
|
# clean, clobber, compile, and compile:digest/xxhash
|
5
|
-
require 'rake/extensiontask'
|
6
6
|
Rake::ExtensionTask.new('digest/xxhash', Bundler::GemHelper.gemspec)
|
7
7
|
|
8
|
+
# install
|
9
|
+
Rake::Task[:install].clear
|
10
|
+
task :install => :build do
|
11
|
+
name = Bundler::GemHelper.gemspec.name
|
12
|
+
pkg_dir = File.join(Bundler::GemHelper.instance.base, "pkg")
|
13
|
+
built_gem = Dir.chdir(pkg_dir){ Dir.glob("#{name}-*.gem").sort_by{ |f| File.mtime(f) }.last }
|
14
|
+
gem_command = (ENV["GEM_COMMAND"].shellsplit rescue nil) || ["gem"]
|
15
|
+
options = ARGV.select{ |e| e =~ /\A--?/ }
|
16
|
+
Process.wait spawn(*gem_command, "install", File.join(pkg_dir, built_gem), *options)
|
17
|
+
end
|
18
|
+
|
8
19
|
# test
|
9
20
|
Rake::TestTask.new(:test => :compile) do |t|
|
10
21
|
t.test_files = FileList['test/test.rb']
|
@@ -17,4 +28,7 @@ task :clean do
|
|
17
28
|
rm_f list unless list.empty?
|
18
29
|
end
|
19
30
|
|
31
|
+
# default
|
32
|
+
task :default => :test
|
33
|
+
|
20
34
|
# Run `rake --tasks` for a list of tasks.
|
data/digest-xxhash.gemspec
CHANGED
@@ -9,15 +9,19 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.version = Digest::XXHash::VERSION
|
10
10
|
spec.authors = ["konsolebox"]
|
11
11
|
spec.email = ["konsolebox@gmail.com"]
|
12
|
-
spec.summary = "XXHash for Ruby"
|
13
|
-
spec.description =
|
12
|
+
spec.summary = "A Digest framework based XXHash library for Ruby"
|
13
|
+
spec.description = <<-EOF
|
14
|
+
This gem provides XXH32, XXH64, XXH3_64bits and XXH3_128bits
|
15
|
+
functionalities for Ruby. It inherits Digest::Class and complies
|
16
|
+
with Digest::Instance's functional design.
|
17
|
+
EOF
|
14
18
|
spec.homepage = "https://github.com/konsolebox/digest-xxhash-ruby"
|
15
19
|
spec.license = "MIT"
|
16
20
|
|
17
21
|
spec.required_ruby_version = '>= 2.2'
|
18
22
|
|
19
|
-
spec.files = `git ls-files -z`.split("\x0")
|
20
|
-
spec.executables = spec.files.grep(%r{^bin/})
|
23
|
+
spec.files = `git ls-files -z`.split("\x0").reject{ |f| f =~ /\.yml$/ }
|
24
|
+
spec.executables = spec.files.grep(%r{^bin/}){ |f| File.basename(f) }
|
21
25
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
26
|
spec.require_paths = ["lib"]
|
23
27
|
|
data/ext/digest/xxhash/ext.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) 2021 konsolebox
|
3
3
|
*
|
4
4
|
* MIT License
|
5
5
|
*
|
@@ -23,12 +23,10 @@
|
|
23
23
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
24
|
*/
|
25
25
|
|
26
|
-
|
27
26
|
#include <ruby.h>
|
28
27
|
#include <ruby/digest.h>
|
29
|
-
#include <stdint.h>
|
30
28
|
|
31
|
-
#define
|
29
|
+
#define XXH_INLINE_ALL
|
32
30
|
#include "xxhash.h"
|
33
31
|
#include "utils.h"
|
34
32
|
|
@@ -39,14 +37,21 @@
|
|
39
37
|
#endif
|
40
38
|
|
41
39
|
#define _XXH32_DIGEST_SIZE 4
|
42
|
-
#define _XXH64_DIGEST_SIZE 8
|
43
|
-
|
44
40
|
#define _XXH32_BLOCK_SIZE 4
|
45
|
-
#define _XXH64_BLOCK_SIZE 8
|
46
|
-
|
47
41
|
#define _XXH32_DEFAULT_SEED 0
|
42
|
+
|
43
|
+
#define _XXH64_DIGEST_SIZE 8
|
44
|
+
#define _XXH64_BLOCK_SIZE 8
|
48
45
|
#define _XXH64_DEFAULT_SEED 0
|
49
46
|
|
47
|
+
#define _XXH3_64BITS_DIGEST_SIZE 8
|
48
|
+
#define _XXH3_64BITS_BLOCK_SIZE 8
|
49
|
+
#define _XXH3_64BITS_DEFAULT_SEED 0
|
50
|
+
|
51
|
+
#define _XXH3_128BITS_DIGEST_SIZE 16
|
52
|
+
#define _XXH3_128BITS_BLOCK_SIZE 16
|
53
|
+
#define _XXH3_128BITS_DEFAULT_SEED 0
|
54
|
+
|
50
55
|
#if 0
|
51
56
|
# define _DEBUG(...) fprintf(stderr, __VA_ARGS__)
|
52
57
|
#else
|
@@ -63,9 +68,19 @@ static ID _id_reset;
|
|
63
68
|
static ID _id_update;
|
64
69
|
|
65
70
|
static VALUE _Digest;
|
71
|
+
static VALUE _Digest_Class;
|
66
72
|
static VALUE _Digest_XXHash;
|
67
73
|
static VALUE _Digest_XXH32;
|
68
74
|
static VALUE _Digest_XXH64;
|
75
|
+
static VALUE _Digest_XXH3_64bits;
|
76
|
+
static VALUE _Digest_XXH3_128bits;
|
77
|
+
|
78
|
+
#define _RSTRING_PTR_U(x) ((unsigned char *)RSTRING_PTR(x))
|
79
|
+
#define _TWICE(x) (x * 2)
|
80
|
+
|
81
|
+
static void _xxh32_free_state(void *);
|
82
|
+
static void _xxh64_free_state(void *);
|
83
|
+
static void _xxh3_free_state(void *);
|
69
84
|
|
70
85
|
/*
|
71
86
|
* Data types
|
@@ -73,13 +88,25 @@ static VALUE _Digest_XXH64;
|
|
73
88
|
|
74
89
|
static const rb_data_type_t _xxh32_state_data_type = {
|
75
90
|
"xxh32_state_data",
|
76
|
-
{ 0,
|
91
|
+
{ 0, _xxh32_free_state, 0, }, 0, 0,
|
77
92
|
RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
|
78
93
|
};
|
79
94
|
|
80
95
|
static const rb_data_type_t _xxh64_state_data_type = {
|
81
96
|
"xxh64_state_data",
|
82
|
-
{ 0,
|
97
|
+
{ 0, _xxh64_free_state, 0, }, 0, 0,
|
98
|
+
RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
|
99
|
+
};
|
100
|
+
|
101
|
+
static const rb_data_type_t _xxh3_64bits_state_data_type = {
|
102
|
+
"xxh3_64bits_state_data",
|
103
|
+
{ 0, _xxh3_free_state, 0, }, 0, 0,
|
104
|
+
RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
|
105
|
+
};
|
106
|
+
|
107
|
+
static const rb_data_type_t _xxh3_128bits_state_data_type = {
|
108
|
+
"xxh3_128bits_state_data",
|
109
|
+
{ 0, _xxh3_free_state, 0, }, 0, 0,
|
83
110
|
RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
|
84
111
|
};
|
85
112
|
|
@@ -87,108 +114,93 @@ static const rb_data_type_t _xxh64_state_data_type = {
|
|
87
114
|
* Common functions
|
88
115
|
*/
|
89
116
|
|
90
|
-
static XXH32_state_t *
|
117
|
+
static XXH32_state_t *_get_state_xxh32(VALUE self)
|
91
118
|
{
|
92
119
|
XXH32_state_t *state_p;
|
93
120
|
TypedData_Get_Struct(self, XXH32_state_t, &_xxh32_state_data_type, state_p);
|
94
121
|
return state_p;
|
95
122
|
}
|
96
123
|
|
97
|
-
static XXH64_state_t *
|
124
|
+
static XXH64_state_t *_get_state_xxh64(VALUE self)
|
98
125
|
{
|
99
126
|
XXH64_state_t *state_p;
|
100
127
|
TypedData_Get_Struct(self, XXH64_state_t, &_xxh64_state_data_type, state_p);
|
101
128
|
return state_p;
|
102
129
|
}
|
103
130
|
|
104
|
-
static
|
131
|
+
static XXH3_state_t *_get_state_xxh3_64bits(VALUE self)
|
105
132
|
{
|
106
|
-
|
107
|
-
|
133
|
+
XXH3_state_t *state_p;
|
134
|
+
TypedData_Get_Struct(self, XXH3_state_t, &_xxh3_64bits_state_data_type, state_p);
|
135
|
+
return state_p;
|
108
136
|
}
|
109
137
|
|
110
|
-
static
|
138
|
+
static XXH3_state_t *_get_state_xxh3_128bits(VALUE self)
|
111
139
|
{
|
112
|
-
|
113
|
-
|
140
|
+
XXH3_state_t *state_p;
|
141
|
+
TypedData_Get_Struct(self, XXH3_state_t, &_xxh3_128bits_state_data_type, state_p);
|
142
|
+
return state_p;
|
114
143
|
}
|
115
144
|
|
116
|
-
static
|
145
|
+
static void _xxh32_reset(XXH32_state_t *state_p, XXH32_hash_t seed)
|
117
146
|
{
|
118
|
-
|
119
|
-
|
120
|
-
if (is_little_endian()) {
|
121
|
-
temp = swap_uint32(num);
|
122
|
-
} else {
|
123
|
-
temp = num;
|
124
|
-
}
|
125
|
-
|
126
|
-
return rb_usascii_str_new((unsigned char *) &temp, sizeof(uint32_t));
|
147
|
+
if (XXH32_reset(state_p, seed) != XXH_OK)
|
148
|
+
rb_raise(rb_eRuntimeError, "Failed to reset state.");
|
127
149
|
}
|
128
150
|
|
129
|
-
static
|
151
|
+
static void _xxh64_reset(XXH64_state_t *state_p, XXH64_hash_t seed)
|
130
152
|
{
|
131
|
-
|
132
|
-
|
133
|
-
if (is_little_endian()) {
|
134
|
-
return swap_uint32(temp);
|
135
|
-
} else {
|
136
|
-
return temp;
|
137
|
-
}
|
153
|
+
if (XXH64_reset(state_p, seed) != XXH_OK)
|
154
|
+
rb_raise(rb_eRuntimeError, "Failed to reset state.");
|
138
155
|
}
|
139
156
|
|
140
|
-
static
|
157
|
+
static void _xxh3_64bits_reset(XXH3_state_t *state_p, XXH64_hash_t seed)
|
141
158
|
{
|
142
|
-
|
159
|
+
if (XXH3_64bits_reset_withSeed(state_p, seed) != XXH_OK)
|
160
|
+
rb_raise(rb_eRuntimeError, "Failed to reset state.");
|
143
161
|
}
|
144
162
|
|
145
|
-
static
|
163
|
+
static void _xxh3_128bits_reset(XXH3_state_t *state_p, XXH64_hash_t seed)
|
146
164
|
{
|
147
|
-
|
148
|
-
|
149
|
-
if (is_little_endian()) {
|
150
|
-
temp = swap_uint64(num);
|
151
|
-
} else {
|
152
|
-
temp = num;
|
153
|
-
}
|
154
|
-
|
155
|
-
return rb_usascii_str_new((unsigned char *) &temp, sizeof(uint64_t));
|
165
|
+
if (XXH3_128bits_reset_withSeed(state_p, seed) != XXH_OK)
|
166
|
+
rb_raise(rb_eRuntimeError, "Failed to reset state.");
|
156
167
|
}
|
157
168
|
|
158
|
-
static
|
169
|
+
static void _xxh32_free_state(void* state)
|
159
170
|
{
|
160
|
-
|
171
|
+
XXH32_freeState((XXH32_state_t *)state);
|
172
|
+
}
|
161
173
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
return temp;
|
166
|
-
}
|
174
|
+
static void _xxh64_free_state(void* state)
|
175
|
+
{
|
176
|
+
XXH64_freeState((XXH64_state_t *)state);
|
167
177
|
}
|
168
178
|
|
169
|
-
static
|
179
|
+
static void _xxh3_free_state(void* state)
|
170
180
|
{
|
171
|
-
|
181
|
+
XXH3_freeState((XXH3_state_t *)state);
|
172
182
|
}
|
173
183
|
|
174
184
|
static VALUE _hex_encode_str(VALUE str)
|
175
185
|
{
|
176
186
|
int len = RSTRING_LEN(str);
|
177
|
-
VALUE hex =
|
178
|
-
hex_encode_str_implied(
|
187
|
+
VALUE hex = rb_usascii_str_new(0, _TWICE(len));
|
188
|
+
hex_encode_str_implied(_RSTRING_PTR_U(str), len, _RSTRING_PTR_U(hex));
|
179
189
|
return hex;
|
180
190
|
}
|
181
191
|
|
182
192
|
/*
|
183
193
|
* Document-class: Digest::XXHash
|
184
194
|
*
|
185
|
-
* This is the base class of Digest::XXH32
|
195
|
+
* This is the base class of Digest::XXH32, Digest::XXH64,
|
196
|
+
* Digest::XXH3_64bits, and Digest::XXH3_128bits.
|
186
197
|
*/
|
187
198
|
|
188
199
|
static VALUE _Digest_XXHash_internal_allocate(VALUE klass)
|
189
200
|
{
|
190
201
|
if (klass == _Digest_XXHash)
|
191
|
-
rb_raise(rb_eRuntimeError, "Digest::XXHash is an incomplete class and cannot be
|
202
|
+
rb_raise(rb_eRuntimeError, "Digest::XXHash is an incomplete class and cannot be "
|
203
|
+
"instantiated.");
|
192
204
|
|
193
205
|
rb_raise(rb_eNotImpError, "Allocator function not implemented.");
|
194
206
|
}
|
@@ -221,7 +233,7 @@ static VALUE _Digest_XXHash_ifinish(VALUE self)
|
|
221
233
|
|
222
234
|
static VALUE _do_digest(int argc, VALUE* argv, VALUE self, ID finish_method_id)
|
223
235
|
{
|
224
|
-
VALUE str, seed;
|
236
|
+
VALUE str, seed, result;
|
225
237
|
int argc2 = argc > 0 ? rb_scan_args(argc, argv, "02", &str, &seed) : 0;
|
226
238
|
|
227
239
|
if (argc2 > 0) {
|
@@ -236,7 +248,7 @@ static VALUE _do_digest(int argc, VALUE* argv, VALUE self, ID finish_method_id)
|
|
236
248
|
rb_funcall(self, _id_update, 1, str);
|
237
249
|
}
|
238
250
|
|
239
|
-
|
251
|
+
result = rb_funcall(self, finish_method_id, 0);
|
240
252
|
|
241
253
|
if (argc2 > 0)
|
242
254
|
rb_funcall(self, _id_reset, 0);
|
@@ -258,8 +270,9 @@ static VALUE _do_digest(int argc, VALUE* argv, VALUE self, ID finish_method_id)
|
|
258
270
|
* with +seed+, and is used as the return value. The instance's state is reset
|
259
271
|
* to default afterwards.
|
260
272
|
*
|
261
|
-
* Providing an argument means that previous
|
262
|
-
*
|
273
|
+
* Providing an argument means that previous initializations done with custom
|
274
|
+
* seeds or secrets, and previous calculations done with #update would be
|
275
|
+
* discarded, so be careful with its use.
|
263
276
|
*
|
264
277
|
* +seed+ can be in the form of a string, a hex string, or a number.
|
265
278
|
*/
|
@@ -278,8 +291,7 @@ static VALUE _Digest_XXHash_digest(int argc, VALUE* argv, VALUE self)
|
|
278
291
|
*/
|
279
292
|
static VALUE _Digest_XXHash_hexdigest(int argc, VALUE* argv, VALUE self)
|
280
293
|
{
|
281
|
-
|
282
|
-
return _hex_encode_str(result);
|
294
|
+
return _hex_encode_str(_do_digest(argc, argv, self, _id_finish));
|
283
295
|
}
|
284
296
|
|
285
297
|
/*
|
@@ -302,7 +314,8 @@ static VALUE _Digest_XXHash_idigest(int argc, VALUE* argv, VALUE self)
|
|
302
314
|
*/
|
303
315
|
static VALUE _Digest_XXHash_idigest_bang(VALUE self)
|
304
316
|
{
|
305
|
-
VALUE result
|
317
|
+
VALUE result;
|
318
|
+
result = rb_funcall(self, _id_ifinish, 0);
|
306
319
|
rb_funcall(self, _id_reset, 0);
|
307
320
|
return result;
|
308
321
|
}
|
@@ -313,7 +326,7 @@ static VALUE _Digest_XXHash_idigest_bang(VALUE self)
|
|
313
326
|
* This method is called when instances are cloned. It is responsible for
|
314
327
|
* replicating internal data.
|
315
328
|
*/
|
316
|
-
static VALUE _Digest_XXHash_initialize_copy(VALUE orig)
|
329
|
+
static VALUE _Digest_XXHash_initialize_copy(VALUE self, VALUE orig)
|
317
330
|
{
|
318
331
|
rb_raise(rb_eNotImpError, "initialize_copy method not implemented.");
|
319
332
|
}
|
@@ -325,27 +338,31 @@ static VALUE _Digest_XXHash_initialize_copy(VALUE orig)
|
|
325
338
|
*/
|
326
339
|
static VALUE _Digest_XXHash_inspect(VALUE self)
|
327
340
|
{
|
328
|
-
VALUE klass
|
329
|
-
|
341
|
+
VALUE klass, klass_name, hexdigest, args[2];
|
342
|
+
klass = rb_obj_class(self);
|
343
|
+
klass_name = rb_class_name(klass);
|
330
344
|
|
331
345
|
if (klass_name == Qnil)
|
332
346
|
klass_name = rb_inspect(klass);
|
333
347
|
|
334
|
-
|
348
|
+
hexdigest = rb_funcall(self, _id_hexdigest, 0);
|
335
349
|
|
336
|
-
|
350
|
+
args[0] = klass_name;
|
351
|
+
args[1] = hexdigest;
|
337
352
|
return rb_str_format(sizeof(args), args, rb_str_new_literal("#<%s|%s>"));
|
338
353
|
}
|
339
354
|
|
340
355
|
static VALUE _instantiate_and_digest(int argc, VALUE* argv, VALUE klass, ID digest_method_id)
|
341
356
|
{
|
342
|
-
VALUE str, seed;
|
343
|
-
int argc2
|
357
|
+
VALUE str, seed, instance;
|
358
|
+
int argc2;
|
359
|
+
|
360
|
+
argc2 = rb_scan_args(argc, argv, "11", &str, &seed);
|
344
361
|
|
345
362
|
if (TYPE(str) != T_STRING)
|
346
363
|
rb_raise(rb_eTypeError, "Argument type not string.");
|
347
364
|
|
348
|
-
|
365
|
+
instance = rb_funcall(klass, _id_new, 0);
|
349
366
|
|
350
367
|
if (argc2 > 1)
|
351
368
|
return rb_funcall(instance, digest_method_id, 2, str, seed);
|
@@ -395,10 +412,9 @@ static VALUE _Digest_XXHash_singleton_idigest(int argc, VALUE* argv, VALUE self)
|
|
395
412
|
|
396
413
|
static VALUE _Digest_XXH32_internal_allocate(VALUE klass)
|
397
414
|
{
|
398
|
-
XXH32_state_t *state_p;
|
399
|
-
VALUE obj = TypedData_Make_Struct(klass, XXH32_state_t, &_xxh32_state_data_type, state_p);
|
415
|
+
XXH32_state_t *state_p = XXH32_createState();
|
400
416
|
_xxh32_reset(state_p, 0);
|
401
|
-
return
|
417
|
+
return TypedData_Wrap_Struct(klass, &_xxh32_state_data_type, state_p);
|
402
418
|
}
|
403
419
|
|
404
420
|
/*
|
@@ -408,8 +424,8 @@ static VALUE _Digest_XXH32_internal_allocate(VALUE klass)
|
|
408
424
|
*/
|
409
425
|
static VALUE _Digest_XXH32_update(VALUE self, VALUE str)
|
410
426
|
{
|
411
|
-
if (XXH32_update(
|
412
|
-
rb_raise(rb_eRuntimeError, "Failed to
|
427
|
+
if (XXH32_update(_get_state_xxh32(self), RSTRING_PTR(str), RSTRING_LEN(str)) != XXH_OK)
|
428
|
+
rb_raise(rb_eRuntimeError, "Failed to update state.");
|
413
429
|
|
414
430
|
return self;
|
415
431
|
}
|
@@ -417,15 +433,17 @@ static VALUE _Digest_XXH32_update(VALUE self, VALUE str)
|
|
417
433
|
/* :nodoc: */
|
418
434
|
static VALUE _Digest_XXH32_finish(VALUE self)
|
419
435
|
{
|
420
|
-
|
421
|
-
|
436
|
+
XXH64_hash_t hash = XXH32_digest(_get_state_xxh32(self));
|
437
|
+
VALUE str = rb_usascii_str_new(0, sizeof(XXH32_canonical_t));
|
438
|
+
XXH32_canonicalFromHash((XXH32_canonical_t *)RSTRING_PTR(str), hash);
|
439
|
+
return str;
|
422
440
|
}
|
423
441
|
|
424
442
|
/* :nodoc: */
|
425
443
|
static VALUE _Digest_XXH32_ifinish(VALUE self)
|
426
444
|
{
|
427
|
-
|
428
|
-
return ULONG2NUM(
|
445
|
+
XXH32_hash_t hash = XXH32_digest(_get_state_xxh32(self));
|
446
|
+
return ULONG2NUM(hash);
|
429
447
|
}
|
430
448
|
|
431
449
|
/*
|
@@ -433,9 +451,10 @@ static VALUE _Digest_XXH32_ifinish(VALUE self)
|
|
433
451
|
*
|
434
452
|
* Resets state to initial form with seed.
|
435
453
|
*
|
436
|
-
* This
|
454
|
+
* This discards previous calculations with #update.
|
437
455
|
*
|
438
456
|
* +seed+ can be in the form of a string, a hex string, or a number.
|
457
|
+
* Its virtual length should be 32-bits.
|
439
458
|
*
|
440
459
|
* If +seed+ is not provided, the default value would be 0.
|
441
460
|
*/
|
@@ -448,36 +467,39 @@ static VALUE _Digest_XXH32_reset(int argc, VALUE* argv, VALUE self)
|
|
448
467
|
case T_STRING:
|
449
468
|
{
|
450
469
|
int len = RSTRING_LEN(seed);
|
451
|
-
|
470
|
+
XXH32_hash_t decoded_seed;
|
452
471
|
|
453
|
-
if (len == (sizeof(
|
454
|
-
unsigned char hex_decoded_seed[sizeof(
|
472
|
+
if (len == _TWICE(sizeof(XXH32_hash_t))) {
|
473
|
+
unsigned char hex_decoded_seed[sizeof(XXH32_hash_t)];
|
455
474
|
|
456
|
-
if (! hex_decode_str_implied(
|
457
|
-
rb_raise(rb_eArgError, "Invalid hex string seed: %s\n",
|
475
|
+
if (! hex_decode_str_implied(_RSTRING_PTR_U(seed), len, hex_decoded_seed))
|
476
|
+
rb_raise(rb_eArgError, "Invalid hex string seed: %s\n",
|
477
|
+
StringValueCStr(seed));
|
458
478
|
|
459
|
-
decoded_seed =
|
460
|
-
} else if (len == sizeof(
|
461
|
-
decoded_seed =
|
479
|
+
decoded_seed = XXH_readBE32(hex_decoded_seed);
|
480
|
+
} else if (len == sizeof(XXH32_hash_t)) {
|
481
|
+
decoded_seed = XXH_readBE32(RSTRING_PTR(seed));
|
462
482
|
} else {
|
463
|
-
rb_raise(rb_eArgError, "Invalid seed length.
|
483
|
+
rb_raise(rb_eArgError, "Invalid seed length. "
|
484
|
+
"Expecting an 8-character hex string or a 4-byte string.");
|
464
485
|
}
|
465
486
|
|
466
|
-
_xxh32_reset(
|
487
|
+
_xxh32_reset(_get_state_xxh32(self), decoded_seed);
|
467
488
|
}
|
468
489
|
|
469
490
|
break;
|
470
491
|
case T_FIXNUM:
|
471
|
-
_xxh32_reset(
|
492
|
+
_xxh32_reset(_get_state_xxh32(self), FIX2UINT(seed));
|
472
493
|
break;
|
473
494
|
case T_BIGNUM:
|
474
|
-
_xxh32_reset(
|
495
|
+
_xxh32_reset(_get_state_xxh32(self), NUM2UINT(seed));
|
475
496
|
break;
|
476
497
|
default:
|
477
|
-
rb_raise(rb_eArgError, "Invalid argument type for seed.
|
498
|
+
rb_raise(rb_eArgError, "Invalid argument type for 'seed'. "
|
499
|
+
"Expecting a string or a number.");
|
478
500
|
}
|
479
501
|
} else {
|
480
|
-
_xxh32_reset(
|
502
|
+
_xxh32_reset(_get_state_xxh32(self), _XXH32_DEFAULT_SEED);
|
481
503
|
}
|
482
504
|
|
483
505
|
return self;
|
@@ -491,14 +513,14 @@ static VALUE _Digest_XXH32_reset(int argc, VALUE* argv, VALUE self)
|
|
491
513
|
*/
|
492
514
|
static VALUE _Digest_XXH32_initialize_copy(VALUE self, VALUE orig)
|
493
515
|
{
|
494
|
-
XXH32_copyState(
|
516
|
+
XXH32_copyState(_get_state_xxh32(self), _get_state_xxh32(orig));
|
495
517
|
return self;
|
496
518
|
}
|
497
519
|
|
498
520
|
/*
|
499
521
|
* call-seq: digest_length -> int
|
500
522
|
*
|
501
|
-
* Returns 4
|
523
|
+
* Returns 4
|
502
524
|
*/
|
503
525
|
static VALUE _Digest_XXH32_digest_length(VALUE self)
|
504
526
|
{
|
@@ -508,7 +530,7 @@ static VALUE _Digest_XXH32_digest_length(VALUE self)
|
|
508
530
|
/*
|
509
531
|
* call-seq: block_length -> int
|
510
532
|
*
|
511
|
-
* Returns 4
|
533
|
+
* Returns 4
|
512
534
|
*/
|
513
535
|
static VALUE _Digest_XXH32_block_length(VALUE self)
|
514
536
|
{
|
@@ -518,7 +540,7 @@ static VALUE _Digest_XXH32_block_length(VALUE self)
|
|
518
540
|
/*
|
519
541
|
* call-seq: digest_length -> int
|
520
542
|
*
|
521
|
-
* Returns 4
|
543
|
+
* Returns 4
|
522
544
|
*/
|
523
545
|
static VALUE _Digest_XXH32_singleton_digest_length(VALUE self)
|
524
546
|
{
|
@@ -528,7 +550,7 @@ static VALUE _Digest_XXH32_singleton_digest_length(VALUE self)
|
|
528
550
|
/*
|
529
551
|
* call-seq: block_length -> int
|
530
552
|
*
|
531
|
-
* Returns 4
|
553
|
+
* Returns 4
|
532
554
|
*/
|
533
555
|
static VALUE _Digest_XXH32_singleton_block_length(VALUE self)
|
534
556
|
{
|
@@ -543,10 +565,9 @@ static VALUE _Digest_XXH32_singleton_block_length(VALUE self)
|
|
543
565
|
|
544
566
|
static VALUE _Digest_XXH64_internal_allocate(VALUE klass)
|
545
567
|
{
|
546
|
-
XXH64_state_t *state_p;
|
547
|
-
VALUE obj = TypedData_Make_Struct(klass, XXH64_state_t, &_xxh64_state_data_type, state_p);
|
568
|
+
XXH64_state_t *state_p = XXH64_createState();
|
548
569
|
_xxh64_reset(state_p, 0);
|
549
|
-
return
|
570
|
+
return TypedData_Wrap_Struct(klass, &_xxh64_state_data_type, state_p);
|
550
571
|
}
|
551
572
|
|
552
573
|
/*
|
@@ -556,8 +577,8 @@ static VALUE _Digest_XXH64_internal_allocate(VALUE klass)
|
|
556
577
|
*/
|
557
578
|
static VALUE _Digest_XXH64_update(VALUE self, VALUE str)
|
558
579
|
{
|
559
|
-
if (XXH64_update(
|
560
|
-
rb_raise(rb_eRuntimeError, "Failed to
|
580
|
+
if (XXH64_update(_get_state_xxh64(self), RSTRING_PTR(str), RSTRING_LEN(str)) != XXH_OK)
|
581
|
+
rb_raise(rb_eRuntimeError, "Failed to update state.");
|
561
582
|
|
562
583
|
return self;
|
563
584
|
}
|
@@ -565,15 +586,17 @@ static VALUE _Digest_XXH64_update(VALUE self, VALUE str)
|
|
565
586
|
/* :nodoc: */
|
566
587
|
static VALUE _Digest_XXH64_finish(VALUE self)
|
567
588
|
{
|
568
|
-
|
569
|
-
|
589
|
+
XXH64_hash_t hash = XXH64_digest(_get_state_xxh64(self));
|
590
|
+
VALUE str = rb_usascii_str_new(0, sizeof(XXH64_canonical_t));
|
591
|
+
XXH64_canonicalFromHash((XXH64_canonical_t *)RSTRING_PTR(str), hash);
|
592
|
+
return str;
|
570
593
|
}
|
571
594
|
|
572
595
|
/* :nodoc: */
|
573
596
|
static VALUE _Digest_XXH64_ifinish(VALUE self)
|
574
597
|
{
|
575
|
-
|
576
|
-
return ULL2NUM(
|
598
|
+
XXH64_hash_t hash = XXH64_digest(_get_state_xxh64(self));
|
599
|
+
return ULL2NUM(hash);
|
577
600
|
}
|
578
601
|
|
579
602
|
/*
|
@@ -581,9 +604,10 @@ static VALUE _Digest_XXH64_ifinish(VALUE self)
|
|
581
604
|
*
|
582
605
|
* Resets state to initial form with seed.
|
583
606
|
*
|
584
|
-
* This
|
607
|
+
* This discards previous calculations with #update.
|
585
608
|
*
|
586
609
|
* +seed+ can be in the form of a string, a hex string, or a number.
|
610
|
+
* Its virtual length should be 64-bits.
|
587
611
|
*
|
588
612
|
* If +seed+ is not provided, the default value would be 0.
|
589
613
|
*/
|
@@ -596,36 +620,39 @@ static VALUE _Digest_XXH64_reset(int argc, VALUE* argv, VALUE self)
|
|
596
620
|
case T_STRING:
|
597
621
|
{
|
598
622
|
int len = RSTRING_LEN(seed);
|
599
|
-
|
623
|
+
XXH64_hash_t decoded_seed;
|
600
624
|
|
601
|
-
if (len == (sizeof(
|
602
|
-
unsigned char hex_decoded_seed[sizeof(
|
625
|
+
if (len == _TWICE(sizeof(XXH64_hash_t))) {
|
626
|
+
unsigned char hex_decoded_seed[sizeof(XXH64_hash_t)];
|
603
627
|
|
604
|
-
if (! hex_decode_str_implied(
|
605
|
-
rb_raise(rb_eArgError, "Invalid hex string seed: %s\n",
|
628
|
+
if (! hex_decode_str_implied(_RSTRING_PTR_U(seed), len, hex_decoded_seed))
|
629
|
+
rb_raise(rb_eArgError, "Invalid hex string seed: %s\n",
|
630
|
+
StringValueCStr(seed));
|
606
631
|
|
607
|
-
decoded_seed =
|
608
|
-
} else if (len == sizeof(
|
609
|
-
decoded_seed =
|
632
|
+
decoded_seed = XXH_readBE64(hex_decoded_seed);
|
633
|
+
} else if (len == sizeof(XXH64_hash_t)) {
|
634
|
+
decoded_seed = XXH_readBE64(RSTRING_PTR(seed));
|
610
635
|
} else {
|
611
|
-
rb_raise(rb_eArgError, "Invalid seed length.
|
636
|
+
rb_raise(rb_eArgError, "Invalid seed length. "
|
637
|
+
"Expecting a 16-character hex string or an 8-byte string.");
|
612
638
|
}
|
613
639
|
|
614
|
-
_xxh64_reset(
|
640
|
+
_xxh64_reset(_get_state_xxh64(self), decoded_seed);
|
615
641
|
}
|
616
642
|
|
617
643
|
break;
|
618
644
|
case T_FIXNUM:
|
619
|
-
_xxh64_reset(
|
645
|
+
_xxh64_reset(_get_state_xxh64(self), FIX2UINT(seed));
|
620
646
|
break;
|
621
647
|
case T_BIGNUM:
|
622
|
-
_xxh64_reset(
|
648
|
+
_xxh64_reset(_get_state_xxh64(self), NUM2ULL(seed));
|
623
649
|
break;
|
624
650
|
default:
|
625
|
-
rb_raise(rb_eArgError, "Invalid argument type for seed.
|
651
|
+
rb_raise(rb_eArgError, "Invalid argument type for 'seed'. "
|
652
|
+
"Expecting a string or a number.");
|
626
653
|
}
|
627
654
|
} else {
|
628
|
-
_xxh64_reset(
|
655
|
+
_xxh64_reset(_get_state_xxh64(self), _XXH64_DEFAULT_SEED);
|
629
656
|
}
|
630
657
|
|
631
658
|
return self;
|
@@ -639,14 +666,14 @@ static VALUE _Digest_XXH64_reset(int argc, VALUE* argv, VALUE self)
|
|
639
666
|
*/
|
640
667
|
static VALUE _Digest_XXH64_initialize_copy(VALUE self, VALUE orig)
|
641
668
|
{
|
642
|
-
XXH64_copyState(
|
669
|
+
XXH64_copyState(_get_state_xxh64(self), _get_state_xxh64(orig));
|
643
670
|
return self;
|
644
671
|
}
|
645
672
|
|
646
673
|
/*
|
647
674
|
* call-seq: digest_length -> int
|
648
675
|
*
|
649
|
-
* Returns 8
|
676
|
+
* Returns 8
|
650
677
|
*/
|
651
678
|
static VALUE _Digest_XXH64_digest_length(VALUE self)
|
652
679
|
{
|
@@ -656,7 +683,7 @@ static VALUE _Digest_XXH64_digest_length(VALUE self)
|
|
656
683
|
/*
|
657
684
|
* call-seq: block_length -> int
|
658
685
|
*
|
659
|
-
* Returns 8
|
686
|
+
* Returns 8
|
660
687
|
*/
|
661
688
|
static VALUE _Digest_XXH64_block_length(VALUE self)
|
662
689
|
{
|
@@ -666,7 +693,7 @@ static VALUE _Digest_XXH64_block_length(VALUE self)
|
|
666
693
|
/*
|
667
694
|
* call-seq: digest_length -> int
|
668
695
|
*
|
669
|
-
* Returns 8
|
696
|
+
* Returns 8
|
670
697
|
*/
|
671
698
|
static VALUE _Digest_XXH64_singleton_digest_length(VALUE self)
|
672
699
|
{
|
@@ -676,13 +703,378 @@ static VALUE _Digest_XXH64_singleton_digest_length(VALUE self)
|
|
676
703
|
/*
|
677
704
|
* call-seq: block_length -> int
|
678
705
|
*
|
679
|
-
* Returns 8
|
706
|
+
* Returns 8
|
680
707
|
*/
|
681
708
|
static VALUE _Digest_XXH64_singleton_block_length(VALUE self)
|
682
709
|
{
|
683
710
|
return INT2FIX(_XXH64_BLOCK_SIZE);
|
684
711
|
}
|
685
712
|
|
713
|
+
/*
|
714
|
+
* Document-class: Digest::XXH3_64bits
|
715
|
+
*
|
716
|
+
* This class implements XXH3_64bits.
|
717
|
+
*/
|
718
|
+
|
719
|
+
static VALUE _Digest_XXH3_64bits_internal_allocate(VALUE klass)
|
720
|
+
{
|
721
|
+
XXH3_state_t *state_p = XXH3_createState();
|
722
|
+
XXH3_64bits_reset(state_p);
|
723
|
+
return TypedData_Wrap_Struct(klass, &_xxh3_64bits_state_data_type, state_p);
|
724
|
+
}
|
725
|
+
|
726
|
+
/*
|
727
|
+
* call-seq: update(str) -> self
|
728
|
+
*
|
729
|
+
* Updates current digest value with string.
|
730
|
+
*/
|
731
|
+
static VALUE _Digest_XXH3_64bits_update(VALUE self, VALUE str)
|
732
|
+
{
|
733
|
+
if (XXH3_64bits_update(_get_state_xxh3_64bits(self), RSTRING_PTR(str), RSTRING_LEN(str)) != XXH_OK)
|
734
|
+
rb_raise(rb_eRuntimeError, "Failed to update state.");
|
735
|
+
|
736
|
+
return self;
|
737
|
+
}
|
738
|
+
|
739
|
+
/* :nodoc: */
|
740
|
+
static VALUE _Digest_XXH3_64bits_finish(VALUE self)
|
741
|
+
{
|
742
|
+
XXH64_hash_t hash = XXH3_64bits_digest(_get_state_xxh3_64bits(self));
|
743
|
+
VALUE str = rb_usascii_str_new(0, sizeof(XXH64_canonical_t));
|
744
|
+
XXH64_canonicalFromHash((XXH64_canonical_t *)RSTRING_PTR(str), hash);
|
745
|
+
return str;
|
746
|
+
}
|
747
|
+
|
748
|
+
/* :nodoc: */
|
749
|
+
static VALUE _Digest_XXH3_64bits_ifinish(VALUE self)
|
750
|
+
{
|
751
|
+
XXH64_hash_t hash = XXH3_64bits_digest(_get_state_xxh3_64bits(self));
|
752
|
+
return ULL2NUM(hash);
|
753
|
+
}
|
754
|
+
|
755
|
+
/*
|
756
|
+
* call-seq: reset(seed = 0) -> self
|
757
|
+
*
|
758
|
+
* Resets state to initial form with seed.
|
759
|
+
*
|
760
|
+
* This discards previous calculations with #update.
|
761
|
+
*
|
762
|
+
* +seed+ can be in the form of a string, a hex string, or a number.
|
763
|
+
* Its virtual length should be 64-bits.
|
764
|
+
*
|
765
|
+
* If +seed+ is not provided, the default value would be 0.
|
766
|
+
*/
|
767
|
+
static VALUE _Digest_XXH3_64bits_reset(int argc, VALUE* argv, VALUE self)
|
768
|
+
{
|
769
|
+
VALUE seed;
|
770
|
+
|
771
|
+
if (rb_scan_args(argc, argv, "01", &seed) > 0) {
|
772
|
+
switch (TYPE(seed)) {
|
773
|
+
case T_STRING:
|
774
|
+
{
|
775
|
+
int len = RSTRING_LEN(seed);
|
776
|
+
XXH64_hash_t decoded_seed;
|
777
|
+
|
778
|
+
if (len == _TWICE(sizeof(XXH64_hash_t))) {
|
779
|
+
unsigned char hex_decoded_seed[sizeof(XXH64_hash_t)];
|
780
|
+
|
781
|
+
if (! hex_decode_str_implied(_RSTRING_PTR_U(seed), len, hex_decoded_seed))
|
782
|
+
rb_raise(rb_eArgError, "Invalid hex string seed: %s\n",
|
783
|
+
StringValueCStr(seed));
|
784
|
+
|
785
|
+
decoded_seed = XXH_readBE64(hex_decoded_seed);
|
786
|
+
} else if (len == sizeof(XXH64_hash_t)) {
|
787
|
+
decoded_seed = XXH_readBE64(RSTRING_PTR(seed));
|
788
|
+
} else {
|
789
|
+
rb_raise(rb_eArgError, "Invalid seed length. "
|
790
|
+
"Expecting a 16-character hex string or an 8-byte string.");
|
791
|
+
}
|
792
|
+
|
793
|
+
_xxh3_64bits_reset(_get_state_xxh3_64bits(self), decoded_seed);
|
794
|
+
}
|
795
|
+
|
796
|
+
break;
|
797
|
+
case T_FIXNUM:
|
798
|
+
_xxh3_64bits_reset(_get_state_xxh3_64bits(self), FIX2UINT(seed));
|
799
|
+
break;
|
800
|
+
case T_BIGNUM:
|
801
|
+
_xxh3_64bits_reset(_get_state_xxh3_64bits(self), NUM2ULL(seed));
|
802
|
+
break;
|
803
|
+
default:
|
804
|
+
rb_raise(rb_eArgError, "Invalid argument type for 'seed'. "
|
805
|
+
"Expecting a string or a number.");
|
806
|
+
}
|
807
|
+
} else {
|
808
|
+
_xxh3_64bits_reset(_get_state_xxh3_64bits(self), _XXH3_64BITS_DEFAULT_SEED);
|
809
|
+
}
|
810
|
+
|
811
|
+
return self;
|
812
|
+
}
|
813
|
+
|
814
|
+
/*
|
815
|
+
* call-seq: reset_with_secret(secret) -> self
|
816
|
+
*
|
817
|
+
* Resets state to initial form using a secret.
|
818
|
+
*
|
819
|
+
* This discards previous calculations with #update.
|
820
|
+
*
|
821
|
+
* Secret should be a string and have a minimum length of XXH3_SECRET_SIZE_MIN.
|
822
|
+
*/
|
823
|
+
static VALUE _Digest_XXH3_64bits_reset_with_secret(VALUE self, VALUE secret)
|
824
|
+
{
|
825
|
+
if (TYPE(secret) != T_STRING)
|
826
|
+
rb_raise(rb_eArgError, "Argument 'secret' needs to be a string.");
|
827
|
+
|
828
|
+
if (RSTRING_LEN(secret) < XXH3_SECRET_SIZE_MIN)
|
829
|
+
rb_raise(rb_eRuntimeError, "Secret needs to be at least %d bytes in length.",
|
830
|
+
XXH3_SECRET_SIZE_MIN);
|
831
|
+
|
832
|
+
if (XXH3_64bits_reset_withSecret(_get_state_xxh3_64bits(self), RSTRING_PTR(secret),
|
833
|
+
RSTRING_LEN(secret)) != XXH_OK)
|
834
|
+
rb_raise(rb_eRuntimeError, "Failed to reset state with secret.");
|
835
|
+
|
836
|
+
return self;
|
837
|
+
}
|
838
|
+
|
839
|
+
/*
|
840
|
+
* call-seq: initialize_copy(orig) -> self
|
841
|
+
*
|
842
|
+
* This method is called when instances are cloned. It is responsible for
|
843
|
+
* replicating internal data.
|
844
|
+
*/
|
845
|
+
static VALUE _Digest_XXH3_64bits_initialize_copy(VALUE self, VALUE orig)
|
846
|
+
{
|
847
|
+
XXH3_copyState(_get_state_xxh3_64bits(self), _get_state_xxh3_64bits(orig));
|
848
|
+
return self;
|
849
|
+
}
|
850
|
+
|
851
|
+
/*
|
852
|
+
* call-seq: digest_length -> int
|
853
|
+
*
|
854
|
+
* Returns 8
|
855
|
+
*/
|
856
|
+
static VALUE _Digest_XXH3_64bits_digest_length(VALUE self)
|
857
|
+
{
|
858
|
+
return INT2FIX(_XXH3_64BITS_DIGEST_SIZE);
|
859
|
+
}
|
860
|
+
|
861
|
+
/*
|
862
|
+
* call-seq: block_length -> int
|
863
|
+
*
|
864
|
+
* Returns 8
|
865
|
+
*/
|
866
|
+
static VALUE _Digest_XXH3_64bits_block_length(VALUE self)
|
867
|
+
{
|
868
|
+
return INT2FIX(_XXH3_64BITS_BLOCK_SIZE);
|
869
|
+
}
|
870
|
+
|
871
|
+
/*
|
872
|
+
* call-seq: digest_length -> int
|
873
|
+
*
|
874
|
+
* Returns 8
|
875
|
+
*/
|
876
|
+
static VALUE _Digest_XXH3_64bits_singleton_digest_length(VALUE self)
|
877
|
+
{
|
878
|
+
return INT2FIX(_XXH3_64BITS_DIGEST_SIZE);
|
879
|
+
}
|
880
|
+
|
881
|
+
/*
|
882
|
+
* call-seq: block_length -> int
|
883
|
+
*
|
884
|
+
* Returns 8
|
885
|
+
*/
|
886
|
+
static VALUE _Digest_XXH3_64bits_singleton_block_length(VALUE self)
|
887
|
+
{
|
888
|
+
return INT2FIX(_XXH3_64BITS_BLOCK_SIZE);
|
889
|
+
}
|
890
|
+
|
891
|
+
/*
|
892
|
+
* Document-class: Digest::XXH3_128bits
|
893
|
+
*
|
894
|
+
* This class implements XXH3_128bits.
|
895
|
+
*/
|
896
|
+
|
897
|
+
static VALUE _Digest_XXH3_128bits_internal_allocate(VALUE klass)
|
898
|
+
{
|
899
|
+
XXH3_state_t *state_p = XXH3_createState();
|
900
|
+
XXH3_128bits_reset(state_p);
|
901
|
+
return TypedData_Wrap_Struct(klass, &_xxh3_128bits_state_data_type, state_p);
|
902
|
+
}
|
903
|
+
|
904
|
+
/*
|
905
|
+
* call-seq: update(str) -> self
|
906
|
+
*
|
907
|
+
* Updates current digest value with string.
|
908
|
+
*/
|
909
|
+
static VALUE _Digest_XXH3_128bits_update(VALUE self, VALUE str)
|
910
|
+
{
|
911
|
+
if (XXH3_128bits_update(_get_state_xxh3_128bits(self), RSTRING_PTR(str), RSTRING_LEN(str)) != XXH_OK)
|
912
|
+
rb_raise(rb_eRuntimeError, "Failed to update state.");
|
913
|
+
|
914
|
+
return self;
|
915
|
+
}
|
916
|
+
|
917
|
+
/* :nodoc: */
|
918
|
+
static VALUE _Digest_XXH3_128bits_finish(VALUE self)
|
919
|
+
{
|
920
|
+
XXH128_hash_t hash = XXH3_128bits_digest(_get_state_xxh3_128bits(self));
|
921
|
+
VALUE str = rb_usascii_str_new(0, sizeof(XXH128_canonical_t));
|
922
|
+
XXH128_canonicalFromHash((XXH128_canonical_t *)RSTRING_PTR(str), hash);
|
923
|
+
return str;
|
924
|
+
}
|
925
|
+
|
926
|
+
/* :nodoc: */
|
927
|
+
static VALUE _Digest_XXH3_128bits_ifinish(VALUE self)
|
928
|
+
{
|
929
|
+
XXH128_hash_t hash = XXH3_128bits_digest(_get_state_xxh3_128bits(self));
|
930
|
+
|
931
|
+
if (! XXH_CPU_LITTLE_ENDIAN) {
|
932
|
+
#define _SWAP_WORDS(x) ((x << 32) & 0xffffffff00000000ULL) | \
|
933
|
+
((x >> 32) & 0x000000000ffffffffULL)
|
934
|
+
hash.low64 = _SWAP_WORDS(hash.low64);
|
935
|
+
hash.high64 = _SWAP_WORDS(hash.high64);
|
936
|
+
}
|
937
|
+
|
938
|
+
return rb_integer_unpack(&hash, 4, sizeof(XXH32_hash_t), 0, INTEGER_PACK_LSWORD_FIRST|
|
939
|
+
INTEGER_PACK_NATIVE_BYTE_ORDER);
|
940
|
+
}
|
941
|
+
|
942
|
+
/*
|
943
|
+
* call-seq: reset(seed = 0) -> self
|
944
|
+
*
|
945
|
+
* Resets state to initial form with seed.
|
946
|
+
*
|
947
|
+
* This discards previous calculations with #update.
|
948
|
+
*
|
949
|
+
* +seed+ can be in the form of a string, a hex string, or a number.
|
950
|
+
* Its virtual length should be 64-bits and not 128-bits.
|
951
|
+
*
|
952
|
+
* If +seed+ is not provided, the default value would be 0.
|
953
|
+
*/
|
954
|
+
static VALUE _Digest_XXH3_128bits_reset(int argc, VALUE* argv, VALUE self)
|
955
|
+
{
|
956
|
+
VALUE seed;
|
957
|
+
|
958
|
+
if (rb_scan_args(argc, argv, "01", &seed) > 0) {
|
959
|
+
switch (TYPE(seed)) {
|
960
|
+
case T_STRING:
|
961
|
+
{
|
962
|
+
int len = RSTRING_LEN(seed);
|
963
|
+
XXH64_hash_t decoded_seed;
|
964
|
+
|
965
|
+
if (len == _TWICE(sizeof(XXH64_hash_t))) {
|
966
|
+
unsigned char hex_decoded_seed[sizeof(XXH64_hash_t)];
|
967
|
+
|
968
|
+
if (! hex_decode_str_implied(_RSTRING_PTR_U(seed), len, hex_decoded_seed))
|
969
|
+
rb_raise(rb_eArgError, "Invalid hex string seed: %s\n",
|
970
|
+
StringValueCStr(seed));
|
971
|
+
|
972
|
+
decoded_seed = XXH_readBE64(hex_decoded_seed);
|
973
|
+
} else if (len == sizeof(XXH64_hash_t)) {
|
974
|
+
decoded_seed = XXH_readBE64(RSTRING_PTR(seed));
|
975
|
+
} else {
|
976
|
+
rb_raise(rb_eArgError, "Invalid seed length. Expecting a 16-character hex "
|
977
|
+
"string or an 8-byte string.");
|
978
|
+
}
|
979
|
+
|
980
|
+
_xxh3_128bits_reset(_get_state_xxh3_128bits(self), decoded_seed);
|
981
|
+
}
|
982
|
+
|
983
|
+
break;
|
984
|
+
case T_FIXNUM:
|
985
|
+
_xxh3_128bits_reset(_get_state_xxh3_128bits(self), FIX2UINT(seed));
|
986
|
+
break;
|
987
|
+
case T_BIGNUM:
|
988
|
+
_xxh3_128bits_reset(_get_state_xxh3_128bits(self), NUM2ULL(seed));
|
989
|
+
break;
|
990
|
+
default:
|
991
|
+
rb_raise(rb_eArgError, "Invalid argument type for 'seed'. "
|
992
|
+
"Expecting a string or a number.");
|
993
|
+
}
|
994
|
+
} else {
|
995
|
+
_xxh3_128bits_reset(_get_state_xxh3_128bits(self), _XXH3_128BITS_DEFAULT_SEED);
|
996
|
+
}
|
997
|
+
|
998
|
+
return self;
|
999
|
+
}
|
1000
|
+
|
1001
|
+
/*
|
1002
|
+
* call-seq: reset_with_secret(secret) -> self
|
1003
|
+
*
|
1004
|
+
* Resets state to initial form using a secret.
|
1005
|
+
*
|
1006
|
+
* This discards previous calculations with #update.
|
1007
|
+
*
|
1008
|
+
* Secret should be a string having a minimum length of XXH3_SECRET_SIZE_MIN.
|
1009
|
+
*/
|
1010
|
+
static VALUE _Digest_XXH3_128bits_reset_with_secret(VALUE self, VALUE secret)
|
1011
|
+
{
|
1012
|
+
if (TYPE(secret) != T_STRING)
|
1013
|
+
rb_raise(rb_eArgError, "Argument 'secret' needs to be a string.");
|
1014
|
+
|
1015
|
+
if (RSTRING_LEN(secret) < XXH3_SECRET_SIZE_MIN)
|
1016
|
+
rb_raise(rb_eRuntimeError, "Secret needs to be at least %d bytes in length.",
|
1017
|
+
XXH3_SECRET_SIZE_MIN);
|
1018
|
+
|
1019
|
+
if (XXH3_128bits_reset_withSecret(_get_state_xxh3_128bits(self), RSTRING_PTR(secret),
|
1020
|
+
RSTRING_LEN(secret)) != XXH_OK)
|
1021
|
+
rb_raise(rb_eRuntimeError, "Failed to reset state with secret.");
|
1022
|
+
|
1023
|
+
return self;
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
/*
|
1027
|
+
* call-seq: initialize_copy(orig) -> self
|
1028
|
+
*
|
1029
|
+
* This method is called when instances are cloned. It is responsible for
|
1030
|
+
* replicating internal data.
|
1031
|
+
*/
|
1032
|
+
static VALUE _Digest_XXH3_128bits_initialize_copy(VALUE self, VALUE orig)
|
1033
|
+
{
|
1034
|
+
XXH3_copyState(_get_state_xxh3_128bits(self), _get_state_xxh3_128bits(orig));
|
1035
|
+
return self;
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
/*
|
1039
|
+
* call-seq: digest_length -> int
|
1040
|
+
*
|
1041
|
+
* Returns 16
|
1042
|
+
*/
|
1043
|
+
static VALUE _Digest_XXH3_128bits_digest_length(VALUE self)
|
1044
|
+
{
|
1045
|
+
return INT2FIX(_XXH3_128BITS_DIGEST_SIZE);
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
/*
|
1049
|
+
* call-seq: block_length -> int
|
1050
|
+
*
|
1051
|
+
* Returns 16
|
1052
|
+
*/
|
1053
|
+
static VALUE _Digest_XXH3_128bits_block_length(VALUE self)
|
1054
|
+
{
|
1055
|
+
return INT2FIX(_XXH3_128BITS_BLOCK_SIZE);
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
/*
|
1059
|
+
* call-seq: digest_length -> int
|
1060
|
+
*
|
1061
|
+
* Returns 16
|
1062
|
+
*/
|
1063
|
+
static VALUE _Digest_XXH3_128bits_singleton_digest_length(VALUE self)
|
1064
|
+
{
|
1065
|
+
return INT2FIX(_XXH3_128BITS_DIGEST_SIZE);
|
1066
|
+
}
|
1067
|
+
|
1068
|
+
/*
|
1069
|
+
* call-seq: block_length -> int
|
1070
|
+
*
|
1071
|
+
* Returns 16
|
1072
|
+
*/
|
1073
|
+
static VALUE _Digest_XXH3_128bits_singleton_block_length(VALUE self)
|
1074
|
+
{
|
1075
|
+
return INT2FIX(_XXH3_128BITS_BLOCK_SIZE);
|
1076
|
+
}
|
1077
|
+
|
686
1078
|
/*
|
687
1079
|
* Initialization
|
688
1080
|
*/
|
@@ -700,19 +1092,22 @@ void Init_xxhash()
|
|
700
1092
|
DEFINE_ID(reset)
|
701
1093
|
DEFINE_ID(update)
|
702
1094
|
|
703
|
-
#if 0
|
704
|
-
_Digest = rb_define_module("Digest"); /* Tell RDoc about Digest since it doesn't recognize rb_path2class. */
|
705
|
-
#endif
|
706
|
-
|
707
1095
|
rb_require("digest");
|
708
1096
|
_Digest = rb_path2class("Digest");
|
1097
|
+
_Digest_Class = rb_path2class("Digest::Class");
|
1098
|
+
|
1099
|
+
#if 0
|
1100
|
+
/* Tell RDoc about Digest and Digest::Class since it doesn't parse rb_path2class. */
|
1101
|
+
_Digest = rb_define_module("Digest");
|
1102
|
+
_Digest_Class = rb_define_class_under(_Digest, "Class", rb_cObject);
|
1103
|
+
#endif
|
709
1104
|
|
710
1105
|
/*
|
711
1106
|
* Document-class: Digest::XXHash
|
712
1107
|
*/
|
713
1108
|
|
714
|
-
_Digest_XXHash = rb_define_class_under(_Digest, "XXHash",
|
715
|
-
|
1109
|
+
_Digest_XXHash = rb_define_class_under(_Digest, "XXHash", _Digest_Class);
|
1110
|
+
rb_define_alloc_func(_Digest_XXHash, _Digest_XXHash_internal_allocate);
|
716
1111
|
rb_define_method(_Digest_XXHash, "digest", _Digest_XXHash_digest, -1);
|
717
1112
|
rb_define_method(_Digest_XXHash, "hexdigest", _Digest_XXHash_hexdigest, -1);
|
718
1113
|
rb_define_method(_Digest_XXHash, "idigest", _Digest_XXHash_idigest, -1);
|
@@ -720,32 +1115,24 @@ void Init_xxhash()
|
|
720
1115
|
rb_define_method(_Digest_XXHash, "initialize", _Digest_XXHash_initialize, -1);
|
721
1116
|
rb_define_method(_Digest_XXHash, "inspect", _Digest_XXHash_inspect, 0);
|
722
1117
|
rb_define_method(_Digest_XXHash, "initialize_copy", _Digest_XXHash_initialize_copy, 1);
|
723
|
-
|
724
1118
|
rb_define_protected_method(_Digest_XXHash, "ifinish", _Digest_XXHash_ifinish, 0);
|
725
|
-
|
726
1119
|
rb_define_singleton_method(_Digest_XXHash, "digest", _Digest_XXHash_singleton_digest, -1);
|
727
1120
|
rb_define_singleton_method(_Digest_XXHash, "hexdigest", _Digest_XXHash_singleton_hexdigest, -1);
|
728
1121
|
rb_define_singleton_method(_Digest_XXHash, "idigest", _Digest_XXHash_singleton_idigest, -1);
|
729
1122
|
|
730
|
-
rb_define_alloc_func(_Digest_XXHash, _Digest_XXHash_internal_allocate);
|
731
|
-
|
732
1123
|
/*
|
733
1124
|
* Document-class: Digest::XXH32
|
734
1125
|
*/
|
735
1126
|
|
736
1127
|
_Digest_XXH32 = rb_define_class_under(_Digest, "XXH32", _Digest_XXHash);
|
737
|
-
|
738
1128
|
rb_define_alloc_func(_Digest_XXH32, _Digest_XXH32_internal_allocate);
|
739
|
-
|
740
1129
|
rb_define_private_method(_Digest_XXH32, "finish", _Digest_XXH32_finish, 0);
|
741
1130
|
rb_define_private_method(_Digest_XXH32, "ifinish", _Digest_XXH32_ifinish, 0);
|
742
|
-
|
743
1131
|
rb_define_method(_Digest_XXH32, "update", _Digest_XXH32_update, 1);
|
744
1132
|
rb_define_method(_Digest_XXH32, "reset", _Digest_XXH32_reset, -1);
|
745
1133
|
rb_define_method(_Digest_XXH32, "digest_length", _Digest_XXH32_digest_length, 0);
|
746
1134
|
rb_define_method(_Digest_XXH32, "block_length", _Digest_XXH32_block_length, 0);
|
747
1135
|
rb_define_method(_Digest_XXH32, "initialize_copy", _Digest_XXH32_initialize_copy, 1);
|
748
|
-
|
749
1136
|
rb_define_singleton_method(_Digest_XXH32, "digest_length", _Digest_XXH32_singleton_digest_length, 0);
|
750
1137
|
rb_define_singleton_method(_Digest_XXH32, "block_length", _Digest_XXH32_singleton_block_length, 0);
|
751
1138
|
|
@@ -754,18 +1141,60 @@ void Init_xxhash()
|
|
754
1141
|
*/
|
755
1142
|
|
756
1143
|
_Digest_XXH64 = rb_define_class_under(_Digest, "XXH64", _Digest_XXHash);
|
757
|
-
|
758
1144
|
rb_define_alloc_func(_Digest_XXH64, _Digest_XXH64_internal_allocate);
|
759
|
-
|
760
1145
|
rb_define_private_method(_Digest_XXH64, "finish", _Digest_XXH64_finish, 0);
|
761
1146
|
rb_define_private_method(_Digest_XXH64, "ifinish", _Digest_XXH64_ifinish, 0);
|
762
|
-
|
763
1147
|
rb_define_method(_Digest_XXH64, "update", _Digest_XXH64_update, 1);
|
764
1148
|
rb_define_method(_Digest_XXH64, "reset", _Digest_XXH64_reset, -1);
|
765
1149
|
rb_define_method(_Digest_XXH64, "digest_length", _Digest_XXH64_digest_length, 0);
|
766
1150
|
rb_define_method(_Digest_XXH64, "block_length", _Digest_XXH64_block_length, 0);
|
767
1151
|
rb_define_method(_Digest_XXH64, "initialize_copy", _Digest_XXH64_initialize_copy, 1);
|
768
|
-
|
769
1152
|
rb_define_singleton_method(_Digest_XXH64, "digest_length", _Digest_XXH64_singleton_digest_length, 0);
|
770
1153
|
rb_define_singleton_method(_Digest_XXH64, "block_length", _Digest_XXH64_singleton_block_length, 0);
|
1154
|
+
|
1155
|
+
/*
|
1156
|
+
* Document-class: Digest::XXH3_64bits
|
1157
|
+
*/
|
1158
|
+
|
1159
|
+
_Digest_XXH3_64bits = rb_define_class_under(_Digest, "XXH3_64bits", _Digest_XXHash);
|
1160
|
+
rb_define_alloc_func(_Digest_XXH3_64bits, _Digest_XXH3_64bits_internal_allocate);
|
1161
|
+
rb_define_private_method(_Digest_XXH3_64bits, "finish", _Digest_XXH3_64bits_finish, 0);
|
1162
|
+
rb_define_private_method(_Digest_XXH3_64bits, "ifinish", _Digest_XXH3_64bits_ifinish, 0);
|
1163
|
+
rb_define_method(_Digest_XXH3_64bits, "update", _Digest_XXH3_64bits_update, 1);
|
1164
|
+
rb_define_method(_Digest_XXH3_64bits, "reset", _Digest_XXH3_64bits_reset, -1);
|
1165
|
+
rb_define_method(_Digest_XXH3_64bits, "reset_with_secret", _Digest_XXH3_64bits_reset_with_secret, 1);
|
1166
|
+
rb_define_method(_Digest_XXH3_64bits, "digest_length", _Digest_XXH3_64bits_digest_length, 0);
|
1167
|
+
rb_define_method(_Digest_XXH3_64bits, "block_length", _Digest_XXH3_64bits_block_length, 0);
|
1168
|
+
rb_define_method(_Digest_XXH3_64bits, "initialize_copy", _Digest_XXH3_64bits_initialize_copy, 1);
|
1169
|
+
rb_define_singleton_method(_Digest_XXH3_64bits, "digest_length", _Digest_XXH3_64bits_singleton_digest_length, 0);
|
1170
|
+
rb_define_singleton_method(_Digest_XXH3_64bits, "block_length", _Digest_XXH3_64bits_singleton_block_length, 0);
|
1171
|
+
|
1172
|
+
/*
|
1173
|
+
* Document-class: Digest::XXH3_128bits
|
1174
|
+
*/
|
1175
|
+
|
1176
|
+
_Digest_XXH3_128bits = rb_define_class_under(_Digest, "XXH3_128bits", _Digest_XXHash);
|
1177
|
+
rb_define_alloc_func(_Digest_XXH3_128bits, _Digest_XXH3_128bits_internal_allocate);
|
1178
|
+
rb_define_private_method(_Digest_XXH3_128bits, "finish", _Digest_XXH3_128bits_finish, 0);
|
1179
|
+
rb_define_private_method(_Digest_XXH3_128bits, "ifinish", _Digest_XXH3_128bits_ifinish, 0);
|
1180
|
+
rb_define_method(_Digest_XXH3_128bits, "update", _Digest_XXH3_128bits_update, 1);
|
1181
|
+
rb_define_method(_Digest_XXH3_128bits, "reset", _Digest_XXH3_128bits_reset, -1);
|
1182
|
+
rb_define_method(_Digest_XXH3_128bits, "reset_with_secret", _Digest_XXH3_128bits_reset_with_secret, 1);
|
1183
|
+
rb_define_method(_Digest_XXH3_128bits, "digest_length", _Digest_XXH3_128bits_digest_length, 0);
|
1184
|
+
rb_define_method(_Digest_XXH3_128bits, "block_length", _Digest_XXH3_128bits_block_length, 0);
|
1185
|
+
rb_define_method(_Digest_XXH3_128bits, "initialize_copy", _Digest_XXH3_128bits_initialize_copy, 1);
|
1186
|
+
rb_define_singleton_method(_Digest_XXH3_128bits, "digest_length", _Digest_XXH3_128bits_singleton_digest_length, 0);
|
1187
|
+
rb_define_singleton_method(_Digest_XXH3_128bits, "block_length", _Digest_XXH3_128bits_singleton_block_length, 0);
|
1188
|
+
|
1189
|
+
/*
|
1190
|
+
* Document-const: Digest::XXHash::XXH3_SECRET_SIZE_MIN
|
1191
|
+
*
|
1192
|
+
* Minimum allowed custom secret size defined in the core XXHash
|
1193
|
+
* code. The current value is 136.
|
1194
|
+
*
|
1195
|
+
* The author of Digest::XXHash doesn't know if this value would
|
1196
|
+
* change in the future.
|
1197
|
+
*/
|
1198
|
+
|
1199
|
+
rb_define_const(_Digest_XXHash, "XXH3_SECRET_SIZE_MIN", INT2FIX(XXH3_SECRET_SIZE_MIN));
|
771
1200
|
}
|