extzstd 0.0.3.CONCEPT → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.ja.md +39 -0
  3. data/LICENSE +6 -6
  4. data/README.md +26 -45
  5. data/contrib/zstd/CHANGELOG +555 -0
  6. data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
  7. data/contrib/zstd/CONTRIBUTING.md +392 -0
  8. data/contrib/zstd/COPYING +339 -0
  9. data/contrib/zstd/LICENSE +13 -9
  10. data/contrib/zstd/Makefile +414 -0
  11. data/contrib/zstd/README.md +170 -45
  12. data/contrib/zstd/TESTING.md +44 -0
  13. data/contrib/zstd/appveyor.yml +289 -0
  14. data/contrib/zstd/lib/BUCK +234 -0
  15. data/contrib/zstd/lib/Makefile +354 -0
  16. data/contrib/zstd/lib/README.md +179 -0
  17. data/contrib/zstd/{common → lib/common}/bitstream.h +170 -130
  18. data/contrib/zstd/lib/common/compiler.h +175 -0
  19. data/contrib/zstd/lib/common/cpu.h +215 -0
  20. data/contrib/zstd/lib/common/debug.c +24 -0
  21. data/contrib/zstd/lib/common/debug.h +114 -0
  22. data/contrib/zstd/{common → lib/common}/entropy_common.c +79 -94
  23. data/contrib/zstd/lib/common/error_private.c +55 -0
  24. data/contrib/zstd/lib/common/error_private.h +80 -0
  25. data/contrib/zstd/{common → lib/common}/fse.h +153 -93
  26. data/contrib/zstd/{common → lib/common}/fse_decompress.c +37 -82
  27. data/contrib/zstd/lib/common/huf.h +340 -0
  28. data/contrib/zstd/{common → lib/common}/mem.h +154 -78
  29. data/contrib/zstd/lib/common/pool.c +344 -0
  30. data/contrib/zstd/lib/common/pool.h +84 -0
  31. data/contrib/zstd/lib/common/threading.c +121 -0
  32. data/contrib/zstd/lib/common/threading.h +155 -0
  33. data/contrib/zstd/{common → lib/common}/xxhash.c +85 -75
  34. data/contrib/zstd/{common → lib/common}/xxhash.h +85 -73
  35. data/contrib/zstd/lib/common/zstd_common.c +83 -0
  36. data/contrib/zstd/lib/common/zstd_errors.h +94 -0
  37. data/contrib/zstd/lib/common/zstd_internal.h +447 -0
  38. data/contrib/zstd/{compress → lib/compress}/fse_compress.c +194 -303
  39. data/contrib/zstd/lib/compress/hist.c +183 -0
  40. data/contrib/zstd/lib/compress/hist.h +75 -0
  41. data/contrib/zstd/lib/compress/huf_compress.c +798 -0
  42. data/contrib/zstd/lib/compress/zstd_compress.c +4278 -0
  43. data/contrib/zstd/lib/compress/zstd_compress_internal.h +1125 -0
  44. data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
  45. data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
  46. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +419 -0
  47. data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
  48. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +845 -0
  49. data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
  50. data/contrib/zstd/lib/compress/zstd_cwksp.h +525 -0
  51. data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
  52. data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
  53. data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
  54. data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
  55. data/contrib/zstd/lib/compress/zstd_lazy.c +1138 -0
  56. data/contrib/zstd/lib/compress/zstd_lazy.h +67 -0
  57. data/contrib/zstd/lib/compress/zstd_ldm.c +619 -0
  58. data/contrib/zstd/lib/compress/zstd_ldm.h +110 -0
  59. data/contrib/zstd/lib/compress/zstd_opt.c +1200 -0
  60. data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
  61. data/contrib/zstd/lib/compress/zstdmt_compress.c +2143 -0
  62. data/contrib/zstd/lib/compress/zstdmt_compress.h +192 -0
  63. data/contrib/zstd/lib/decompress/huf_decompress.c +1248 -0
  64. data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
  65. data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
  66. data/contrib/zstd/lib/decompress/zstd_decompress.c +1885 -0
  67. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1432 -0
  68. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +59 -0
  69. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +189 -0
  70. data/contrib/zstd/{common → lib/deprecated}/zbuff.h +86 -69
  71. data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
  72. data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
  73. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
  74. data/contrib/zstd/lib/dictBuilder/cover.c +1236 -0
  75. data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
  76. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
  77. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +5 -5
  78. data/contrib/zstd/lib/dictBuilder/fastcover.c +757 -0
  79. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +437 -347
  80. data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
  81. data/contrib/zstd/lib/legacy/zstd_legacy.h +415 -0
  82. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +272 -292
  83. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +26 -32
  84. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +162 -392
  85. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +26 -32
  86. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +162 -391
  87. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +27 -33
  88. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +195 -604
  89. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +26 -32
  90. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +300 -575
  91. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +22 -31
  92. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +165 -592
  93. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +54 -67
  94. data/contrib/zstd/lib/legacy/zstd_v07.c +4541 -0
  95. data/contrib/zstd/lib/legacy/zstd_v07.h +187 -0
  96. data/contrib/zstd/lib/libzstd.pc.in +15 -0
  97. data/contrib/zstd/lib/zstd.h +2090 -0
  98. data/ext/depend +2 -0
  99. data/ext/extconf.rb +18 -5
  100. data/ext/extzstd.c +296 -214
  101. data/ext/extzstd.h +81 -36
  102. data/ext/extzstd_nogvls.h +0 -117
  103. data/ext/extzstd_stream.c +622 -0
  104. data/ext/libzstd_conf.h +8 -0
  105. data/ext/zstd_common.c +11 -0
  106. data/ext/zstd_compress.c +15 -0
  107. data/ext/zstd_decompress.c +6 -0
  108. data/ext/zstd_dictbuilder.c +10 -0
  109. data/ext/zstd_dictbuilder_fastcover.c +3 -0
  110. data/ext/zstd_legacy_v01.c +3 -1
  111. data/ext/zstd_legacy_v02.c +3 -1
  112. data/ext/zstd_legacy_v03.c +3 -1
  113. data/ext/zstd_legacy_v04.c +3 -1
  114. data/ext/zstd_legacy_v05.c +3 -1
  115. data/ext/zstd_legacy_v06.c +3 -1
  116. data/ext/zstd_legacy_v07.c +3 -0
  117. data/gemstub.rb +27 -21
  118. data/lib/extzstd.rb +82 -161
  119. data/lib/extzstd/version.rb +1 -1
  120. data/test/test_basic.rb +19 -6
  121. metadata +127 -59
  122. data/contrib/zstd/common/error_private.h +0 -125
  123. data/contrib/zstd/common/error_public.h +0 -77
  124. data/contrib/zstd/common/huf.h +0 -228
  125. data/contrib/zstd/common/zstd.h +0 -475
  126. data/contrib/zstd/common/zstd_common.c +0 -91
  127. data/contrib/zstd/common/zstd_internal.h +0 -238
  128. data/contrib/zstd/compress/huf_compress.c +0 -577
  129. data/contrib/zstd/compress/zbuff_compress.c +0 -327
  130. data/contrib/zstd/compress/zstd_compress.c +0 -3074
  131. data/contrib/zstd/compress/zstd_opt.h +0 -1046
  132. data/contrib/zstd/decompress/huf_decompress.c +0 -894
  133. data/contrib/zstd/decompress/zbuff_decompress.c +0 -294
  134. data/contrib/zstd/decompress/zstd_decompress.c +0 -1362
  135. data/contrib/zstd/dictBuilder/zdict.h +0 -113
  136. data/contrib/zstd/legacy/zstd_legacy.h +0 -140
  137. data/ext/extzstd_buffered.c +0 -265
  138. data/ext/zstd_amalgam.c +0 -18
