zlib 3.1.1 → 3.2.3

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 (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/zlib/zlib.c +274 -201
  4. metadata +4 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7624f93a6b0776160dfd770df3287b57fa23e5844c15f036423feef6e3bd63ad
4
- data.tar.gz: d7d82956712f9408ad0734246f0e3a16ecdba892fa7228ba4e96ab2288e50602
3
+ metadata.gz: 336dc64dd83cbbd9a74ca0494fd75bc2324ff0a615baa20b3c45c232ea6ee35a
4
+ data.tar.gz: f23633ed1053a62b9423628edf0ad19149bf1785371f5c5bc3b08900dabeb56e
5
5
  SHA512:
6
- metadata.gz: 386968de72d272c978ab1d8be50eb27de3966c3f361d1b974fbec121836b7226eb92ad5c9b46acef8a68aa798232cb151693b29e4ac20decca2968102cfa0db7
7
- data.tar.gz: a1562b664638ffc2fd3428d9fb4fda6d5011336d3b3b34afa05d4b8a6ba60f98a46790c682a0fab0992892704ac65ffa308c4d13622c7cbbdca12559a23f59d8
6
+ metadata.gz: d6b289bcde42b602690993bd4dc087928f1d50542ed9ddeffb148071f3e5eb9e37bd3891cfa9ec435648a62e01b6cffcfdc1dd92995674efe39c88c434843c6f
7
+ data.tar.gz: 00764a29cf1ecbe3a0db97919a911e98ec21d1690599381c12e34a736469f1be8643997964575b4782aa5a100b0f219e645ca067bd22ad222e34b723f886d2f0
data/README.md CHANGED
@@ -53,7 +53,7 @@ puts "Uncompressed data is: #{uncompressed_data}"
53
53
 
54
54
  ## Development
55
55
 
56
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
56
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake compile test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
57
57
 
58
58
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
59
59
 
data/ext/zlib/zlib.c CHANGED
@@ -25,7 +25,7 @@
25
25
  # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
26
26
  #endif
27
27
 
28
- #define RUBY_ZLIB_VERSION "3.1.1"
28
+ #define RUBY_ZLIB_VERSION "3.2.3"
29
29
 
30
30
  #ifndef RB_PASS_CALLED_KEYWORDS
31
31
  # define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
@@ -90,7 +90,7 @@ static void zstream_expand_buffer_into(struct zstream*, unsigned long);
90
90
  static int zstream_expand_buffer_non_stream(struct zstream *z);
91
91
  static void zstream_append_buffer(struct zstream*, const Bytef*, long);
92
92
  static VALUE zstream_detach_buffer(struct zstream*);
93
- static VALUE zstream_shift_buffer(struct zstream*, long);
93
+ static VALUE zstream_shift_buffer(struct zstream*, long, VALUE);
94
94
  static void zstream_buffer_ungets(struct zstream*, const Bytef*, unsigned long);
95
95
  static void zstream_buffer_ungetbyte(struct zstream*, int);
96
96
  static void zstream_append_input(struct zstream*, const Bytef*, long);
@@ -170,8 +170,8 @@ static void gzfile_check_footer(struct gzfile*, VALUE outbuf);
170
170
  static void gzfile_write(struct gzfile*, Bytef*, long);
171
171
  static long gzfile_read_more(struct gzfile*, VALUE outbuf);
172
172
  static void gzfile_calc_crc(struct gzfile*, VALUE);
173
- static VALUE gzfile_read(struct gzfile*, long);
174
- static VALUE gzfile_read_all(struct gzfile*);
173
+ static VALUE gzfile_read(struct gzfile*, long, VALUE);
174
+ static VALUE gzfile_read_all(struct gzfile*, VALUE);
175
175
  static void gzfile_ungets(struct gzfile*, const Bytef*, long);
176
176
  static void gzfile_ungetbyte(struct gzfile*, int);
177
177
  static VALUE gzfile_writer_end_run(VALUE);
@@ -674,9 +674,7 @@ zstream_expand_buffer(struct zstream *z)
674
674
  rb_obj_reveal(z->buf, rb_cString);
675
675
  }
676
676
 
677
- rb_mutex_unlock(z->mutex);
678
- rb_protect(rb_yield, z->buf, &state);
679
- rb_mutex_lock(z->mutex);
677
+ rb_protect(rb_yield, z->buf, &state);
680
678
 
681
679
  if (ZSTREAM_REUSE_BUFFER_P(z)) {
682
680
  rb_str_modify(z->buf);
@@ -720,15 +718,14 @@ zstream_expand_buffer_into(struct zstream *z, unsigned long size)
720
718
  }
721
719
  }
722
720
 
723
- static void *
724
- zstream_expand_buffer_protect(void *ptr)
721
+ static int
722
+ zstream_expand_buffer_protect(struct zstream *z)
725
723
  {
726
- struct zstream *z = (struct zstream *)ptr;
727
724
  int state = 0;
728
725
 
729
726
  rb_protect((VALUE (*)(VALUE))zstream_expand_buffer, (VALUE)z, &state);
730
727
 
731
- return (void *)(VALUE)state;
728
+ return state;
732
729
  }
733
730
 
734
731
  static int
@@ -820,19 +817,31 @@ zstream_detach_buffer(struct zstream *z)
820
817
  }
