digest-xxhash 0.1.2 → 0.2.0

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