@@ -2,8 +2,10 @@
2
2
  #define EXTZSTD_H 1
3
3
 
4
4
  #define ZSTD_LEGACY_SUPPORT 1
5
- #define ZBUFF_STATIC_LINKING_ONLY 1
6
- #include <zbuff.h>
5
+ #define ZDICT_STATIC_LINKING_ONLY 1
6
+ //#define ZSTD_STATIC_LINKING_ONLY 1
7
+ #include <common/zstd_internal.h> /* for MIN() */
8
+ #include <zstd.h>
7
9
  #include <stdarg.h>
8
10
  #include <ruby.h>
9
11
  #include <ruby/thread.h>
@@ -23,38 +25,21 @@ extern VALUE extzstd_mZstd;
23
25
  RDOCFAKE(extzstd_mZstd = rb_define_module("Zstd"));
24
26
 
25
27
  extern VALUE extzstd_cParams;
26
- RDOCFAKE(extzstd_cParams = rb_define_class_under(extzstd_mZstd, "EncodeParameters", rb_cObject));
28
+ RDOCFAKE(extzstd_cParams = rb_define_class_under(extzstd_mZstd, "Parameters", rb_cObject));
27
29
 
28
30
  extern VALUE extzstd_mExceptions;
29
31
  extern VALUE extzstd_eError;
30
- extern VALUE extzstd_eGenericError;
31
- extern VALUE extzstd_ePrefixUnknownError;
32
- extern VALUE extzstd_eFrameParameterUnsupportedError;
33
- extern VALUE extzstd_eFrameParameterUnsupportedBy32bitsError;
34
- extern VALUE extzstd_eCompressionParameterUnsupportedError;
35
- extern VALUE extzstd_eInitMissingError;
36
- extern VALUE extzstd_eMemoryAllocationError;
37
- extern VALUE extzstd_eStageWrongError;
38
- extern VALUE extzstd_eDstSizeTooSmallError;
39
- extern VALUE extzstd_eSrcSizeWrongError;
40
- extern VALUE extzstd_eCorruptionDetectedError;
41
- extern VALUE extzstd_eChecksumWrongError;
42
- extern VALUE extzstd_eTableLogTooLargeError;
43
- extern VALUE extzstd_eMaxSymbolValueTooLargeError;
44
- extern VALUE extzstd_eMaxSymbolValueTooSmallError;
45
- extern VALUE extzstd_eDictionaryCorruptedError;
46
- extern VALUE extzstd_eDictionaryWrongError;
47
-
48
32
 
49
33
  extern void init_extzstd_stream(void);
50
34
  extern void extzstd_init_buffered(void);
35
+ extern void extzstd_init_stream(void);
51
36
  extern void extzstd_error(ssize_t errcode);
52
37
  extern void extzstd_check_error(ssize_t errcode);
53
38
  extern VALUE extzstd_make_error(ssize_t errcode);
54
- extern VALUE extzstd_make_errorf(VALUE exc, const char *fmt, ...);
39
+ extern VALUE extzstd_make_errorf(ssize_t errcode, const char *fmt, ...);
55
40
 
56
- extern ZSTD_parameters *extzstd_getencparams(VALUE v);
57
- extern int extzstd_encparams_p(VALUE v);
41
+ extern ZSTD_parameters *extzstd_getparams(VALUE v);
42
+ extern int extzstd_params_p(VALUE v);
58
43
  extern VALUE extzstd_params_alloc(ZSTD_parameters **p);
59
44
 
60
45
  static inline void
@@ -161,7 +146,7 @@ aux_num2int_u64(VALUE v, uint64_t default_value)
161
146
  }