821
818
 
822
819
  static VALUE
823
- zstream_shift_buffer(struct zstream *z, long len)
820
+ zstream_shift_buffer(struct zstream *z, long len, VALUE dst)
824
821
  {
825
- VALUE dst;
826
822
  char *bufptr;
827
823
  long buflen = ZSTREAM_BUF_FILLED(z);
828
824
 
829
825
  if (buflen <= len) {
830
- return zstream_detach_buffer(z);
826
+ if (NIL_P(dst) || (!ZSTREAM_IS_FINISHED(z) && !ZSTREAM_IS_GZFILE(z) &&
827
+ rb_block_given_p())) {
828
+ return zstream_detach_buffer(z);
829
+ } else {
830
+ bufptr = RSTRING_PTR(z->buf);
831
+ rb_str_resize(dst, buflen);
832
+ memcpy(RSTRING_PTR(dst), bufptr, buflen);
833
+ }
834
+ buflen = 0;
835
+ } else {
836
+ bufptr = RSTRING_PTR(z->buf);
837
+ if (NIL_P(dst)) {
838
+ dst = rb_str_new(bufptr, len);
839
+ } else {
840
+ rb_str_resize(dst, len);
841
+ memcpy(RSTRING_PTR(dst), bufptr, len);
842
+ }
843
+ buflen -= len;
831
844
  }
832
-
833
- bufptr = RSTRING_PTR(z->buf);
834
- dst = rb_str_new(bufptr, len);
835
- buflen -= len;
836
845
  memmove(bufptr, bufptr + len, buflen);
837
846
  rb_str_set_len(z->buf, buflen);
838
847
  z->stream.next_out = (Bytef*)RSTRING_END(z->buf);
@@ -851,9 +860,7 @@ zstream_buffer_ungets(struct zstream *z, const Bytef *b, unsigned long len)
851
860
  char *bufptr;
852
861
  long filled;
853
862
 
854
- if (NIL_P(z->buf) || (long)rb_str_capacity(z->buf) <= ZSTREAM_BUF_FILLED(z)) {
855
- zstream_expand_buffer_into(z, len);
856
- }
863
+ zstream_expand_buffer_into(z, len);
857
864
 
858
865
  RSTRING_GETMEM(z->buf, bufptr, filled);
859
866
  memmove(bufptr + len, bufptr, filled);
@@ -1011,57 +1018,14 @@ zstream_ensure_end(VALUE v)
1011
1018
  }
1012
1019
 
1013
1020
  static void *
1014
- zstream_run_func(void *ptr)
1021
+ zstream_run_once(void *_arguments)
1015
1022
  {
1016
- struct zstream_run_args *args = (struct zstream_run_args *)ptr;
1017
- int err, state, flush = args->flush;
1018
- struct zstream *z = args->z;
1019
- uInt n;
1020
-
1021
- err = Z_OK;
1022
- while (!args->interrupt) {
1023
- n = z->stream.avail_out;
1024
- err = z->func->run(&z->stream, flush);
1025
- rb_str_set_len(z->buf, ZSTREAM_BUF_FILLED(z) + (n - z->stream.avail_out));
1023
+ struct zstream_run_args *arguments = (struct zstream_run_args *)_arguments;
1024
+ struct zstream *z = arguments->z;
1026
1025
 
1027
- if (err == Z_STREAM_END) {
1028
- z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
1029
- z->flags |= ZSTREAM_FLAG_FINISHED;
1030
- break;
1031
- }
1026
+ uintptr_t error = z->func->run(&z->stream, arguments->flush);
1032
1027
 
1033
- if (err != Z_OK && err != Z_BUF_ERROR)
1034
- break;
1035
-
1036
- if (z->stream.avail_out > 0) {
1037
- z->flags |= ZSTREAM_FLAG_IN_STREAM;
1038
- break;
1039
- }
1040
-
1041
- if (z->stream.avail_in == 0 && z->func == &inflate_funcs) {
1042
- /* break here because inflate() return Z_BUF_ERROR when avail_in == 0. */
1043
- /* but deflate() could be called with avail_in == 0 (there's hidden buffer
1044
- in zstream->state) */
1045
- z->flags |= ZSTREAM_FLAG_IN_STREAM;
1046
- break;
1047
- }
1048
-
1049
- if (args->stream_output) {
1050
- state = (int)(VALUE)rb_thread_call_with_gvl(zstream_expand_buffer_protect,
1051
- (void *)z);
1052
- }
1053
- else {
1054
- state = zstream_expand_buffer_non_stream(z);
1055
- }
1056
-
1057
- if (state) {
1058
- err = Z_OK; /* buffer expanded but stream processing was stopped */
1059
- args->jump_state = state;
1060
- break;
1061
- }
1062
- }
1063
-
1064
- return (void *)(VALUE)err;
1028
+ return (void*)error;
1065
1029
  }
1066
1030
 
