ruby-lzws 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/LICENSE +21 -0
- data/README.md +188 -0
- data/ext/extconf.rb +77 -0
- data/ext/lzws_ext/common.h +9 -0
- data/ext/lzws_ext/error.c +14 -0
- data/ext/lzws_ext/error.h +11 -0
- data/ext/lzws_ext/io.c +92 -0
- data/ext/lzws_ext/io.h +12 -0
- data/ext/lzws_ext/macro.h +15 -0
- data/ext/lzws_ext/main.c +42 -0
- data/ext/lzws_ext/option.c +22 -0
- data/ext/lzws_ext/option.h +60 -0
- data/ext/lzws_ext/stream/compressor.c +217 -0
- data/ext/lzws_ext/stream/compressor.h +27 -0
- data/ext/lzws_ext/stream/decompressor.c +206 -0
- data/ext/lzws_ext/stream/decompressor.h +26 -0
- data/ext/lzws_ext/string.c +78 -0
- data/ext/lzws_ext/string.h +12 -0
- data/lib/lzws/error.rb +20 -0
- data/lib/lzws/file.rb +56 -0
- data/lib/lzws/option.rb +66 -0
- data/lib/lzws/stream/abstract.rb +153 -0
- data/lib/lzws/stream/delegates.rb +36 -0
- data/lib/lzws/stream/raw/abstract.rb +46 -0
- data/lib/lzws/stream/raw/compressor.rb +100 -0
- data/lib/lzws/stream/raw/decompressor.rb +78 -0
- data/lib/lzws/stream/reader.rb +163 -0
- data/lib/lzws/stream/reader_helpers.rb +192 -0
- data/lib/lzws/stream/stat.rb +78 -0
- data/lib/lzws/stream/writer.rb +145 -0
- data/lib/lzws/stream/writer_helpers.rb +93 -0
- data/lib/lzws/string.rb +27 -0
- data/lib/lzws/validation.rb +36 -0
- data/lib/lzws/version.rb +6 -0
- data/lib/lzws.rb +4 -0
- metadata +163 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5e42a999e18187b07931b4c7127274339f8d6eb61490d2c3bcd504180c674d43
|
4
|
+
data.tar.gz: 8516d4a94686aeeb2587fcb6bd862dc85ff651ac6e71ae0449e3797a85653f78
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c8f80f27ac4b2e12bc3628468b94bbebe5b00b688a6dc586013797b5eabb8a1a85da39fdd2ba5d48ed81d71d77df463800f6ef8c285d41bf057c1d306ed2727
|
7
|
+
data.tar.gz: f4ced4337b346873836d004c57ca6411f62ba604d32a69001658db3705c4098f1a938e23c2242092bd76e645792824daeba93680ea3d3da5c4529872279095cc
|
data/AUTHORS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Andrew Aladjev
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2019 AUTHORS
|
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 all
|
13
|
+
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 THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
# Ruby bindings for lzws library
|
2
|
+
|
3
|
+
[![Travis build status](https://travis-ci.org/andrew-aladev/ruby-lzws.svg?branch=master)](https://travis-ci.org/andrew-aladev/ruby-lzws)
|
4
|
+
[![AppVeyor build status](https://ci.appveyor.com/api/projects/status/github/andrew-aladev/ruby-lzws?branch=master&svg=true)](https://ci.appveyor.com/project/andrew-aladev/ruby-lzws/branch/master)
|
5
|
+
|
6
|
+
See [lzws library](https://github.com/andrew-aladev/lzws).
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Please install lzws library first.
|
11
|
+
|
12
|
+
```sh
|
13
|
+
gem install ruby-lzws
|
14
|
+
```
|
15
|
+
|
16
|
+
You can build it from source.
|
17
|
+
|
18
|
+
```sh
|
19
|
+
rake gem
|
20
|
+
gem install pkg/ruby-lzws-*.gem
|
21
|
+
```
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
There are simple APIs: `String` and `File`. Also you can use generic streaming API: `Stream::Writer` and `Stream::Reader`.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require "lzws"
|
29
|
+
|
30
|
+
data = LZWS::String.compress "TOBEORNOTTOBEORTOBEORNOT"
|
31
|
+
puts LZWS::String.decompress(data)
|
32
|
+
|
33
|
+
LZWS::File.compress "file.txt", "file.txt.Z"
|
34
|
+
LZWS::File.decompress "file.txt.Z", "file.txt"
|
35
|
+
|
36
|
+
LZWS::Stream::Writer.open("file.txt.Z") { |writer| writer << "TOBEORNOTTOBEORTOBEORNOT" }
|
37
|
+
puts LZWS::Stream::Reader.open("file.txt.Z") { |reader| reader.read }
|
38
|
+
```
|
39
|
+
|
40
|
+
You can create and read `tar.Z` archives with `minitar` for example.
|
41
|
+
LZWS is fully compatible with UNIX compress (with default options).
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
require "lzws"
|
45
|
+
require "minitar"
|
46
|
+
|
47
|
+
LZWS::Stream::Writer.open "file.tar.Z" do |writer|
|
48
|
+
Minitar::Writer.open writer do |tar|
|
49
|
+
tar.add_file_simple "file", :data => "TOBEORNOTTOBEORTOBEORNOT"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
LZWS::Stream::Reader.open "file.tar.Z" do |reader|
|
54
|
+
Minitar::Reader.open reader do |tar|
|
55
|
+
tar.each_entry do |entry|
|
56
|
+
puts entry.name
|
57
|
+
puts entry.read
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Each API supports additional options, please read lzws docs for more info.
|
64
|
+
|
65
|
+
Compressor:
|
66
|
+
|
67
|
+
```
|
68
|
+
:max_code_bit_length
|
69
|
+
:block_mode
|
70
|
+
:buffer_length
|
71
|
+
:without_magic_header
|
72
|
+
:msb
|
73
|
+
:unaligned_bit_groups
|
74
|
+
:quiet
|
75
|
+
```
|
76
|
+
|
77
|
+
Decompressor:
|
78
|
+
|
79
|
+
```
|
80
|
+
:buffer_length
|
81
|
+
:without_magic_header
|
82
|
+
:msb
|
83
|
+
:unaligned_bit_groups
|
84
|
+
:quiet
|
85
|
+
```
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
require "lzws"
|
89
|
+
|
90
|
+
data = LZWS::String.compress "TOBEORNOTTOBEORTOBEORNOT", :msb => true
|
91
|
+
puts LZWS::String.decompress(data, :msb => true)
|
92
|
+
```
|
93
|
+
|
94
|
+
You can use `Content-Encoding: compress`.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
require "lzws"
|
98
|
+
require "sinatra"
|
99
|
+
|
100
|
+
get "/" do
|
101
|
+
headers["Content-Encoding"] = "compress"
|
102
|
+
LZWS::String.compress "TOBEORNOTTOBEORTOBEORNOT"
|
103
|
+
end
|
104
|
+
```
|
105
|
+
|
106
|
+
## Docs
|
107
|
+
|
108
|
+
`LZWS::String`:
|
109
|
+
|
110
|
+
```
|
111
|
+
::compress(source, options = {})
|
112
|
+
::decompress(source, options = {})
|
113
|
+
```
|
114
|
+
|
115
|
+
`LZWS::File`:
|
116
|
+
|
117
|
+
```
|
118
|
+
::compress(source, destination, options = {})
|
119
|
+
::decompress(source, destination, options = {})
|
120
|
+
```
|
121
|
+
|
122
|
+
`LZWS::Stream::Writer` and `LZWS::Stream::Reader`:
|
123
|
+
|
124
|
+
```
|
125
|
+
::open(file_path, options = {}, :external_encoding => nil, :internal_encoding => nil, &block)
|
126
|
+
#io
|
127
|
+
#stat
|
128
|
+
#external_encoding
|
129
|
+
#internal_encoding
|
130
|
+
#pos
|
131
|
+
#tell
|
132
|
+
#advise
|
133
|
+
#set_encoding(external_encoding, internal_encoding, transcode_options)
|
134
|
+
#rewind
|
135
|
+
#close
|
136
|
+
#closed?
|
137
|
+
#to_io
|
138
|
+
```
|
139
|
+
|
140
|
+
`Stream::Writer`:
|
141
|
+
|
142
|
+
```
|
143
|
+
::new(destination_io, options = {}, :external_encoding => nil)
|
144
|
+
#write(*objects)
|
145
|
+
#flush
|
146
|
+
#write_nonblock(object, *options)
|
147
|
+
#flush_nonblock(*options)
|
148
|
+
#rewind_nonblock(*options)
|
149
|
+
#close_nonblock(*options)
|
150
|
+
#<<(object)
|
151
|
+
#print(*objects)
|
152
|
+
#printf(*args)
|
153
|
+
#putc(object, encoding: ::Encoding::BINARY)
|
154
|
+
#puts(*objects)
|
155
|
+
```
|
156
|
+
|
157
|
+
`Stream::Reader`:
|
158
|
+
|
159
|
+
```
|
160
|
+
::new(source_io, options = {}, :external_encoding => nil, :internal_encoding => nil)
|
161
|
+
#lineno
|
162
|
+
#lineno=
|
163
|
+
#read(bytes_to_read = nil, out_buffer = nil)
|
164
|
+
#readpartial(bytes_to_read = nil, out_buffer = nil)
|
165
|
+
#read_nonblock(bytes_to_read, out_buffer = nil, *options)
|
166
|
+
#eof?
|
167
|
+
#getbyte
|
168
|
+
#each_byte(&block)
|
169
|
+
#readbyte
|
170
|
+
#ungetbyte(byte)
|
171
|
+
#getc
|
172
|
+
#readchar
|
173
|
+
#each_char(&block)
|
174
|
+
#ungetc(char)
|
175
|
+
#gets(separator = $OUTPUT_RECORD_SEPARATOR, limit = nil)
|
176
|
+
#readline
|
177
|
+
#readlines
|
178
|
+
#each(&block)
|
179
|
+
#each_line(&block)
|
180
|
+
#ungetline(line)
|
181
|
+
```
|
182
|
+
|
183
|
+
`LZWS::Stream::Writer` and `LZWS::Stream::Reader` behaviour is the same as builtin [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.6.3/libdoc/zlib/rdoc/Zlib/GzipReader.html), [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.6.3/libdoc/zlib/rdoc/Zlib/GzipWriter.html) and [`IO`](https://ruby-doc.org/core-2.6.3/IO.html).
|
184
|
+
Please read these method descriptions in ruby doc.
|
185
|
+
|
186
|
+
## License
|
187
|
+
|
188
|
+
MIT license, see LICENSE and AUTHORS.
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# Ruby bindings for lzws library.
|
2
|
+
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
require "mkmf"
|
5
|
+
|
6
|
+
def require_header(name)
|
7
|
+
abort "Can't find #{name} header" unless find_header name
|
8
|
+
end
|
9
|
+
|
10
|
+
require_header "lzws/buffer.h"
|
11
|
+
require_header "lzws/compressor/common.h"
|
12
|
+
require_header "lzws/compressor/header.h"
|
13
|
+
require_header "lzws/compressor/main.h"
|
14
|
+
require_header "lzws/compressor/state.h"
|
15
|
+
require_header "lzws/decompressor/common.h"
|
16
|
+
require_header "lzws/decompressor/header.h"
|
17
|
+
require_header "lzws/decompressor/main.h"
|
18
|
+
require_header "lzws/decompressor/state.h"
|
19
|
+
require_header "lzws/file.h"
|
20
|
+
require_header "lzws/string.h"
|
21
|
+
|
22
|
+
def require_library(name, functions)
|
23
|
+
functions.each do |function|
|
24
|
+
abort "Can't find #{name} library and #{function} function" unless find_library name, function
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
functions = %w[
|
29
|
+
lzws_create_buffer_for_compressor
|
30
|
+
lzws_create_buffer_for_decompressor
|
31
|
+
lzws_resize_buffer
|
32
|
+
|
33
|
+
lzws_compress_string
|
34
|
+
lzws_decompress_string
|
35
|
+
|
36
|
+
lzws_compress_file
|
37
|
+
lzws_decompress_file
|
38
|
+
|
39
|
+
lzws_compressor_write_magic_header
|
40
|
+
lzws_compressor_get_initial_state
|
41
|
+
lzws_compress
|
42
|
+
lzws_flush_compressor
|
43
|
+
lzws_compressor_free_state
|
44
|
+
|
45
|
+
lzws_decompressor_read_magic_header
|
46
|
+
lzws_decompressor_get_initial_state
|
47
|
+
lzws_decompress
|
48
|
+
lzws_decompressor_free_state
|
49
|
+
]
|
50
|
+
.freeze
|
51
|
+
|
52
|
+
require_library "lzws", functions
|
53
|
+
|
54
|
+
extension_name = "lzws_ext".freeze
|
55
|
+
dir_config extension_name
|
56
|
+
|
57
|
+
sources = %w[
|
58
|
+
stream/compressor
|
59
|
+
stream/decompressor
|
60
|
+
error
|
61
|
+
io
|
62
|
+
main
|
63
|
+
option
|
64
|
+
string
|
65
|
+
]
|
66
|
+
.freeze
|
67
|
+
|
68
|
+
# rubocop:disable Style/GlobalVars
|
69
|
+
$srcs = sources
|
70
|
+
.map { |name| "src/#{extension_name}/#{name}.c" }
|
71
|
+
.freeze
|
72
|
+
|
73
|
+
$CFLAGS << " -Wno-declaration-after-statement"
|
74
|
+
$VPATH << "$(srcdir)/#{extension_name}:$(srcdir)/#{extension_name}/stream"
|
75
|
+
# rubocop:enable Style/GlobalVars
|
76
|
+
|
77
|
+
create_makefile extension_name
|
@@ -0,0 +1,14 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
#include "lzws_ext/common.h"
|
7
|
+
#include "lzws_ext/error.h"
|
8
|
+
|
9
|
+
void lzws_ext_raise_error(const char* name, const char* description)
|
10
|
+
{
|
11
|
+
VALUE module = rb_define_module(LZWS_EXT_MODULE_NAME);
|
12
|
+
VALUE error = rb_const_get(module, rb_intern(name));
|
13
|
+
rb_raise(error, "%s", description);
|
14
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#if !defined(LZWS_EXT_ERROR_H)
|
5
|
+
#define LZWS_EXT_ERROR_H
|
6
|
+
|
7
|
+
#include "ruby.h"
|
8
|
+
|
9
|
+
NORETURN(void lzws_ext_raise_error(const char* name, const char* description));
|
10
|
+
|
11
|
+
#endif // LZWS_EXT_ERROR_H
|
data/ext/lzws_ext/io.c
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#include <lzws/file.h>
|
5
|
+
|
6
|
+
#include "ruby.h"
|
7
|
+
#include "ruby/io.h"
|
8
|
+
|
9
|
+
#include "lzws_ext/error.h"
|
10
|
+
#include "lzws_ext/io.h"
|
11
|
+
#include "lzws_ext/macro.h"
|
12
|
+
#include "lzws_ext/option.h"
|
13
|
+
|
14
|
+
#define GET_FILE(target) \
|
15
|
+
Check_Type(target, T_FILE); \
|
16
|
+
\
|
17
|
+
rb_io_t *target##_io; \
|
18
|
+
GetOpenFile(target, target##_io); \
|
19
|
+
\
|
20
|
+
FILE *target##_file = rb_io_stdio_file(target##_io); \
|
21
|
+
if (target##_file == NULL) { \
|
22
|
+
lzws_ext_raise_error("AccessIOError", "failed to access IO"); \
|
23
|
+
}
|
24
|
+
|
25
|
+
VALUE lzws_ext_compress_io(VALUE LZWS_EXT_UNUSED(self), VALUE source, VALUE destination, VALUE options)
|
26
|
+
{
|
27
|
+
GET_FILE(source);
|
28
|
+
GET_FILE(destination);
|
29
|
+
LZWS_EXT_GET_COMPRESSOR_OPTIONS(options);
|
30
|
+
|
31
|
+
lzws_result_t result = lzws_compress_file(
|
32
|
+
source_file, buffer_length,
|
33
|
+
destination_file, buffer_length,
|
34
|
+
without_magic_header, max_code_bit_length, block_mode, msb, unaligned_bit_groups, quiet);
|
35
|
+
|
36
|
+
if (result == LZWS_FILE_ALLOCATE_FAILED) {
|
37
|
+
lzws_ext_raise_error("AllocateError", "allocate error");
|
38
|
+
}
|
39
|
+
else if (result == LZWS_FILE_VALIDATE_FAILED) {
|
40
|
+
lzws_ext_raise_error("ValidateError", "validate error");
|
41
|
+
}
|
42
|
+
else if (result == LZWS_FILE_READ_FAILED) {
|
43
|
+
lzws_ext_raise_error("ReadIOError", "failed to read IO");
|
44
|
+
}
|
45
|
+
else if (result == LZWS_FILE_WRITE_FAILED) {
|
46
|
+
lzws_ext_raise_error("WriteIOError", "failed to write IO");
|
47
|
+
}
|
48
|
+
else if (result != 0) {
|
49
|
+
lzws_ext_raise_error("UnexpectedError", "unexpected error");
|
50
|
+
}
|
51
|
+
|
52
|
+
// Ruby itself won't flush stdio file before closing fd, flush is required.
|
53
|
+
fflush(destination_file);
|
54
|
+
|
55
|
+
return Qnil;
|
56
|
+
}
|
57
|
+
|
58
|
+
VALUE lzws_ext_decompress_io(VALUE LZWS_EXT_UNUSED(self), VALUE source, VALUE destination, VALUE options)
|
59
|
+
{
|
60
|
+
GET_FILE(source);
|
61
|
+
GET_FILE(destination);
|
62
|
+
LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
|
63
|
+
|
64
|
+
lzws_result_t result = lzws_decompress_file(
|
65
|
+
source_file, buffer_length,
|
66
|
+
destination_file, buffer_length,
|
67
|
+
without_magic_header, msb, unaligned_bit_groups, quiet);
|
68
|
+
|
69
|
+
if (result == LZWS_FILE_ALLOCATE_FAILED) {
|
70
|
+
lzws_ext_raise_error("AllocateError", "allocate error");
|
71
|
+
}
|
72
|
+
else if (result == LZWS_FILE_VALIDATE_FAILED) {
|
73
|
+
lzws_ext_raise_error("ValidateError", "validate error");
|
74
|
+
}
|
75
|
+
else if (result == LZWS_FILE_DECOMPRESSOR_CORRUPTED_SOURCE) {
|
76
|
+
lzws_ext_raise_error("DecompressorCorruptedSourceError", "decompressor received corrupted source");
|
77
|
+
}
|
78
|
+
else if (result == LZWS_FILE_READ_FAILED) {
|
79
|
+
lzws_ext_raise_error("ReadIOError", "failed to read IO");
|
80
|
+
}
|
81
|
+
else if (result == LZWS_FILE_WRITE_FAILED) {
|
82
|
+
lzws_ext_raise_error("WriteIOError", "failed to write IO");
|
83
|
+
}
|
84
|
+
else if (result != 0) {
|
85
|
+
lzws_ext_raise_error("UnexpectedError", "unexpected error");
|
86
|
+
}
|
87
|
+
|
88
|
+
// Ruby itself won't flush stdio file before closing fd, flush is required.
|
89
|
+
fflush(destination_file);
|
90
|
+
|
91
|
+
return Qnil;
|
92
|
+
}
|
data/ext/lzws_ext/io.h
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#if !defined(LZWS_EXT_IO_H)
|
5
|
+
#define LZWS_EXT_IO_H
|
6
|
+
|
7
|
+
#include "ruby.h"
|
8
|
+
|
9
|
+
VALUE lzws_ext_compress_io(VALUE self, VALUE source, VALUE destination, VALUE options);
|
10
|
+
VALUE lzws_ext_decompress_io(VALUE self, VALUE source, VALUE destination, VALUE options);
|
11
|
+
|
12
|
+
#endif // LZWS_EXT_IO_H
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#if !defined(LZWS_EXT_MACRO_H)
|
5
|
+
#define LZWS_EXT_MACRO_H
|
6
|
+
|
7
|
+
#if defined(__GNUC__)
|
8
|
+
#define LZWS_EXT_UNUSED(x) x __attribute__((__unused__))
|
9
|
+
#else
|
10
|
+
#define LZWS_EXT_UNUSED(x) x
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#define LZWS_EXT_UNUSED_VARIABLE(x) (void)(x)
|
14
|
+
|
15
|
+
#endif // LZWS_EXT_MACRO_H
|
data/ext/lzws_ext/main.c
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
#include "lzws_ext/common.h"
|
7
|
+
#include "lzws_ext/io.h"
|
8
|
+
#include "lzws_ext/stream/compressor.h"
|
9
|
+
#include "lzws_ext/stream/decompressor.h"
|
10
|
+
#include "lzws_ext/string.h"
|
11
|
+
|
12
|
+
void Init_lzws_ext()
|
13
|
+
{
|
14
|
+
VALUE root = rb_define_module(LZWS_EXT_MODULE_NAME);
|
15
|
+
|
16
|
+
// It is better to use these functions internally and prepare pretty wrappers for public usage.
|
17
|
+
rb_define_module_function(root, "_native_compress_io", RUBY_METHOD_FUNC(lzws_ext_compress_io), 3);
|
18
|
+
rb_define_module_function(root, "_native_decompress_io", RUBY_METHOD_FUNC(lzws_ext_decompress_io), 3);
|
19
|
+
rb_define_module_function(root, "_native_compress_string", RUBY_METHOD_FUNC(lzws_ext_compress_string), 2);
|
20
|
+
rb_define_module_function(root, "_native_decompress_string", RUBY_METHOD_FUNC(lzws_ext_decompress_string), 2);
|
21
|
+
|
22
|
+
// -----
|
23
|
+
|
24
|
+
VALUE stream = rb_define_module_under(root, "Stream");
|
25
|
+
|
26
|
+
VALUE compressor = rb_define_class_under(stream, "NativeCompressor", rb_cObject);
|
27
|
+
rb_define_alloc_func(compressor, lzws_ext_allocate_compressor);
|
28
|
+
rb_define_method(compressor, "initialize", lzws_ext_initialize_compressor, 1);
|
29
|
+
rb_define_method(compressor, "write_magic_header", lzws_ext_compressor_write_magic_header, 0);
|
30
|
+
rb_define_method(compressor, "write", lzws_ext_compress, 1);
|
31
|
+
rb_define_method(compressor, "flush", lzws_ext_flush_compressor, 0);
|
32
|
+
rb_define_method(compressor, "read_result", lzws_ext_compressor_read_result, 0);
|
33
|
+
rb_define_method(compressor, "close", lzws_ext_compressor_close, 0);
|
34
|
+
|
35
|
+
VALUE decompressor = rb_define_class_under(stream, "NativeDecompressor", rb_cObject);
|
36
|
+
rb_define_alloc_func(decompressor, lzws_ext_allocate_decompressor);
|
37
|
+
rb_define_method(decompressor, "initialize", lzws_ext_initialize_decompressor, 1);
|
38
|
+
rb_define_method(decompressor, "read_magic_header", lzws_ext_decompressor_read_magic_header, 1);
|
39
|
+
rb_define_method(decompressor, "read", lzws_ext_decompress, 1);
|
40
|
+
rb_define_method(decompressor, "read_result", lzws_ext_decompressor_read_result, 0);
|
41
|
+
rb_define_method(decompressor, "close", lzws_ext_decompressor_close, 0);
|
42
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
#include "lzws_ext/option.h"
|
7
|
+
|
8
|
+
VALUE lzws_ext_get_option(VALUE options, const char* name)
|
9
|
+
{
|
10
|
+
VALUE name_symbol = ID2SYM(rb_intern(name));
|
11
|
+
return rb_funcall(options, rb_intern("[]"), 1, name_symbol);
|
12
|
+
}
|
13
|
+
|
14
|
+
void lzws_ext_check_bool_type(VALUE option, const char* name)
|
15
|
+
{
|
16
|
+
int type = TYPE(option);
|
17
|
+
|
18
|
+
if (type != T_TRUE && type != T_FALSE) {
|
19
|
+
VALUE message = rb_sprintf("wrong value for \"%s\" (expected true or false)", name);
|
20
|
+
rb_exc_raise(rb_exc_new_str(rb_eFatal, message));
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#if !defined(LZWS_EXT_OPTIONS_H)
|
5
|
+
#define LZWS_EXT_OPTIONS_H
|
6
|
+
|
7
|
+
#include "ruby.h"
|
8
|
+
|
9
|
+
VALUE lzws_ext_get_option(VALUE options, const char* name);
|
10
|
+
void lzws_ext_check_bool_type(VALUE option, const char* name);
|
11
|
+
|
12
|
+
#define LZWS_EXT_GET_COMPRESSOR_OPTIONS(options) \
|
13
|
+
Check_Type(options, T_HASH); \
|
14
|
+
\
|
15
|
+
VALUE buffer_length_value = lzws_ext_get_option(options, "buffer_length"); \
|
16
|
+
VALUE without_magic_header_value = lzws_ext_get_option(options, "without_magic_header"); \
|
17
|
+
VALUE max_code_bit_length_value = lzws_ext_get_option(options, "max_code_bit_length"); \
|
18
|
+
VALUE block_mode_value = lzws_ext_get_option(options, "block_mode"); \
|
19
|
+
VALUE msb_value = lzws_ext_get_option(options, "msb"); \
|
20
|
+
VALUE unaligned_bit_groups_value = lzws_ext_get_option(options, "unaligned_bit_groups"); \
|
21
|
+
VALUE quiet_value = lzws_ext_get_option(options, "quiet"); \
|
22
|
+
\
|
23
|
+
Check_Type(buffer_length_value, T_FIXNUM); \
|
24
|
+
lzws_ext_check_bool_type(without_magic_header_value, "without_magic_header"); \
|
25
|
+
Check_Type(max_code_bit_length_value, T_FIXNUM); \
|
26
|
+
lzws_ext_check_bool_type(block_mode_value, "block_mode"); \
|
27
|
+
lzws_ext_check_bool_type(msb_value, "msb"); \
|
28
|
+
lzws_ext_check_bool_type(unaligned_bit_groups_value, "unaligned_bit_groups"); \
|
29
|
+
lzws_ext_check_bool_type(quiet_value, "quiet"); \
|
30
|
+
\
|
31
|
+
size_t buffer_length = rb_num2uint(buffer_length_value); \
|
32
|
+
bool without_magic_header = TYPE(without_magic_header_value) == T_TRUE; \
|
33
|
+
uint_fast8_t max_code_bit_length = rb_num2uint(max_code_bit_length_value); \
|
34
|
+
bool block_mode = TYPE(block_mode_value) == T_TRUE; \
|
35
|
+
bool msb = TYPE(msb_value) == T_TRUE; \
|
36
|
+
bool unaligned_bit_groups = TYPE(unaligned_bit_groups_value) == T_TRUE; \
|
37
|
+
bool quiet = TYPE(quiet_value) == T_TRUE;
|
38
|
+
|
39
|
+
#define LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options) \
|
40
|
+
Check_Type(options, T_HASH); \
|
41
|
+
\
|
42
|
+
VALUE buffer_length_value = lzws_ext_get_option(options, "buffer_length"); \
|
43
|
+
VALUE without_magic_header_value = lzws_ext_get_option(options, "without_magic_header"); \
|
44
|
+
VALUE msb_value = lzws_ext_get_option(options, "msb"); \
|
45
|
+
VALUE unaligned_bit_groups_value = lzws_ext_get_option(options, "unaligned_bit_groups"); \
|
46
|
+
VALUE quiet_value = lzws_ext_get_option(options, "quiet"); \
|
47
|
+
\
|
48
|
+
Check_Type(buffer_length_value, T_FIXNUM); \
|
49
|
+
lzws_ext_check_bool_type(without_magic_header_value, "without_magic_header"); \
|
50
|
+
lzws_ext_check_bool_type(msb_value, "msb"); \
|
51
|
+
lzws_ext_check_bool_type(unaligned_bit_groups_value, "unaligned_bit_groups"); \
|
52
|
+
lzws_ext_check_bool_type(quiet_value, "quiet"); \
|
53
|
+
\
|
54
|
+
size_t buffer_length = rb_num2uint(buffer_length_value); \
|
55
|
+
bool without_magic_header = TYPE(without_magic_header_value) == T_TRUE; \
|
56
|
+
bool msb = TYPE(msb_value) == T_TRUE; \
|
57
|
+
bool unaligned_bit_groups = TYPE(unaligned_bit_groups_value) == T_TRUE; \
|
58
|
+
bool quiet = TYPE(quiet_value) == T_TRUE;
|
59
|
+
|
60
|
+
#endif // LZWS_EXT_OPTIONS_H
|