162
147
 
163
148
  static inline VALUE
164
- aux_const_dig_str_0(VALUE obj, const char *p[], const char *pp)
149
+ aux_const_dig_str_0(VALUE obj, const char *p[], const char **pp)
165
150
  {
166
151
  for (; p < pp; p ++) {
167
152
  obj = rb_const_get(obj, rb_intern(*p));
@@ -169,16 +154,76 @@ aux_const_dig_str_0(VALUE obj, const char *p[], const char *pp)
169
154
  return obj;
170
155
  }
171
156
 
172
- #define aux_const_dig_str(OBJ, ...) \
173
- ({ \
174
- const char *names__[] = { __VA_ARGS__ }; \
175
- aux_const_dig_str_0((OBJ), names__, ENDOF(names__)); \
176
- }) \
177
-
178
- #define AUX_TUPLE(...) \
179
- ({ \
180
- VALUE v__[] = { __VA_ARGS__ }; \
181
- rb_ary_new4(ELEMENTOF(v__), v__); \
182
- }) \
157
+ #define aux_const_dig_str(OBJ, ...) \
158
+ aux_const_dig_str_0((OBJ), \
159
+ ((const char *[]){ __VA_ARGS__ }), \
160
+ ENDOF(((const char *[]){ __VA_ARGS__ }))) \
161
+
162
+ #define AUX_TUPLE(...) \
163
+ rb_ary_new4(ELEMENTOF(((VALUE[]) { __VA_ARGS__ })), \
164
+ ((VALUE[]) { __VA_ARGS__ })) \
165
+
166
+ #define AUX_FUNCALL(RECV, MID, ...) \
167
+ rb_funcall2((RECV), (MID), \
168
+ ELEMENTOF(((const VALUE[]){ __VA_ARGS__ })), \
169
+ ((const VALUE[]){ __VA_ARGS__ })) \
170
+
171
+ #define AUX_TRY_WITH_GC(cond, mesg) \
172
+ do { \
173
+ if (!(cond)) { \
174
+ rb_gc(); \
175
+ if (!(cond)) { \
176
+ errno = ENOMEM; \
177
+ rb_sys_fail(mesg); \
178
+ } \
179
+ } \
180
+ } while (0) \
181
+
182
+ #if defined _WIN32 || defined __CYGWIN__
183
+ # define RBEXT_IMPORT __declspec(dllimport)
184
+ # define RBEXT_EXPORT __declspec(dllexport)
185
+ # define RBEXT_LOCAL
186
+ #elif defined(__GNUC__) && __GNUC__ >= 4 || defined(__clang__)
187
+ # define RBEXT_IMPORT __attribute__((visibility("default")))
188
+ # define RBEXT_EXPORT __attribute__((visibility("default")))
189
+ # define RBEXT_LOCAL __attribute__((visibility("hidden")))
190
+ #else
191
+ # define RBEXT_IMPORT
192
+ # define RBEXT_EXPORT
193
+ # define RBEXT_LOCAL
194
+ #endif
195
+
196
+ #ifndef RBEXT_API
197
+ # define RBEXT_API RBEXT_EXPORT
198
+ #endif
199
+
200
+
201
+ static void
202
+ aux_string_pointer(VALUE str, const char **ptr, size_t *size)
203
+ {
204
+ rb_check_type(str, RUBY_T_STRING);
205
+ RSTRING_GETMEM(str, *ptr, *size);
206
+ }
207
+
208
+ static void
209
+ aux_string_pointer_with_nil(VALUE str, const char **ptr, size_t *size)
210
+ {
211
+ if (NIL_P(str)) {
212
+ *ptr = NULL;
213
+ *size = 0;
214
+ } else {
215
+ aux_string_pointer(str, ptr, size);
216
+ }
217
+ }
218
+
219
+ static void
220
+ aux_string_expand_pointer(VALUE str, char **ptr, size_t size)
221
+ {
222
+ rb_check_type(str, RUBY_T_STRING);
223
+ rb_str_modify(str);
224
+ rb_str_set_len(str, 0);
225
+ rb_str_modify_expand(str, size);
226
+ *ptr = RSTRING_PTR(str);
227
+ }
183
228
 
184
229
  #endif /* EXTZSTD_H */
@@ -54,121 +54,4 @@ aux_ZSTD_decompress(char *dest, size_t destsize, const char *src, size_t srcsize
54
54
  dest, destsize, src, srcsize);
55
55
  }
56
56
 