1067
1031
  /*
@@ -1076,6 +1040,91 @@ zstream_unblock_func(void *ptr)
1076
1040
  args->interrupt = 1;
1077
1041
  }
1078
1042
 
1043
+ #ifndef RB_NOGVL_OFFLOAD_SAFE
1044
+ // Default to no-op if it's not defined:
1045
+ #define RB_NOGVL_OFFLOAD_SAFE 0
1046
+ #endif
1047
+
1048
+ static VALUE
1049
+ zstream_run_once_begin(VALUE _arguments)
1050
+ {
1051
+ struct zstream_run_args *arguments = (struct zstream_run_args *)_arguments;
1052
+ struct zstream *z = arguments->z;
1053
+
1054
+ rb_str_locktmp(z->buf);
1055
+
1056
+ #ifndef RB_NOGVL_UBF_ASYNC_SAFE
1057
+ return (VALUE)rb_thread_call_without_gvl(zstream_run_once, (void *)arguments, zstream_unblock_func, (void *)arguments);
1058
+ #else
1059
+ return (VALUE)rb_nogvl(zstream_run_once, (void *)arguments, zstream_unblock_func, (void *)arguments, RB_NOGVL_UBF_ASYNC_SAFE | RB_NOGVL_OFFLOAD_SAFE);
1060
+ #endif
1061
+ }
1062
+
1063
+ static VALUE
1064
+ zstream_run_once_ensure(VALUE _arguments)
1065
+ {
1066
+ struct zstream_run_args *arguments = (struct zstream_run_args *)_arguments;
1067
+ struct zstream *z = arguments->z;
1068
+
1069
+ rb_str_unlocktmp(z->buf);
1070
+
1071
+ return Qnil;
1072
+ }
1073
+
1074
+ static int
1075
+ zstream_run_func(struct zstream_run_args *args)
1076
+ {
1077
+ struct zstream *z = args->z;
1078
+ int state;
1079
+ uInt n;
1080
+
1081
+ int err = Z_OK;
1082
+ while (!args->interrupt) {
1083
+ n = z->stream.avail_out;
1084
+
1085
+ err = (int)(VALUE)rb_ensure(zstream_run_once_begin, (VALUE)args, zstream_run_once_ensure, (VALUE)args);
1086
+
1087
+ rb_str_set_len(z->buf, ZSTREAM_BUF_FILLED(z) + (n - z->stream.avail_out));
1088
+
1089
+ if (err == Z_STREAM_END) {
1090
+ z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
1091
+ z->flags |= ZSTREAM_FLAG_FINISHED;
1092
+ break;
1093
+ }
1094
+
1095
+ if (err != Z_OK && err != Z_BUF_ERROR)
1096
+ break;
1097
+
1098
+ if (z->stream.avail_out > 0) {
1099
+ z->flags |= ZSTREAM_FLAG_IN_STREAM;
1100
+ break;
1101
+ }
1102
+
1103
+ if (z->stream.avail_in == 0 && z->func == &inflate_funcs) {
1104
+ /* break here because inflate() return Z_BUF_ERROR when avail_in == 0. */
1105
+ /* but deflate() could be called with avail_in == 0 (there's hidden buffer
1106
+ in zstream->state) */
1107
+ z->flags |= ZSTREAM_FLAG_IN_STREAM;
1108
+ break;
1109
+ }
1110
+
1111
+ if (args->stream_output) {
1112
+ state = zstream_expand_buffer_protect(z);
1113
+ }
1114
+ else {
1115
+ state = zstream_expand_buffer_non_stream(z);
1116
+ }
1117
+
1118
+ if (state) {
1119
+ err = Z_OK; /* buffer expanded but stream processing was stopped */
1120
+ args->jump_state = state;
1121
+ break;
1122
+ }
1123
+ }
1124
+
1125
+ return err;
1126
+ }
1127
+
1079
1128
  static VALUE
1080
1129
  zstream_run_try(VALUE value_arg)
1081
1130
  {
@@ -1088,6 +1137,12 @@ zstream_run_try(VALUE value_arg)
1088
1137
  int err;
1089
1138
  VALUE old_input = Qnil;
1090
1139
 
1140
+ /* Cannot start zstream while it is in progress. */
1141
+ if (z->flags & ZSTREAM_IN_PROGRESS) {
1142
+ rb_raise(cInProgressError, "zlib stream is in progress");
1143
+ }
1144
+ z->flags |= ZSTREAM_IN_PROGRESS;
1145
+
1091
1146
  if (NIL_P(z->input) && len == 0) {
1092
1147
  z->stream.next_in = (Bytef*)"";
1093
1148
  z->stream.avail_in = 0;
@@ -1108,14 +1163,7 @@ zstream_run_try(VALUE value_arg)
1108
1163
  }
1109
1164
 
1110
1165
  loop:
1111
- #ifndef RB_NOGVL_UBF_ASYNC_SAFE
1112
- err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)args,
1113
- zstream_unblock_func, (void *)args);
1114
- #else
1115
- err = (int)(VALUE)rb_nogvl(zstream_run_func, (void *)args,
1116
- zstream_unblock_func, (void *)args,
1117
- RB_NOGVL_UBF_ASYNC_SAFE);
1118
- #endif
1166
+ err = zstream_run_func(args);
1119
1167
 
1120
1168
  /* retry if no exception is thrown */
1121
1169
  if (err == Z_OK && args->interrupt) {
@@ -1155,9 +1203,6 @@ loop:
1155
1203
  rb_str_resize(old_input, 0);
1156
1204
  }
1157
1205
 
1158
- if (args->jump_state)
1159
- rb_jump_tag(args->jump_state);
1160
-
1161
1206
  return Qnil;
1162
1207
  }
1163
1208
 
