digest-xxhash 0.1.2 → 0.2.0
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 +4 -4
- data/README.md +17 -4
- data/Rakefile +13 -2
- data/digest-xxhash.gemspec +7 -3
- data/ext/digest/xxhash/ext.c +552 -134
- data/ext/digest/xxhash/extconf.rb +19 -1
- data/ext/digest/xxhash/utils.h +6 -0
- data/ext/digest/xxhash/xxhash.h +5193 -161
- data/lib/digest/xxhash/version.rb +1 -1
- data/test/produce-vectors-with-ruby-xxhash.rb +5 -4
- data/test/produce-vectors-with-xxhsum.rb +112 -0
- data/test/test.rb +40 -15
- data/test/test.vectors +960 -462
- data/test/xxhsum.c.c0e86bc0.diff +424 -0
- metadata +11 -5
- data/ext/digest/xxhash/xxhash.c +0 -888
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5aa94f079152f6f34485582fffd2dfa9a405d7e202fef418d9c569c28404b99a
|
4
|
+
data.tar.gz: aaaceebacfe3616bb16f974e1a4611d79d9662baf72e4e84622f6ea91232e7cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3800479093f35a377f17faf7f41a7624ba5fecff8ce12a13a3b88cdd75ec79e053f216203e02399ad0557e741d6051159866a0d75279897fe2a053cb06370fce
|
7
|
+
data.tar.gz: 79c51f9b3bc4ef219419441133276b3b6cb90a2db53e7f44c2d0c7e277a6ed7918a4759aaf0c629660024f870f84b36a01241b6214caf8e7e1682d41f597682c
|
data/README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# digest-xxhash
|
2
2
|
|
3
|
-
This gem
|
4
|
-
inherits Digest::Class and complies
|
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.
|
5
6
|
|
6
|
-
Its core implementation
|
7
|
-
|
7
|
+
Its core implementation comes from the official source, which is in
|
8
|
+
https://github.com/Cyan4973/xxHash.
|
8
9
|
|
9
10
|
## Installation
|
10
11
|
|
@@ -62,6 +63,18 @@ The library can also be installed in Gentoo system-wide using 'layman':
|
|
62
63
|
Digest::XXH64.new.reset("0123456789abcdef").update("12").update("34").hexdigest
|
63
64
|
=> "d7544504de216507"
|
64
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
|
+
|
65
78
|
## API Documentation
|
66
79
|
|
67
80
|
RubyGems.org provides autogenerated API documentation of the library in
|
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,7 +28,7 @@ task :clean do
|
|
17
28
|
rm_f list unless list.empty?
|
18
29
|
end
|
19
30
|
|
20
|
-
#
|
31
|
+
# default
|
21
32
|
task :default => :test
|
22
33
|
|
23
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
23
|
spec.files = `git ls-files -z`.split("\x0").reject{ |f| f =~ /\.yml$/ }
|
20
|
-
spec.executables = spec.files.grep(%r{^bin/})
|
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
@@ -25,9 +25,8 @@
|
|
25
25
|
|
26
26
|
#include <ruby.h>
|
27
27
|
#include <ruby/digest.h>
|
28
|
-
#include <stdint.h>
|
29
28
|
|
30
|
-
#define
|
29
|
+
#define XXH_INLINE_ALL
|
31
30
|
#include "xxhash.h"
|
32
31
|
#include "utils.h"
|
33
32
|
|
@@ -38,14 +37,21 @@
|
|
38
37
|
#endif
|
39
38
|
|
40
39
|
#define _XXH32_DIGEST_SIZE 4
|
41
|
-
#define _XXH64_DIGEST_SIZE 8
|
42
|
-
|
43
40
|
#define _XXH32_BLOCK_SIZE 4
|
44
|
-
#define _XXH64_BLOCK_SIZE 8
|
45
|
-
|
46
41
|
#define _XXH32_DEFAULT_SEED 0
|
42
|
+
|
43
|
+
#define _XXH64_DIGEST_SIZE 8
|
44
|
+
#define _XXH64_BLOCK_SIZE 8
|
47
45
|
#define _XXH64_DEFAULT_SEED 0
|
48
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
|
+
|
49
55
|
#if 0
|
50
56
|
# define _DEBUG(...) fprintf(stderr, __VA_ARGS__)
|
51
57
|
#else
|
@@ -66,8 +72,15 @@ 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)
|
69
80
|
|
70
|
-
|
81
|
+
static void _xxh32_free_state(void *);
|
82
|
+
static void _xxh64_free_state(void *);
|
83
|
+
static void _xxh3_free_state(void *);
|
71
84
|
|
72
85
|
/*
|
73
86
|
* Data types
|
@@ -75,13 +88,25 @@ static VALUE _Digest_XXH64;
|
|
75
88
|
|
76
89
|
static const rb_data_type_t _xxh32_state_data_type = {
|
77
90
|
"xxh32_state_data",
|
78
|
-
{ 0,
|
91
|
+
{ 0, _xxh32_free_state, 0, }, 0, 0,
|
79
92
|
RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
|
80
93
|
};
|
81
94
|
|
82
95
|
static const rb_data_type_t _xxh64_state_data_type = {
|
83
96
|
"xxh64_state_data",
|
84
|
-
{ 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,
|
85
110
|
RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
|
86
111
|
};
|
87
112
|
|
@@ -89,108 +114,93 @@ static const rb_data_type_t _xxh64_state_data_type = {
|
|
89
114
|
* Common functions
|
90
115
|
*/
|
91
116
|
|
92
|
-
static XXH32_state_t *
|
117
|
+
static XXH32_state_t *_get_state_xxh32(VALUE self)
|
93
118
|
{
|
94
119
|
XXH32_state_t *state_p;
|
95
120
|
TypedData_Get_Struct(self, XXH32_state_t, &_xxh32_state_data_type, state_p);
|
96
121
|
return state_p;
|
97
122
|
}
|
98
123
|
|
99
|
-
static XXH64_state_t *
|
124
|
+
static XXH64_state_t *_get_state_xxh64(VALUE self)
|
100
125
|
{
|
101
126
|
XXH64_state_t *state_p;
|
102
127
|
TypedData_Get_Struct(self, XXH64_state_t, &_xxh64_state_data_type, state_p);
|
103
128
|
return state_p;
|
104
129
|
}
|
105
130
|
|
106
|
-
static
|
131
|
+
static XXH3_state_t *_get_state_xxh3_64bits(VALUE self)
|
107
132
|
{
|
108
|
-
|
109
|
-
|
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;
|
110
136
|
}
|
111
137
|
|
112
|
-
static
|
138
|
+
static XXH3_state_t *_get_state_xxh3_128bits(VALUE self)
|
113
139
|
{
|
114
|
-
|
115
|
-
|
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;
|
116
143
|
}
|
117
144
|
|
118
|
-
static
|
145
|
+
static void _xxh32_reset(XXH32_state_t *state_p, XXH32_hash_t seed)
|
119
146
|
{
|
120
|
-
|
121
|
-
|
122
|
-
if (is_little_endian()) {
|
123
|
-
temp = swap_uint32(num);
|
124
|
-
} else {
|
125
|
-
temp = num;
|
126
|
-
}
|
127
|
-
|
128
|
-
return rb_usascii_str_new((char *) &temp, sizeof(uint32_t));
|
147
|
+
if (XXH32_reset(state_p, seed) != XXH_OK)
|
148
|
+
rb_raise(rb_eRuntimeError, "Failed to reset state.");
|
129
149
|
}
|
130
150
|
|
131
|
-
static
|
151
|
+
static void _xxh64_reset(XXH64_state_t *state_p, XXH64_hash_t seed)
|
132
152
|
{
|
133
|
-
|
134
|
-
|
135
|
-
if (is_little_endian()) {
|
136
|
-
return swap_uint32(temp);
|
137
|
-
} else {
|
138
|
-
return temp;
|
139
|
-
}
|
153
|
+
if (XXH64_reset(state_p, seed) != XXH_OK)
|
154
|
+
rb_raise(rb_eRuntimeError, "Failed to reset state.");
|
140
155
|
}
|
141
156
|
|
142
|
-
static
|
157
|
+
static void _xxh3_64bits_reset(XXH3_state_t *state_p, XXH64_hash_t seed)
|
143
158
|
{
|
144
|
-
|
159
|
+
if (XXH3_64bits_reset_withSeed(state_p, seed) != XXH_OK)
|
160
|
+
rb_raise(rb_eRuntimeError, "Failed to reset state.");
|
145
161
|
}
|
146
162
|
|
147
|
-
static
|
163
|
+
static void _xxh3_128bits_reset(XXH3_state_t *state_p, XXH64_hash_t seed)
|
148
164
|
{
|
149
|
-
|
150
|
-
|
151
|
-
if (is_little_endian()) {
|
152
|
-
temp = swap_uint64(num);
|
153
|
-
} else {
|
154
|
-
temp = num;
|
155
|
-
}
|
156
|
-
|
157
|
-
return rb_usascii_str_new((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.");
|
158
167
|
}
|
159
168
|
|
160
|
-
static
|
169
|
+
static void _xxh32_free_state(void* state)
|
161
170
|
{
|
162
|
-
|
171
|
+
XXH32_freeState((XXH32_state_t *)state);
|
172
|
+
}
|
163
173
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
return temp;
|
168
|
-
}
|
174
|
+
static void _xxh64_free_state(void* state)
|
175
|
+
{
|
176
|
+
XXH64_freeState((XXH64_state_t *)state);
|
169
177
|
}
|
170
178
|
|
171
|
-
static
|
179
|
+
static void _xxh3_free_state(void* state)
|
172
180
|
{
|
173
|
-
|
181
|
+
XXH3_freeState((XXH3_state_t *)state);
|
174
182
|
}
|
175
183
|
|
176
184
|
static VALUE _hex_encode_str(VALUE str)
|
177
185
|
{
|
178
186
|
int len = RSTRING_LEN(str);
|
179
|
-
VALUE hex =
|
180
|
-
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));
|
181
189
|
return hex;
|
182
190
|
}
|
183
191
|
|
184
192
|
/*
|
185
193
|
* Document-class: Digest::XXHash
|
186
194
|
*
|
187
|
-
* 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.
|
188
197
|
*/
|
189
198
|
|
190
199
|
static VALUE _Digest_XXHash_internal_allocate(VALUE klass)
|
191
200
|
{
|
192
201
|
if (klass == _Digest_XXHash)
|
193
|
-
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.");
|
194
204
|
|
195
205
|
rb_raise(rb_eNotImpError, "Allocator function not implemented.");
|
196
206
|
}
|
@@ -260,8 +270,9 @@ static VALUE _do_digest(int argc, VALUE* argv, VALUE self, ID finish_method_id)
|
|
260
270
|
* with +seed+, and is used as the return value. The instance's state is reset
|
261
271
|
* to default afterwards.
|
262
272
|
*
|
263
|
-
* Providing an argument means that previous
|
264
|
-
*
|
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.
|
265
276
|
*
|
266
277
|
* +seed+ can be in the form of a string, a hex string, or a number.
|
267
278
|
*/
|
@@ -280,9 +291,7 @@ static VALUE _Digest_XXHash_digest(int argc, VALUE* argv, VALUE self)
|
|
280
291
|
*/
|
281
292
|
static VALUE _Digest_XXHash_hexdigest(int argc, VALUE* argv, VALUE self)
|
282
293
|
{
|
283
|
-
|
284
|
-
result = _do_digest(argc, argv, self, _id_finish);
|
285
|
-
return _hex_encode_str(result);
|
294
|
+
return _hex_encode_str(_do_digest(argc, argv, self, _id_finish));
|
286
295
|
}
|
287
296
|
|
288
297
|
/*
|
@@ -403,10 +412,9 @@ static VALUE _Digest_XXHash_singleton_idigest(int argc, VALUE* argv, VALUE self)
|
|
403
412
|
|
404
413
|
static VALUE _Digest_XXH32_internal_allocate(VALUE klass)
|
405
414
|
{
|
406
|
-
XXH32_state_t *state_p;
|
407
|
-
VALUE obj = TypedData_Make_Struct(klass, XXH32_state_t, &_xxh32_state_data_type, state_p);
|
415
|
+
XXH32_state_t *state_p = XXH32_createState();
|
408
416
|
_xxh32_reset(state_p, 0);
|
409
|
-
return
|
417
|
+
return TypedData_Wrap_Struct(klass, &_xxh32_state_data_type, state_p);
|
410
418
|
}
|
411
419
|
|
412
420
|
/*
|
@@ -416,7 +424,7 @@ static VALUE _Digest_XXH32_internal_allocate(VALUE klass)
|
|
416
424
|
*/
|
417
425
|
static VALUE _Digest_XXH32_update(VALUE self, VALUE str)
|
418
426
|
{
|
419
|
-
if (XXH32_update(
|
427
|
+
if (XXH32_update(_get_state_xxh32(self), RSTRING_PTR(str), RSTRING_LEN(str)) != XXH_OK)
|
420
428
|
rb_raise(rb_eRuntimeError, "Failed to update state.");
|
421
429
|
|
422
430
|
return self;
|
@@ -425,15 +433,17 @@ static VALUE _Digest_XXH32_update(VALUE self, VALUE str)
|
|
425
433
|
/* :nodoc: */
|
426
434
|
static VALUE _Digest_XXH32_finish(VALUE self)
|
427
435
|
{
|
428
|
-
|
429
|
-
|
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;
|
430
440
|
}
|
431
441
|
|
432
442
|
/* :nodoc: */
|
433
443
|
static VALUE _Digest_XXH32_ifinish(VALUE self)
|
434
444
|
{
|
435
|
-
|
436
|
-
return ULONG2NUM(
|
445
|
+
XXH32_hash_t hash = XXH32_digest(_get_state_xxh32(self));
|
446
|
+
return ULONG2NUM(hash);
|
437
447
|
}
|
438
448
|
|
439
449
|
/*
|
@@ -441,9 +451,10 @@ static VALUE _Digest_XXH32_ifinish(VALUE self)
|
|
441
451
|
*
|
442
452
|
* Resets state to initial form with seed.
|
443
453
|
*
|
444
|
-
* This
|
454
|
+
* This discards previous calculations with #update.
|
445
455
|
*
|
446
456
|
* +seed+ can be in the form of a string, a hex string, or a number.
|
457
|
+
* Its virtual length should be 32-bits.
|
447
458
|
*
|
448
459
|
* If +seed+ is not provided, the default value would be 0.
|
449
460
|
*/
|
@@ -456,36 +467,39 @@ static VALUE _Digest_XXH32_reset(int argc, VALUE* argv, VALUE self)
|
|
456
467
|
case T_STRING:
|
457
468
|
{
|
458
469
|
int len = RSTRING_LEN(seed);
|
459
|
-
|
470
|
+
XXH32_hash_t decoded_seed;
|
460
471
|
|
461
|
-
if (len == (sizeof(
|
462
|
-
unsigned char hex_decoded_seed[sizeof(
|
472
|
+
if (len == _TWICE(sizeof(XXH32_hash_t))) {
|
473
|
+
unsigned char hex_decoded_seed[sizeof(XXH32_hash_t)];
|
463
474
|
|
464
|
-
if (! hex_decode_str_implied(
|
465
|
-
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));
|
466
478
|
|
467
|
-
decoded_seed =
|
468
|
-
} else if (len == sizeof(
|
469
|
-
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));
|
470
482
|
} else {
|
471
|
-
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.");
|
472
485
|
}
|
473
486
|
|
474
|
-
_xxh32_reset(
|
487
|
+
_xxh32_reset(_get_state_xxh32(self), decoded_seed);
|
475
488
|
}
|
476
489
|
|
477
490
|
break;
|
478
491
|
case T_FIXNUM:
|
479
|
-
_xxh32_reset(
|
492
|
+
_xxh32_reset(_get_state_xxh32(self), FIX2UINT(seed));
|
480
493
|
break;
|
481
494
|
case T_BIGNUM:
|
482
|
-
_xxh32_reset(
|
495
|
+
_xxh32_reset(_get_state_xxh32(self), NUM2UINT(seed));
|
483
496
|
break;
|
484
497
|
default:
|
485
|
-
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.");
|
486
500
|
}
|
487
501
|
} else {
|
488
|
-
_xxh32_reset(
|
502
|
+
_xxh32_reset(_get_state_xxh32(self), _XXH32_DEFAULT_SEED);
|
489
503
|
}
|
490
504
|
|
491
505
|
return self;
|
@@ -499,14 +513,14 @@ static VALUE _Digest_XXH32_reset(int argc, VALUE* argv, VALUE self)
|
|
499
513
|
*/
|
500
514
|
static VALUE _Digest_XXH32_initialize_copy(VALUE self, VALUE orig)
|
501
515
|
{
|
502
|
-
XXH32_copyState(
|
516
|
+
XXH32_copyState(_get_state_xxh32(self), _get_state_xxh32(orig));
|
503
517
|
return self;
|
504
518
|
}
|
505
519
|
|
506
520
|
/*
|
507
521
|
* call-seq: digest_length -> int
|
508
522
|
*
|
509
|
-
* Returns 4
|
523
|
+
* Returns 4
|
510
524
|
*/
|
511
525
|
static VALUE _Digest_XXH32_digest_length(VALUE self)
|
512
526
|
{
|
@@ -516,7 +530,7 @@ static VALUE _Digest_XXH32_digest_length(VALUE self)
|
|
516
530
|
/*
|
517
531
|
* call-seq: block_length -> int
|
518
532
|
*
|
519
|
-
* Returns 4
|
533
|
+
* Returns 4
|
520
534
|
*/
|
521
535
|
static VALUE _Digest_XXH32_block_length(VALUE self)
|
522
536
|
{
|
@@ -526,7 +540,7 @@ static VALUE _Digest_XXH32_block_length(VALUE self)
|
|
526
540
|
/*
|
527
541
|
* call-seq: digest_length -> int
|
528
542
|
*
|
529
|
-
* Returns 4
|
543
|
+
* Returns 4
|
530
544
|
*/
|
531
545
|
static VALUE _Digest_XXH32_singleton_digest_length(VALUE self)
|
532
546
|
{
|
@@ -536,7 +550,7 @@ static VALUE _Digest_XXH32_singleton_digest_length(VALUE self)
|
|
536
550
|
/*
|
537
551
|
* call-seq: block_length -> int
|
538
552
|
*
|
539
|
-
* Returns 4
|
553
|
+
* Returns 4
|
540
554
|
*/
|
541
555
|
static VALUE _Digest_XXH32_singleton_block_length(VALUE self)
|
542
556
|
{
|
@@ -551,10 +565,9 @@ static VALUE _Digest_XXH32_singleton_block_length(VALUE self)
|
|
551
565
|
|
552
566
|
static VALUE _Digest_XXH64_internal_allocate(VALUE klass)
|
553
567
|
{
|
554
|
-
XXH64_state_t *state_p;
|
555
|
-
VALUE obj = TypedData_Make_Struct(klass, XXH64_state_t, &_xxh64_state_data_type, state_p);
|
568
|
+
XXH64_state_t *state_p = XXH64_createState();
|
556
569
|
_xxh64_reset(state_p, 0);
|
557
|
-
return
|
570
|
+
return TypedData_Wrap_Struct(klass, &_xxh64_state_data_type, state_p);
|
558
571
|
}
|
559
572
|
|
560
573
|
/*
|
@@ -564,7 +577,7 @@ static VALUE _Digest_XXH64_internal_allocate(VALUE klass)
|
|
564
577
|
*/
|
565
578
|
static VALUE _Digest_XXH64_update(VALUE self, VALUE str)
|
566
579
|
{
|
567
|
-
if (XXH64_update(
|
580
|
+
if (XXH64_update(_get_state_xxh64(self), RSTRING_PTR(str), RSTRING_LEN(str)) != XXH_OK)
|
568
581
|
rb_raise(rb_eRuntimeError, "Failed to update state.");
|
569
582
|
|
570
583
|
return self;
|
@@ -573,15 +586,17 @@ static VALUE _Digest_XXH64_update(VALUE self, VALUE str)
|
|
573
586
|
/* :nodoc: */
|
574
587
|
static VALUE _Digest_XXH64_finish(VALUE self)
|
575
588
|
{
|
576
|
-
|
577
|
-
|
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;
|
578
593
|
}
|
579
594
|
|
580
595
|
/* :nodoc: */
|
581
596
|
static VALUE _Digest_XXH64_ifinish(VALUE self)
|
582
597
|
{
|
583
|
-
|
584
|
-
return ULL2NUM(
|
598
|
+
XXH64_hash_t hash = XXH64_digest(_get_state_xxh64(self));
|
599
|
+
return ULL2NUM(hash);
|
585
600
|
}
|
586
601
|
|
587
602
|
/*
|
@@ -589,9 +604,10 @@ static VALUE _Digest_XXH64_ifinish(VALUE self)
|
|
589
604
|
*
|
590
605
|
* Resets state to initial form with seed.
|
591
606
|
*
|
592
|
-
* This
|
607
|
+
* This discards previous calculations with #update.
|
593
608
|
*
|
594
609
|
* +seed+ can be in the form of a string, a hex string, or a number.
|
610
|
+
* Its virtual length should be 64-bits.
|
595
611
|
*
|
596
612
|
* If +seed+ is not provided, the default value would be 0.
|
597
613
|
*/
|
@@ -604,36 +620,39 @@ static VALUE _Digest_XXH64_reset(int argc, VALUE* argv, VALUE self)
|
|
604
620
|
case T_STRING:
|
605
621
|
{
|
606
622
|
int len = RSTRING_LEN(seed);
|
607
|
-
|
623
|
+
XXH64_hash_t decoded_seed;
|
608
624
|
|
609
|
-
if (len == (sizeof(
|
610
|
-
unsigned char hex_decoded_seed[sizeof(
|
625
|
+
if (len == _TWICE(sizeof(XXH64_hash_t))) {
|
626
|
+
unsigned char hex_decoded_seed[sizeof(XXH64_hash_t)];
|
611
627
|
|
612
|
-
if (! hex_decode_str_implied(
|
613
|
-
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));
|
614
631
|
|
615
|
-
decoded_seed =
|
616
|
-
} else if (len == sizeof(
|
617
|
-
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));
|
618
635
|
} else {
|
619
|
-
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.");
|
620
638
|
}
|
621
639
|
|
622
|
-
_xxh64_reset(
|
640
|
+
_xxh64_reset(_get_state_xxh64(self), decoded_seed);
|
623
641
|
}
|
624
642
|
|
625
643
|
break;
|
626
644
|
case T_FIXNUM:
|
627
|
-
_xxh64_reset(
|
645
|
+
_xxh64_reset(_get_state_xxh64(self), FIX2UINT(seed));
|
628
646
|
break;
|
629
647
|
case T_BIGNUM:
|
630
|
-
_xxh64_reset(
|
648
|
+
_xxh64_reset(_get_state_xxh64(self), NUM2ULL(seed));
|
631
649
|
break;
|
632
650
|
default:
|
633
|
-
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.");
|
634
653
|
}
|
635
654
|
} else {
|
636
|
-
_xxh64_reset(
|
655
|
+
_xxh64_reset(_get_state_xxh64(self), _XXH64_DEFAULT_SEED);
|
637
656
|
}
|
638
657
|
|
639
658
|
return self;
|
@@ -647,14 +666,14 @@ static VALUE _Digest_XXH64_reset(int argc, VALUE* argv, VALUE self)
|
|
647
666
|
*/
|
648
667
|
static VALUE _Digest_XXH64_initialize_copy(VALUE self, VALUE orig)
|
649
668
|
{
|
650
|
-
XXH64_copyState(
|
669
|
+
XXH64_copyState(_get_state_xxh64(self), _get_state_xxh64(orig));
|
651
670
|
return self;
|
652
671
|
}
|
653
672
|
|
654
673
|
/*
|
655
674
|
* call-seq: digest_length -> int
|
656
675
|
*
|
657
|
-
* Returns 8
|
676
|
+
* Returns 8
|
658
677
|
*/
|
659
678
|
static VALUE _Digest_XXH64_digest_length(VALUE self)
|
660
679
|
{
|
@@ -664,7 +683,7 @@ static VALUE _Digest_XXH64_digest_length(VALUE self)
|
|
664
683
|
/*
|
665
684
|
* call-seq: block_length -> int
|
666
685
|
*
|
667
|
-
* Returns 8
|
686
|
+
* Returns 8
|
668
687
|
*/
|
669
688
|
static VALUE _Digest_XXH64_block_length(VALUE self)
|
670
689
|
{
|
@@ -674,7 +693,7 @@ static VALUE _Digest_XXH64_block_length(VALUE self)
|
|
674
693
|
/*
|
675
694
|
* call-seq: digest_length -> int
|
676
695
|
*
|
677
|
-
* Returns 8
|
696
|
+
* Returns 8
|
678
697
|
*/
|
679
698
|
static VALUE _Digest_XXH64_singleton_digest_length(VALUE self)
|
680
699
|
{
|
@@ -684,13 +703,378 @@ static VALUE _Digest_XXH64_singleton_digest_length(VALUE self)
|
|
684
703
|
/*
|
685
704
|
* call-seq: block_length -> int
|
686
705
|
*
|
687
|
-
* Returns 8
|
706
|
+
* Returns 8
|
688
707
|
*/
|
689
708
|
static VALUE _Digest_XXH64_singleton_block_length(VALUE self)
|
690
709
|
{
|
691
710
|
return INT2FIX(_XXH64_BLOCK_SIZE);
|
692
711
|
}
|
693
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
|
+
|
694
1078
|
/*
|
695
1079
|
* Initialization
|
696
1080
|
*/
|
@@ -723,7 +1107,7 @@ void Init_xxhash()
|
|
723
1107
|
*/
|
724
1108
|
|
725
1109
|
_Digest_XXHash = rb_define_class_under(_Digest, "XXHash", _Digest_Class);
|
726
|
-
|
1110
|
+
rb_define_alloc_func(_Digest_XXHash, _Digest_XXHash_internal_allocate);
|
727
1111
|
rb_define_method(_Digest_XXHash, "digest", _Digest_XXHash_digest, -1);
|
728
1112
|
rb_define_method(_Digest_XXHash, "hexdigest", _Digest_XXHash_hexdigest, -1);
|
729
1113
|
rb_define_method(_Digest_XXHash, "idigest", _Digest_XXHash_idigest, -1);
|
@@ -731,32 +1115,24 @@ void Init_xxhash()
|
|
731
1115
|
rb_define_method(_Digest_XXHash, "initialize", _Digest_XXHash_initialize, -1);
|
732
1116
|
rb_define_method(_Digest_XXHash, "inspect", _Digest_XXHash_inspect, 0);
|
733
1117
|
rb_define_method(_Digest_XXHash, "initialize_copy", _Digest_XXHash_initialize_copy, 1);
|
734
|
-
|
735
1118
|
rb_define_protected_method(_Digest_XXHash, "ifinish", _Digest_XXHash_ifinish, 0);
|
736
|
-
|
737
1119
|
rb_define_singleton_method(_Digest_XXHash, "digest", _Digest_XXHash_singleton_digest, -1);
|
738
1120
|
rb_define_singleton_method(_Digest_XXHash, "hexdigest", _Digest_XXHash_singleton_hexdigest, -1);
|
739
1121
|
rb_define_singleton_method(_Digest_XXHash, "idigest", _Digest_XXHash_singleton_idigest, -1);
|
740
1122
|
|
741
|
-
rb_define_alloc_func(_Digest_XXHash, _Digest_XXHash_internal_allocate);
|
742
|
-
|
743
1123
|
/*
|
744
1124
|
* Document-class: Digest::XXH32
|
745
1125
|
*/
|
746
1126
|
|
747
1127
|
_Digest_XXH32 = rb_define_class_under(_Digest, "XXH32", _Digest_XXHash);
|
748
|
-
|
749
1128
|
rb_define_alloc_func(_Digest_XXH32, _Digest_XXH32_internal_allocate);
|
750
|
-
|
751
1129
|
rb_define_private_method(_Digest_XXH32, "finish", _Digest_XXH32_finish, 0);
|
752
1130
|
rb_define_private_method(_Digest_XXH32, "ifinish", _Digest_XXH32_ifinish, 0);
|
753
|
-
|
754
1131
|
rb_define_method(_Digest_XXH32, "update", _Digest_XXH32_update, 1);
|
755
1132
|
rb_define_method(_Digest_XXH32, "reset", _Digest_XXH32_reset, -1);
|
756
1133
|
rb_define_method(_Digest_XXH32, "digest_length", _Digest_XXH32_digest_length, 0);
|
757
1134
|
rb_define_method(_Digest_XXH32, "block_length", _Digest_XXH32_block_length, 0);
|
758
1135
|
rb_define_method(_Digest_XXH32, "initialize_copy", _Digest_XXH32_initialize_copy, 1);
|
759
|
-
|
760
1136
|
rb_define_singleton_method(_Digest_XXH32, "digest_length", _Digest_XXH32_singleton_digest_length, 0);
|
761
1137
|
rb_define_singleton_method(_Digest_XXH32, "block_length", _Digest_XXH32_singleton_block_length, 0);
|
762
1138
|
|
@@ -765,18 +1141,60 @@ void Init_xxhash()
|
|
765
1141
|
*/
|
766
1142
|
|
767
1143
|
_Digest_XXH64 = rb_define_class_under(_Digest, "XXH64", _Digest_XXHash);
|
768
|
-
|
769
1144
|
rb_define_alloc_func(_Digest_XXH64, _Digest_XXH64_internal_allocate);
|
770
|
-
|
771
1145
|
rb_define_private_method(_Digest_XXH64, "finish", _Digest_XXH64_finish, 0);
|
772
1146
|
rb_define_private_method(_Digest_XXH64, "ifinish", _Digest_XXH64_ifinish, 0);
|
773
|
-
|
774
1147
|
rb_define_method(_Digest_XXH64, "update", _Digest_XXH64_update, 1);
|
775
1148
|
rb_define_method(_Digest_XXH64, "reset", _Digest_XXH64_reset, -1);
|
776
1149
|
rb_define_method(_Digest_XXH64, "digest_length", _Digest_XXH64_digest_length, 0);
|
777
1150
|
rb_define_method(_Digest_XXH64, "block_length", _Digest_XXH64_block_length, 0);
|
778
1151
|
rb_define_method(_Digest_XXH64, "initialize_copy", _Digest_XXH64_initialize_copy, 1);
|
779
|
-
|
780
1152
|
rb_define_singleton_method(_Digest_XXH64, "digest_length", _Digest_XXH64_singleton_digest_length, 0);
|
781
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));
|
782
1200
|
}
|