57
- static void *
58
- aux_ZBUFF_compressInit_nogvl(va_list *vp)
59
- {
60
- ZBUFF_CCtx *p = va_arg(*vp, ZBUFF_CCtx *);
61
- const void *dict = va_arg(*vp, const void *);
62
- size_t dictsize = va_arg(*vp, size_t);
63
- int level = va_arg(*vp, int);
64
- return (void *)ZBUFF_compressInitDictionary(p, dict, dictsize, level);
65
- }
66
-
67
- static inline size_t
68
- aux_ZBUFF_compressInitDictionary(ZBUFF_CCtx *p, const void* dict, size_t dictsize, int level)
69
- {
70
- return (size_t)aux_thread_call_without_gvl(
71
- aux_ZBUFF_compressInit_nogvl, NULL, p, dict, dictsize, level);
72
- }
73
-
74
- static inline void *
75
- aux_ZBUFF_compressInit_advanced_nogvl(va_list *vp)
76
- {
77
- ZBUFF_CCtx *p = va_arg(*vp, ZBUFF_CCtx *);
78
- const void *dict = va_arg(*vp, const void *);
79
- size_t dictsize = va_arg(*vp, size_t);
80
- const ZSTD_parameters *q = va_arg(*vp, const ZSTD_parameters *);
81
- unsigned long long pledgedsrcsize = va_arg(*vp, unsigned long long);
82
- return (void *)ZBUFF_compressInit_advanced(p, dict, dictsize, *q, pledgedsrcsize);
83
- }
84
-
85
- static inline size_t
86
- aux_ZBUFF_compressInit_advanced(ZBUFF_CCtx *p, const void *dict, size_t dictsize, const ZSTD_parameters *q, unsigned long long pledgedsrcsize)
87
- {
88
- return (size_t)aux_thread_call_without_gvl(
89
- aux_ZBUFF_compressInit_advanced_nogvl, NULL, p, dict, dictsize, q, pledgedsrcsize);
90
- }
91
-
92
- static inline void *
93
- aux_ZBUFF_compressContinue_nogvl(va_list *vp)
94
- {
95
- ZBUFF_CCtx *p = va_arg(*vp, ZBUFF_CCtx *);
96
- char *destp = va_arg(*vp, char *);
97
- size_t *destsize = va_arg(*vp, size_t *);
98
- const char *srcp = va_arg(*vp, const char *);
99
- size_t *srcsize = va_arg(*vp, size_t *);
100
- return (void *)ZBUFF_compressContinue(p, destp, destsize, srcp, srcsize);
101
- }
102
-
103
- static inline size_t
104
- aux_ZBUFF_compressContinue(ZBUFF_CCtx *p, char *destp, size_t *destsize, const char *srcp, size_t *srcsize)
105
- {
106
- return (size_t)aux_thread_call_without_gvl(
107
- aux_ZBUFF_compressContinue_nogvl, NULL, p, destp, destsize, srcp, srcsize);
108
- }
109
-
110
- static inline void *
111
- aux_ZBUFF_compressFlush_nogvl(va_list *vp)
112
- {
113
- ZBUFF_CCtx *p = va_arg(*vp, ZBUFF_CCtx *);
114
- char *destp = va_arg(*vp, char *);
115
- size_t *destsize = va_arg(*vp, size_t *);
116
- return (void *)ZBUFF_compressFlush(p, destp, destsize);
117
- }
118
-
119
- static inline size_t
120
- aux_ZBUFF_compressFlush(ZBUFF_CCtx *p, char *destp, size_t *destsize)
121
- {
122
- return (size_t)aux_thread_call_without_gvl(
123
- aux_ZBUFF_compressFlush_nogvl, NULL, p, destp, destsize);
124
- }
125
-
126
- static inline void *
127
- aux_ZBUFF_compressEnd_nogvl(va_list *vp)
128
- {
129
- ZBUFF_CCtx *p = va_arg(*vp, ZBUFF_CCtx *);
130
- char *destp = va_arg(*vp, char *);
131
- size_t *destsize = va_arg(*vp, size_t *);
132
- return (void *)ZBUFF_compressEnd(p, destp, destsize);
133
- }
134
-
135
- static inline size_t
136
- aux_ZBUFF_compressEnd(ZBUFF_CCtx *p, char *destp, size_t *destsize)
137
- {
138
- return (size_t)aux_thread_call_without_gvl(
139
- aux_ZBUFF_compressEnd_nogvl, NULL, p, destp, destsize);
140
- }
141
-
142
- static inline void *
143
- aux_ZBUFF_decompressInit_nogvl(va_list *vp)
144
- {
145
- ZBUFF_DCtx *p = va_arg(*vp, ZBUFF_DCtx *);
146
- return (void *)ZBUFF_decompressInit(p);
147
- }
148
-
149
- static inline size_t
150
- aux_ZBUFF_decompressInit(ZBUFF_DCtx *p)
151
- {
152
- return (size_t)aux_thread_call_without_gvl(
153
- aux_ZBUFF_decompressInit_nogvl, NULL, p);
154
- }
155
-
156
- static inline void *
157
- aux_ZBUFF_decompressContinue_nogvl(va_list *vp)
158
- {
159
- ZBUFF_DCtx *p = va_arg(*vp, ZBUFF_DCtx *);
160
- char *destp = va_arg(*vp, char *);
161
- size_t *destsize = va_arg(*vp, size_t *);
162
- const char *srcp = va_arg(*vp, const char *);
163
- size_t *srcsize = va_arg(*vp, size_t *);
164
- return (void *)ZBUFF_decompressContinue(p, destp, destsize, srcp, srcsize);
165
- }
166
-
167
- static inline size_t
168
- aux_ZBUFF_decompressContinue(ZBUFF_DCtx *p, char *destp, size_t *destsize, const char *srcp, size_t *srcsize)
169
- {
170
- return (size_t)aux_thread_call_without_gvl(
171
- aux_ZBUFF_decompressContinue_nogvl, NULL, p, destp, destsize, srcp, srcsize);
172
- }
173
-
174
57
  #endif /* EXTZSTD_NOGVLS_H */