@@ -1165,25 +1210,10 @@ static VALUE
1165
1210
  zstream_run_ensure(VALUE value_arg)
1166
1211
  {
1167
1212
  struct zstream_run_args *args = (struct zstream_run_args *)value_arg;
1213
+ struct zstream *z = args->z;
1168
1214
 
1169
1215
  /* Remove ZSTREAM_IN_PROGRESS flag to signal that this zstream is not in use. */
1170
- args->z->flags &= ~ZSTREAM_IN_PROGRESS;
1171
-
1172
- return Qnil;
1173
- }
1174
-
1175
- static VALUE
1176
- zstream_run_synchronized(VALUE value_arg)
1177
- {
1178
- struct zstream_run_args *args = (struct zstream_run_args *)value_arg;
1179
-
1180
- /* Cannot start zstream while it is in progress. */
1181
- if (args->z->flags & ZSTREAM_IN_PROGRESS) {
1182
- rb_raise(cInProgressError, "zlib stream is in progress");
1183
- }
1184
- args->z->flags |= ZSTREAM_IN_PROGRESS;
1185
-
1186
- rb_ensure(zstream_run_try, value_arg, zstream_run_ensure, value_arg);
1216
+ z->flags &= ~ZSTREAM_IN_PROGRESS;
1187
1217
 
1188
1218
  return Qnil;
1189
1219
  }
@@ -1200,7 +1230,10 @@ zstream_run(struct zstream *z, Bytef *src, long len, int flush)
1200
1230
  .jump_state = 0,
1201
1231
  .stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p(),
1202
1232
  };
1203
- rb_mutex_synchronize(z->mutex, zstream_run_synchronized, (VALUE)&args);
1233
+
1234
+ rb_ensure(zstream_run_try, (VALUE)&args, zstream_run_ensure, (VALUE)&args);
1235
+ if (args.jump_state)
1236
+ rb_jump_tag(args.jump_state);
1204
1237
  }
1205
1238
 
1206
1239
  static VALUE
@@ -1509,7 +1542,7 @@ rb_zstream_total_out(VALUE obj)
1509
1542
  }
1510
1543
 
1511
1544
  /*
1512
- * Guesses the type of the data which have been inputed into the stream. The
1545
+ * Guesses the type of the data which have been inputted into the stream. The
1513
1546
  * returned value is either <tt>BINARY</tt>, <tt>ASCII</tt>, or
1514
1547
  * <tt>UNKNOWN</tt>.
1515
1548
  */
@@ -1766,6 +1799,22 @@ do_deflate(struct zstream *z, VALUE src, int flush)
1766
1799
  }
1767
1800
  }
1768
1801
 
1802
+ struct rb_zlib_deflate_arguments {
1803
+ struct zstream *z;
1804
+ VALUE src;
1805
+ int flush;
1806
+ };
1807
+
1808
+ static VALUE
1809
+ rb_deflate_deflate_body(VALUE args)
1810
+ {
1811
+ struct rb_zlib_deflate_arguments *arguments = (struct rb_zlib_deflate_arguments *)args;
1812
+
1813
+ do_deflate(arguments->z, arguments->src, arguments->flush);
1814
+
1815
+ return zstream_detach_buffer(arguments->z);
1816
+ }
1817
+
1769
1818
  /*
1770
1819
  * Document-method: Zlib::Deflate#deflate
1771
1820
  *
@@ -1797,11 +1846,10 @@ rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
1797
1846
  {
1798
1847
  struct zstream *z = get_zstream(obj);
1799
1848
  VALUE src, flush;
1800
-
1801
1849
  rb_scan_args(argc, argv, "11", &src, &flush);
1802
- do_deflate(z, src, ARG_FLUSH(flush));
1850
+ struct rb_zlib_deflate_arguments arguments = {z, src, ARG_FLUSH(flush)};
1803
1851
 
1804
- return zstream_detach_buffer(z);
1852
+ return rb_mutex_synchronize(z->mutex, rb_deflate_deflate_body, (VALUE)&arguments);
1805
1853
  }
1806
1854
 
1807
1855
  /*
@@ -2097,56 +2145,19 @@ rb_inflate_add_dictionary(VALUE obj, VALUE dictionary)
2097
2145
  return obj;
2098
2146
  }
2099
2147
 
2100
- /*
2101
- * Document-method: Zlib::Inflate#inflate
2102
- *
2103
- * call-seq:
2104
- * inflate(deflate_string, buffer: nil) -> String
2105
- * inflate(deflate_string, buffer: nil) { |chunk| ... } -> nil
2106
- *
2107
- * Inputs +deflate_string+ into the inflate stream and returns the output from
2108
- * the stream. Calling this method, both the input and the output buffer of
2109
- * the stream are flushed. If string is +nil+, this method finishes the
2110
- * stream, just like Zlib::ZStream#finish.
2111
- *
2112
- * If a block is given consecutive inflated chunks from the +deflate_string+
2113
- * are yielded to the block and +nil+ is returned.
2114
- *
2115
- * If a :buffer keyword argument is given and not nil:
2116
- *
2117
- * * The :buffer keyword should be a String, and will used as the output buffer.
2118
- * Using this option can reuse the memory required during inflation.
2119
- * * When not passing a block, the return value will be the same object as the
2120
- * :buffer keyword argument.
2121
- * * When passing a block, the yielded chunks will be the same value as the
2122
- * :buffer keyword argument.
2123
- *
2124
- * Raises a Zlib::NeedDict exception if a preset dictionary is needed to
2125
- * decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
2126
- * call this method again with an empty string to flush the stream:
2127
- *
2128
- * inflater = Zlib::Inflate.new
2129
- *
2130
- * begin
2131
- * out = inflater.inflate compressed
2132
- * rescue Zlib::NeedDict
2133
- * # ensure the dictionary matches the stream's required dictionary
2134
- * raise unless inflater.adler == Zlib.adler32(dictionary)
2135
- *
2136
- * inflater.set_dictionary dictionary
2137
- * inflater.inflate ''
2138
- * end
2139
- *
2140
- * # ...
2141
- *
2142
- * inflater.close
2143
- *
2144
- * See also Zlib::Inflate.new
2145
- */
2148
+ struct rb_zlib_inflate_arguments {
2149
+ struct zstream *z;
2150
+ int argc;
2151
+ VALUE *argv;
2152
+ };
2153
+
2146
2154
  static VALUE
