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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 557c034e51c5ed220c3ebba704e0b6d5dbd415c4178b2fecf4d6adb153cb9562
4
- data.tar.gz: 209905cf00b851386b306a5a61a8a8a8de42cc7d30159fea4384ffb060cbc114
3
+ metadata.gz: 5aa94f079152f6f34485582fffd2dfa9a405d7e202fef418d9c569c28404b99a
4
+ data.tar.gz: aaaceebacfe3616bb16f974e1a4611d79d9662baf72e4e84622f6ea91232e7cc
5
5
  SHA512:
6
- metadata.gz: 528a1c15bf7aa8c9aecc9e86c4e953b1fefb6b38b64c64852cffd2dbc254550ef8062f6ebbb5324e6026cc69b4d32f0db2c865a4088dbff1ee1c7c5bf440b511
7
- data.tar.gz: dec45992be6ff41b92f26ff55e06be1832a115ac2885aa012342cb51643950b35e8a18aaedfb445bd2da7bbaa110d008b5be9b11fbe8fd5f5ed71a87533edda8
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 'digest-xxhash' provides XXH32 and XXH64 functions for Ruby. It
4
- inherits Digest::Class and complies with Digest::Instance's functional design.
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 was taken from the official source, which is
7
- in https://github.com/Cyan4973/xxHash.
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
- # Set 'test' as default task.
31
+ # default
21
32
  task :default => :test
22
33
 
23
34
  # Run `rake --tasks` for a list of tasks.
@@ -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 = "An XXHash library that complies with Digest::Instance's functional design."
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/}) { |f| File.basename(f) }
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
 
