extzstd 0.0.3.CONCEPT → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }