extzstd 0.0.1.CONCEPT

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,102 @@
1
+ /*
2
+ zstd - standard compression library
3
+ Header File
4
+ Copyright (C) 2014-2015, Yann Collet.
5
+
6
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are
10
+ met:
11
+ * Redistributions of source code must retain the above copyright
12
+ notice, this list of conditions and the following disclaimer.
13
+ * Redistributions in binary form must reproduce the above
14
+ copyright notice, this list of conditions and the following disclaimer
15
+ in the documentation and/or other materials provided with the
16
+ distribution.
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ You can contact the author at :
30
+ - zstd source repository : https://github.com/Cyan4973/zstd
31
+ - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
32
+ */
33
+ #pragma once
34
+
35
+ #if defined (__cplusplus)
36
+ extern "C" {
37
+ #endif
38
+
39
+ /**************************************
40
+ * Includes
41
+ **************************************/
42
+ #include <stddef.h> /* size_t */
43
+
44
+
45
+ /**************************************
46
+ * Version
47
+ **************************************/
48
+ #define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */
49
+ #define ZSTD_VERSION_MINOR 0 /* for new (non-breaking) interface capabilities */
50
+ #define ZSTD_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */
51
+ #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
52
+ unsigned ZSTD_versionNumber (void);
53
+
54
+
55
+ /**************************************
56
+ * Simple one-step functions
57
+ **************************************/
58
+ size_t ZSTD_compress( void* dst, size_t maxDstSize,
59
+ const void* src, size_t srcSize);
60
+
61
+ size_t ZSTD_decompress( void* dst, size_t maxOriginalSize,
62
+ const void* src, size_t compressedSize);
63
+
64
+ /*
65
+ ZSTD_compress() :
66
+ Compresses 'srcSize' bytes from buffer 'src' into buffer 'dst', of maximum size 'dstSize'.
67
+ Destination buffer should be sized to handle worst cases situations (input data not compressible).
68
+ Worst case size evaluation is provided by function ZSTD_compressBound().
69
+ return : the number of bytes written into buffer 'dst'
70
+ or an error code if it fails (which can be tested using ZSTD_isError())
71
+
72
+ ZSTD_decompress() :
73
+ compressedSize : is obviously the source size
74
+ maxOriginalSize : is the size of the 'dst' buffer, which must be already allocated.
75
+ It must be equal or larger than originalSize, otherwise decompression will fail.
76
+ return : the number of bytes decompressed into destination buffer (originalSize)
77
+ or an errorCode if it fails (which can be tested using ZSTD_isError())
78
+ */
79
+
80
+
81
+ /**************************************
82
+ * Tool functions
83
+ **************************************/
84
+ size_t ZSTD_compressBound(size_t srcSize); /* maximum compressed size */
85
+
86
+ /* Error Management */
87
+ unsigned ZSTD_isError(size_t code); /* tells if a return value is an error code */
88
+ const char* ZSTD_getErrorName(size_t code); /* provides error code string (useful for debugging) */
89
+
90
+
91
+ #define CHECK_OVERFLOW(statment) \
92
+ do { \
93
+ if (!(statment)) { \
94
+ fprintf(stderr, \
95
+ "%s:%d:%s: detect buffer overflow - assert for (%s)\n", \
96
+ __FILE__, __LINE__, __func__, #statment); \
97
+ } \
98
+ } while (0) \
99
+
100
+ #if defined (__cplusplus)
101
+ }
102
+ #endif
@@ -0,0 +1,80 @@
1
+ /*
2
+ zstd - standard compression library
3
+ Header File for static linking only
4
+ Copyright (C) 2014-2015, Yann Collet.
5
+
6
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are
10
+ met:
11
+ * Redistributions of source code must retain the above copyright
12
+ notice, this list of conditions and the following disclaimer.
13
+ * Redistributions in binary form must reproduce the above
14
+ copyright notice, this list of conditions and the following disclaimer
15
+ in the documentation and/or other materials provided with the
16
+ distribution.
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ You can contact the author at :
30
+ - zstd source repository : https://github.com/Cyan4973/zstd
31
+ - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
32
+ */
33
+ #pragma once
34
+
35
+ #if defined (__cplusplus)
36
+ extern "C" {
37
+ #endif
38
+
39
+ /**************************************
40
+ * Includes
41
+ **************************************/
42
+ #include "zstd.h"
43
+
44
+
45
+ /**************************************
46
+ * Streaming functions
47
+ **************************************/
48
+ typedef void* ZSTD_cctx_t;
49
+ ZSTD_cctx_t ZSTD_createCCtx(void);
50
+ size_t ZSTD_freeCCtx(ZSTD_cctx_t cctx);
51
+
52
+ size_t ZSTD_compressBegin(ZSTD_cctx_t cctx, void* dst, size_t maxDstSize);
53
+ size_t ZSTD_compressContinue(ZSTD_cctx_t cctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
54
+ size_t ZSTD_compressEnd(ZSTD_cctx_t cctx, void* dst, size_t maxDstSize);
55
+
56
+ typedef void* ZSTD_dctx_t;
57
+ ZSTD_dctx_t ZSTD_createDCtx(void);
58
+ size_t ZSTD_freeDCtx(ZSTD_dctx_t dctx);
59
+
60
+ size_t ZSTD_getNextcBlockSize(ZSTD_dctx_t dctx);
61
+ size_t ZSTD_decompressContinue(ZSTD_dctx_t dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
62
+
63
+
64
+ /**************************************
65
+ * Error management
66
+ **************************************/
67
+ #define ZSTD_LIST_ERRORS(ITEM) \
68
+ ITEM(ZSTD_OK_NoError) ITEM(ZSTD_ERROR_GENERIC) \
69
+ ITEM(ZSTD_ERROR_wrongMagicNumber) \
70
+ ITEM(ZSTD_ERROR_wrongSrcSize) ITEM(ZSTD_ERROR_maxDstSize_tooSmall) \
71
+ ITEM(ZSTD_ERROR_wrongLBlockSize) \
72
+ ITEM(ZSTD_ERROR_maxCode)
73
+
74
+ #define ZSTD_GENERATE_ENUM(ENUM) ENUM,
75
+ typedef enum { ZSTD_LIST_ERRORS(ZSTD_GENERATE_ENUM) } ZSTD_errorCodes; /* exposed list of errors; static linking only */
76
+
77
+
78
+ #if defined (__cplusplus)
79
+ }
80
+ #endif
data/ext/extconf.rb ADDED
@@ -0,0 +1,17 @@
1
+ #!ruby
2
+ #vim: set fileencoding:utf-8
3
+
4
+ require "mkmf"
5
+
6
+ dir = File.dirname(__FILE__).gsub(/[\[\{\?\*]/, "[\\0]")
7
+ filepattern = "{.,../contrib/zstd}/*.c"
8
+ target = File.join(dir, filepattern)
9
+ files = Dir.glob(target).map { |n| File.basename n }
10
+ files.reject! { |n| "/contrib/zstd/fse.c".include?(n) }
11
+ $srcs = files
12
+
13
+ $VPATH.push "$(srcdir)/../contrib/zstd"
14
+
15
+ find_header "zstd.h", "$(srcdir)/../contrib/zstd"
16
+
17
+ create_makefile("extzstd")
@@ -0,0 +1,219 @@
1
+ #include "extzstd.h"
2
+
3
+ VALUE cEncoder;
4
+ ID id_op_lshift;
5
+
6
+ struct zstdencoder
7
+ {
8
+ VALUE outport;
9
+ VALUE destbuf;
10
+ ZSTD_cctx_t encoder;
11
+ };
12
+
13
+ static void
14
+ zstdenc_mark(void *pp)
15
+ {
16
+ if (pp) {
17
+ struct zstdencoder *p = pp;
18
+ rb_gc_mark(p->outport);
19
+ rb_gc_mark(p->destbuf);
20
+ }
21
+ }
22
+
23
+ static void
24
+ zstdenc_free(void *pp)
25
+ {
26
+ if (pp) {
27
+ struct zstdencoder *p = pp;
28
+ if (p->encoder) {
29
+ ZSTD_freeCCtx(p->encoder);
30
+ }
31
+ if (!NIL_P(p->destbuf)) {
32
+ rb_str_resize(p->destbuf, 0);
33
+ }
34
+ free(p);
35
+ }
36
+ }
37
+
38
+ static const rb_data_type_t zstdencoder_type = {
39
+ .wrap_struct_name = "extzstd.Zstd.Encoder",
40
+ .function.dmark = zstdenc_mark,
41
+ .function.dfree = zstdenc_free,
42
+ /* .function.dsize = zstdenc_size, */
43
+ };
44
+
45
+
46
+ static VALUE
47
+ zstdenc_alloc(VALUE klass)
48
+ {
49
+ struct zstdencoder *p;
50
+ VALUE v = TypedData_Make_Struct(klass, struct zstdencoder, &zstdencoder_type, p);
51
+ p->outport = Qnil;
52
+ p->destbuf = Qnil;
53
+ p->encoder = NULL;
54
+ return v;
55
+ }
56
+
57
+ static inline struct zstdencoder *
58
+ getencoderp(VALUE enc)
59
+ {
60
+ return getrefp(enc, &zstdencoder_type);
61
+ }
62
+
63
+ static inline struct zstdencoder *
64
+ getencoder(VALUE enc)
65
+ {
66
+ return getref(enc, &zstdencoder_type);
67
+ }
68
+
69
+ static inline void
70
+ zstdenc_init_args(int argc, VALUE argv[], VALUE *outport)
71
+ {
72
+ rb_scan_args(argc, argv, "01", outport);
73
+ if (NIL_P(*outport)) {
74
+ *outport = rb_str_buf_new(0);
75
+ }
76
+ }
77
+
78
+ /*
79
+ * call-seq:
80
+ * initialize(outport) -> self
81
+ */
82
+ static VALUE
83
+ zstdenc_init(int argc, VALUE argv[], VALUE senc)
84
+ {
85
+ struct zstdencoder *p = getencoder(senc);
86
+ if (p->encoder) { reiniterror(senc); }
87
+ zstdenc_init_args(argc, argv, &p->outport);
88
+ p->destbuf = rb_str_buf_new(4 * 1024); /* FIXME: ``4 * 1024`` to constant value */
89
+ p->encoder = ZSTD_createCCtx();
90
+ if (!p->encoder) {
91
+ rb_raise(eError,
92
+ "failed ZSTD_createCCtx()");
93
+ }
94
+
95
+ size_t destsize = rb_str_capacity(p->destbuf);
96
+ //rb_str_resize(p->destbuf, destsize); /* FIXME: rb_str_resize は縮小もするので、できれば rb_str_modify_expand をつかう */
97
+
98
+ size_t s = ZSTD_compressBegin(p->encoder, RSTRING_PTR(p->destbuf), destsize);
99
+ if (ZSTD_isError(s)) {
100
+ rb_raise(eError,
101
+ "failed ZSTD_compressBegin() - %s (%d)",
102
+ ZSTD_getErrorName(s), (int)s);
103
+ }
104
+
105
+ if (s > destsize) {
106
+ rb_bug("detect buffer overflow from in ZSTD_compressBegin() (destbuf.bytesize=%d, returned bytesize=%d)",
107
+ (int)RSTRING_LEN(p->destbuf), (int)s);
108
+ }
109
+
110
+ rb_str_set_len(p->destbuf, s);
111
+ rb_funcall2(p->outport, id_op_lshift, 1, &p->destbuf);
112
+
113
+ return senc;
114
+ }
115
+
116
+ /*
117
+ * call-seq:
118
+ * write(src) -> self
119
+ */
120
+ static VALUE
121
+ zstdenc_write(int argc, VALUE argv[], VALUE senc)
122
+ {
123
+ struct zstdencoder *p = getencoder(senc);
124
+ if (!p->encoder) { referror(senc); }
125
+
126
+ VALUE src;
127
+ rb_scan_args(argc, argv, "1", &src);
128
+ rb_check_type(src, RUBY_T_STRING);
129
+
130
+ size_t destsize = ZSTD_compressBound(RSTRING_LEN(src)) + 64; /* FIXME: おそらくストリームブロックヘッダのようなものがくっつく */
131
+ rb_str_modify(p->destbuf);
132
+ rb_str_set_len(p->destbuf, 0);
133
+ rb_str_modify_expand(p->destbuf, destsize);
134
+
135
+ size_t s = ZSTD_compressContinue(p->encoder, RSTRING_PTR(p->destbuf), destsize, RSTRING_PTR(src), RSTRING_LEN(src));
136
+ if (ZSTD_isError(s)) {
137
+ rb_raise(eError,
138
+ "failed ZSTD_compressContinue() - %s (%d)",
139
+ ZSTD_getErrorName(s), (int)s);
140
+ }
141
+
142
+ if (s > destsize) {
143
+ rb_bug("detect buffer overflow from in ZSTD_compressContinue() (destbuf.bytesize=%d, returned bytesize=%d)",
144
+ (int)RSTRING_LEN(p->destbuf), (int)s);
145
+ }
146
+
147
+ rb_str_set_len(p->destbuf, s);
148
+ rb_funcall2(p->outport, id_op_lshift, 1, &p->destbuf);
149
+
150
+ return senc;
151
+ }
152
+
153
+ /*
154
+ * call-seq:
155
+ * finish -> self
156
+ */
157
+ static VALUE
158
+ zstdenc_finish(int argc, VALUE argv[], VALUE senc)
159
+ {
160
+ struct zstdencoder *p = getencoder(senc);
161
+ if (!p->encoder) { referror(senc); }
162
+
163
+ rb_scan_args(argc, argv, "0");
164
+
165
+ size_t destsize = 64; /* FIXME: ストリームフッターはどのくらい? */
166
+ rb_str_modify(p->destbuf);
167
+ rb_str_set_len(p->destbuf, 0);
168
+ rb_str_modify_expand(p->destbuf, destsize);
169
+
170
+ size_t s = ZSTD_compressEnd(p->encoder, RSTRING_PTR(p->destbuf), destsize);
171
+ if (ZSTD_isError(s)) {
172
+ rb_raise(eError,
173
+ "failed ZSTD_compressEnd() - %s (%d)",
174
+ ZSTD_getErrorName(s), (int)s);
175
+ }
176
+
177
+ if (s > destsize) {
178
+ rb_bug("detect buffer overflow from in ZSTD_compressEnd() (destbuf.bytesize=%d, returned bytesize=%d)",
179
+ (int)RSTRING_LEN(p->destbuf), (int)s);
180
+ }
181
+
182
+ rb_str_set_len(p->destbuf, s);
183
+ rb_funcall2(p->outport, id_op_lshift, 1, &p->destbuf);
184
+
185
+ return senc;
186
+ }
187
+
188
+ static VALUE
189
+ zstdenc_getoutport(VALUE enc)
190
+ {
191
+ return getencoder(enc)->outport;
192
+ }
193
+
194
+ static VALUE
195
+ zstdenc_setoutport(VALUE enc, VALUE outport)
196
+ {
197
+ return getencoder(enc)->outport = outport;
198
+ }
199
+
200
+ void
201
+ init_extzstd_stream(void)
202
+ {
203
+ id_op_lshift = rb_intern("<<");
204
+
205
+ cEncoder = rb_define_class_under(mZstd, "Encoder", rb_cObject);
206
+ rb_define_alloc_func(cEncoder, zstdenc_alloc);
207
+ rb_define_method(cEncoder, "initialize", RUBY_METHOD_FUNC(zstdenc_init), -1);
208
+ rb_define_method(cEncoder, "write", RUBY_METHOD_FUNC(zstdenc_write), -1);
209
+ rb_define_method(cEncoder, "finish", RUBY_METHOD_FUNC(zstdenc_finish), -1);
210
+ rb_define_method(cEncoder, "outport", RUBY_METHOD_FUNC(zstdenc_getoutport), 0);
211
+ rb_define_method(cEncoder, "outport=", RUBY_METHOD_FUNC(zstdenc_setoutport), 1);
212
+ /*
213
+ cStreamDecoder = rb_define_class_under(mZstd, "StreamDecoder", rb_cObject);
214
+ rb_define_alloc_func(cStreamDecoder, zstdenc_alloc);
215
+ rb_define_method(cStreamDecoder, "initialize", RUBY_METHOD_FUNC(ext_sdec_init), -1);
216
+ rb_define_method(cStreamDecoder, "read", RUBY_METHOD_FUNC(ext_sdec_read), -1);
217
+ rb_define_method(cStreamDecoder, "finish", RUBY_METHOD_FUNC(ext_sdec_finish), -1);
218
+ */
219
+ }
data/ext/extzstd.c ADDED
@@ -0,0 +1,134 @@
1
+ #include "extzstd.h"
2
+
3
+ VALUE mZstd;
4
+ VALUE eError;
5
+
6
+ static inline void
7
+ zstd_encode_args(int argc, VALUE argv[], VALUE *src, VALUE *dest, size_t *maxsize)
8
+ {
9
+ switch (argc) {
10
+ case 1:
11
+ *src = argv[0];
12
+ rb_check_type(*src, RUBY_T_STRING);
13
+ *maxsize = ZSTD_compressBound(RSTRING_LEN(*src));
14
+ *dest = rb_str_buf_new(*maxsize);
15
+ return;
16
+ case 2:
17
+ *src = argv[0];
18
+ rb_check_type(*src, RUBY_T_STRING);
19
+ *dest = argv[1];
20
+ if (rb_type_p(*dest, RUBY_T_STRING)) {
21
+ *maxsize = ZSTD_compressBound(RSTRING_LEN(*src));
22
+ rb_str_resize(*dest, *maxsize);
23
+ } else {
24
+ *maxsize = NUM2SIZET(*dest);
25
+ *dest = rb_str_buf_new(*maxsize);
26
+ }
27
+ return;
28
+ case 3:
29
+ *src = argv[0];
30
+ rb_check_type(*src, RUBY_T_STRING);
31
+ *maxsize = NUM2SIZET(argv[1]);
32
+ *dest = argv[2];
33
+ rb_check_type(*dest, RUBY_T_STRING);
34
+ rb_str_resize(*dest, *maxsize);
35
+ return;
36
+ default:
37
+ rb_error_arity(argc, 1, 3);
38
+ }
39
+ }
40
+
41
+ /*
42
+ * call-seq:
43
+ * encode(src) -> encoded string
44
+ * encode(src, size) -> encoded string
45
+ * encode(src, dest) -> dest with encoded string
46
+ * encode(src, size, dest) -> dest with encoded string
47
+ */
48
+ static VALUE
49
+ zstd_encode(int argc, VALUE argv[], VALUE mod)
50
+ {
51
+ VALUE src, dest;
52
+ size_t maxsize;
53
+ zstd_encode_args(argc, argv, &src, &dest, &maxsize);
54
+ const char *srcp;
55
+ size_t srcsize;
56
+ RSTRING_GETMEM(src, srcp, srcsize);
57
+ size_t s = ZSTD_compress(RSTRING_PTR(dest), maxsize, srcp, srcsize);
58
+ if (ZSTD_isError(s)) {
59
+ rb_raise(eError,
60
+ "%s:%d:%s: ZSTD_compress error - %s (%d)",
61
+ __FILE__, __LINE__, __func__,
62
+ ZSTD_getErrorName(s), (int)s);
63
+ }
64
+ if (s > maxsize) {
65
+ rb_bug("%s:%d:%s: detect buffer overflow in ZSTD_compress - maxsize is %zd, but returned size is %zd",
66
+ __FILE__, __LINE__, __func__, maxsize, s);
67
+ }
68
+ rb_str_set_len(dest, s);
69
+ return dest;
70
+ }
71
+
72
+ static inline void
73
+ zstd_decode_args(int argc, VALUE argv[], VALUE *src, VALUE *dest, size_t *maxsize)
74
+ {
75
+ switch (argc) {
76
+ case 2:
77
+ *src = argv[0];
78
+ rb_check_type(*src, RUBY_T_STRING);
79
+ *maxsize = NUM2SIZET(argv[1]);
80
+ *dest = rb_str_buf_new(*maxsize);
81
+ return;
82
+ case 3:
83
+ *src = argv[0];
84
+ rb_check_type(*src, RUBY_T_STRING);
85
+ *maxsize = NUM2SIZET(argv[1]);
86
+ *dest = argv[2];
87
+ rb_check_type(*dest, RUBY_T_STRING);
88
+ rb_str_resize(*dest, *maxsize);
89
+ return;
90
+ default:
91
+ rb_error_arity(argc, 2, 3);
92
+ }
93
+ }
94
+
95
+ /*
96
+ * call-seq:
97
+ * decode(src, size) -> decoded string
98
+ * decode(src, size, dest) -> dest with decoded string
99
+ */
100
+ static VALUE
101
+ zstd_decode(int argc, VALUE argv[], VALUE mod)
102
+ {
103
+ VALUE src, dest;
104
+ size_t maxsize;
105
+ zstd_decode_args(argc, argv, &src, &dest, &maxsize);
106
+ const char *srcp;
107
+ size_t srcsize;
108
+ RSTRING_GETMEM(src, srcp, srcsize);
109
+ size_t s = ZSTD_decompress(RSTRING_PTR(dest), maxsize, srcp, srcsize);
110
+ if (ZSTD_isError(s)) {
111
+ rb_raise(eError,
112
+ "%s:%d:%s: ZSTD_compress error - %s (%d)",
113
+ __FILE__, __LINE__, __func__,
114
+ ZSTD_getErrorName(s), (int)s);
115
+ }
116
+ if (s > maxsize) {
117
+ rb_bug("%s:%d:%s: detect buffer overflow in ZSTD_compress - maxsize is %zd, but returned size is %zd",
118
+ __FILE__, __LINE__, __func__, maxsize, s);
119
+ }
120
+ rb_str_set_len(dest, s);
121
+ return dest;
122
+ }
123
+
124
+ void
125
+ Init_extzstd(void)
126
+ {
127
+ mZstd = rb_define_module("Zstd");
128
+ rb_define_singleton_method(mZstd, "encode", RUBY_METHOD_FUNC(zstd_encode), -1);
129
+ rb_define_singleton_method(mZstd, "decode", RUBY_METHOD_FUNC(zstd_decode), -1);
130
+
131
+ eError = rb_define_class_under(mZstd, "Error", rb_eRuntimeError);
132
+
133
+ init_extzstd_stream();
134
+ }
data/ext/extzstd.h ADDED
@@ -0,0 +1,52 @@
1
+ #ifndef EXTZSTD_H
2
+ #define EXTZSTD_H 1
3
+
4
+ #include <ruby.h>
5
+ #include <zstd.h>
6
+ #include <zstd_static.h>
7
+
8
+ extern VALUE mZstd;
9
+ extern VALUE cStreamEncoder;
10
+ extern VALUE cStreamDecoder;
11
+ extern VALUE eError;
12
+
13
+ void init_extzstd_stream(void);
14
+
15
+ static inline void
16
+ referror(VALUE v)
17
+ {
18
+ rb_raise(rb_eRuntimeError,
19
+ "invalid reference - not initialized yet (#<%s:%p>)",
20
+ rb_obj_classname(v), (void *)v);
21
+ }
22
+
23
+ static inline void
24
+ reiniterror(VALUE v)
25
+ {
26
+ rb_raise(rb_eRuntimeError,
27
+ "already initialized (#<%s:%p>)",
28
+ rb_obj_classname(v), (void *)v);
29
+ }
30
+
31
+ static inline void *
32
+ checkref(VALUE v, void *p)
33
+ {
34
+ if (!p) { referror(v); }
35
+ return p;
36
+ }
37
+
38
+ static inline void *
39
+ getrefp(VALUE v, const rb_data_type_t *type)
40
+ {
41
+ void *p;
42
+ TypedData_Get_Struct(v, void, type, p);
43
+ return p;
44
+ }
45
+
46
+ static inline void *
47
+ getref(VALUE v, const rb_data_type_t *type)
48
+ {
49
+ return checkref(v, getrefp(v, type));
50
+ }
51
+
52
+ #endif /* !EXTZSTD_H */
data/gemstub.rb ADDED
@@ -0,0 +1,19 @@
1
+ require_relative "lib/extzstd/version"
2
+
3
+ GEMSTUB = Gem::Specification.new do |s|
4
+ s.name = "extzstd"
5
+ s.version = Zstd::VERSION
6
+ s.summary = "ruby bindings for Zstandard (zstd)"
7
+ s.description = <<EOS
8
+ ruby bindings for Zstandard (zstd) <https://github.com/Cyan4973/zstd>.
9
+ EOS
10
+ s.homepage = "http://sourceforge.jp/projects/rutsubo/"
11
+ s.license = "2-clause BSD License"
12
+ s.author = "dearblue"
13
+ s.email = "dearblue@users.sourceforge.jp"
14
+
15
+ s.required_ruby_version = ">= 2.0"
16
+ s.add_development_dependency "rake", "~> 10.0"
17
+ end
18
+
19
+ EXTRA.concat(FileList["contrib/**/*"])
@@ -0,0 +1,5 @@
1
+ require "rubygems"
2
+
3
+ module Zstd
4
+ VERSION = Gem::Version.new("0.0.1.CONCEPT")
5
+ end
data/lib/extzstd.rb ADDED
@@ -0,0 +1,12 @@
1
+ #vim: set fileencoding:utf-8
2
+
3
+ ver = RbConfig::CONFIG["ruby_version"]
4
+ soname = File.basename(__FILE__, ".rb") << ".so"
5
+ lib = File.join(File.dirname(__FILE__), ver, soname)
6
+ if File.file?(lib)
7
+ require_relative File.join(ver, soname)
8
+ else
9
+ require_relative soname
10
+ end
11
+
12
+ require_relative "extzstd/version"