@@ -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 XXH_STATIC_LINKING_ONLY
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
- #define _RSTRING_PTR_UCHAR(x) ((const unsigned char *)RSTRING_PTR(x))
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, RUBY_TYPED_DEFAULT_FREE, 0, }, 0, 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, RUBY_TYPED_DEFAULT_FREE, 0, }, 0, 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 *_get_state_32(VALUE self)
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 *_get_state_64(VALUE self)
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 void _xxh32_reset(XXH32_state_t *state_p, uint32_t seed)
131
+ static XXH3_state_t *_get_state_xxh3_64bits(VALUE self)
107
132
  {
108
- if (XXH32_reset(state_p, seed) != XXH_OK)
109
- rb_raise(rb_eRuntimeError, "Failed to reset state.");
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 void _xxh64_reset(XXH64_state_t *state_p, uint64_t seed)
138
+ static XXH3_state_t *_get_state_xxh3_128bits(VALUE self)
113
139
  {
114
- if (XXH64_reset(state_p, seed) != XXH_OK)
115
- rb_raise(rb_eRuntimeError, "Failed to reset state.");
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 VALUE _encode_big_endian_32(uint32_t num)
145
+ static void _xxh32_reset(XXH32_state_t *state_p, XXH32_hash_t seed)
119
146
  {
120
- uint32_t temp;
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 uint32_t _decode_big_endian_32_cstr(const char *str)
151
+ static void _xxh64_reset(XXH64_state_t *state_p, XXH64_hash_t seed)
132
152
  {
133
- uint32_t temp = read32(str);
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 uint32_t _decode_big_endian_32(VALUE str)
157
+ static void _xxh3_64bits_reset(XXH3_state_t *state_p, XXH64_hash_t seed)
143
158
  {
144
- return _decode_big_endian_32_cstr(RSTRING_PTR(str));
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 VALUE _encode_big_endian_64(uint64_t num)
163
+ static void _xxh3_128bits_reset(XXH3_state_t *state_p, XXH64_hash_t seed)
148
164
  {
149
- uint64_t temp;
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 uint64_t _decode_big_endian_64_cstr(const char *str)
169
+ static void _xxh32_free_state(void* state)
161
170
  {
162
- uint64_t temp = read64(str);
171
+ XXH32_freeState((XXH32_state_t *)state);
172
+ }
163
173
 
164
- if (is_little_endian()) {
165
- return swap_uint64(temp);
166
- } else {
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 uint64_t _decode_big_endian_64(VALUE str)
179
+ static void _xxh3_free_state(void* state)
172
180
  {
173
- return _decode_big_endian_64_cstr(RSTRING_PTR(str));
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 = rb_str_new(0, len * 2);
180
- hex_encode_str_implied(_RSTRING_PTR_UCHAR(str), len, (unsigned char *)RSTRING_PTR(hex));
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 and Digest::XXH64.
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 instantiated.");
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 calculations done with #update
264
- * would be discarded, so be careful with its use.
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
- VALUE result;
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 obj;
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(_get_state_32(self), RSTRING_PTR(str), RSTRING_LEN(str)) != XXH_OK)
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
- uint32_t result = XXH32_digest(_get_state_32(self));
429
- return _encode_big_endian_32(result);
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
- uint32_t result = XXH32_digest(_get_state_32(self));
436
- return ULONG2NUM(result);
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 would discard previous calculations with #update.
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
- uint32_t decoded_seed;
470
+ XXH32_hash_t decoded_seed;
460
471
 
461
- if (len == (sizeof(uint32_t) * 2)) {
462
- unsigned char hex_decoded_seed[sizeof(uint32_t)];
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(_RSTRING_PTR_UCHAR(seed), sizeof(uint32_t) * 2, hex_decoded_seed))
465
- rb_raise(rb_eArgError, "Invalid hex string seed: %s\n", StringValueCStr(seed));
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 = _decode_big_endian_32_cstr((const char *)hex_decoded_seed);
468
- } else if (len == sizeof(uint32_t)) {
469
- decoded_seed = _decode_big_endian_32(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. Expecting an 8-character hex string or a 4-byte string.");
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(_get_state_32(self), decoded_seed);
487
+ _xxh32_reset(_get_state_xxh32(self), decoded_seed);
475
488
  }
476
489
 
477
490
  break;
478
491
  case T_FIXNUM:
479
- _xxh32_reset(_get_state_32(self), FIX2UINT(seed));
492
+ _xxh32_reset(_get_state_xxh32(self), FIX2UINT(seed));
480
493
  break;
481
494
  case T_BIGNUM:
482
- _xxh32_reset(_get_state_32(self), NUM2UINT(seed));
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. Expecting a string or number.");
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(_get_state_32(self), _XXH32_DEFAULT_SEED);
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(_get_state_32(self), _get_state_32(orig));
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 obj;
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(_get_state_64(self), RSTRING_PTR(str), RSTRING_LEN(str)) != XXH_OK)
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
- uint64_t result = XXH64_digest(_get_state_64(self));
577
- return _encode_big_endian_64(result);
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
- uint64_t result = XXH64_digest(_get_state_64(self));
584
- return ULL2NUM(result);
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 would discard previous calculations with #update.
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
- uint64_t decoded_seed;
623
+ XXH64_hash_t decoded_seed;
608
624
 
609
- if (len == (sizeof(uint64_t) * 2)) {
610
- unsigned char hex_decoded_seed[sizeof(uint64_t)];
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(_RSTRING_PTR_UCHAR(seed), sizeof(uint64_t) * 2, hex_decoded_seed))
613
- rb_raise(rb_eArgError, "Invalid hex string seed: %s\n", StringValueCStr(seed));
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 = _decode_big_endian_64_cstr((const char *)hex_decoded_seed);
616
- } else if (len == sizeof(uint64_t)) {
617
- decoded_seed = _decode_big_endian_64(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. Expecting a 16-character hex string or an 8-byte string.");
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(_get_state_64(self), decoded_seed);
640
+ _xxh64_reset(_get_state_xxh64(self), decoded_seed);
623
641
  }
624
642
 
625
643
  break;
626
644
  case T_FIXNUM:
627
- _xxh64_reset(_get_state_64(self), FIX2UINT(seed));
645
+ _xxh64_reset(_get_state_xxh64(self), FIX2UINT(seed));
628
646
  break;
629
647
  case T_BIGNUM:
630
- _xxh64_reset(_get_state_64(self), NUM2ULL(seed));
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. Expecting a string or number.");
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(_get_state_64(self), _XXH64_DEFAULT_SEED);
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(_get_state_64(self), _get_state_64(orig));
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
  }