@@ -0,0 +1,622 @@
1
+ #include "extzstd.h"
2
+ #include "extzstd_nogvls.h"
3
+ #include <errno.h>
4
+
5
+ enum {
6
+ EXT_PARTIAL_READ_SIZE = 256 * 1024, /* 256 KiB */
7
+ EXT_READ_GROWUP_SIZE = 256 * 1024, /* 256 KiB */
8
+ EXT_READ_DOUBLE_GROWUP_LIMIT_SIZE = 4 * 1024 * 1024, /* 4 MiB */
9
+ };
10
+
11
+ static inline VALUE
12
+ aux_str_buf_recycle(VALUE str, size_t capacity)
13
+ {
14
+ if (!RTEST(str) || rb_obj_frozen_p(str) || !rb_type_p(str, RUBY_T_STRING)) {
15
+ return rb_str_buf_new(capacity);
16
+ } else {
17
+ return aux_str_modify_expand(str, capacity);
18
+ }
19
+ }
20
+
21
+ static ID id_op_lsh, id_read;
22
+
23
+ /*
24
+ * class Zstd::Encoder
25
+ */
26
+
27
+ static VALUE cStreamEncoder;
28
+
29
+ struct encoder
30
+ {
31
+ ZSTD_CStream *context;
32
+ VALUE outport;
33
+ VALUE predict;
34
+ VALUE destbuf;
35
+ int reached_eof;
36
+ };
37
+
38
+ static void
39
+ enc_gc_mark(void *pp)
40
+ {
41
+ if (pp) {
42
+ struct encoder *p = (struct encoder *)pp;
43
+ rb_gc_mark(p->outport);
44
+ rb_gc_mark(p->predict);
45
+ rb_gc_mark(p->destbuf);
46
+ }
47
+ }
48
+
49
+ static void
50
+ enc_free(void *pp)
51
+ {
52
+ if (pp) {
53
+ struct encoder *p = (struct encoder *)pp;
54
+ if (p->context) {
55
+ ZSTD_freeCStream(p->context);
56
+ p->context = NULL;
57
+ }
58
+ xfree(p);
59
+ }
60
+ }
61
+
62
+ AUX_IMPLEMENT_CONTEXT(
63
+ struct encoder, encoder_type, "extzstd.Zstd::Encoder",
64
+ encoder_alloc_dummy, enc_gc_mark, enc_free, NULL,
65
+ getencoderp, getencoder, encoder_p);
66
+
67
+ static VALUE
68
+ enc_alloc(VALUE mod)
69
+ {
70
+ struct encoder *p;
71
+ VALUE obj = TypedData_Make_Struct(mod, struct encoder, &encoder_type, p);
72
+ p->outport = Qnil;
73
+ p->predict = Qnil;
74
+ p->destbuf = Qnil;
75
+ return obj;
76
+ }
77
+
78
+ static struct encoder *
79
+ encoder_context(VALUE self)
80
+ {
81
+ struct encoder *p = getencoder(self);
82
+ if (!p->context) {
83
+ rb_raise(rb_eTypeError,
84
+ "wrong initialized context - #<%s:%p>",
85
+ rb_obj_classname(self), (void *)self);
86
+ }
87
+ return p;
88
+ }
89
+
90
+ /*
91
+ * call-seq:
92
+ * initialize(outport, compression_parameters = nil, predict = nil)
93
+ */
94
+ static VALUE
95
+ enc_init(int argc, VALUE argv[], VALUE self)
96
+ {
97
+ /*
98
+ * ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
99
+ * ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel);
100
+ * ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
101
+ * ZSTD_parameters params, unsigned long long pledgedSrcSize);
102
+ */
103
+
104
+ VALUE outport, params, predict;
105
+ switch (argc) {
106
+ case 1:
107
+ outport = argv[0];
108
+ params = predict = Qnil;
109
+ break;
110
+ case 2:
111
+ outport = argv[0];
112
+ params = argv[1];
113
+ predict = Qnil;
114
+ break;
115
+ case 3:
116
+ outport = argv[0];
117
+ params = argv[1];
118
+ predict = argv[2];
119
+ break;
120
+ default:
121
+ rb_error_arity(argc, 1, 3);
122
+ }
123
+
124
+ struct encoder *p = getencoder(self);
125
+ if (p->context) {
126
+ rb_raise(rb_eTypeError,
127
+ "initialized already - #<%s:%p>",
128
+ rb_obj_classname(self), (void *)self);
129
+ }
130
+
131
+ AUX_TRY_WITH_GC(
132
+ p->context = ZSTD_createCStream(),
133
+ "failed ZSTD_createCStream()");
134
+
135
+ const void *predictp;
136
+ size_t predictsize;
137
+ if (NIL_P(predict)) {
138
+ predictp = NULL;
139
+ predictsize = 0;
140
+ } else {
141
+ rb_check_type(predict, RUBY_T_STRING);
142
+ predict = rb_str_new_frozen(predict);
143
+ RSTRING_GETMEM(predict, predictp, predictsize);
144
+ }
145
+
146
+ if (extzstd_params_p(params)) {
147
+ ZSTD_parameters *paramsp = extzstd_getparams(params);
148
+ size_t s = ZSTD_initCStream_advanced(p->context, predictp, predictsize, *paramsp, -1);
149
+ extzstd_check_error(s);
150
+ } else {
151
+ size_t s = ZSTD_initCStream_usingDict(p->context, predictp, predictsize, aux_num2int(params, 1));
152
+ extzstd_check_error(s);
153
+ }
154
+
155
+ p->predict = predict;
156
+ p->outport = outport;
157
+
158
+ return self;
159
+ }
160
+
161
+ static VALUE
162
+ enc_write(VALUE self, VALUE src)
163
+ {
164
+ /*
165
+ * ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
166
+ */
167
+
168
+ struct encoder *p = encoder_context(self);
169
+ src = rb_String(src);
170
+ ZSTD_inBuffer input = { RSTRING_PTR(src), RSTRING_LEN(src), 0 };
171
+
172
+ while (input.pos < input.size) {
173
+ p->destbuf = aux_str_buf_recycle(p->destbuf, ZSTD_CStreamOutSize() * 2);
174
+ rb_str_set_len(p->destbuf, 0);
175
+ rb_obj_infect(self, src);
176
+ rb_obj_infect(p->destbuf, self);
177
+ ZSTD_outBuffer output = { RSTRING_PTR(p->destbuf), rb_str_capacity(p->destbuf), 0 };
178
+ size_t s = ZSTD_compressStream(p->context, &output, &input);
179
+ extzstd_check_error(s);
180
+ rb_str_set_len(p->destbuf, output.pos);
181
+
182
+ // TODO: 例外や帯域脱出した場合の挙動は?
183
+ // TODO: src の途中経過状態を保存するべきか?
184
+ AUX_FUNCALL(p->outport, id_op_lsh, p->destbuf);
185
+ }
186
+
187
+ return self;
188
+ }
189
+
190
+ static VALUE
191
+ enc_sync(VALUE self)
192
+ {
193
+ /*
194
+ * ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
195
+ */
196
+
197
+ struct encoder *p = encoder_context(self);
198
+ aux_str_buf_recycle(p->destbuf, ZSTD_CStreamOutSize());
199
+ rb_str_set_len(p->destbuf, 0);
200
+ rb_obj_infect(p->destbuf, self);
201
+ ZSTD_outBuffer output = { RSTRING_PTR(p->destbuf), rb_str_capacity(p->destbuf), 0 };
202
+ size_t s = ZSTD_flushStream(p->context, &output);
203
+ extzstd_check_error(s);
204
+ rb_str_set_len(p->destbuf, output.pos);
205
+
206
+ AUX_FUNCALL(p->outport, id_op_lsh, p->destbuf);
207
+
208
+ return self;
209
+ }
210
+
211
+ static VALUE
212
+ enc_close(VALUE self)
213
+ {
214
+ /*
215
+ * ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
216
+ */
217
+
218
+ struct encoder *p = encoder_context(self);
219
+ aux_str_buf_recycle(p->destbuf, ZSTD_CStreamOutSize());
220
+ rb_str_set_len(p->destbuf, 0);
221
+ rb_obj_infect(p->destbuf, self);
222
+ ZSTD_outBuffer output = { RSTRING_PTR(p->destbuf), rb_str_capacity(p->destbuf), 0 };
223
+ size_t s = ZSTD_endStream(p->context, &output);
224
+ extzstd_check_error(s);
225
+ rb_str_set_len(p->destbuf, output.pos);
226
+
227
+ AUX_FUNCALL(p->outport, id_op_lsh, p->destbuf);
228
+
229
+ p->reached_eof = 1;
230
+
231
+ return Qnil;
232
+ }
233
+
234
+ static VALUE
235
+ enc_eof(VALUE self)
236
+ {
237
+ return (encoder_context(self)->reached_eof == 0 ? Qfalse : Qtrue);
238
+ }
239
+
240
+ static VALUE
241
+ enc_reset(VALUE self, VALUE pledged_srcsize)
242
+ {
243
+ /*
244
+ * ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
245
+ */
246
+
247
+ size_t s = ZSTD_resetCStream(encoder_context(self)->context, NUM2ULL(pledged_srcsize));
248
+ extzstd_check_error(s);
249
+ return self;
250
+ }
251
+
252
+ static VALUE
253
+ enc_sizeof(VALUE self)
254
+ {
255
+ /*
256
+ * ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
257
+ */
258
+
259
+ size_t s = ZSTD_sizeof_CStream(encoder_context(self)->context);
260
+ extzstd_check_error(s);
261
+ return SIZET2NUM(s);
262
+ }
263
+
264
+ static void
265
+ init_encoder(void)
266
+ {
267
+ cStreamEncoder = rb_define_class_under(extzstd_mZstd, "Encoder", rb_cObject);
268
+ rb_define_alloc_func(cStreamEncoder, enc_alloc);
269
+ rb_define_const(cStreamEncoder, "INSIZE", SIZET2NUM(ZSTD_CStreamInSize()));
270
+ rb_define_const(cStreamEncoder, "OUTSIZE", SIZET2NUM(ZSTD_CStreamOutSize()));
271
+ rb_define_method(cStreamEncoder, "initialize", enc_init, -1);
272
+ rb_define_method(cStreamEncoder, "write", enc_write, 1);
273
+ rb_define_method(cStreamEncoder, "sync", enc_sync, 0);
274
+ rb_define_method(cStreamEncoder, "close", enc_close, 0);
275
+ rb_define_method(cStreamEncoder, "eof", enc_eof, 0);
276
+ rb_define_alias(cStreamEncoder, "eof?", "eof");
277
+ rb_define_method(cStreamEncoder, "reset", enc_reset, 1);
278
+ rb_define_method(cStreamEncoder, "sizeof", enc_sizeof, 0);
279
+ rb_define_alias(cStreamEncoder, "<<", "write");
280
+ rb_define_alias(cStreamEncoder, "update", "write");
281
+ rb_define_alias(cStreamEncoder, "flush", "sync");
282
+ rb_define_alias(cStreamEncoder, "end", "close");
283
+ rb_define_alias(cStreamEncoder, "finish", "close");
284
+ }
285
+
286
+ /*
287
+ * class Zstd::Decoder
288
+ */
289
+
290
+ static VALUE cStreamDecoder;
291
+
292
+ struct decoder
293
+ {
294
+ ZSTD_DStream *context;
295
+ VALUE inport;
296
+ VALUE readbuf;
297
+ VALUE predict;
298
+ ZSTD_inBuffer inbuf;
299
+ int reached_eof;
300
+ };
301
+
302
+ static void
303
+ dec_mark(void *pp)
304
+ {
305
+ struct decoder *p = (struct decoder *)pp;
306
+ rb_gc_mark(p->inport);
307
+ rb_gc_mark(p->readbuf);
308
+ rb_gc_mark(p->predict);
309
+ }
310
+
311
+ static void
312
+ dec_free(void *pp)
313
+ {
314
+ struct decoder *p = (struct decoder *)pp;
315
+ if (p->context) {
316
+ ZSTD_freeDStream(p->context);
317
+ p->context = NULL;
318
+ }
319
+ xfree(p);
320
+ }
321
+
322
+ AUX_IMPLEMENT_CONTEXT(
323
+ struct decoder, decoder_type, "extzstd.Zstd::Decoder",
324
+ decoder_alloc_dummy, dec_mark, dec_free, NULL,
325
+ getdecoderp, getdecoder, decoder_p);
326
+
327
+ static struct decoder *
328
+ decoder_context(VALUE self)
329
+ {
330
+ struct decoder *p = getdecoder(self);
331
+ if (!p->context) {
332
+ rb_raise(rb_eTypeError,
333
+ "uninitialized context - #<%s:%p>",
334
+ rb_obj_classname(self), (void *)self);
335
+ }
336
+ return p;
337
+ }
338
+
339
+ static VALUE
340
+ dec_alloc(VALUE mod)
341
+ {
342
+ struct decoder *p;
343
+ VALUE obj = TypedData_Make_Struct(mod, struct decoder, &decoder_type, p);
344
+ return obj;
345
+ }
346
+
347
+ /*
348
+ * call-seq:
349
+ * initialize(inport, predict = Qnil)
350
+ */
351
+ static VALUE
352
+ dec_init(int argc, VALUE argv[], VALUE self)
353
+ {
354
+ /*
355
+ * ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds);
356
+ * ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
357
+ */
358
+
359
+ VALUE inport, predict;
360
+
361
+ switch (argc) {
362
+ case 1:
363
+ inport = argv[0];
364
+ predict = Qnil;
365
+ break;
366
+ case 2:
367
+ inport = argv[0];
368
+ predict = argv[1];
369
+ break;
370
+ default:
371
+ rb_error_arity(argc, 1, 2);
372
+ }
373
+
374
+ struct decoder *p = getdecoder(self);
375
+ if (p->context) {
376
+ rb_raise(rb_eTypeError,
377
+ "initialized context already - #<%s:%p>",
378
+ rb_obj_classname(self), (void *)self);
379
+ }
380
+
381
+ AUX_TRY_WITH_GC(
382
+ p->context = ZSTD_createDStream(),
383
+ "failed ZSTD_createDStream()");
384
+
385
+ if (NIL_P(predict)) {
386
+ size_t s = ZSTD_initDStream(p->context);
387
+ extzstd_check_error(s);
388
+ } else {
389
+ rb_check_type(predict, RUBY_T_STRING);
390
+ predict = rb_str_new_frozen(predict);
391
+ size_t s = ZSTD_initDStream_usingDict(p->context, RSTRING_PTR(predict), RSTRING_LEN(predict));
392
+ extzstd_check_error(s);
393
+ }
394
+
395
+ p->inport = inport;
396
+ p->predict = predict;
397
+
398
+ return self;
399
+ }
400
+
401
+ static int
402
+ dec_read_fetch(VALUE o, struct decoder *p)
403
+ {
404
+ if (!p->inbuf.src || NIL_P(p->readbuf) || p->inbuf.pos >= RSTRING_LEN(p->readbuf)) {
405
+ p->readbuf = aux_str_buf_recycle(p->readbuf, EXT_PARTIAL_READ_SIZE);
406
+ VALUE st = AUX_FUNCALL(p->inport, id_read, INT2FIX(EXT_PARTIAL_READ_SIZE), p->readbuf);
407
+ if (NIL_P(st)) { return -1; }
408
+ rb_check_type(st, RUBY_T_STRING);
409
+ p->readbuf = st;
410
+ rb_obj_infect(o, p->readbuf);
411
+ p->inbuf.size = RSTRING_LEN(p->readbuf);
412
+ p->inbuf.pos = 0;
413
+ }
414
+
415
+ p->inbuf.src = RSTRING_PTR(p->readbuf);
416
+
417
+ return 0;
418
+ }
419
+
420
+ static size_t
421
+ dec_read_decode(VALUE o, struct decoder *p, char *buf, ssize_t size)
422
+ {
423
+ if (p->reached_eof != 0) {
424
+ return 0;
425
+ }
426
+
427
+ ZSTD_outBuffer output = { buf, size, 0 };
428
+
429
+ while (size < 0 || output.pos < size) {
430
+ if (dec_read_fetch(o, p) != 0) {
431
+ if (p->reached_eof == 0) {
432
+ rb_raise(rb_eRuntimeError,
433
+ "unexpected EOF - #<%s:%p>",
434
+ rb_obj_classname(p->inport), (void *)p->inport);
435
+ }
436
+
437
+ break;
438
+ }
439
+
440
+ rb_thread_check_ints();
441
+ size_t s = ZSTD_decompressStream(p->context, &output, &p->inbuf);
442
+ extzstd_check_error(s);
443
+ if (s == 0) {
444
+ p->reached_eof = 1;
445
+ break;
446
+ }
447
+ }
448
+
449
+ return output.pos;
450
+ }
451
+
452
+ static void
453
+ dec_read_args(int argc, VALUE argv[], VALUE self, VALUE *buf, ssize_t *size)
454
+ {
455
+ switch (argc) {
456
+ case 0:
457
+ *size = -1;
458
+ *buf = rb_str_buf_new(EXT_READ_GROWUP_SIZE);
459
+ break;
460
+ case 1:
461
+ case 2:
462
+ {
463
+ if (NIL_P(argv[0])) {
464
+ *size = -1;
465
+
466
+ if (argc == 1 || NIL_P(argv[1])) {
467
+ *buf = rb_str_buf_new(EXT_READ_GROWUP_SIZE);
468
+ } else {
469
+ rb_check_type(argv[1], RUBY_T_STRING);
470
+ *buf = aux_str_modify_expand(argv[1], EXT_READ_GROWUP_SIZE);
471
+ rb_str_set_len(*buf, 0);
472
+ }
473
+ } else {
474
+ *size = NUM2SIZET(argv[0]);
475
+
476
+ if (*size < 0) {
477
+ rb_raise(rb_eArgError,
478
+ "``size'' is negative or too large (%"PRIdPTR")",
479
+ (intptr_t)*size);
480
+ }
481
+
482
+ if (argc == 1 || NIL_P(argv[1])) {
483
+ *buf = rb_str_buf_new(*size);
484
+ } else {
485
+ rb_check_type(argv[1], RUBY_T_STRING);
486
+ *buf = aux_str_modify_expand(argv[1], *size);
487
+ rb_str_set_len(*buf, 0);
488
+ }
489
+ }
490
+ }
491
+ break;
492
+ default:
493
+ rb_error_arity(argc, 0, 2);
494
+ }
495
+ }
496
+
497
+ /*
498
+ * call-seq:
499
+ * read -> read_data
500
+ * read(readsize, buf = "".b) -> buf
501
+ */
502
+ static VALUE
503
+ dec_read(int argc, VALUE argv[], VALUE self)
504
+ {
505
+ /*
506
+ * ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
507
+ */
508
+
509
+ ssize_t size;
510
+ VALUE buf;
511
+ dec_read_args(argc, argv, self, &buf, &size);
512
+
513
+ struct decoder *p = decoder_context(self);
514
+
515
+ if (size == 0) {
516
+ rb_str_set_len(buf, 0);
517
+ return buf;
518
+ } else if (size > 0) {
519
+ size = dec_read_decode(self, p, RSTRING_PTR(buf), size);
520
+ rb_str_set_len(buf, size);
521
+ } else {
522
+ /* if (size < 0) */
523
+
524
+ size_t capa = EXT_READ_GROWUP_SIZE;
525
+
526
+ for (;;) {
527
+ aux_str_modify_expand(buf, capa);
528
+ size = dec_read_decode(self, p, RSTRING_PTR(buf) + RSTRING_LEN(buf), capa - RSTRING_LEN(buf));
529
+ rb_str_set_len(buf, RSTRING_LEN(buf) + size);
530
+ if (size == 0) { break; }
531
+ size = rb_str_capacity(buf);
532
+ if (size > RSTRING_LEN(buf)) { break; }
533
+ if (size > EXT_READ_DOUBLE_GROWUP_LIMIT_SIZE) {
534
+ capa += EXT_READ_DOUBLE_GROWUP_LIMIT_SIZE;
535
+ } else {
536
+ capa *= 2;
537
+ }
538
+ }
539
+ }
540
+
541
+ rb_obj_infect(buf, self);
542
+
543
+ if (RSTRING_LEN(buf) == 0) {
544
+ return Qnil;
545
+ } else {
546
+ return buf;
547
+ }
548
+ }
549
+
550
+ static VALUE
551
+ dec_eof(VALUE self)
552
+ {
553
+ return (decoder_context(self)->reached_eof == 0 ? Qfalse : Qtrue);
554
+ }
555
+
556
+ static VALUE
557
+ dec_close(VALUE self)
558
+ {
559
+ decoder_context(self)->reached_eof = 1;
560
+ return Qnil;
561
+ }
562
+
563
+ static VALUE
564
+ dec_reset(VALUE self)
565
+ {
566
+ /*
567
+ * ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
568
+ */
569
+ size_t s = ZSTD_resetDStream(decoder_context(self)->context);
570
+ extzstd_check_error(s);
571
+ return self;
572
+ }
573
+
574
+ static VALUE
575
+ dec_sizeof(VALUE self)
576
+ {
577
+ /*
578
+ * ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
579
+ */
580
+
581
+ size_t s = ZSTD_sizeof_DStream(decoder_context(self)->context);
582
+ extzstd_check_error(s);
583
+ return SIZET2NUM(s);
584
+ }
585
+
586
+ static VALUE
587
+ dec_pos(VALUE self)
588
+ {
589
+ decoder_context(self); /* check only */
590
+ return INT2FIX(0);
591
+ }
592
+
593
+ static void
594
+ init_decoder(void)
595
+ {
596
+ cStreamDecoder = rb_define_class_under(extzstd_mZstd, "Decoder", rb_cObject);
597
+ rb_define_alloc_func(cStreamDecoder, dec_alloc);
598
+ rb_define_const(cStreamDecoder, "INSIZE", SIZET2NUM(ZSTD_DStreamInSize()));
599
+ rb_define_const(cStreamDecoder, "OUTSIZE", SIZET2NUM(ZSTD_DStreamOutSize()));
600
+ rb_define_method(cStreamDecoder, "initialize", dec_init, -1);
601
+ rb_define_method(cStreamDecoder, "read", dec_read, -1);
602
+ rb_define_method(cStreamDecoder, "eof", dec_eof, 0);
603
+ rb_define_alias(cStreamDecoder, "eof?", "eof");
604
+ rb_define_method(cStreamDecoder, "close", dec_close, 0);
605
+ rb_define_method(cStreamDecoder, "reset", dec_reset, 0);
606
+ rb_define_method(cStreamDecoder, "sizeof", dec_sizeof, 0);
607
+ rb_define_method(cStreamDecoder, "pos", dec_pos, 0);
608
+ }
609
+
610
+ /*
611
+ * initialize for extzstd_stream.c
612
+ */
613
+
614
+ void
615
+ extzstd_init_stream(void)
616
+ {
617
+ id_op_lsh = rb_intern("<<");
618
+ id_read = rb_intern("read");
619
+
620
+ init_encoder();
621
+ init_decoder();
622
+ }