ob64 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/main.yml +77 -16
- data/.standard.yml +1 -2
- data/CHANGELOG.md +18 -1
- data/README.md +57 -19
- data/benchmark.rb +60 -95
- data/ext/ob64/extconf.rb +0 -42
- data/ext/ob64/ob64.h +3 -1
- data/ext/ob64/ob64_ext.c +80 -23
- data/ext/ob64/ob64_pack.c +228 -0
- data/ext/ob64/pack_base64.c +5182 -0
- data/ext/ob64/pack_base64.h +33 -0
- data/ext/ob64/pack_generic.h +151 -0
- data/ext/ob64/pack_simd.h +22 -0
- data/ext/ob64/pack_uuencode.c +1741 -0
- data/ext/ob64/pack_uuencode.h +18 -0
- data/lib/ob64/core_ext.rb +2 -25
- data/lib/ob64/version.rb +1 -1
- data/lib/ob64.rb +149 -70
- data/ob64.gemspec +3 -3
- metadata +17 -13
- data/.gitmodules +0 -3
- data/ext/ob64/libbase64.h +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8b76a774595914a6124939fe2410fe4ae5bb0687286315ab4ec1f05b8569d70
|
|
4
|
+
data.tar.gz: 662b74f7505f28362436d44771e51720884cf0ea48076b12e59094eacf4e87b6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b0e357acff49af3e42b36cb41b521393ed4f6604fc4f5943c491a504741b985d5a47e63217acd27e0896cb2b23a8df2412fe133fff1d76d275decc5cf0a39f7f
|
|
7
|
+
data.tar.gz: 560f3439cff65bc442f16a8815afa729422e6286f6305a044f92035bf28666b80c80c8471ffd7ac0b83379ea999643a531ef9a5905449093dafe10cff36490e9
|
data/.github/workflows/main.yml
CHANGED
|
@@ -1,34 +1,95 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: CI
|
|
2
2
|
|
|
3
3
|
on: [push, pull_request]
|
|
4
4
|
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
defaults:
|
|
13
|
+
run:
|
|
14
|
+
shell: bash
|
|
15
|
+
|
|
5
16
|
jobs:
|
|
17
|
+
lint:
|
|
18
|
+
runs-on: ubuntu-24.04
|
|
19
|
+
timeout-minutes: 10
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
22
|
+
with:
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
|
|
25
|
+
- uses: ruby/setup-ruby@7f797815d8adceb1c412e7abefdd1ab4abc47a5f # v1.335.0
|
|
26
|
+
with:
|
|
27
|
+
ruby-version: "3.4"
|
|
28
|
+
bundler-cache: true
|
|
29
|
+
|
|
30
|
+
- run: bundle exec standardrb --no-fix
|
|
31
|
+
|
|
6
32
|
test:
|
|
7
33
|
strategy:
|
|
8
34
|
fail-fast: false
|
|
9
35
|
matrix:
|
|
10
|
-
ruby: [
|
|
11
|
-
|
|
36
|
+
ruby: ["3.3", "3.4", "4.0"]
|
|
37
|
+
os: [ubuntu-24.04, ubuntu-24.04-arm]
|
|
38
|
+
cc: [gcc, clang]
|
|
39
|
+
runs-on: ${{ matrix.os }}
|
|
40
|
+
timeout-minutes: 15
|
|
12
41
|
steps:
|
|
13
|
-
-
|
|
14
|
-
uses: actions/checkout@v2
|
|
42
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
15
43
|
with:
|
|
16
|
-
|
|
44
|
+
persist-credentials: false
|
|
17
45
|
|
|
18
|
-
-
|
|
19
|
-
uses: ruby/setup-ruby@v1
|
|
46
|
+
- uses: ruby/setup-ruby@7f797815d8adceb1c412e7abefdd1ab4abc47a5f # v1.335.0
|
|
20
47
|
with:
|
|
21
48
|
ruby-version: ${{ matrix.ruby }}
|
|
49
|
+
bundler-cache: true
|
|
22
50
|
|
|
23
|
-
- name:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- name: bundle install
|
|
27
|
-
run: bundle install --path .bundle/gems --without development
|
|
51
|
+
- name: Install Clang
|
|
52
|
+
if: matrix.cc == 'clang'
|
|
53
|
+
run: command -v clang || { sudo apt-get update && sudo apt-get install -y clang; }
|
|
28
54
|
|
|
29
|
-
- name:
|
|
55
|
+
- name: Compile
|
|
56
|
+
env:
|
|
57
|
+
# Same warnings for both compilers; Ruby's defaults are GCC-only.
|
|
58
|
+
MAKEFLAGS: 'CC=${{ matrix.cc }} warnflags=-Wall\ -Wextra\ -Wno-unused-parameter\ -Werror'
|
|
30
59
|
run: bundle exec rake compile
|
|
31
60
|
|
|
32
|
-
- name:
|
|
61
|
+
- name: Show codecs
|
|
62
|
+
run: bundle exec ruby -Ilib -rob64 -e 'p Ob64.codecs, Ob64.codec'
|
|
63
|
+
|
|
64
|
+
- name: Test
|
|
33
65
|
run: bundle exec rake spec
|
|
34
|
-
|
|
66
|
+
|
|
67
|
+
package:
|
|
68
|
+
runs-on: ubuntu-24.04
|
|
69
|
+
timeout-minutes: 10
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
72
|
+
with:
|
|
73
|
+
persist-credentials: false
|
|
74
|
+
|
|
75
|
+
- uses: ruby/setup-ruby@7f797815d8adceb1c412e7abefdd1ab4abc47a5f # v1.335.0
|
|
76
|
+
with:
|
|
77
|
+
ruby-version: "3.4"
|
|
78
|
+
|
|
79
|
+
- name: Build gem
|
|
80
|
+
run: gem build ob64.gemspec
|
|
81
|
+
|
|
82
|
+
- name: Install gem
|
|
83
|
+
run: gem install --local ./ob64-*.gem
|
|
84
|
+
|
|
85
|
+
- name: Smoke test
|
|
86
|
+
working-directory: ${{ runner.temp }}
|
|
87
|
+
run: |
|
|
88
|
+
ruby -e '
|
|
89
|
+
require "ob64"
|
|
90
|
+
require "ob64/core_ext"
|
|
91
|
+
s = Random.bytes(4096)
|
|
92
|
+
abort "Base64 round trip failed" unless Ob64::Base64.decode(Ob64::Base64.encode(s)) == s
|
|
93
|
+
abort "UU round trip failed" unless Ob64::UU.decode(Ob64::UU.encode(s)) == s
|
|
94
|
+
abort "pack round trip failed" unless [s].pack("m0").unpack1("m0") == s
|
|
95
|
+
'
|
data/.standard.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [0.6.0] - 2026-10-26
|
|
2
|
+
|
|
3
|
+
- **Breaking:** `ob64/core_ext` patches `Array#pack`, `String#unpack` and `String#unpack1` instead of `Base64`.
|
|
4
|
+
- **Breaking:** Require Ruby >= 3.3.
|
|
5
|
+
- **Breaking:** Drop CMake and libbase64. Require GCC or Clang.
|
|
6
|
+
- **Breaking:** Base64 methods move from `Ob64` to `Ob64::Base64` (e.g. `Ob64.encode` is now `Ob64::Base64.encode`).
|
|
7
|
+
- **Breaking:** `decode` and `urlsafe_decode` reject non-zero trailing bits (e.g. `"AB=="`), like `unpack1("m0")`.
|
|
8
|
+
- Port SIMD codecs (AVX2, AVX512, NEON64) into the extension. They also run line-wrapped `m` and `u`.
|
|
9
|
+
- AVX512 requires VBMI2.
|
|
10
|
+
- Add `Ob64.codec`, `Ob64.codec=`, `Ob64.codecs` and `Ob64.best_codec`.
|
|
11
|
+
- Add `Ob64::Base64.decode(string, loose: true)`.
|
|
12
|
+
- Add `Ob64::UU.encode`, `Ob64::UU.decode`, `Ob64::UU.encoded_length_of` and `Ob64::UU.decoded_length_of`.
|
|
13
|
+
- Encode and decode URL-safe in C.
|
|
14
|
+
- Support Linux on AArch64.
|
|
15
|
+
|
|
16
|
+
# [0.5.0] - 2021-09-29
|
|
17
|
+
|
|
18
|
+
- Ignore all previous versions as they weren't including libbase64 (:
|
|
2
19
|
|
|
3
20
|
# [0.4.0] - 2021-09-28
|
|
4
21
|
|
data/README.md
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
# Ob64 gem
|
|
2
2
|
|
|
3
3
|
[](http://rubygems.org/gems/ob64)
|
|
4
|
-
[](http://www.rubydoc.info/gems/ob64/0.
|
|
4
|
+
[](https://github.com/jcmfernandes/ob64/actions/workflows/main.yml)
|
|
5
|
+
[](http://www.rubydoc.info/gems/ob64/0.6.0)
|
|
6
6
|
|
|
7
|
-
A *fast* Base64 encoder and decoder as a Ruby gem.
|
|
7
|
+
A *fast* Base64 and uuencode encoder and decoder as a Ruby gem.
|
|
8
8
|
|
|
9
9
|
How fast? Try it yourself, execute:
|
|
10
10
|
|
|
11
11
|
$ rake benchmark
|
|
12
12
|
|
|
13
|
-
When compared to Ruby's own `Base64` module, expect a 4x speedup in encoding, and a 2x speedup in decoding. YMMV.
|
|
14
|
-
|
|
15
13
|
## Acknowledgements
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
The SIMD codecs (AVX2, AVX512, NEON64) derive from [aklomp/base64](https://github.com/aklomp/base64).
|
|
18
16
|
|
|
19
17
|
## Installation
|
|
20
18
|
|
|
@@ -32,33 +30,75 @@ Or install it yourself as:
|
|
|
32
30
|
|
|
33
31
|
$ gem install ob64
|
|
34
32
|
|
|
35
|
-
Requires
|
|
36
|
-
|
|
37
|
-
**WARNING:** Only tested on Linux and x86-64.
|
|
33
|
+
Requires Ruby >= 3.3 and GCC or Clang. Linux on x86-64 and AArch64.
|
|
38
34
|
|
|
39
35
|
## Usage
|
|
40
36
|
|
|
41
37
|
```ruby
|
|
42
38
|
require "ob64"
|
|
39
|
+
```
|
|
43
40
|
|
|
41
|
+
### Base64
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
44
|
bin1 = "This is data!"
|
|
45
|
-
string = Ob64.encode(bin1)
|
|
45
|
+
string = Ob64::Base64.encode(bin1)
|
|
46
46
|
# string = "VGhpcyBpcyBkYXRhIQ=="
|
|
47
47
|
|
|
48
|
-
bin2 = Ob64.decode(string)
|
|
48
|
+
bin2 = Ob64::Base64.decode(string)
|
|
49
49
|
puts "Same? #{bin1 == bin2}"
|
|
50
50
|
# "Same? true"
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Decode input with or without padding:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
Ob64::Base64.decode("VGhpcyBpcyBkYXRhIQ", loose: true)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Bad padding, non-zero trailing bits and non-alphabet characters still raise `ArgumentError`.
|
|
60
|
+
|
|
61
|
+
URL-safe alphabet: `Ob64::Base64.urlsafe_encode(bin, padding: false)`, `Ob64::Base64.urlsafe_decode(string)`.
|
|
62
|
+
|
|
63
|
+
### uuencode
|
|
64
|
+
|
|
65
|
+
Same output as `pack("u")` / `unpack1("u")`:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
string = Ob64::UU.encode("This is data!")
|
|
69
|
+
# string = "-5&AI<R!I<R!D871A(0``\n"
|
|
70
|
+
|
|
71
|
+
Ob64::UU.decode(string)
|
|
72
|
+
# "This is data!"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Codecs
|
|
76
|
+
|
|
77
|
+
The best codec this CPU runs is picked at load and used for every call. `Ob64.codec=` forces one for the whole process (e.g. `:scalar`, plain C).
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
Ob64.codecs
|
|
81
|
+
# x86-64 with AVX512 => [:scalar, :avx2, :avx512]
|
|
82
|
+
# x86-64 with AVX2 => [:scalar, :avx2]
|
|
83
|
+
# AArch64 => [:scalar, :neon64]
|
|
84
|
+
# other => [:scalar]
|
|
85
|
+
|
|
86
|
+
Ob64.best_codec # => :avx512
|
|
87
|
+
Ob64.codec # => :avx512
|
|
88
|
+
Ob64.codec = :scalar
|
|
89
|
+
Ob64.codec = Ob64.best_codec
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
AVX512 needs VL, VBMI and VBMI2.
|
|
93
|
+
|
|
94
|
+
### `pack` / `unpack`
|
|
54
95
|
|
|
55
96
|
```ruby
|
|
56
97
|
require "ob64/core_ext"
|
|
57
|
-
# It does NOT replace:
|
|
58
|
-
# - Base64.encode64
|
|
59
|
-
# - Base64.decode64
|
|
60
98
|
```
|
|
61
99
|
|
|
100
|
+
Patches `Array#pack`, `String#unpack` and `String#unpack1`. Fast only for single-directive formats `m`, `mN`, `m*`, `u`, `uN`, `u*`. Everything else runs Ruby's own code. Passing `buffer:`, `offset:`, a block, or a non-String first element also runs Ruby's own code. Output is identical to Ruby's.
|
|
101
|
+
|
|
62
102
|
See [YARD documentation](http://www.rubydoc.info/gems/ob64).
|
|
63
103
|
|
|
64
104
|
## Releases
|
|
@@ -77,10 +117,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/jcmfer
|
|
|
77
117
|
|
|
78
118
|
## TODO
|
|
79
119
|
|
|
80
|
-
* URL-safe encoding/decoding using separate alphabet/tables
|
|
81
120
|
* Streaming interface
|
|
82
121
|
* RFC 2045 (MIME) encoding/decoding
|
|
83
|
-
* Make the OpenMP threshold configurable (and enable OpenMP acceleration)
|
|
84
122
|
* Windows support
|
|
85
123
|
|
|
86
124
|
## License
|
|
@@ -107,9 +145,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
107
145
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
108
146
|
THE SOFTWARE.
|
|
109
147
|
|
|
110
|
-
###
|
|
148
|
+
### aklomp/base64
|
|
111
149
|
|
|
112
|
-
Released under the BSD 2-clause License. See [LICENSE](https://github.com/
|
|
150
|
+
Released under the BSD 2-clause License. See [LICENSE](https://github.com/aklomp/base64/blob/master/LICENSE).
|
|
113
151
|
|
|
114
152
|
Copyright (c) 2005-2007, Nick Galbreath
|
|
115
153
|
Copyright (c) 2013-2019, Alfred Klomp
|
data/benchmark.rb
CHANGED
|
@@ -1,118 +1,83 @@
|
|
|
1
1
|
require "benchmark/ips"
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
# Ruby's own, captured before ob64/core_ext patches them.
|
|
4
|
+
NATIVE_PACK = Array.instance_method(:pack)
|
|
5
|
+
NATIVE_UNPACK1 = String.instance_method(:unpack1)
|
|
3
6
|
|
|
4
7
|
require "ob64"
|
|
5
|
-
require "
|
|
8
|
+
require "ob64/core_ext"
|
|
6
9
|
|
|
7
|
-
$
|
|
8
|
-
$
|
|
9
|
-
$run_urlsafe_encode_benchmark = true
|
|
10
|
-
$run_urlsafe_decode_benchmark = true
|
|
10
|
+
$run_base64_benchmark = true
|
|
11
|
+
$run_uu_benchmark = true
|
|
11
12
|
|
|
12
13
|
def to_size(bytes)
|
|
13
14
|
bytes >= 2**20 ? "#{bytes / 2**20} MB" : "#{bytes / 2**10} kB"
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
def
|
|
17
|
-
[
|
|
18
|
-
[1, :kb],
|
|
19
|
-
[4, :kb],
|
|
20
|
-
[64, :kb],
|
|
21
|
-
[1, :mb],
|
|
22
|
-
[10, :mb],
|
|
23
|
-
[64, :mb]
|
|
24
|
-
].each do |(n, unit)|
|
|
25
|
-
yield(n * 2**({kb: 10, mb: 20}.fetch(unit)))
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def benchmark(setup_block)
|
|
30
|
-
each_block do |size|
|
|
31
|
-
setup_block.call(size)
|
|
32
|
-
GC.start
|
|
17
|
+
def each_size
|
|
18
|
+
[1 * 2**10, 4 * 2**10, 64 * 2**10, 1 * 2**20, 10 * 2**20, 64 * 2**20].each do |size|
|
|
33
19
|
puts "\n\n#{"=" * 60}\nbenchmark with block size #{to_size(size)}"
|
|
34
|
-
yield
|
|
20
|
+
yield Random.bytes(size)
|
|
35
21
|
end
|
|
36
22
|
end
|
|
37
23
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
&block
|
|
42
|
-
)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def decode_benchmark(&block)
|
|
46
|
-
benchmark(
|
|
47
|
-
lambda { |size| $encoded = SecureRandom.base64(size) },
|
|
48
|
-
&block
|
|
49
|
-
)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
encode_benchmark do
|
|
53
|
-
Benchmark.ips do |x|
|
|
54
|
-
x.time = 5
|
|
55
|
-
x.warmup = 2
|
|
56
|
-
|
|
57
|
-
x.report("base64 .strict_encode64") do
|
|
58
|
-
Base64.strict_encode64($unencoded)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
x.report("ob64 .encode") do
|
|
62
|
-
Ob64.encode($unencoded)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
x.compare!
|
|
66
|
-
end
|
|
67
|
-
end if $run_encode_benchmark
|
|
68
|
-
|
|
69
|
-
decode_benchmark do
|
|
70
|
-
Benchmark.ips do |x|
|
|
71
|
-
x.time = 5
|
|
72
|
-
x.warmup = 2
|
|
73
|
-
|
|
74
|
-
x.report("base64 .strict_decode64") do
|
|
75
|
-
Base64.strict_decode64($encoded)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
x.report("ob64 .decode") do
|
|
79
|
-
Ob64.decode($encoded)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
x.compare!
|
|
83
|
-
end
|
|
84
|
-
end if $run_decode_benchmark
|
|
85
|
-
|
|
86
|
-
encode_benchmark do
|
|
24
|
+
# Compares reports, label => block
|
|
25
|
+
def compare(reports)
|
|
26
|
+
GC.start
|
|
87
27
|
Benchmark.ips do |x|
|
|
88
28
|
x.time = 5
|
|
89
29
|
x.warmup = 2
|
|
90
30
|
|
|
91
|
-
x.report(
|
|
92
|
-
Base64.urlsafe_encode64($unencoded)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
x.report("ob64 .urlsafe_encode") do
|
|
96
|
-
Ob64.urlsafe_encode($unencoded)
|
|
97
|
-
end
|
|
31
|
+
reports.each { |label, block| x.report(label, &block) }
|
|
98
32
|
|
|
99
|
-
x.compare!
|
|
33
|
+
x.compare!(order: :baseline)
|
|
100
34
|
end
|
|
101
|
-
end
|
|
35
|
+
end
|
|
102
36
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
37
|
+
each_size do |bin|
|
|
38
|
+
m0 = NATIVE_PACK.bind_call([bin], "m0")
|
|
39
|
+
urlsafe = m0.tr("+/", "-_")
|
|
40
|
+
m = NATIVE_PACK.bind_call([bin], "m")
|
|
107
41
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
42
|
+
compare(
|
|
43
|
+
"Ruby pack(\"m0\")" => -> { NATIVE_PACK.bind_call([bin], "m0") },
|
|
44
|
+
"ob64 Base64.encode" => -> { Ob64::Base64.encode(bin) },
|
|
45
|
+
"ob64 pack(\"m0\")" => -> { [bin].pack("m0") }
|
|
46
|
+
)
|
|
47
|
+
compare(
|
|
48
|
+
"Ruby unpack1(\"m0\")" => -> { NATIVE_UNPACK1.bind_call(m0, "m0") },
|
|
49
|
+
"ob64 Base64.decode" => -> { Ob64::Base64.decode(m0) },
|
|
50
|
+
"ob64 unpack1(\"m0\")" => -> { m0.unpack1("m0") }
|
|
51
|
+
)
|
|
52
|
+
compare(
|
|
53
|
+
"Ruby pack(\"m0\").tr" => -> { NATIVE_PACK.bind_call([bin], "m0").tr("+/", "-_") },
|
|
54
|
+
"ob64 Base64.urlsafe_encode" => -> { Ob64::Base64.urlsafe_encode(bin) }
|
|
55
|
+
)
|
|
56
|
+
compare(
|
|
57
|
+
"Ruby tr.unpack1(\"m0\")" => -> { NATIVE_UNPACK1.bind_call(urlsafe.tr("-_", "+/"), "m0") },
|
|
58
|
+
"ob64 Base64.urlsafe_decode" => -> { Ob64::Base64.urlsafe_decode(urlsafe) }
|
|
59
|
+
)
|
|
60
|
+
compare(
|
|
61
|
+
"Ruby pack(\"m\")" => -> { NATIVE_PACK.bind_call([bin], "m") },
|
|
62
|
+
"ob64 pack(\"m\")" => -> { [bin].pack("m") }
|
|
63
|
+
)
|
|
64
|
+
compare(
|
|
65
|
+
"Ruby unpack1(\"m\")" => -> { NATIVE_UNPACK1.bind_call(m, "m") },
|
|
66
|
+
"ob64 unpack1(\"m\")" => -> { m.unpack1("m") }
|
|
67
|
+
)
|
|
68
|
+
end if $run_base64_benchmark
|
|
111
69
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
end
|
|
70
|
+
each_size do |bin|
|
|
71
|
+
u = NATIVE_PACK.bind_call([bin], "u")
|
|
115
72
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
73
|
+
compare(
|
|
74
|
+
"Ruby pack(\"u\")" => -> { NATIVE_PACK.bind_call([bin], "u") },
|
|
75
|
+
"ob64 UU.encode" => -> { Ob64::UU.encode(bin) },
|
|
76
|
+
"ob64 pack(\"u\")" => -> { [bin].pack("u") }
|
|
77
|
+
)
|
|
78
|
+
compare(
|
|
79
|
+
"Ruby unpack1(\"u\")" => -> { NATIVE_UNPACK1.bind_call(u, "u") },
|
|
80
|
+
"ob64 UU.decode" => -> { Ob64::UU.decode(u) },
|
|
81
|
+
"ob64 unpack1(\"u\")" => -> { u.unpack1("u") }
|
|
82
|
+
)
|
|
83
|
+
end if $run_uu_benchmark
|
data/ext/ob64/extconf.rb
CHANGED
|
@@ -2,46 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
require "mkmf"
|
|
4
4
|
|
|
5
|
-
def sys(cmd)
|
|
6
|
-
puts " -- #{cmd}"
|
|
7
|
-
unless ret = xsystem(cmd)
|
|
8
|
-
raise "ERROR: '#{cmd}' failed"
|
|
9
|
-
end
|
|
10
|
-
ret
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def run_cmake(args)
|
|
14
|
-
pid = Process.spawn("cmake #{args}")
|
|
15
|
-
Process.waitpid(pid)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
if !find_executable("cmake")
|
|
19
|
-
abort "ERROR: CMake is required to build ob64"
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
MAKE = find_executable("make") || find_executable("gmake")
|
|
23
|
-
if !MAKE
|
|
24
|
-
abort "ERROR: make is required to build ob64"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
CWD = __dir__
|
|
28
|
-
LIBBASE64_DIR = File.join(CWD, "..", "..", "vendor", "libbase64")
|
|
29
|
-
|
|
30
|
-
Dir.chdir(LIBBASE64_DIR) do
|
|
31
|
-
Dir.mkdir("build") unless Dir.exist?("build")
|
|
32
|
-
|
|
33
|
-
Dir.chdir("build") do
|
|
34
|
-
run_cmake(".. -DBUILD_SHARED_LIBS=true -DOPENMP=false")
|
|
35
|
-
sys(MAKE)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
$DEFLIBPATH.unshift("#{LIBBASE64_DIR}/build/bin")
|
|
39
|
-
dir_config("base64", "#{LIBBASE64_DIR}/include", "#{LIBBASE64_DIR}/build/bin")
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
unless have_library("base64") && have_header("libbase64.h")
|
|
43
|
-
abort "ERROR: Failed to build libbase64"
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
dir_config("ob64_ext")
|
|
47
5
|
create_makefile("ob64_ext")
|