crc-turbo 0.1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +24 -0
- data/README.md +52 -0
- data/Rakefile +212 -0
- data/ext/crc/crcturbo.c +720 -0
- data/ext/crc/extconf.rb +9 -0
- data/gemstub.rb +19 -0
- data/lib/crc/2.0/_turbo.so +0 -0
- data/lib/crc/2.1/_turbo.so +0 -0
- data/lib/crc/2.2/_turbo.so +0 -0
- data/lib/crc/2.3/_turbo.so +0 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 263718966306d1579a8e54c12ffcc39ceee33a13
|
4
|
+
data.tar.gz: 57ce8a4a8f07392f847bc472f82af1c0aa322d62
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e60394e399127f22937feec6e670d6e7c53563e7b72b041c03a5d5fec2b7ea8cae2a73a2f3165a9a2d97b1f68fd9c3e37ba48d1da2ee5b4d8192bc9d34259222
|
7
|
+
data.tar.gz: 4fed18b1b53b477b85c9ebd032d40746210f1738e759cc79296d2738567dacbb9ca722f39aa8e562ed5001d6556ad04cd6f26540ff67b87031e37d1b179ca02d
|
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2016, dearblue. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or
|
4
|
+
without modification, are permitted provided that the following
|
5
|
+
conditions are met:
|
6
|
+
|
7
|
+
1. Redistributions of source code must retain the above copyright
|
8
|
+
notice, this list of conditions and the following disclaimer.
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer in
|
11
|
+
the documentation and/or other materials provided with the
|
12
|
+
distribution.
|
13
|
+
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
15
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
16
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
17
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
18
|
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
19
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
20
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
21
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
22
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
# crc-turbo - CRC generator for ruby
|
3
|
+
|
4
|
+
This is a C extention for "crc" gem library.
|
5
|
+
|
6
|
+
Just install this, and "require 'crc'". Additional other work is not required.
|
7
|
+
|
8
|
+
|
9
|
+
## SUMMARY
|
10
|
+
|
11
|
+
* package name: crc-turbo
|
12
|
+
* author: dearblue (mailto:dearblue@users.osdn.me)
|
13
|
+
* report issue to: <https://osdn.jp/projects/rutsubo/ticket/>
|
14
|
+
* how to install: ``gem install crc-turbo``
|
15
|
+
* version: 0.1
|
16
|
+
* release quality: thechnical preview
|
17
|
+
* licensing: BSD-2-Clause
|
18
|
+
* dependency gems: crc (<https://rubygems/gems/crc>)
|
19
|
+
* dependency external c libraries: none
|
20
|
+
* bundled external c libraries: none
|
21
|
+
|
22
|
+
|
23
|
+
## HOW TO USAGE
|
24
|
+
|
25
|
+
First, install on your system.
|
26
|
+
|
27
|
+
``` shell:shell
|
28
|
+
# gem install crc-turbo
|
29
|
+
.....
|
30
|
+
#
|
31
|
+
```
|
32
|
+
|
33
|
+
And, to do ``require "crc"``.
|
34
|
+
|
35
|
+
``` shell:shell
|
36
|
+
$ ruby -r crc -e 'puts $".grep(/crc/)'
|
37
|
+
/usr/local/lib/ruby/gems/2.3/gems/crc-turbo-0.1/lib/crc/_turbo.so
|
38
|
+
/usr/local/lib/ruby/gems/2.3/gems/crc-0.1/lib/crc/_modules.rb
|
39
|
+
/usr/local/lib/ruby/gems/2.3/gems/crc-0.1/lib/crc.rb
|
40
|
+
$
|
41
|
+
```
|
42
|
+
|
43
|
+
If you want not use crc-turbo, set ``RUBY_CRC_NOFAST`` enviroment variable.
|
44
|
+
|
45
|
+
``` shell:shell
|
46
|
+
$ RUBY_CRC_NOFAST=1
|
47
|
+
$ ruby -r crc -e 'puts $".grep(/crc/)'
|
48
|
+
/usr/local/lib/ruby/gems/2.3/gems/crc-0.1/lib/crc/_byruby.rb
|
49
|
+
/usr/local/lib/ruby/gems/2.3/gems/crc-0.1/lib/crc/_modules.rb
|
50
|
+
/usr/local/lib/ruby/gems/2.3/gems/crc-0.1/lib/crc.rb
|
51
|
+
$
|
52
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
|
2
|
+
require "pathname"
|
3
|
+
require "rake/clean"
|
4
|
+
|
5
|
+
docnames = "{README,LICENSE,CHANGELOG,Changelog,HISTORY}"
|
6
|
+
doctypes = "{,.txt,.rd,.rdoc,.md,.markdown}"
|
7
|
+
cexttypes = "{c,C,cc,cxx,cpp,h,H,hh}"
|
8
|
+
|
9
|
+
DOC = FileList["#{docnames}{,.ja}#{doctypes}"] +
|
10
|
+
FileList["{contrib,ext}/**/#{docnames}{,.ja}#{doctypes}"] +
|
11
|
+
FileList["ext/**/*.#{cexttypes}"]
|
12
|
+
EXT = FileList["ext/**/*"]
|
13
|
+
BIN = FileList["bin/*"]
|
14
|
+
LIB = FileList["lib/**/*.rb"]
|
15
|
+
SPEC = FileList["spec/**/*"]
|
16
|
+
TEST = FileList["test/**/*"]
|
17
|
+
EXAMPLE = FileList["examples/**/*"]
|
18
|
+
GEMSTUB_SRC = "gemstub.rb"
|
19
|
+
RAKEFILE = [File.basename(__FILE__), GEMSTUB_SRC]
|
20
|
+
EXTRA = []
|
21
|
+
EXTCONF = FileList["ext/**/extconf.rb"]
|
22
|
+
EXTCONF.reject! { |n| !File.file?(n) }
|
23
|
+
EXTMAP = {}
|
24
|
+
|
25
|
+
load GEMSTUB_SRC
|
26
|
+
|
27
|
+
EXTMAP.dup.each_pair do |dir, name|
|
28
|
+
EXTMAP[Pathname.new(dir).cleanpath.to_s] = Pathname.new(name).cleanpath.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
GEMSTUB.extensions += EXTCONF
|
32
|
+
GEMSTUB.executables += FileList["bin/*"].map { |n| File.basename n }
|
33
|
+
GEMSTUB.executables.sort!
|
34
|
+
|
35
|
+
PACKAGENAME = "#{GEMSTUB.name}-#{GEMSTUB.version}"
|
36
|
+
GEMFILE = "#{PACKAGENAME}.gem"
|
37
|
+
GEMSPEC = "#{PACKAGENAME}.gemspec"
|
38
|
+
|
39
|
+
GEMSTUB.files += DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + EXTRA
|
40
|
+
GEMSTUB.files.sort!
|
41
|
+
if GEMSTUB.rdoc_options.nil? || GEMSTUB.rdoc_options.empty?
|
42
|
+
readme = %W(.md .markdown .rd .rdoc .txt #{""}).map { |ext| "README#{ext}" }.find { |m| DOC.find { |n| n == m } }
|
43
|
+
GEMSTUB.rdoc_options = %w(--charset UTF-8) + (readme ? %W(-m #{readme}) : [])
|
44
|
+
end
|
45
|
+
GEMSTUB.extra_rdoc_files += DOC + LIB + EXT.reject { |n| n.include?("/externals/") || !%w(.h .hh .c .cc .cpp .cxx).include?(File.extname(n)) }
|
46
|
+
GEMSTUB.extra_rdoc_files.sort!
|
47
|
+
|
48
|
+
GEMSTUB_TRYOUT = GEMSTUB.dup
|
49
|
+
GEMSTUB_TRYOUT.version = "#{GEMSTUB.version}#{Time.now.strftime(".TRYOUT.%Y%m%d.%H%M%S")}"
|
50
|
+
PACKAGENAME_TRYOUT = "#{GEMSTUB.name}-#{GEMSTUB_TRYOUT.version}"
|
51
|
+
GEMFILE_TRYOUT = "#{PACKAGENAME_TRYOUT}.gem"
|
52
|
+
GEMSPEC_TRYOUT = "#{PACKAGENAME_TRYOUT}.gemspec"
|
53
|
+
|
54
|
+
CLEAN << GEMSPEC << GEMSPEC_TRYOUT
|
55
|
+
CLOBBER << GEMFILE
|
56
|
+
|
57
|
+
task :default => :tryout do
|
58
|
+
$stderr.puts <<-EOS
|
59
|
+
#{__FILE__}:#{__LINE__}:
|
60
|
+
\ttype ``rake release'' to build release package.
|
61
|
+
EOS
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "build tryout package"
|
65
|
+
task :tryout
|
66
|
+
|
67
|
+
desc "build release package"
|
68
|
+
task :release => :all
|
69
|
+
|
70
|
+
unless EXTCONF.empty?
|
71
|
+
RUBYSET ||= (ENV["RUBYSET"] || "").split(",")
|
72
|
+
|
73
|
+
if RUBYSET.nil? || RUBYSET.empty?
|
74
|
+
$stderr.puts <<-EOS
|
75
|
+
#{__FILE__}:
|
76
|
+
|
|
77
|
+
| If you want binary gem package, launch rake with ``RUBYSET`` enviroment
|
78
|
+
| variable for set ruby interpreters by comma separated.
|
79
|
+
|
|
80
|
+
| e.g.) $ rake RUBYSET=ruby
|
81
|
+
| or) $ rake RUBYSET=ruby21,ruby22,ruby23
|
82
|
+
|
|
83
|
+
EOS
|
84
|
+
else
|
85
|
+
platforms = RUBYSET.map { |ruby| `#{ruby} --disable-gems -e "puts RUBY_PLATFORM"`.chomp }
|
86
|
+
platforms1 = platforms.uniq
|
87
|
+
unless platforms1.size == 1 && !platforms1[0].empty?
|
88
|
+
abort <<-EOS
|
89
|
+
#{__FILE__}:#{__LINE__}: different platforms:
|
90
|
+
#{RUBYSET.zip(platforms).map { |ruby, platform| "%24s => %s" % [ruby, platform] }.join("\n")}
|
91
|
+
ABORTED.
|
92
|
+
EOS
|
93
|
+
end
|
94
|
+
PLATFORM = platforms1[0]
|
95
|
+
|
96
|
+
RUBY_VERSIONS = RUBYSET.map do |ruby|
|
97
|
+
ver = `#{ruby} --disable-gems -e "puts RUBY_VERSION"`.slice(/\d+\.\d+/)
|
98
|
+
raise "failed ruby checking - ``#{ruby}''" unless $?.success?
|
99
|
+
[ver, ruby]
|
100
|
+
end
|
101
|
+
|
102
|
+
SOFILES_SET = RUBY_VERSIONS.map { |(ver, ruby)|
|
103
|
+
EXTCONF.map { |extconf|
|
104
|
+
extdir = Pathname.new(extconf).cleanpath.dirname.to_s
|
105
|
+
case
|
106
|
+
when soname = EXTMAP[extdir.sub(/^ext\//i, "")]
|
107
|
+
soname = soname.sub(/\.so$/i, "")
|
108
|
+
when extdir == "ext" || extdir == "."
|
109
|
+
soname = GEMSTUB.name
|
110
|
+
else
|
111
|
+
soname = File.basename(extdir)
|
112
|
+
end
|
113
|
+
|
114
|
+
[ruby, File.join("lib", "#{soname.sub(/(?<=\/)|^(?!.*\/)/, "#{ver}/")}.so"), extconf]
|
115
|
+
}
|
116
|
+
}.flatten(1)
|
117
|
+
SOFILES = SOFILES_SET.map { |(ruby, sopath, extconf)| sopath }
|
118
|
+
|
119
|
+
GEMSTUB_NATIVE = GEMSTUB.dup
|
120
|
+
GEMSTUB_NATIVE.files += SOFILES
|
121
|
+
GEMSTUB_NATIVE.platform = Gem::Platform.new(PLATFORM).to_s
|
122
|
+
GEMSTUB_NATIVE.extensions.clear
|
123
|
+
GEMFILE_NATIVE = "#{GEMSTUB_NATIVE.name}-#{GEMSTUB_NATIVE.version}-#{GEMSTUB_NATIVE.platform}.gem"
|
124
|
+
GEMSPEC_NATIVE = "#{GEMSTUB_NATIVE.name}-#{GEMSTUB_NATIVE.platform}.gemspec"
|
125
|
+
|
126
|
+
task :all => ["native-gem", GEMFILE]
|
127
|
+
|
128
|
+
desc "build binary gem package"
|
129
|
+
task "native-gem" => GEMFILE_NATIVE
|
130
|
+
|
131
|
+
desc "generate binary gemspec"
|
132
|
+
task "native-gemspec" => GEMSPEC_NATIVE
|
133
|
+
|
134
|
+
file GEMFILE_NATIVE => DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + SOFILES + RAKEFILE + [GEMSPEC_NATIVE] do
|
135
|
+
sh "gem build #{GEMSPEC_NATIVE}"
|
136
|
+
end
|
137
|
+
|
138
|
+
file GEMSPEC_NATIVE => RAKEFILE do
|
139
|
+
File.write(GEMSPEC_NATIVE, GEMSTUB_NATIVE.to_ruby, mode: "wb")
|
140
|
+
end
|
141
|
+
|
142
|
+
desc "build c-extension libraries"
|
143
|
+
task "sofiles" => SOFILES
|
144
|
+
|
145
|
+
SOFILES_SET.each do |(ruby, soname, extconf)|
|
146
|
+
sodir = File.dirname(soname)
|
147
|
+
makefile = File.join(sodir, "Makefile")
|
148
|
+
|
149
|
+
CLEAN << GEMSPEC_NATIVE << sodir
|
150
|
+
CLOBBER << GEMFILE_NATIVE
|
151
|
+
|
152
|
+
directory sodir
|
153
|
+
|
154
|
+
desc "generate Makefile for binary extension library"
|
155
|
+
file makefile => [sodir, extconf] do
|
156
|
+
rel_extconf = Pathname.new(extconf).relative_path_from(Pathname.new(sodir)).to_s
|
157
|
+
cd sodir do
|
158
|
+
sh *%W"#{ruby} #{rel_extconf} --ruby=#{ruby} #{ENV["EXTCONF"]}"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
desc "build binary extension library"
|
163
|
+
file soname => [makefile] + EXT do
|
164
|
+
cd sodir do
|
165
|
+
sh "make"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
task :all => GEMFILE
|
174
|
+
task :tryout => GEMFILE_TRYOUT
|
175
|
+
|
176
|
+
desc "generate local rdoc"
|
177
|
+
task :rdoc => DOC + LIB do
|
178
|
+
sh *(%w(rdoc) + GEMSTUB.rdoc_options + DOC + LIB)
|
179
|
+
end
|
180
|
+
|
181
|
+
desc "launch rspec"
|
182
|
+
task rspec: :all do
|
183
|
+
sh "rspec"
|
184
|
+
end
|
185
|
+
|
186
|
+
desc "build gem package"
|
187
|
+
task gem: GEMFILE
|
188
|
+
|
189
|
+
desc "generate gemspec"
|
190
|
+
task gemspec: GEMSPEC
|
191
|
+
|
192
|
+
desc "print package name"
|
193
|
+
task "package-name" do
|
194
|
+
puts PACKAGENAME
|
195
|
+
end
|
196
|
+
|
197
|
+
file GEMFILE => DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + [GEMSPEC] do
|
198
|
+
sh "gem build #{GEMSPEC}"
|
199
|
+
end
|
200
|
+
|
201
|
+
file GEMFILE_TRYOUT => DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + [GEMSPEC_TRYOUT] do
|
202
|
+
#file GEMFILE_TRYOUT do
|
203
|
+
sh "gem build #{GEMSPEC_TRYOUT}"
|
204
|
+
end
|
205
|
+
|
206
|
+
file GEMSPEC => RAKEFILE do
|
207
|
+
File.write(GEMSPEC, GEMSTUB.to_ruby, mode: "wb")
|
208
|
+
end
|
209
|
+
|
210
|
+
file GEMSPEC_TRYOUT => RAKEFILE do
|
211
|
+
File.write(GEMSPEC_TRYOUT, GEMSTUB_TRYOUT.to_ruby, mode: "wb")
|
212
|
+
end
|
data/ext/crc/crcturbo.c
ADDED
@@ -0,0 +1,720 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <ruby/version.h>
|
3
|
+
#include <stdint.h>
|
4
|
+
|
5
|
+
enum {
|
6
|
+
TYPE_MASK = 0xff,
|
7
|
+
TYPE_UINT8_T = 1,
|
8
|
+
TYPE_UINT16_T = 2,
|
9
|
+
TYPE_UINT32_T = 4,
|
10
|
+
TYPE_UINT64_T = 8,
|
11
|
+
TYPE_UINT128_T = 16,
|
12
|
+
|
13
|
+
REFLECT_INPUT = 0x0100,
|
14
|
+
REFLECT_OUTPUT = 0x0200,
|
15
|
+
|
16
|
+
TABLE_NOTREADY = 0x1000,
|
17
|
+
};
|
18
|
+
|
19
|
+
#define SWITCH_BY_TYPE(FLAGS, STMT_U8, STMT_U16, STMT_U32, STMT_U64, STMT_U128) \
|
20
|
+
switch ((FLAGS) & TYPE_MASK) { \
|
21
|
+
case TYPE_UINT8_T: { STMT_U8; break; } \
|
22
|
+
case TYPE_UINT16_T: { STMT_U16; break; } \
|
23
|
+
case TYPE_UINT32_T: { STMT_U32; break; } \
|
24
|
+
case TYPE_UINT64_T: { STMT_U64; break; } \
|
25
|
+
/* case TYPE_UINT128_T: { STMT_U128; break; } */ \
|
26
|
+
default: { rb_bug(" [INVALID TYPE FLAGS: 0x%02X] ", (FLAGS) & TYPE_MASK); } \
|
27
|
+
} \
|
28
|
+
|
29
|
+
static inline uint8_t
|
30
|
+
to_uint8(VALUE num)
|
31
|
+
{
|
32
|
+
unsigned long n;
|
33
|
+
rb_big_pack(num, &n, 1);
|
34
|
+
return n;
|
35
|
+
}
|
36
|
+
|
37
|
+
static inline VALUE
|
38
|
+
conv_uint8(uint8_t n)
|
39
|
+
{
|
40
|
+
return INT2FIX(n);
|
41
|
+
}
|
42
|
+
|
43
|
+
static inline uint16_t
|
44
|
+
to_uint16(VALUE num)
|
45
|
+
{
|
46
|
+
unsigned long n;
|
47
|
+
rb_big_pack(num, &n, 1);
|
48
|
+
return n;
|
49
|
+
}
|
50
|
+
|
51
|
+
static inline VALUE
|
52
|
+
conv_uint16(uint16_t n)
|
53
|
+
{
|
54
|
+
return INT2FIX(n);
|
55
|
+
}
|
56
|
+
|
57
|
+
static inline uint32_t
|
58
|
+
to_uint32(VALUE num)
|
59
|
+
{
|
60
|
+
unsigned long n;
|
61
|
+
rb_big_pack(num, &n, 1);
|
62
|
+
return n;
|
63
|
+
}
|
64
|
+
|
65
|
+
static inline VALUE
|
66
|
+
conv_uint32(uint32_t n)
|
67
|
+
{
|
68
|
+
return UINT2NUM(n);
|
69
|
+
}
|
70
|
+
|
71
|
+
static inline uint64_t
|
72
|
+
to_uint64(VALUE num)
|
73
|
+
{
|
74
|
+
if (sizeof(unsigned long) < 8) {
|
75
|
+
static const int len = sizeof(uint64_t) / sizeof(unsigned long);
|
76
|
+
unsigned long tmp[len];
|
77
|
+
rb_big_pack(num, tmp, len);
|
78
|
+
const unsigned long *p = tmp + len;
|
79
|
+
uint64_t n = 0;
|
80
|
+
while (p -- > tmp) {
|
81
|
+
n <<= sizeof(unsigned long) * CHAR_BIT;
|
82
|
+
n |= *p;
|
83
|
+
}
|
84
|
+
return n;
|
85
|
+
} else {
|
86
|
+
unsigned long n;
|
87
|
+
rb_big_pack(num, &n, 1);
|
88
|
+
return n;
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
static inline VALUE
|
93
|
+
conv_uint64(uint64_t n)
|
94
|
+
{
|
95
|
+
return ULL2NUM(n);
|
96
|
+
}
|
97
|
+
|
98
|
+
#ifdef HAVE_TYPE_UINT128_T
|
99
|
+
static inline uint128_t
|
100
|
+
to_uint128(VALUE num)
|
101
|
+
{
|
102
|
+
if (sizeof(unsigned long) < 16) {
|
103
|
+
static const int len = sizeof(uint128_t) / sizeof(unsigned long);
|
104
|
+
unsigned long tmp[len];
|
105
|
+
rb_big_pack(num, tmp, len);
|
106
|
+
const unsigned long *p = tmp + len;
|
107
|
+
uint128_t n = 0;
|
108
|
+
while (p -- > tmp) {
|
109
|
+
n <<= sizeof(unsigned long) * CHAR_BIT;
|
110
|
+
n |= *p;
|
111
|
+
}
|
112
|
+
return n;
|
113
|
+
} else {
|
114
|
+
unsigned long n;
|
115
|
+
rb_big_pack(num, &n, 1);
|
116
|
+
return n;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
static inline VALUE
|
121
|
+
conv_uint128(uint128_t n)
|
122
|
+
{
|
123
|
+
if (sizeof(unsigned long) >= 16) {
|
124
|
+
return ULL2NUM(n);
|
125
|
+
} else {
|
126
|
+
static const int len = sizeof(uint128_t) / sizeof(unsigned long);
|
127
|
+
unsigned long tmp[len];
|
128
|
+
memset(tmp, 0, sizeof(tmp));
|
129
|
+
unsigned long *p = tmp;
|
130
|
+
while (n > 0) {
|
131
|
+
*p ++ = n;
|
132
|
+
n >>= sizeof(unsigned long) * CHAR_BIT;
|
133
|
+
}
|
134
|
+
return rb_big_unpack(tmp, len);
|
135
|
+
}
|
136
|
+
}
|
137
|
+
#endif /* HAVE_TYPE_UINT128_T */
|
138
|
+
|
139
|
+
/*
|
140
|
+
* bitreflect: 整数値のビットを逆順にする
|
141
|
+
*
|
142
|
+
* 高速化のためにビットをまとめて入れ替えていく (この例では8ビット整数値)
|
143
|
+
*
|
144
|
+
* 最初は4ビット 次は2ビット 最後に1ビット
|
145
|
+
* [abcdefgh] => [efgh abcd] => [gh ef] [cd ab] => [h g] [f e] [d c] [b a]
|
146
|
+
*/
|
147
|
+
static inline uint8_t
|
148
|
+
bitreflect8(uint8_t n)
|
149
|
+
{
|
150
|
+
n = (n >> 4) | ( n << 4);
|
151
|
+
n = ((n >> 2) & 0x33) | ((n & 0x33) << 2);
|
152
|
+
n = ((n >> 1) & 0x55) | ((n & 0x55) << 1);
|
153
|
+
return n;
|
154
|
+
}
|
155
|
+
|
156
|
+
static inline uint16_t
|
157
|
+
bitreflect16(uint16_t n)
|
158
|
+
{
|
159
|
+
n = (n >> 8) | ( n << 8);
|
160
|
+
n = ((n >> 4) & 0x0f0f) | ((n & 0x0f0f) << 4);
|
161
|
+
n = ((n >> 2) & 0x3333) | ((n & 0x3333) << 2);
|
162
|
+
n = ((n >> 1) & 0x5555) | ((n & 0x5555) << 1);
|
163
|
+
return n;
|
164
|
+
}
|
165
|
+
|
166
|
+
static inline uint32_t
|
167
|
+
bitreflect32(uint32_t n)
|
168
|
+
{
|
169
|
+
n = (n >> 16) | ( n << 16);
|
170
|
+
n = ((n >> 8) & 0x00ff00ff) | ((n & 0x00ff00ff) << 8);
|
171
|
+
n = ((n >> 4) & 0x0f0f0f0f) | ((n & 0x0f0f0f0f) << 4);
|
172
|
+
n = ((n >> 2) & 0x33333333) | ((n & 0x33333333) << 2);
|
173
|
+
n = ((n >> 1) & 0x55555555) | ((n & 0x55555555) << 1);
|
174
|
+
return n;
|
175
|
+
}
|
176
|
+
|
177
|
+
static inline uint64_t
|
178
|
+
bitreflect64(uint64_t n)
|
179
|
+
{
|
180
|
+
n = (n >> 32) | ( n << 32);
|
181
|
+
n = ((n >> 16) & 0x0000ffff0000ffff) | ((n & 0x0000ffff0000ffff) << 16);
|
182
|
+
n = ((n >> 8) & 0x00ff00ff00ff00ff) | ((n & 0x00ff00ff00ff00ff) << 8);
|
183
|
+
n = ((n >> 4) & 0x0f0f0f0f0f0f0f0f) | ((n & 0x0f0f0f0f0f0f0f0f) << 4);
|
184
|
+
n = ((n >> 2) & 0x3333333333333333) | ((n & 0x3333333333333333) << 2);
|
185
|
+
n = ((n >> 1) & 0x5555555555555555) | ((n & 0x5555555555555555) << 1);
|
186
|
+
return n;
|
187
|
+
|
188
|
+
#if 0
|
189
|
+
/* 優位な差はない */
|
190
|
+
n = ( n >> 32) | ( n << 32);
|
191
|
+
n = ((n & 0xffff0000ffff0000) >> 16) | ((n & 0x0000ffff0000ffff) << 16);
|
192
|
+
n = ((n & 0xff00ff00ff00ff00) >> 8) | ((n & 0x00ff00ff00ff00ff) << 8);
|
193
|
+
n = ((n & 0xf0f0f0f0f0f0f0f0) >> 4) | ((n & 0x0f0f0f0f0f0f0f0f) << 4);
|
194
|
+
n = ((n & 0xcccccccccccccccc) >> 2) | ((n & 0x3333333333333333) << 2);
|
195
|
+
n = ((n & 0xaaaaaaaaaaaaaaaa) >> 1) | ((n & 0x5555555555555555) << 1);
|
196
|
+
return n;
|
197
|
+
|
198
|
+
/* 1割前後遅い */
|
199
|
+
n = ((n >> 1) & 0x5555555555555555) | ((n & 0x5555555555555555) << 1);
|
200
|
+
n = ((n >> 2) & 0x3333333333333333) | ((n & 0x3333333333333333) << 2);
|
201
|
+
n = ((n >> 4) & 0x0f0f0f0f0f0f0f0f) | ((n & 0x0f0f0f0f0f0f0f0f) << 4);
|
202
|
+
n = ((n >> 8) & 0x00ff00ff00ff00ff) | ((n & 0x00ff00ff00ff00ff) << 8);
|
203
|
+
n = ((n >> 16) & 0x0000ffff0000ffff) | ((n & 0x0000ffff0000ffff) << 16);
|
204
|
+
n = (n >> 32) | ( n << 32);
|
205
|
+
return n;
|
206
|
+
#endif
|
207
|
+
}
|
208
|
+
|
209
|
+
#ifdef HAVE_TYPE_UINT128_T
|
210
|
+
static inline uint128_t
|
211
|
+
bitreflect128(uint128_t n)
|
212
|
+
{
|
213
|
+
static const uint128_t mask32 = ((uint128_t)0x00000000ffffffffull << 64) | 0x00000000ffffffffull;
|
214
|
+
static const uint128_t mask16 = ((uint128_t)0x0000ffff0000ffffull << 64) | 0x0000ffff0000ffffull;
|
215
|
+
static const uint128_t mask8 = ((uint128_t)0x00ff00ff00ff00ffull << 64) | 0x00ff00ff00ff00ffull;
|
216
|
+
static const uint128_t mask4 = ((uint128_t)0x0f0f0f0f0f0f0f0full << 64) | 0x0f0f0f0f0f0f0f0full;
|
217
|
+
static const uint128_t mask2 = ((uint128_t)0x3333333333333333ull << 64) | 0x3333333333333333ull;
|
218
|
+
static const uint128_t mask1 = ((uint128_t)0x5555555555555555ull << 64) | 0x5555555555555555ull;
|
219
|
+
|
220
|
+
n = (n >> 64) | ( n << 64);
|
221
|
+
n = ((n >> 32) & mask32) | ((n & mask32) << 32);
|
222
|
+
n = ((n >> 16) & mask16) | ((n & mask16) << 16);
|
223
|
+
n = ((n >> 8) & mask8) | ((n & mask8) << 8);
|
224
|
+
n = ((n >> 4) & mask4) | ((n & mask4) << 4);
|
225
|
+
n = ((n >> 2) & mask2) | ((n & mask2) << 2);
|
226
|
+
n = ((n >> 1) & mask1) | ((n & mask1) << 1);
|
227
|
+
return n;
|
228
|
+
}
|
229
|
+
#endif
|
230
|
+
|
231
|
+
static inline int
|
232
|
+
bitsize_to_type(int bitsize)
|
233
|
+
{
|
234
|
+
if (bitsize <= 8) {
|
235
|
+
return TYPE_UINT8_T;
|
236
|
+
} else if (bitsize <= 16) {
|
237
|
+
return TYPE_UINT16_T;
|
238
|
+
} else if (bitsize <= 32) {
|
239
|
+
return TYPE_UINT32_T;
|
240
|
+
#ifdef HAVE_TYPE_UINT128_T
|
241
|
+
} else if (bitsize > 64) {
|
242
|
+
return TYPE_UINT128_T;
|
243
|
+
#endif
|
244
|
+
} else {
|
245
|
+
return TYPE_UINT64_T;
|
246
|
+
}
|
247
|
+
}
|
248
|
+
|
249
|
+
|
250
|
+
#define IMP_BUILD_TABLE(NAME, TYPE) \
|
251
|
+
static void \
|
252
|
+
NAME(TYPE table[8][256], int bitsize, TYPE poly) \
|
253
|
+
{ \
|
254
|
+
static const int typesize = sizeof(TYPE) * CHAR_BIT; \
|
255
|
+
poly <<= (typesize - bitsize); \
|
256
|
+
TYPE (*t)[256] = table; \
|
257
|
+
int s, b, i; \
|
258
|
+
for (s = 0; s < 8; s ++) { \
|
259
|
+
TYPE *p = *t; \
|
260
|
+
for (b = 0; b < 256; b ++) { \
|
261
|
+
TYPE r = (s == 0) ? ((TYPE)b << (typesize - 8)) : t[-1][b]; \
|
262
|
+
for (i = 0; i < 8; i ++) { \
|
263
|
+
r = (r << 1) ^ (poly & -(r >> (typesize - 1))); \
|
264
|
+
} \
|
265
|
+
*p ++ = r; \
|
266
|
+
} \
|
267
|
+
t ++; \
|
268
|
+
} \
|
269
|
+
}
|
270
|
+
|
271
|
+
#define IMP_CRC_UPDATE(NAME, TYPE) \
|
272
|
+
static TYPE \
|
273
|
+
NAME(int bitsize, const TYPE table[8][256], \
|
274
|
+
const char *p, const char *pp, TYPE state) \
|
275
|
+
{ \
|
276
|
+
static const int typesize = sizeof(TYPE) * CHAR_BIT; \
|
277
|
+
const char *pp8 = ((pp - p) & ~0x07) + p; \
|
278
|
+
state <<= typesize - bitsize; \
|
279
|
+
for (; p < pp8; p += 8) { \
|
280
|
+
state = table[7][(uint8_t)p[0] ^ (uint8_t)(state >> (typesize - 8)) ] ^ \
|
281
|
+
table[6][(uint8_t)p[1] ^ (typesize > 8 ? (uint8_t)(state >> (typesize - 16)) : 0)] ^ \
|
282
|
+
table[5][(uint8_t)p[2] ^ (typesize > 16 ? (uint8_t)(state >> (typesize - 24)) : 0)] ^ \
|
283
|
+
table[4][(uint8_t)p[3] ^ (typesize > 24 ? (uint8_t)(state >> (typesize - 32)) : 0)] ^ \
|
284
|
+
table[3][(uint8_t)p[4] ^ (typesize > 32 ? (uint8_t)(state >> (typesize - 40)) : 0)] ^ \
|
285
|
+
table[2][(uint8_t)p[5] ^ (typesize > 40 ? (uint8_t)(state >> (typesize - 48)) : 0)] ^ \
|
286
|
+
table[1][(uint8_t)p[6] ^ (typesize > 48 ? (uint8_t)(state >> (typesize - 56)) : 0)] ^ \
|
287
|
+
table[0][(uint8_t)p[7] ^ (typesize > 56 ? (uint8_t)(state >> (typesize - 64)) : 0)]; \
|
288
|
+
} \
|
289
|
+
\
|
290
|
+
int sh = typesize - 8; \
|
291
|
+
for (; p < pp; p ++) { \
|
292
|
+
state = table[0][(uint8_t)*p ^ (uint8_t)(state >> sh)] ^ (state << 8); \
|
293
|
+
} \
|
294
|
+
\
|
295
|
+
return state >> (typesize - bitsize); \
|
296
|
+
} \
|
297
|
+
|
298
|
+
IMP_BUILD_TABLE(build_table8_u8, uint8_t);
|
299
|
+
IMP_CRC_UPDATE(crc_update_u8, uint8_t);
|
300
|
+
IMP_BUILD_TABLE(build_table8_u16, uint16_t);
|
301
|
+
IMP_CRC_UPDATE(crc_update_u16, uint16_t);
|
302
|
+
IMP_BUILD_TABLE(build_table8_u32, uint32_t);
|
303
|
+
IMP_CRC_UPDATE(crc_update_u32, uint32_t);
|
304
|
+
IMP_BUILD_TABLE(build_table8_u64, uint64_t);
|
305
|
+
IMP_CRC_UPDATE(crc_update_u64, uint64_t);
|
306
|
+
#ifdef HAVE_TYPE_UINT128_T
|
307
|
+
IMP_BUILD_TABLE(build_table8_u128, uint128_t);
|
308
|
+
IMP_CRC_UPDATE(crc_update_u128, uint128_t);
|
309
|
+
#endif
|
310
|
+
|
311
|
+
#undef IMP_BUILD_TABLE
|
312
|
+
|
313
|
+
#define IMP_BUILD_REFLECT_TABLE(NAME, TYPE, BITREFLECT) \
|
314
|
+
static void \
|
315
|
+
NAME(TYPE table[8][256], int bitsize, TYPE poly) \
|
316
|
+
{ \
|
317
|
+
static const int typesize = sizeof(TYPE) * CHAR_BIT; \
|
318
|
+
poly = BITREFLECT(poly << (typesize - bitsize)); \
|
319
|
+
TYPE (*t)[256] = table; \
|
320
|
+
int s, b, i; \
|
321
|
+
for (s = 0; s < 8; s ++) { \
|
322
|
+
TYPE *p = *t; \
|
323
|
+
for (b = 0; b < 256; b ++) { \
|
324
|
+
TYPE r = (s == 0) ? (TYPE)b : t[-1][b]; \
|
325
|
+
for (i = 0; i < 8; i ++) { \
|
326
|
+
r = (r >> 1) ^ (poly & -(r & 1)); \
|
327
|
+
} \
|
328
|
+
*p ++ = r; \
|
329
|
+
} \
|
330
|
+
t ++; \
|
331
|
+
} \
|
332
|
+
} \
|
333
|
+
|
334
|
+
#define IMP_CRC_REFLECT_UPDATE(NAME, TYPE) \
|
335
|
+
static TYPE \
|
336
|
+
NAME(int bitsize, const TYPE table[8][256], \
|
337
|
+
const char *p, const char *pp, TYPE state) \
|
338
|
+
{ \
|
339
|
+
static const int typesize = sizeof(TYPE) * CHAR_BIT; \
|
340
|
+
const char *pp8 = ((pp - p) & ~0x07) + p; \
|
341
|
+
for (; p < pp8; p += 8) { \
|
342
|
+
state = table[7][(uint8_t)p[0] ^ (uint8_t)(state >> 0) ] ^ \
|
343
|
+
table[6][(uint8_t)p[1] ^ (typesize > 8 ? (uint8_t)(state >> 8) : 0)] ^ \
|
344
|
+
table[5][(uint8_t)p[2] ^ (typesize > 16 ? (uint8_t)(state >> 16) : 0)] ^ \
|
345
|
+
table[4][(uint8_t)p[3] ^ (typesize > 24 ? (uint8_t)(state >> 24) : 0)] ^ \
|
346
|
+
table[3][(uint8_t)p[4] ^ (typesize > 32 ? (uint8_t)(state >> 32) : 0)] ^ \
|
347
|
+
table[2][(uint8_t)p[5] ^ (typesize > 40 ? (uint8_t)(state >> 40) : 0)] ^ \
|
348
|
+
table[1][(uint8_t)p[6] ^ (typesize > 48 ? (uint8_t)(state >> 48) : 0)] ^ \
|
349
|
+
table[0][(uint8_t)p[7] ^ (typesize > 56 ? (uint8_t)(state >> 56) : 0)]; \
|
350
|
+
} \
|
351
|
+
\
|
352
|
+
for (; p < pp; p ++) { \
|
353
|
+
state = table[0][(uint8_t)*p ^ (uint8_t)state] ^ (state >> 8); \
|
354
|
+
} \
|
355
|
+
\
|
356
|
+
return state; \
|
357
|
+
} \
|
358
|
+
|
359
|
+
IMP_BUILD_REFLECT_TABLE(build_reflect_table8_u8, uint8_t, bitreflect8);
|
360
|
+
IMP_CRC_REFLECT_UPDATE(crc_reflect_update_u8, uint8_t);
|
361
|
+
IMP_BUILD_REFLECT_TABLE(build_reflect_table8_u16, uint16_t, bitreflect16);
|
362
|
+
IMP_CRC_REFLECT_UPDATE(crc_reflect_update_u16, uint16_t);
|
363
|
+
IMP_BUILD_REFLECT_TABLE(build_reflect_table8_u32, uint32_t, bitreflect32);
|
364
|
+
IMP_CRC_REFLECT_UPDATE(crc_reflect_update_u32, uint32_t);
|
365
|
+
IMP_BUILD_REFLECT_TABLE(build_reflect_table8_u64, uint64_t, bitreflect64);
|
366
|
+
IMP_CRC_REFLECT_UPDATE(crc_reflect_update_u64, uint64_t);
|
367
|
+
#ifdef HAVE_TYPE_UINT128_T
|
368
|
+
IMP_BUILD_REFLECT_TABLE(build_reflect_table8_u128, uint128_t, bitreflect128);
|
369
|
+
IMP_CRC_REFLECT_UPDATE(crc_reflect_update_u128, uint128_t);
|
370
|
+
#endif
|
371
|
+
|
372
|
+
#undef IMP_BUILD_REFLECT_TABLE
|
373
|
+
#undef IMP_CRC_REFLECT_UPDATE
|
374
|
+
|
375
|
+
/*
|
376
|
+
*
|
377
|
+
* ここから ruby のターン
|
378
|
+
*
|
379
|
+
*/
|
380
|
+
|
381
|
+
typedef struct anyuint_t
|
382
|
+
{
|
383
|
+
union {
|
384
|
+
uint8_t as8;
|
385
|
+
uint16_t as16;
|
386
|
+
uint32_t as32;
|
387
|
+
uint64_t as64;
|
388
|
+
#ifdef HAVE_TYPE_UINT128_T
|
389
|
+
uint128_t as128;
|
390
|
+
#endif
|
391
|
+
};
|
392
|
+
} anyuint_t;
|
393
|
+
|
394
|
+
struct generator
|
395
|
+
{
|
396
|
+
int bitsize;
|
397
|
+
int flags; /* int type, refin, refout */
|
398
|
+
anyuint_t bitmask, polynomial, initial, xorout;
|
399
|
+
union {
|
400
|
+
uint8_t as8[8][256];
|
401
|
+
uint16_t as16[8][256];
|
402
|
+
uint32_t as32[8][256];
|
403
|
+
uint64_t as64[8][256];
|
404
|
+
#ifdef HAVE_TYPE_UINT128_T
|
405
|
+
uint128_t as128[8][256];
|
406
|
+
#endif
|
407
|
+
} table[0];
|
408
|
+
};
|
409
|
+
|
410
|
+
static VALUE mCRC; /* module CRC */
|
411
|
+
static VALUE mUtils; /* module CRC::Utils */
|
412
|
+
static VALUE cGenerator; /* class CRC::Generator */
|
413
|
+
static ID generator_iv_name;
|
414
|
+
|
415
|
+
static const rb_data_type_t generator_type = {
|
416
|
+
.wrap_struct_name = "crc-turbo.CRC::Generator",
|
417
|
+
.function.dmark = NULL,
|
418
|
+
.function.dsize = NULL,
|
419
|
+
.function.dfree = (void *)-1,
|
420
|
+
};
|
421
|
+
|
422
|
+
static void
|
423
|
+
check_generator_notinit(VALUE obj)
|
424
|
+
{
|
425
|
+
struct generator *p;
|
426
|
+
TypedData_Get_Struct(obj, struct generator, &generator_type, p);
|
427
|
+
if (p) { rb_raise(rb_eArgError, "already initialized object - #<%s:0x%p>", rb_obj_classname(obj), (void *)obj); }
|
428
|
+
}
|
429
|
+
|
430
|
+
static struct generator *
|
431
|
+
get_generator(VALUE obj)
|
432
|
+
{
|
433
|
+
struct generator *p;
|
434
|
+
TypedData_Get_Struct(obj, struct generator, &generator_type, p);
|
435
|
+
if (!p) { rb_raise(rb_eArgError, "wrong initialized object - #<%s:0x%p>", rb_obj_classname(obj), (void *)obj); }
|
436
|
+
return p;
|
437
|
+
}
|
438
|
+
|
439
|
+
static VALUE
|
440
|
+
generator_alloc(VALUE mod)
|
441
|
+
{
|
442
|
+
return TypedData_Wrap_Struct(mod, &generator_type, NULL);
|
443
|
+
}
|
444
|
+
|
445
|
+
static void
|
446
|
+
generator_init_args(int argc, VALUE argv[], int *flags, int *bitsize, VALUE *poly, VALUE *init, VALUE *xorout, VALUE *name)
|
447
|
+
{
|
448
|
+
rb_check_arity(argc, 2, 7);
|
449
|
+
*bitsize = NUM2INT(argv[0]);
|
450
|
+
if (*bitsize < 1 || *bitsize > 64) {
|
451
|
+
rb_raise(rb_eArgError, "wrong bitsize (expect 1..64, but given %d)", *bitsize);
|
452
|
+
} else if (*bitsize <= 8) {
|
453
|
+
*flags = TYPE_UINT8_T;
|
454
|
+
} else if (*bitsize <= 16) {
|
455
|
+
*flags = TYPE_UINT16_T;
|
456
|
+
} else if (*bitsize <= 32) {
|
457
|
+
*flags = TYPE_UINT32_T;
|
458
|
+
} else if (*bitsize <= 64) {
|
459
|
+
*flags = TYPE_UINT64_T;
|
460
|
+
}
|
461
|
+
|
462
|
+
*poly = argv[1];
|
463
|
+
*init = (argc > 2) ? argv[2] : INT2FIX(0);
|
464
|
+
*flags |= (argc > 3 && !RTEST(argv[3])) ? 0 : REFLECT_INPUT;
|
465
|
+
*flags |= (argc > 4 && !RTEST(argv[4])) ? 0 : REFLECT_OUTPUT;
|
466
|
+
*xorout = (argc > 5) ? argv[5] : INT2FIX(~0);
|
467
|
+
*name = (argc > 6 && !NIL_P(argv[6])) ? rb_String(argv[6]) : Qnil;
|
468
|
+
}
|
469
|
+
|
470
|
+
/*
|
471
|
+
* call-seq:
|
472
|
+
* initialize(bitsize, polynomial, initial_state = 0, reflect_input = true, reflect_output = true, xor_output = ~0, name = nil)
|
473
|
+
*/
|
474
|
+
static VALUE
|
475
|
+
generator_init(int argc, VALUE argv[], VALUE obj)
|
476
|
+
{
|
477
|
+
int flags, bitsize;
|
478
|
+
VALUE poly, init, xorout, name;
|
479
|
+
check_generator_notinit(obj);
|
480
|
+
generator_init_args(argc, argv, &flags, &bitsize, &poly, &init, &xorout, &name);
|
481
|
+
|
482
|
+
struct generator *p;
|
483
|
+
size_t allocsize = sizeof(struct generator) + (flags & TYPE_MASK) * 256 * 8;
|
484
|
+
RTYPEDDATA_DATA(obj) = p = (struct generator *)ALLOC_N(char, allocsize);
|
485
|
+
p->bitsize = bitsize;
|
486
|
+
p->flags = flags | TABLE_NOTREADY;
|
487
|
+
|
488
|
+
/*
|
489
|
+
* bitmask の代入でわざわざ1ビット分を後から行う理由は、
|
490
|
+
* 例えば uint8_t に対して << 8 をすると何もしないため、
|
491
|
+
* これへの対処を目的とする。
|
492
|
+
*/
|
493
|
+
#define INIT_GENERATOR(TYPE, AS, TO_UINT, CONV_UINT, P, BITSIZE, POLY, INIT, XOROUT) \
|
494
|
+
P->bitmask.AS = ~(~(TYPE)0 << 1 << (BITSIZE - 1)); \
|
495
|
+
P->polynomial.AS = P->bitmask.AS & TO_UINT(POLY); \
|
496
|
+
P->initial.AS = P->bitmask.AS & TO_UINT(INIT); \
|
497
|
+
P->xorout.AS = P->bitmask.AS & TO_UINT(XOROUT); \
|
498
|
+
|
499
|
+
SWITCH_BY_TYPE(flags,
|
500
|
+
INIT_GENERATOR(uint8_t, as8, to_uint8, conv_uint8, p, bitsize, poly, init, xorout),
|
501
|
+
INIT_GENERATOR(uint16_t, as16, to_uint16, conv_uint16, p, bitsize, poly, init, xorout),
|
502
|
+
INIT_GENERATOR(uint32_t, as32, to_uint32, conv_uint32, p, bitsize, poly, init, xorout),
|
503
|
+
INIT_GENERATOR(uint64_t, as64, to_uint64, conv_uint64, p, bitsize, poly, init, xorout),
|
504
|
+
INIT_GENERATOR(uint128_t, as128, to_uint128, conv_uint128, p, bitsize, poly, init, xorout));
|
505
|
+
|
506
|
+
#undef INIT_GENERATOR
|
507
|
+
|
508
|
+
rb_ivar_set(obj, generator_iv_name, name);
|
509
|
+
|
510
|
+
return obj;
|
511
|
+
}
|
512
|
+
|
513
|
+
static VALUE
|
514
|
+
generator_bitsize(VALUE t)
|
515
|
+
{
|
516
|
+
return INT2FIX(get_generator(t)->bitsize);
|
517
|
+
}
|
518
|
+
|
519
|
+
static VALUE
|
520
|
+
generator_bitmask(VALUE t)
|
521
|
+
{
|
522
|
+
struct generator *p = get_generator(t);
|
523
|
+
SWITCH_BY_TYPE(p->flags,
|
524
|
+
return conv_uint8(p->bitmask.as8),
|
525
|
+
return conv_uint16(p->bitmask.as16),
|
526
|
+
return conv_uint32(p->bitmask.as32),
|
527
|
+
return conv_uint64(p->bitmask.as64),
|
528
|
+
return conv_uint128(p->bitmask.as128));
|
529
|
+
}
|
530
|
+
|
531
|
+
static VALUE
|
532
|
+
generator_polynomial(VALUE t)
|
533
|
+
{
|
534
|
+
struct generator *p = get_generator(t);
|
535
|
+
SWITCH_BY_TYPE(p->flags,
|
536
|
+
return conv_uint8(p->bitmask.as8),
|
537
|
+
return conv_uint16(p->bitmask.as16),
|
538
|
+
return conv_uint32(p->bitmask.as32),
|
539
|
+
return conv_uint64(p->bitmask.as64),
|
540
|
+
return conv_uint128(p->bitmask.as128));
|
541
|
+
}
|
542
|
+
|
543
|
+
static VALUE
|
544
|
+
generator_initial_state(VALUE t)
|
545
|
+
{
|
546
|
+
struct generator *p = get_generator(t);
|
547
|
+
SWITCH_BY_TYPE(p->flags,
|
548
|
+
return conv_uint8(p->initial.as8),
|
549
|
+
return conv_uint16(p->initial.as16),
|
550
|
+
return conv_uint32(p->initial.as32),
|
551
|
+
return conv_uint64(p->initial.as64),
|
552
|
+
return conv_uint128(p->initial.as128));
|
553
|
+
}
|
554
|
+
|
555
|
+
static VALUE
|
556
|
+
generator_table8(VALUE t)
|
557
|
+
{
|
558
|
+
struct generator *p = get_generator(t);
|
559
|
+
rb_raise(rb_eNotImpError, "");
|
560
|
+
}
|
561
|
+
|
562
|
+
static VALUE
|
563
|
+
generator_reflect_input(VALUE t)
|
564
|
+
{
|
565
|
+
struct generator *p = get_generator(t);
|
566
|
+
return (p->flags & REFLECT_INPUT) ? Qtrue : Qfalse;
|
567
|
+
}
|
568
|
+
|
569
|
+
static VALUE
|
570
|
+
generator_reflect_output(VALUE t)
|
571
|
+
{
|
572
|
+
struct generator *p = get_generator(t);
|
573
|
+
return (p->flags & REFLECT_OUTPUT) ? Qtrue : Qfalse;
|
574
|
+
}
|
575
|
+
|
576
|
+
static VALUE
|
577
|
+
generator_xor_output(VALUE t)
|
578
|
+
{
|
579
|
+
struct generator *p = get_generator(t);
|
580
|
+
SWITCH_BY_TYPE(p->flags,
|
581
|
+
return conv_uint8(p->xorout.as8),
|
582
|
+
return conv_uint16(p->xorout.as16),
|
583
|
+
return conv_uint32(p->xorout.as32),
|
584
|
+
return conv_uint64(p->xorout.as64),
|
585
|
+
return conv_uint128(p->xorout.as128));
|
586
|
+
}
|
587
|
+
|
588
|
+
static VALUE
|
589
|
+
generator_name(VALUE t)
|
590
|
+
{
|
591
|
+
// get_generator で初期化の確認
|
592
|
+
get_generator(t);
|
593
|
+
|
594
|
+
return rb_ivar_get(t, generator_iv_name);
|
595
|
+
}
|
596
|
+
|
597
|
+
static VALUE
|
598
|
+
generator_set_name(VALUE t, VALUE name)
|
599
|
+
{
|
600
|
+
// get_generator で初期化の確認
|
601
|
+
get_generator(t);
|
602
|
+
|
603
|
+
rb_ivar_set(t, generator_iv_name, rb_String(name));
|
604
|
+
return name;
|
605
|
+
}
|
606
|
+
|
607
|
+
static VALUE
|
608
|
+
generator_update(VALUE t, VALUE seq, VALUE state)
|
609
|
+
{
|
610
|
+
struct generator *p = get_generator(t);
|
611
|
+
|
612
|
+
if (p->flags & TABLE_NOTREADY) {
|
613
|
+
if (p->flags & REFLECT_INPUT) {
|
614
|
+
SWITCH_BY_TYPE(p->flags,
|
615
|
+
build_reflect_table8_u8(p->table[0].as8, p->bitsize, p->polynomial.as8),
|
616
|
+
build_reflect_table8_u16(p->table[0].as16, p->bitsize, p->polynomial.as16),
|
617
|
+
build_reflect_table8_u32(p->table[0].as32, p->bitsize, p->polynomial.as32),
|
618
|
+
build_reflect_table8_u64(p->table[0].as64, p->bitsize, p->polynomial.as64),
|
619
|
+
build_reflect_table8_u128(p->table[0].as128, p->bitsize, p->polynomial.as128));
|
620
|
+
} else {
|
621
|
+
SWITCH_BY_TYPE(p->flags,
|
622
|
+
build_table8_u8(p->table[0].as8, p->bitsize, p->polynomial.as8),
|
623
|
+
build_table8_u16(p->table[0].as16, p->bitsize, p->polynomial.as16),
|
624
|
+
build_table8_u32(p->table[0].as32, p->bitsize, p->polynomial.as32),
|
625
|
+
build_table8_u64(p->table[0].as64, p->bitsize, p->polynomial.as64),
|
626
|
+
build_table8_u128(p->table[0].as128, p->bitsize, p->polynomial.as128));
|
627
|
+
}
|
628
|
+
p->flags ^= TABLE_NOTREADY;
|
629
|
+
}
|
630
|
+
|
631
|
+
rb_check_type(seq, RUBY_T_STRING);
|
632
|
+
const char *q = RSTRING_PTR(seq);
|
633
|
+
const char *qq = q + RSTRING_LEN(seq);
|
634
|
+
if (p->flags & REFLECT_INPUT) {
|
635
|
+
SWITCH_BY_TYPE(p->flags,
|
636
|
+
return conv_uint8(crc_reflect_update_u8(p->bitsize, p->table[0].as8, q, qq, to_uint8(state))),
|
637
|
+
return conv_uint16(crc_reflect_update_u16(p->bitsize, p->table[0].as16, q, qq, to_uint16(state))),
|
638
|
+
return conv_uint32(crc_reflect_update_u32(p->bitsize, p->table[0].as32, q, qq, to_uint32(state))),
|
639
|
+
return conv_uint64(crc_reflect_update_u64(p->bitsize, p->table[0].as64, q, qq, to_uint64(state))),
|
640
|
+
return conv_uint128(crc_reflect_update_u128(p->bitsize, p->table[0].as128, q, qq, to_uint128(state))));
|
641
|
+
} else {
|
642
|
+
SWITCH_BY_TYPE(p->flags,
|
643
|
+
return conv_uint8(crc_update_u8(p->bitsize, p->table[0].as8, q, qq, to_uint8(state))),
|
644
|
+
return conv_uint16(crc_update_u16(p->bitsize, p->table[0].as16, q, qq, to_uint16(state))),
|
645
|
+
return conv_uint32(crc_update_u32(p->bitsize, p->table[0].as32, q, qq, to_uint32(state))),
|
646
|
+
return conv_uint64(crc_update_u64(p->bitsize, p->table[0].as64, q, qq, to_uint64(state))),
|
647
|
+
return conv_uint128(crc_update_u128(p->bitsize, p->table[0].as128, q, qq, to_uint128(state))));
|
648
|
+
}
|
649
|
+
}
|
650
|
+
|
651
|
+
/*
|
652
|
+
* module CRC::Utils
|
653
|
+
*/
|
654
|
+
|
655
|
+
static VALUE
|
656
|
+
utils_s_bitref8(VALUE mod, VALUE num)
|
657
|
+
{
|
658
|
+
return conv_uint8(bitreflect8(to_uint8(num)));
|
659
|
+
}
|
660
|
+
|
661
|
+
static VALUE
|
662
|
+
utils_s_bitref16(VALUE mod, VALUE num)
|
663
|
+
{
|
664
|
+
return conv_uint16(bitreflect16(to_uint16(num)));
|
665
|
+
}
|
666
|
+
|
667
|
+
static VALUE
|
668
|
+
utils_s_bitref32(VALUE mod, VALUE num)
|
669
|
+
{
|
670
|
+
return conv_uint32(bitreflect32(to_uint32(num)));
|
671
|
+
}
|
672
|
+
|
673
|
+
static VALUE
|
674
|
+
utils_s_bitref64(VALUE mod, VALUE num)
|
675
|
+
{
|
676
|
+
return conv_uint64(bitreflect64(to_uint64(num)));
|
677
|
+
}
|
678
|
+
|
679
|
+
static VALUE
|
680
|
+
utils_s_bitref128(VALUE mod, VALUE num)
|
681
|
+
{
|
682
|
+
#ifdef HAVE_TYPE_UINT128_T
|
683
|
+
return conv_uint128(bitreflect128(to_uint128(num)));
|
684
|
+
#endif
|
685
|
+
rb_raise(rb_eNotImpError, "");
|
686
|
+
}
|
687
|
+
|
688
|
+
/*
|
689
|
+
* library crc/_turbo.so
|
690
|
+
*/
|
691
|
+
|
692
|
+
void
|
693
|
+
Init__turbo(void)
|
694
|
+
{
|
695
|
+
generator_iv_name = rb_intern("crc-turbo.CRC::Generator.name");
|
696
|
+
|
697
|
+
mCRC = rb_define_module("CRC");
|
698
|
+
|
699
|
+
mUtils = rb_define_module_under(mCRC, "Utils");
|
700
|
+
rb_define_method(mUtils, "bitreflect8", utils_s_bitref8, 1);
|
701
|
+
rb_define_method(mUtils, "bitreflect16", utils_s_bitref16, 1);
|
702
|
+
rb_define_method(mUtils, "bitreflect32", utils_s_bitref32, 1);
|
703
|
+
rb_define_method(mUtils, "bitreflect64", utils_s_bitref64, 1);
|
704
|
+
rb_define_method(mUtils, "bitreflect128", utils_s_bitref128, 1);
|
705
|
+
|
706
|
+
cGenerator = rb_define_class_under(mCRC, "Generator", rb_cObject);
|
707
|
+
rb_define_alloc_func(cGenerator, generator_alloc);
|
708
|
+
rb_define_method(cGenerator, "initialize", generator_init, -1);
|
709
|
+
rb_define_method(cGenerator, "bitsize", generator_bitsize, 0);
|
710
|
+
rb_define_method(cGenerator, "bitmask", generator_bitmask, 0);
|
711
|
+
rb_define_method(cGenerator, "polynomial", generator_polynomial, 0);
|
712
|
+
rb_define_method(cGenerator, "initial_state", generator_initial_state, 0);
|
713
|
+
rb_define_method(cGenerator, "table8", generator_table8, 0);
|
714
|
+
rb_define_method(cGenerator, "reflect_input", generator_reflect_input, 0);
|
715
|
+
rb_define_method(cGenerator, "reflect_output", generator_reflect_output, 0);
|
716
|
+
rb_define_method(cGenerator, "xor_output", generator_xor_output, 0);
|
717
|
+
rb_define_method(cGenerator, "name", generator_name, 0);
|
718
|
+
rb_define_method(cGenerator, "name=", generator_set_name, 1);
|
719
|
+
rb_define_method(cGenerator, "update", generator_update, 2);
|
720
|
+
}
|
data/ext/crc/extconf.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
3
|
+
require "mkmf"
|
4
|
+
|
5
|
+
have_type("uint32_t", "stdint.h") or abort
|
6
|
+
have_type("uint64_t", "stdint.h") or abort
|
7
|
+
#(have_type("uint128_t") || have_type("uint128_t", "stdint.h")) || have_type("__uint128_t", "stdint.h")
|
8
|
+
|
9
|
+
create_makefile File.join("crc", RUBY_VERSION[/\d+\.\d+/], "_turbo")
|
data/gemstub.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
GEMSTUB = Gem::Specification.new do |s|
|
2
|
+
s.name = "crc-turbo"
|
3
|
+
s.version = "0.1"
|
4
|
+
s.summary = "general CRC generator"
|
5
|
+
s.description = <<EOS
|
6
|
+
This is a C extention for "crc" gem library.
|
7
|
+
Just install this, and "require 'crc'". Additional other work is not required.
|
8
|
+
EOS
|
9
|
+
s.homepage = "https://osdn.jp/projects/rutsubo/"
|
10
|
+
s.license = "BSD-2-Clause"
|
11
|
+
s.author = "dearblue"
|
12
|
+
s.email = "dearblue@users.osdn.me"
|
13
|
+
|
14
|
+
s.required_ruby_version = ">= 2.0"
|
15
|
+
s.add_development_dependency "rake", "~> 11.0"
|
16
|
+
s.add_runtime_dependency "crc", "~> 0.1"
|
17
|
+
end
|
18
|
+
|
19
|
+
EXTMAP["crc"] = "crc/_turbo"
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: crc-turbo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: x86-mingw32
|
6
|
+
authors:
|
7
|
+
- dearblue
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '11.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '11.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: crc
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.1'
|
41
|
+
description: |
|
42
|
+
This is a C extention for "crc" gem library.
|
43
|
+
Just install this, and "require 'crc'". Additional other work is not required.
|
44
|
+
email: dearblue@users.osdn.me
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files:
|
48
|
+
- LICENSE
|
49
|
+
- README.md
|
50
|
+
- ext/crc/crcturbo.c
|
51
|
+
files:
|
52
|
+
- LICENSE
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- ext/crc/crcturbo.c
|
56
|
+
- ext/crc/extconf.rb
|
57
|
+
- gemstub.rb
|
58
|
+
- lib/crc/2.0/_turbo.so
|
59
|
+
- lib/crc/2.1/_turbo.so
|
60
|
+
- lib/crc/2.2/_turbo.so
|
61
|
+
- lib/crc/2.3/_turbo.so
|
62
|
+
homepage: https://osdn.jp/projects/rutsubo/
|
63
|
+
licenses:
|
64
|
+
- BSD-2-Clause
|
65
|
+
metadata: {}
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options:
|
68
|
+
- "--charset"
|
69
|
+
- UTF-8
|
70
|
+
- "-m"
|
71
|
+
- README.md
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '2.0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.6.2
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: general CRC generator
|
90
|
+
test_files: []
|
91
|
+
has_rdoc:
|