2147
- rb_inflate_inflate(int argc, VALUE* argv, VALUE obj)
2155
+ rb_inflate_inflate_body(VALUE _arguments)
2148
2156
  {
2149
- struct zstream *z = get_zstream(obj);
2157
+ struct rb_zlib_inflate_arguments *arguments = (struct rb_zlib_inflate_arguments*)_arguments;
2158
+ struct zstream *z = arguments->z;
2159
+ int argc = arguments->argc;
2160
+ VALUE *argv = arguments->argv;
2150
2161
  VALUE dst, src, opts, buffer = Qnil;
2151
2162
 
2152
2163
  if (OPTHASH_GIVEN_P(opts)) {
@@ -2201,6 +2212,60 @@ rb_inflate_inflate(int argc, VALUE* argv, VALUE obj)
2201
2212
  return dst;
2202
2213
  }
2203
2214
 
2215
+ /*
2216
+ * Document-method: Zlib::Inflate#inflate
2217
+ *
2218
+ * call-seq:
2219
+ * inflate(deflate_string, buffer: nil) -> String
2220
+ * inflate(deflate_string, buffer: nil) { |chunk| ... } -> nil
2221
+ *
2222
+ * Inputs +deflate_string+ into the inflate stream and returns the output from
2223
+ * the stream. Calling this method, both the input and the output buffer of
2224
+ * the stream are flushed. If string is +nil+, this method finishes the
2225
+ * stream, just like Zlib::ZStream#finish.
2226
+ *
2227
+ * If a block is given consecutive inflated chunks from the +deflate_string+
2228
+ * are yielded to the block and +nil+ is returned.
2229
+ *
2230
+ * If a :buffer keyword argument is given and not nil:
2231
+ *
2232
+ * * The :buffer keyword should be a String, and will used as the output buffer.
2233
+ * Using this option can reuse the memory required during inflation.
2234
+ * * When not passing a block, the return value will be the same object as the
2235
+ * :buffer keyword argument.
2236
+ * * When passing a block, the yielded chunks will be the same value as the
2237
+ * :buffer keyword argument.
2238
+ *
2239
+ * Raises a Zlib::NeedDict exception if a preset dictionary is needed to
2240
+ * decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
2241
+ * call this method again with an empty string to flush the stream:
2242
+ *
2243
+ * inflater = Zlib::Inflate.new
2244
+ *
2245
+ * begin
2246
+ * out = inflater.inflate compressed
2247
+ * rescue Zlib::NeedDict
2248
+ * # ensure the dictionary matches the stream's required dictionary
2249
+ * raise unless inflater.adler == Zlib.adler32(dictionary)
2250
+ *
2251
+ * inflater.set_dictionary dictionary
2252
+ * inflater.inflate ''
2253
+ * end
2254
+ *
2255
+ * # ...
2256
+ *
2257
+ * inflater.close
2258
+ *
2259
+ * See also Zlib::Inflate.new
2260
+ */
2261
+ static VALUE
2262
+ rb_inflate_inflate(int argc, VALUE* argv, VALUE obj)
2263
+ {
2264
+ struct zstream *z = get_zstream(obj);
2265
+ struct rb_zlib_inflate_arguments arguments = {z, argc, argv};
2266
+ return rb_mutex_synchronize(z->mutex, rb_inflate_inflate_body, (VALUE)&arguments);
2267
+ }
2268
+
2204
2269
  /*
2205
2270
  * call-seq: << string
2206
2271
  *
@@ -2377,17 +2442,16 @@ struct gzfile {
2377
2442
 
2378
2443
  #define GZFILE_READ_SIZE 2048
2379
2444
 
2445
+ enum { read_raw_arg_len, read_raw_arg_buf, read_raw_arg__count};
2380
2446
  struct read_raw_arg {
2381
2447
  VALUE io;
2382
- union {
2383
- const VALUE argv[2]; /* for rb_funcallv */
2384
- struct {
2385
- VALUE len;
2386
- VALUE buf;
2387
- } in;
2388
- } as;
2448
+ const VALUE argv[read_raw_arg__count]; /* for rb_funcallv */
2389
2449
  };
2390
2450
 
