zstandard 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: be082988dab6b74aeeb9b9a22f5d3bc2a7c4e458
4
+ data.tar.gz: b85823b5c30374c5bbef7b5d3ff34db8d0bfad1b
5
+ SHA512:
6
+ metadata.gz: 72bcd58d297a430824218ec3dacb656f11aaa118e53cc952aa1e575202e6e24fa253d1d831eec16733d0ced2521809fb39d7da76b83e1cc52728b1f85a7b0b11
7
+ data.tar.gz: 248e3858167a8e58e7baaf494803e54ff3a19f2e83a440db1b3027328546b82589eecd993b2717035ed3e64a682d62d3139cf0dc53f8862711e18067c668f4ce
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.10
7
+ - 2.2.6
8
+ - 2.3.3
9
+ - 2.4.1
10
+ - jruby-1.7.26
11
+ - jruby-9.1.7.0
12
+
13
+ before_install:
14
+ - gem install bundler -v 1.13.6
15
+
16
+ script: bundle && ./run_rspec_with_bundled_libraries.sh
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup=markdown
data/Gemfile ADDED
@@ -0,0 +1,31 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in zstandard.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem "benchmark-ips"
8
+ gem "bundler"
9
+ gem "rake"
10
+ gem "ruby-progressbar", "~> 1.0"
11
+ gem "rspec", "~> 3.0"
12
+
13
+ if RUBY_ENGINE == "ruby"
14
+ gem "simplecov" if RUBY_VERSION >= "2.0.0"
15
+
16
+ if !ENV["CI"]
17
+ gem "pry"
18
+
19
+ if RUBY_VERSION < "2.0.0"
20
+ gem "pry-nav"
21
+ else
22
+ gem "pry-byebug"
23
+ end
24
+
25
+ # yard and friends
26
+ gem "redcarpet"
27
+ gem "github-markup"
28
+ gem "yard"
29
+ end
30
+ end
31
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Michael Sievers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # zstandard-ruby
2
+
3
+ [![Build Status](https://travis-ci.org/msievers/zstandard-ruby.svg?branch=master)](https://travis-ci.org/msievers/zstandard-ruby)
4
+
5
+ * [Installation](#installation)
6
+ * [Usage](#usage)
7
+ * [Advanced Usage](#advanced-usage)
8
+ * [Configuration](#configuration)
9
+ * [Docs](#docs)
10
+ * [Examples for installing `libzstd`](#examples-for-installing-libzstd)
11
+ * [Contributing](#contributing)
12
+ * [License](#license)
13
+
14
+ This gem implements FFI based bindings to the [Zstandard](https://facebook.github.io/zstd) compression library `libzstd`. The [Zstandard](https://facebook.github.io/zstd) compression algorithm shines because it compresses data with the same or better ratio as *Zlib* but does this (much) faster, depending on the input. For the majority of cases it's **faster and better** then *Zlib*.
15
+
16
+ It **does not** ship the actual `libzstd` library but expects some version to be present on your system.
17
+
18
+ ## Installation
19
+
20
+ Make sure you have `libzstd` installed on your system. In doubt, have a look at the [examples for installing `libzstd`](#examples-for-installing-libzstd).
21
+
22
+ Add this line to your application's Gemfile:
23
+
24
+ ```ruby
25
+ gem "zstandard"
26
+ ```
27
+
28
+ And then execute:
29
+
30
+ ```
31
+ bundle
32
+ ```
33
+
34
+ Or install it yourself as:
35
+
36
+ ```
37
+ gem install zstandard
38
+ ```
39
+
40
+ ## Usage
41
+
42
+ The gem provides an API which aims compatibility the with `zlib` gem. There are two module methods
43
+ * `deflate(string, level)`
44
+ * `inflate(compressed_string)`
45
+
46
+ The only difference between this and the `zlib` gem is the interpretation of the compression level. For `zlib`, this is a value between `1..9`, whereas for `Zstandard` it's between `1..22`.
47
+
48
+ For most use cases, you should try to keep the compression level (very) low for `Zstandard`, because often compression time increases without significant better compression ratios. If in doubt, *do not specify* a compression level at all, which will use the default compression level.
49
+
50
+ ```ruby
51
+ require "zstandard"
52
+
53
+ compressed_string = Zstandard.deflate(string)
54
+ decompressed_string = Zstandard.inflate(compressed_string)
55
+ ```
56
+
57
+ ## Advanced Usage
58
+
59
+ *This is not intended to be used by regular users.*
60
+
61
+ Besides the high level API which targets compatibility with the well known `zlib` gem there are two additional layers you can interact with. There is a low-level API which tries to cover differences between various `libzstd` version, e.g. different *frame header* formats. You should only use this if you know, what you are doing.
62
+
63
+ ```ruby
64
+ require "zstandard"
65
+
66
+ compressed_string = Zstandard::API.simple_compress(string)
67
+ decompressed_string = Zstandard::API.simple_decompress(compressed_string)
68
+ ```
69
+
70
+ The most low-level bindings are exposed via `Zstandard::FFIBindings`. If there is any reason for this, you can do the following.
71
+
72
+ ```ruby
73
+ require "zstandard"
74
+
75
+ zstd_library_version = Zstandard::FFIBindings.zstd_version_number
76
+ ```
77
+
78
+ ## Configuration
79
+
80
+ This gem can be configured by setting various environment variables. Please be carefull if you decide to change/overwrite any of these. The default values are carefully choosen and there should be no need to alter one of these for regular use cases.
81
+
82
+ ### `ZSTANDARD_LIBRARY`
83
+
84
+ If you have `libzstd` installed in some unusual location or if you want to explictly tell, which library to use, you can set `ZSTANDARD_LIBRARY` to the path of the library you want to use. This can be handy for example if you have the latest version compiled in `/usr/local/lib`, but your system has an old version in `/usr/lib`.
85
+
86
+ ```
87
+ ZSTANDARD_LIBRARY=/usr/local/lib/libzstd.so bundle exec rake rspec
88
+ ```
89
+
90
+ ### `ZSTANDARD_MAX_SIMPLE_DECOMPRESS_SIZE`
91
+
92
+ This specifies the maximum (decompressed) size of a string for which the simple decompression approach should be used. In order minimise memory consumption, if the expected decompressed size exceeds this limit, streaming decompression is used.
93
+
94
+ ### `ZSTANDARD_MAX_STREAMING_DECOMRPESS_BUFFER_SIZE`
95
+
96
+ For streaming decompression, this specifies the size of the decompression bufffer.
97
+
98
+ ## Docs
99
+
100
+ Yard generated docs can be found at [http://www.rubydoc.info/github/msievers/zstandard-ruby](http://www.rubydoc.info/github/msievers/zstandard-ruby).
101
+
102
+ ## Examples for installing `libzstd`
103
+
104
+ * [Debian](#debian)
105
+ * [Fedora](#fedora)
106
+ * [FreeBSD](#freebsd)
107
+ * [Mac](#mac)
108
+ * [NetBSD](#netbsd)
109
+ * [Ubuntu](#ubuntu)
110
+
111
+ ### Debian
112
+
113
+ #### Jessie (8.x)
114
+
115
+ The package is only included in `sid`, the unstable Debian version. There are guides describing how to install unstable packages into a stable Debian, for example at [Linuxaria](https://linuxaria.com/howto/how-to-install-a-single-package-from-debian-sid-or-debian-testing) or [serverfault.com](https://serverfault.com/questions/22414/how-can-i-run-debian-stable-but-install-some-packages-from-testing).
116
+
117
+ ```
118
+ # run as root
119
+
120
+ apt-get install zstd
121
+ ```
122
+
123
+ ### Fedora
124
+
125
+ #### Fedora 23
126
+
127
+ ```
128
+ sudo dnf install libzstd
129
+ ```
130
+
131
+ ### FreeBSD
132
+
133
+ #### FreeBSD 10
134
+
135
+ ```
136
+ # run as root
137
+
138
+ portsnap fetch && portsnap extract
139
+
140
+ cd /usr/ports/archivers/zstd
141
+ make install
142
+ ```
143
+
144
+ ### Mac
145
+
146
+ ```
147
+ brew install zstd
148
+ ```
149
+
150
+ ### NetBSD
151
+
152
+ #### NetBSD 7
153
+
154
+ ```
155
+ # run as root
156
+
157
+ # the following assumes you are running a x86_64 system with NetBSD 7.0.x
158
+
159
+ export PATH="/usr/pkg/sbin:$PATH"
160
+ export PKG_PATH="ftp://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/x86_64/7.0_current/All/"
161
+
162
+ pkg_add zstd
163
+ ```
164
+
165
+ ### Ubuntu
166
+
167
+ #### Xenial Xerus (16.04) and above
168
+
169
+ ```
170
+ sudo apt-get install zstd
171
+ ```
172
+
173
+ ## Contributing
174
+
175
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/msievers/zstandard-ruby](https://github.com/msievers/zstandard-ruby).
176
+
177
+ ## License
178
+
179
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
8
+ Dir.glob("benchmarks/*.rake").each do |file|
9
+ import file
10
+ end
11
+
12
+ desc "Run benchmarks"
13
+ task :benchmark => ["benchmarks:deflate"]
data/lib/zstandard.rb ADDED
@@ -0,0 +1,23 @@
1
+ require_relative "./zstandard/api"
2
+ require_relative "./zstandard/config"
3
+ require_relative "./zstandard/version"
4
+
5
+ module Zstandard
6
+ class Error < ::StandardError; end;
7
+ class DecompressedSizeUnknownError < Error; end;
8
+ class LibraryVersionNotSupportedError < Error; end;
9
+
10
+ def self.deflate(string, level = nil)
11
+ API.simple_compress(string, level: level)
12
+ end
13
+
14
+ def self.inflate(string)
15
+ decompressed_size = API.decompressed_size(string)
16
+
17
+ if decompressed_size > 0 && decompressed_size <= Config::MAX_SIMPLE_DECOMPRESS_SIZE
18
+ API.simple_decompress(string)
19
+ else
20
+ API.streaming_decompress(string)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,123 @@
1
+ require_relative "./config"
2
+ require_relative "./ffi_bindings"
3
+
4
+ module Zstandard
5
+ # Internal API layer to abstract different libzstd calling semantics/versions
6
+ module API
7
+ def self.streaming_decompress(string, options = {})
8
+ dst_size = window_size(string)
9
+
10
+ # The docs propose to check the dst size (windowSize), because it could be manipulated
11
+ raise "Invalid dst size!" if dst_size <= 0 || dst_size > Config::MAX_STREAMING_DECOMRPESS_BUFFER_SIZE
12
+
13
+ src = FFI::MemoryPointer.from_string(string) # we need the pointer for arithmetics
14
+ dst = FFI::MemoryPointer.new(:char, dst_size)
15
+
16
+ dst_offset = 0
17
+ src_offset = 0
18
+ result = []
19
+
20
+ dctx = FFIBindings.zstd_create_dctx
21
+ FFIBindings.zstd_decompress_begin(dctx)
22
+
23
+ while (src_size = FFIBindings.zstd_next_src_size_to_deompress(dctx)) != 0
24
+ nbytes = FFIBindings.zstd_decompress_continue(
25
+ dctx,
26
+ dst + dst_offset,
27
+ (dst + dst_offset).size,
28
+ src + src_offset,
29
+ src_size
30
+ )
31
+
32
+ if FFIBindings.zstd_is_error(error_code = nbytes) > 0
33
+ raise FFIBindings.zstd_get_error_name(error_code)
34
+ elsif nbytes > 0
35
+ result << (dst + dst_offset).read_bytes(nbytes)
36
+ dst_offset += nbytes
37
+ dst_offset = 0 if (dst + dst_offset).size == 0
38
+ end
39
+
40
+ src_offset += src_size
41
+ end
42
+
43
+ dst.free
44
+ src.free
45
+ FFIBindings.zstd_free_dctx(dctx)
46
+
47
+ result.join
48
+ end
49
+
50
+ #
51
+ # Tries to gather the size of the decompressed data.
52
+ #
53
+ # @param [String] string Compressed data
54
+ # @return [Integer] size of the decompressed data or 0
55
+ #
56
+ def self.decompressed_size(string)
57
+ if FFIBindings.zstd_version_number < 600
58
+ parameters = FFIBindings::ZSTD_parameters.new
59
+ FFIBindings.zstd_get_frame_params(parameters, string, string.bytesize)
60
+ parameters[:srcSize]
61
+ elsif FFIBindings.zstd_version_number < 10104
62
+ frame_params = FFIBindings::ZSTD_frameParams.new
63
+ FFIBindings.zstd_get_frame_params(frame_params, string, string.bytesize)
64
+ frame_params[:frameContentSize]
65
+ else
66
+ FFIBindings.zstd_find_decompressed_size(string, string.bytesize)
67
+ end
68
+ end
69
+
70
+ def self.simple_compress(string, options = {})
71
+ level = options[:level] || 0 # 0 means default
72
+
73
+ dst_size = FFIBindings.zstd_compress_bound(string.bytesize)
74
+ dst = FFI::MemoryPointer.new(:char, dst_size)
75
+
76
+ error_code = number_of_bytes = FFIBindings.zstd_compress(dst, dst_size, string, string.bytesize, level)
77
+
78
+ if FFIBindings.zstd_is_error(error_code) >= 0
79
+ dst.read_bytes(number_of_bytes)
80
+ else
81
+ raise "error"
82
+ end
83
+ end
84
+
85
+ def self.simple_decompress(string, options = {})
86
+ #
87
+ # The docs state, that one should be carefull when using the simple decompress API, because
88
+ # it relies on the upfront knowledge of the decompressed (dst) size. This information may
89
+ # by present within the frame header (or not). If it's present, it can be very large and/or
90
+ # intentionally modified, so it's vital to check that this value is within the systems limits
91
+ # and fallback to streaming decompression if unsure.
92
+ #
93
+ dst = FFI::MemoryPointer.new(:char, dst_size = API.decompressed_size(string))
94
+ error_code = number_of_bytes = FFIBindings.zstd_decompress(dst, dst_size, string, string.bytesize)
95
+
96
+ if FFIBindings.zstd_is_error(error_code) != 0
97
+ raise FFIBindings.zstd_get_error_name(error_code).read_string
98
+ else
99
+ dst.read_bytes(number_of_bytes)
100
+ end
101
+ end
102
+
103
+ def self.window_size(string)
104
+ if FFIBindings.zstd_version_number < 600
105
+ parameters = FFIBindings::ZSTD_parameters.new
106
+ FFIBindings.zstd_get_frame_params(parameters, string, string.bytesize)
107
+ 2 ** parameters[:windowLog]
108
+ elsif FFIBindings.zstd_version_number < 700
109
+ frame_params = FFIBindings::ZSTD_frameParams.new
110
+ FFIBindings.zstd_get_frame_params(frame_params, string, string.bytesize)
111
+ 2 ** frame_params[:windowLog]
112
+ elsif Zstandard::FFIBindings.zstd_version_number < 10300
113
+ frame_params = FFIBindings::ZSTD_frameParams.new
114
+ FFIBindings.zstd_get_frame_params(frame_params, string, string.bytesize)
115
+ frame_params[:windowSize]
116
+ else
117
+ frame_header = FFIBindings::ZSTD_frameHeader.new
118
+ FFIBindings.zstd_get_frame_header(frame_header, string, string.bytesize)
119
+ frame_header[:windowSize]
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,24 @@
1
+ module Zstandard
2
+ module Config
3
+ LIBRARY_PATH = ENV["ZSTANDARD_LIBRARY"] || "zstd"
4
+
5
+ # Threshold for switching to streaming decompression
6
+ MAX_SIMPLE_DECOMPRESS_SIZE =
7
+ begin
8
+ default = 1024 * 1024 * 32
9
+ env_param = ENV["ZSTANDARD_MAX_SIMPLE_DECOMPRESS_SIZE"].to_i
10
+ env_param > 0 ? env_param : default
11
+ end
12
+ .freeze
13
+
14
+ # Caps the window size of compressed data to prohibit abuse (e.g. by
15
+ # manipulated frame headers). The docs propose to support at least 8MB.
16
+ MAX_STREAMING_DECOMRPESS_BUFFER_SIZE =
17
+ begin
18
+ default = 1024 * 1024 * 8
19
+ env_param = ENV["ZSTANDARD_MAX_STREAMING_DECOMRPESS_BUFFER_SIZE"].to_i
20
+ env_param > 0 ? env_param : default
21
+ end
22
+ .freeze
23
+ end
24
+ end
@@ -0,0 +1,214 @@
1
+ require "ffi"
2
+ require_relative "./config"
3
+
4
+ module Zstandard
5
+ module FFIBindings
6
+ extend FFI::Library
7
+ begin
8
+ ffi_lib Config::LIBRARY_PATH
9
+ rescue LoadError => e
10
+ STDERR.puts "Could not open #{Config::LIBRARY_PATH} shared library!"
11
+ STDERR.puts
12
+ STDERR.puts "Please be sure you have zstd installed. This can be accomplished via"
13
+ STDERR.puts "- your systems package management (e.g. apt-get install zstd)"
14
+ STDERR.puts "- compiled/installed by yourself (use ZSTANDARD_LIBRARY env variable for non-default paths)"
15
+ STDERR.puts
16
+ raise e
17
+ end
18
+
19
+ # this is placed upfront because it's needed for various conditionals
20
+ attach_function :zstd_version_number, :ZSTD_versionNumber, [], :uint
21
+
22
+ raise Zstandard::LibraryVersionNotSupportedError if zstd_version_number < 500
23
+
24
+ #
25
+ # @!group Simple API
26
+ #
27
+
28
+ # @!method self.zstd_compress(dst, dstCapacity, src, srcSize, compressionLevel)
29
+ # @param [void*] dst
30
+ # @param [size_t] dstCapacity
31
+ # @param [const void*] src
32
+ # @param [size_t] srcSize
33
+ # @param [int] compressionLevel
34
+ # @return [size_t] the compressed size
35
+ attach_function :zstd_compress, :ZSTD_compress, [:pointer, :size_t, :pointer, :size_t, :int], :size_t
36
+
37
+
38
+ # @!method self.zstd_compress_bound(srcSize)
39
+ # @param [size_t] srcSize
40
+ # @return [size_t]
41
+ attach_function :zstd_compress_bound, :ZSTD_compressBound, [:size_t], :size_t
42
+
43
+ # @!method self.zstd_decompress(dst, dstCapacity, src, compressedSize)
44
+ # @param [void*] dst
45
+ # @param [size_t] dstCapacity
46
+ # @param [const void*] src
47
+ # @param [size_t] compressedSize
48
+ # @return [size_t] the decompressed size
49
+ attach_function :zstd_decompress, :ZSTD_decompress, [:pointer, :size_t, :pointer, :size_t], :size_t
50
+
51
+ #
52
+ # @!group Buffer-less streaming decompression
53
+ #
54
+
55
+ # @!method self.zstd_create_dctx
56
+ # @return [ZSTD_DCtx*]
57
+ attach_function :zstd_create_dctx, :ZSTD_createDCtx, [], :pointer
58
+
59
+ # @!method self.zstd_decompress_begin(dctx)
60
+ # @param [ZSTD_DCtx*] dctx
61
+ # @return [size_t]
62
+ attach_function :zstd_decompress_begin, :ZSTD_decompressBegin, [:pointer], :size_t
63
+
64
+ # @!method self.zstd_decompress_continue(dctx, dst, dstCapacity, src, srcSize)
65
+ # @param [ZSTD_DCtx*] dctx
66
+ # @param [void*] dst
67
+ # @param [size_t] dstCapacity
68
+ # @param [const void*] src
69
+ # @param [size_t] srcSize
70
+ # @return [size_t]
71
+ attach_function :zstd_decompress_continue, :ZSTD_decompressContinue, [:pointer, :pointer, :size_t, :pointer, :size_t], :size_t
72
+
73
+ # @!method self.zstd_find_decompressed_size
74
+ # @param [const void*] src
75
+ # @param [size_t] srcSize
76
+ # @return [unsigned long long]
77
+ if zstd_version_number >= 10104
78
+ attach_function :zstd_find_decompressed_size, :ZSTD_findDecompressedSize, [:pointer, :size_t], :uint64
79
+ end
80
+
81
+ # @!method self.zstd_free_dctx(dctx)
82
+ # @param [ZSTD_DCtx*] dctx
83
+ # @return [size_t]
84
+ attach_function :zstd_free_dctx, :ZSTD_freeDCtx, [:pointer], :size_t
85
+
86
+ # @!method self.zstd_get_frame_params(fparamsPtr, src, srcSize)
87
+ # @param [ZSTD_parameters,ZSTD_frameParams] fparamsPtr (type depends on the version of `libzstd`, from `>= 0.6.0`, it's {ZSTD_frameParams}, before it's {ZSTD_parameters})
88
+ # @param [const void*] src
89
+ # @param [size_t] srcSize
90
+ # @return [size_t]
91
+ # size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize)
92
+ if zstd_version_number < 10300
93
+ attach_function :zstd_get_frame_params, :ZSTD_getFrameParams, [:pointer, :pointer, :size_t], :size_t
94
+ else
95
+ attach_function :zstd_get_frame_header, :ZSTD_getFrameHeader, [:pointer, :pointer, :size_t], :size_t
96
+ end
97
+
98
+ # @!method zstd_next_src_size_to_deompress(dctx)
99
+ # @param [ZSTD_DCtx*] dctx
100
+ # @return [size_t]
101
+ attach_function :zstd_next_src_size_to_deompress, :ZSTD_nextSrcSizeToDecompress, [:pointer], :size_t
102
+
103
+ #
104
+ # @!group Helpers
105
+ #
106
+
107
+ # @!method zstd_get_error_name(code)
108
+ # @param [size_t] code
109
+ # @return [const char*]
110
+ attach_function :zstd_get_error_name, :ZSTD_getErrorName, [:size_t], :pointer
111
+
112
+ # @!method zstd_is_error(code)
113
+ # @param [size_t] code
114
+ # @return [unsigned] an integer indicating if this is an error code. A value > 0 indicates `true`.
115
+ # unsigned ZSTD_isError(size_t code)
116
+ attach_function :zstd_is_error, :ZSTD_isError, [:size_t], :uint
117
+
118
+ # @!method zstd_version_number
119
+ # @return [uint]
120
+
121
+ # @!endgroup Helpers
122
+
123
+ #
124
+ # (Advanced) types (requires zstd_version_number to be attached for conditionals)
125
+ #
126
+
127
+ if zstd_version_number < 600
128
+ enum :ZSTD_strategy, [:ZSTD_fast, :ZSTD_greedy, :ZSTD_lazy, :ZSTD_lazy2, :ZSTD_btlazy2]
129
+ elsif zstd_version_number < 800
130
+ enum :ZSTD_strategy, [:ZSTD_fast, :ZSTD_greedy, :ZSTD_lazy, :ZSTD_lazy2, :ZSTD_btlazy2, :ZSTD_btopt]
131
+ else
132
+ enum :ZSTD_strategy, [:ZSTD_fast, :ZSTD_dfast, :ZSTD_greedy, :ZSTD_lazy, :ZSTD_lazy2, :ZSTD_btlazy2, :ZSTD_btopt]
133
+ end
134
+
135
+ # The format of this struct depends on the version of `libzstd` you are using.
136
+ #
137
+ # `<= v0.6.x`
138
+ # ```
139
+ # typedef struct {
140
+ # U64 frameContentSize;
141
+ # U32 windowLog;
142
+ # } ZSTD_frameParams;
143
+ # ```
144
+ #
145
+ # `>= v0.7.x`
146
+ # ```
147
+ # typedef struct {
148
+ # unsigned long long frameContentSize;
149
+ # unsigned windowSize;
150
+ # unsigned dictID;
151
+ # unsigned checksumFlag;
152
+ # } ZSTD_frameParams;
153
+ # ```
154
+ if Zstandard::FFIBindings.zstd_version_number < 10300
155
+ class ZSTD_frameParams < FFI::Struct
156
+ # @!method [](member)
157
+ if Zstandard::FFIBindings.zstd_version_number < 700
158
+ # `<= v0.6.x`
159
+ # @overload [](member)
160
+ # @param [:frameContentSize, :windowLog] member
161
+ layout(
162
+ frameContentSize: :uint64,
163
+ windowLog: :uint32
164
+ )
165
+ elsif Zstandard::FFIBindings.zstd_version_number < 800
166
+ # `>= v0.7.x`
167
+ # @overload [](member)
168
+ # @param [:frameContentSize, :windowSize, :dictID, :checksumFlag] member
169
+ layout(
170
+ :frameContentSize, :uint64,
171
+ :windowSize, :uint32,
172
+ :dictID, :uint32,
173
+ :checksumFlag, :uint32
174
+ )
175
+ else
176
+ layout(
177
+ :frameContentSize, :ulong_long,
178
+ :windowSize, :uint,
179
+ :dictID, :uint,
180
+ :checksumFlag, :uint
181
+ )
182
+ end
183
+ end
184
+ else
185
+ class ZSTD_frameHeader < FFI::Struct
186
+ layout(
187
+ :frameContentSize, :ulong_long,
188
+ :windowSize, :uint,
189
+ :dictID, :uint,
190
+ :checksumFlag, :uint
191
+ )
192
+ end
193
+ end
194
+
195
+ class ZSTD_parameters < FFI::Struct
196
+ # @!method[](member)
197
+ if Zstandard::FFIBindings.zstd_version_number < 600
198
+ # `<= v0.5.x`
199
+ # @overload [](member)
200
+ # @param [:srcSize, :windowLog, :contentLog, :hashLog, :searchLog, :searchLength, :targetLength, :strategy]
201
+ layout(
202
+ :srcSize, :uint64,
203
+ :windowLog, :uint32,
204
+ :contentLog, :uint32,
205
+ :hashLog, :uint32,
206
+ :searchLog, :uint32,
207
+ :searchLength, :uint32,
208
+ :targetLength, :uint32,
209
+ :strategy, :ZSTD_strategy
210
+ )
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,3 @@
1
+ module Zstandard
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+
3
+ PROCESSOR_TYPE=$(uname -p)
4
+ DISTRIBUTOR_ID=$(lsb_release -i -s|tr '[:upper:]' '[:lower:]')
5
+ RELEASE=$(lsb_release -r -s)
6
+
7
+ LIBRARIES_DIRECTORY="./spec/libzstd/${PROCESSOR_TYPE}/${DISTRIBUTOR_ID}/${RELEASE}"
8
+
9
+ if [ -d "$LIBRARIES_DIRECTORY" ]; then
10
+ for library in ${LIBRARIES_DIRECTORY}/*
11
+ do
12
+ bundle exec rake ZSTANDARD_LIBRARY=$library
13
+ if [ "$?" -ne "0" ]; then
14
+ exit 1
15
+ fi
16
+ done
17
+ else
18
+ echo "There are no bundled libraries for the current system."
19
+ exit 1
20
+ fi
data/zstandard.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'zstandard/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "zstandard"
8
+ spec.version = Zstandard::VERSION
9
+ spec.authors = ["Michael Sievers"]
10
+ spec.email = ["michael_sievers@web.de"]
11
+ spec.summary = %q{Zstandard compression library bindings}
12
+ spec.homepage = "https://github.com/msievers/zstandard"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features|bin|benchmarks|run_rspec_with_bundled_libraries.sh)/})
17
+ end
18
+
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "ffi", "~> 1.0"
24
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zstandard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Sievers
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-07-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ description:
28
+ email:
29
+ - michael_sievers@web.de
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - ".rspec"
36
+ - ".travis.yml"
37
+ - ".yardopts"
38
+ - Gemfile
39
+ - LICENSE.txt
40
+ - README.md
41
+ - Rakefile
42
+ - lib/zstandard.rb
43
+ - lib/zstandard/api.rb
44
+ - lib/zstandard/config.rb
45
+ - lib/zstandard/ffi_bindings.rb
46
+ - lib/zstandard/version.rb
47
+ - run_rspec_with_bundled_libraries.sh
48
+ - zstandard.gemspec
49
+ homepage: https://github.com/msievers/zstandard
50
+ licenses:
51
+ - MIT
52
+ metadata: {}
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 2.6.11
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Zstandard compression library bindings
73
+ test_files: []