2451
+ #define read_raw_arg_argc(ra) \
2452
+ ((int)read_raw_arg__count - NIL_P((ra)->argv[read_raw_arg__count - 1]))
2453
+ #define read_raw_arg_init(io, len, buf) { io, { len, buf } }
2454
+
2391
2455
  static void
2392
2456
  gzfile_mark(void *p)
2393
2457
  {
@@ -2513,9 +2577,9 @@ gzfile_read_raw_partial(VALUE arg)
2513
2577
  {
2514
2578
  struct read_raw_arg *ra = (struct read_raw_arg *)arg;
2515
2579
  VALUE str;
2516
- int argc = NIL_P(ra->as.argv[1]) ? 1 : 2;
2580
+ int argc = read_raw_arg_argc(ra);
2517
2581
 
2518
- str = rb_funcallv(ra->io, id_readpartial, argc, ra->as.argv);
2582
+ str = rb_funcallv(ra->io, id_readpartial, argc, ra->argv);
2519
2583
  Check_Type(str, T_STRING);
2520
2584
  return str;
2521
2585
  }
@@ -2526,8 +2590,8 @@ gzfile_read_raw_rescue(VALUE arg, VALUE _)
2526
2590
  struct read_raw_arg *ra = (struct read_raw_arg *)arg;
2527
2591
  VALUE str = Qnil;
2528
2592
  if (rb_obj_is_kind_of(rb_errinfo(), rb_eNoMethodError)) {
2529
- int argc = NIL_P(ra->as.argv[1]) ? 1 : 2;
2530
- str = rb_funcallv(ra->io, id_read, argc, ra->as.argv);
2593
+ int argc = read_raw_arg_argc(ra);
2594
+ str = rb_funcallv(ra->io, id_read, argc, ra->argv);
2531
2595
  if (!NIL_P(str)) {
2532
2596
  Check_Type(str, T_STRING);
2533
2597
  }
@@ -2538,11 +2602,8 @@ gzfile_read_raw_rescue(VALUE arg, VALUE _)
2538
2602
  static VALUE
2539
2603
  gzfile_read_raw(struct gzfile *gz, VALUE outbuf)
2540
2604
  {
2541
- struct read_raw_arg ra;
2542
-
2543
- ra.io = gz->io;
2544
- ra.as.in.len = INT2FIX(GZFILE_READ_SIZE);
2545
- ra.as.in.buf = outbuf;
2605
+ struct read_raw_arg ra =
2606
+ read_raw_arg_init(gz->io, INT2FIX(GZFILE_READ_SIZE), outbuf);
2546
2607
 
2547
2608
  return rb_rescue2(gzfile_read_raw_partial, (VALUE)&ra,
2548
2609
  gzfile_read_raw_rescue, (VALUE)&ra,
@@ -2874,18 +2935,18 @@ gzfile_newstr(struct gzfile *gz, VALUE str)
2874
2935
  }
2875
2936
 
2876
2937
  static long
2877
- gzfile_fill(struct gzfile *gz, long len)
2938
+ gzfile_fill(struct gzfile *gz, long len, VALUE outbuf)
2878
2939
  {
2879
2940
  if (len < 0)
2880
2941
  rb_raise(rb_eArgError, "negative length %ld given", len);
2881
2942
  if (len == 0)
2882
2943
  return 0;
2883
2944
  while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) < len) {
2884
- gzfile_read_more(gz, Qnil);
2945
+ gzfile_read_more(gz, outbuf);
2885
2946
  }
2886
2947
  if (GZFILE_IS_FINISHED(gz)) {
2887
2948
  if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2888
- gzfile_check_footer(gz, Qnil);
2949
+ gzfile_check_footer(gz, outbuf);
2889
2950
  }
2890
2951
  return -1;
2891
2952
  }
@@ -2893,14 +2954,27 @@ gzfile_fill(struct gzfile *gz, long len)
2893
2954
  }
2894
2955
 
2895
2956
  static VALUE
2896
- gzfile_read(struct gzfile *gz, long len)
2957
+ gzfile_read(struct gzfile *gz, long len, VALUE outbuf)
2897
2958
  {
2898
2959
  VALUE dst;
2899
2960
 
2900
- len = gzfile_fill(gz, len);
2901
- if (len == 0) return rb_str_new(0, 0);
2902
- if (len < 0) return Qnil;
2903
- dst = zstream_shift_buffer(&gz->z, len);
2961
+ len = gzfile_fill(gz, len, outbuf);
2962
+
2963
+ if (len < 0) {
2964
+ if (!NIL_P(outbuf))
2965
+ rb_str_resize(outbuf, 0);
2966
+ return Qnil;
2967
+ }
2968
+ if (len == 0) {
2969
+ if (NIL_P(outbuf))
2970
+ return rb_str_new(0, 0);
2971
+ else {
2972
+ rb_str_resize(outbuf, 0);
2973
+ return outbuf;
2974
+ }
2975
+ }
2976
+
2977
+ dst = zstream_shift_buffer(&gz->z, len, outbuf);
2904
2978
  if (!NIL_P(dst)) gzfile_calc_crc(gz, dst);
2905
2979
  return dst;
2906
2980
  }
@@ -2933,29 +3007,26 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
2933
3007
  rb_raise(rb_eEOFError, "end of file reached");
2934
3008
  }
2935
3009
 
2936
- dst = zstream_shift_buffer(&gz->z, len);
3010
+ dst = zstream_shift_buffer(&gz->z, len, outbuf);
2937
3011
  gzfile_calc_crc(gz, dst);
2938
3012
 
2939
- if (!NIL_P(outbuf)) {
2940
- rb_str_resize(outbuf, RSTRING_LEN(dst));
2941
- memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
2942
- dst = outbuf;
2943
- }
2944
3013
  return dst;
2945
3014
  }
2946
3015
 
2947
3016
  static VALUE
2948
- gzfile_read_all(struct gzfile *gz)
3017
+ gzfile_read_all(struct gzfile *gz, VALUE dst)
2949
3018
  {
2950
- VALUE dst;
2951
-
2952
3019
  while (!ZSTREAM_IS_FINISHED(&gz->z)) {
2953
- gzfile_read_more(gz, Qnil);
3020
+ gzfile_read_more(gz, dst);
2954
3021
  }
2955
3022
  if (GZFILE_IS_FINISHED(gz)) {
2956
3023
  if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2957
- gzfile_check_footer(gz, Qnil);
3024
+ gzfile_check_footer(gz, dst);
2958
3025
  }
3026
+ if (!NIL_P(dst)) {
3027
+ rb_str_resize(dst, 0);
3028
+ return dst;
3029
+ }
2959
3030
  return rb_str_new(0, 0);
2960
3031
  }
2961
3032
 
@@ -2993,7 +3064,7 @@ gzfile_getc(struct gzfile *gz)
2993
3064
  de = (unsigned char *)ds + GZFILE_CBUF_CAPA;
2994
3065
  (void)rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
2995
3066
  rb_econv_check_error(gz->ec);
2996
- dst = zstream_shift_buffer(&gz->z, sp - ss);
3067
+ dst = zstream_shift_buffer(&gz->z, sp - ss, Qnil);
2997
3068
  gzfile_calc_crc(gz, dst);
2998
3069
  rb_str_resize(cbuf, dp - ds);
2999
3070
  return cbuf;
@@ -3001,7 +3072,7 @@ gzfile_getc(struct gzfile *gz)
3001
3072
  else {
3002
3073
  buf = gz->z.buf;
3003
3074
  len = rb_enc_mbclen(RSTRING_PTR(buf), RSTRING_END(buf), gz->enc);
3004
- dst = gzfile_read(gz, len);
3075
+ dst = gzfile_read(gz, len, Qnil);
3005
3076
  if (NIL_P(dst)) return dst;
3006
3077
  return gzfile_newstr(gz, dst);
3007
3078
  }
@@ -3909,7 +3980,7 @@ rb_gzreader_s_zcat(int argc, VALUE *argv, VALUE klass)
3909
3980
  if (!buf) {
3910
3981
  buf = rb_str_new(0, 0);
3911
3982
  }
3912
- tmpbuf = gzfile_read_all(get_gzfile(obj));
3983
+ tmpbuf = gzfile_read_all(get_gzfile(obj), Qnil);
3913
3984
  rb_str_cat(buf, RSTRING_PTR(tmpbuf), RSTRING_LEN(tmpbuf));
3914
3985
  }
3915
3986
 
@@ -4011,19 +4082,19 @@ static VALUE
4011
4082
  rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
4012
4083
  {
4013
4084
  struct gzfile *gz = get_gzfile(obj);
4014
- VALUE vlen;
4085
+ VALUE vlen, outbuf;
4015
4086
  long len;
4016
4087
 
4017
- rb_scan_args(argc, argv, "01", &vlen);
4088
+ rb_scan_args(argc, argv, "02", &vlen, &outbuf);
4018
4089
  if (NIL_P(vlen)) {
4019
- return gzfile_read_all(gz);
4090
+ return gzfile_read_all(gz, outbuf);
4020
4091
  }
4021
4092
 
4022
4093
  len = NUM2INT(vlen);
4023
4094
  if (len < 0) {
4024
4095
  rb_raise(rb_eArgError, "negative length %ld given", len);
4025
4096
  }
4026
- return gzfile_read(gz, len);
4097
+ return gzfile_read(gz, len, outbuf);
4027
4098
  }
4028
4099
 
4029
4100
  /*
@@ -4032,7 +4103,7 @@ rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
4032
4103
  * call-seq:
4033
4104
  * gzipreader.readpartial(maxlen [, outbuf]) => string, outbuf
4034
4105
  *
4035
- * Reads at most <i>maxlen</i> bytes from the gziped stream but
4106
+ * Reads at most <i>maxlen</i> bytes from the gzipped stream but
4036
4107
  * it blocks only if <em>gzipreader</em> has no data immediately available.
4037
4108
  * If the optional <i>outbuf</i> argument is present,
4038
4109
  * it must reference a String, which will receive the data.
@@ -4096,7 +4167,7 @@ rb_gzreader_getbyte(VALUE obj)
4096
4167
  struct gzfile *gz = get_gzfile(obj);
4097
4168
  VALUE dst;
4098
4169
 
4099
- dst = gzfile_read(gz, 1);
4170
+ dst = gzfile_read(gz, 1, Qnil);
4100
4171
  if (!NIL_P(dst)) {
4101
4172
  dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
4102
4173
  }
@@ -4207,6 +4278,7 @@ gzreader_skip_linebreaks(struct gzfile *gz)
4207
4278
  while (n++, *(p++) == '\n') {
4208
4279
  if (n >= ZSTREAM_BUF_FILLED(&gz->z)) {
4209
4280
  str = zstream_detach_buffer(&gz->z);
4281
+ ASSUME(!NIL_P(str));
4210
4282
  gzfile_calc_crc(gz, str);
4211
4283
  while (ZSTREAM_BUF_FILLED(&gz->z) == 0) {
4212
4284
  if (GZFILE_IS_FINISHED(gz)) return;
@@ -4217,7 +4289,7 @@ gzreader_skip_linebreaks(struct gzfile *gz)
4217
4289
  }
4218
4290
  }
4219
4291
 
4220
- str = zstream_shift_buffer(&gz->z, n - 1);
4292
+ str = zstream_shift_buffer(&gz->z, n - 1, Qnil);
4221
4293
  gzfile_calc_crc(gz, str);
4222
4294
  }
4223
4295
 
@@ -4238,7 +4310,7 @@ gzreader_charboundary(struct gzfile *gz, long n)
4238
4310
  if (l < n) {
4239
4311
  int n_bytes = rb_enc_precise_mbclen(p, e, gz->enc);
4240
4312
  if (MBCLEN_NEEDMORE_P(n_bytes)) {
4241
- if ((l = gzfile_fill(gz, n + MBCLEN_NEEDMORE_LEN(n_bytes))) > 0) {
4313
+ if ((l = gzfile_fill(gz, n + MBCLEN_NEEDMORE_LEN(n_bytes), Qnil)) > 0) {
4242
4314
  return l;
4243
4315
  }
4244
4316
  }
@@ -4290,10 +4362,10 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
4290
4362
 
4291
4363
  if (NIL_P(rs)) {
4292
4364
  if (limit < 0) {
4293
- dst = gzfile_read_all(gz);
4365
+ dst = gzfile_read_all(gz, Qnil);
4294
4366
  if (RSTRING_LEN(dst) == 0) return Qnil;
4295
4367
  }
4296
- else if ((n = gzfile_fill(gz, limit)) <= 0) {
4368
+ else if ((n = gzfile_fill(gz, limit, Qnil)) <= 0) {
4297
4369
  return Qnil;
4298
4370
  }
4299
4371
  else {
@@ -4303,7 +4375,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
4303
4375
  else {
4304
4376
  n = limit;
4305
4377
  }
4306
- dst = zstream_shift_buffer(&gz->z, n);
4378
+ dst = zstream_shift_buffer(&gz->z, n, Qnil);
4307
4379
  if (NIL_P(dst)) return dst;
4308
4380
  gzfile_calc_crc(gz, dst);
4309
4381
  dst = gzfile_newstr(gz, dst);
@@ -4330,7 +4402,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
4330
4402
  while (ZSTREAM_BUF_FILLED(&gz->z) < rslen) {
4331
4403
  if (ZSTREAM_IS_FINISHED(&gz->z)) {
4332
4404
  if (ZSTREAM_BUF_FILLED(&gz->z) > 0) gz->lineno++;
4333
- return gzfile_read(gz, rslen);
4405
+ return gzfile_read(gz, rslen, Qnil);
4334
4406
  }
4335
4407
  gzfile_read_more(gz, Qnil);
4336
4408
  }
@@ -4367,7 +4439,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
4367
4439
  }
4368
4440
 
4369
4441
  gz->lineno++;
4370
- dst = gzfile_read(gz, n);
4442
+ dst = gzfile_read(gz, n, Qnil);
4371
4443
  if (NIL_P(dst)) return dst;
4372
4444
  if (rspara) {
4373
4445
  gzreader_skip_linebreaks(gz);
@@ -4615,6 +4687,7 @@ zlib_gunzip_run(VALUE arg)
4615
4687
 
4616
4688
  gzfile_read_header(gz, Qnil);
4617
4689
  dst = zstream_detach_buffer(&gz->z);
4690
+ ASSUME(!NIL_P(dst));
4618
4691
  gzfile_calc_crc(gz, dst);
4619
4692
  if (!ZSTREAM_IS_FINISHED(&gz->z)) {
4620
4693
  rb_raise(cGzError, "unexpected end of file");
metadata CHANGED
@@ -1,20 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zlib
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yukihiro Matsumoto
8
8
  - UENO Katsuhiro
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2024-05-29 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: Ruby interface for the zlib compression/decompression library
15
14
  email:
16
15
  - matz@ruby-lang.org
17
- -
16
+ -
18
17
  executables: []
19
18
  extensions:
20
19
  - ext/zlib/extconf.rb
@@ -31,7 +30,6 @@ licenses:
31
30
  - Ruby
32
31
  - BSD-2-Clause
33
32
  metadata: {}
34
- post_install_message:
35
33
  rdoc_options: []
36
34
  require_paths:
37
35
  - lib
@@ -46,8 +44,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
44
  - !ruby/object:Gem::Version
47
45
  version: '0'
48
46
  requirements: []
49
- rubygems_version: 3.5.9
50
- signing_key:
47
+ rubygems_version: 3.6.9
51
48
  specification_version: 4
52
49
  summary: Ruby interface for the zlib compression/decompression library
53
50
  test_files: []