ruby-lzws 1.0.0 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +1,17 @@
1
1
  // Ruby bindings for lzws library.
2
2
  // Copyright (c) 2019 AUTHORS, MIT License.
3
3
 
4
+ #include "lzws_ext/stream/compressor.h"
5
+
4
6
  #include <lzws/buffer.h>
7
+ #include <lzws/common.h>
5
8
  #include <lzws/compressor/common.h>
6
- #include <lzws/compressor/header.h>
7
9
  #include <lzws/compressor/main.h>
8
10
  #include <lzws/compressor/state.h>
9
11
 
10
- #include "ruby.h"
11
-
12
12
  #include "lzws_ext/error.h"
13
- #include "lzws_ext/macro.h"
14
13
  #include "lzws_ext/option.h"
15
- #include "lzws_ext/stream/compressor.h"
14
+ #include "ruby.h"
16
15
 
17
16
  static void free_compressor(lzws_ext_compressor_t* compressor_ptr)
18
17
  {
@@ -21,7 +20,7 @@ static void free_compressor(lzws_ext_compressor_t* compressor_ptr)
21
20
  lzws_compressor_free_state(state_ptr);
22
21
  }
23
22
 
24
- uint8_t* destination_buffer = compressor_ptr->destination_buffer;
23
+ lzws_ext_byte_t* destination_buffer = compressor_ptr->destination_buffer;
25
24
  if (destination_buffer != NULL) {
26
25
  free(destination_buffer);
27
26
  }
@@ -51,37 +50,36 @@ VALUE lzws_ext_allocate_compressor(VALUE klass)
51
50
  VALUE lzws_ext_initialize_compressor(VALUE self, VALUE options)
52
51
  {
53
52
  GET_COMPRESSOR(self);
53
+ Check_Type(options, T_HASH);
54
54
  LZWS_EXT_GET_COMPRESSOR_OPTIONS(options);
55
- LZWS_EXT_UNUSED_VARIABLE(without_magic_header);
55
+ LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
56
56
 
57
- lzws_compressor_state_t* compressor_state_ptr;
57
+ lzws_compressor_state_t* state_ptr;
58
58
 
59
59
  lzws_result_t result = lzws_compressor_get_initial_state(
60
- &compressor_state_ptr,
61
- max_code_bit_length, block_mode, msb, unaligned_bit_groups, quiet);
60
+ &state_ptr,
61
+ without_magic_header, max_code_bit_length, block_mode, msb, unaligned_bit_groups, quiet);
62
62
 
63
- if (result == LZWS_COMPRESSOR_ALLOCATE_FAILED) {
64
- lzws_ext_raise_error("AllocateError", "allocate error");
65
- }
66
- else if (result == LZWS_COMPRESSOR_INVALID_MAX_CODE_BIT_LENGTH) {
67
- lzws_ext_raise_error("ValidateError", "validate error");
68
- }
69
- else if (result != 0) {
70
- lzws_ext_raise_error("UnexpectedError", "unexpected error");
63
+ if (result != 0) {
64
+ switch (result) {
65
+ case LZWS_COMPRESSOR_ALLOCATE_FAILED:
66
+ lzws_ext_raise_error(LZWS_EXT_ERROR_ALLOCATE_FAILED);
67
+ case LZWS_COMPRESSOR_INVALID_MAX_CODE_BIT_LENGTH:
68
+ lzws_ext_raise_error(LZWS_EXT_ERROR_VALIDATE_FAILED);
69
+ default:
70
+ lzws_ext_raise_error(LZWS_EXT_ERROR_UNEXPECTED);
71
+ }
71
72
  }
72
73
 
73
- compressor_ptr->state_ptr = compressor_state_ptr;
74
-
75
- // -----
74
+ lzws_ext_byte_t* destination_buffer;
76
75
 
77
- uint8_t* destination_buffer;
78
- size_t destination_buffer_length = buffer_length;
79
-
80
- result = lzws_create_buffer_for_compressor(&destination_buffer, &destination_buffer_length, quiet);
76
+ result = lzws_create_destination_buffer_for_compressor(&destination_buffer, &destination_buffer_length, quiet);
81
77
  if (result != 0) {
82
- lzws_ext_raise_error("AllocateError", "allocate error");
78
+ lzws_compressor_free_state(state_ptr);
79
+ lzws_ext_raise_error(LZWS_EXT_ERROR_ALLOCATE_FAILED);
83
80
  }
84
81
 
82
+ compressor_ptr->state_ptr = state_ptr;
85
83
  compressor_ptr->destination_buffer = destination_buffer;
86
84
  compressor_ptr->destination_buffer_length = destination_buffer_length;
87
85
  compressor_ptr->remaining_destination_buffer = destination_buffer;
@@ -92,83 +90,58 @@ VALUE lzws_ext_initialize_compressor(VALUE self, VALUE options)
92
90
 
93
91
  #define DO_NOT_USE_AFTER_CLOSE(compressor_ptr) \
94
92
  if (compressor_ptr->state_ptr == NULL || compressor_ptr->destination_buffer == NULL) { \
95
- lzws_ext_raise_error("UsedAfterCloseError", "compressor used after closed"); \
93
+ lzws_ext_raise_error(LZWS_EXT_ERROR_USED_AFTER_CLOSE); \
96
94
  }
97
95
 
98
- VALUE lzws_ext_compressor_write_magic_header(VALUE self)
99
- {
100
- GET_COMPRESSOR(self);
101
- DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
96
+ #define GET_SOURCE_DATA(source_value) \
97
+ Check_Type(source_value, T_STRING); \
98
+ \
99
+ const char* source = RSTRING_PTR(source_value); \
100
+ size_t source_length = RSTRING_LEN(source_value); \
101
+ lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*)source; \
102
+ size_t remaining_source_length = source_length;
102
103
 
103
- lzws_result_t result = lzws_compressor_write_magic_header(
104
- &compressor_ptr->remaining_destination_buffer,
105
- &compressor_ptr->remaining_destination_buffer_length);
106
-
107
- if (result == 0) {
108
- return Qfalse;
109
- }
110
- else if (result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
111
- return Qtrue;
112
- }
113
- else {
114
- lzws_ext_raise_error("UnexpectedError", "unexpected error");
115
- }
116
- }
117
-
118
- #define GET_STRING(source) \
119
- Check_Type(source, T_STRING); \
120
- \
121
- const char* source_data = RSTRING_PTR(source); \
122
- size_t source_length = RSTRING_LEN(source);
123
-
124
- VALUE lzws_ext_compress(VALUE self, VALUE source)
104
+ VALUE lzws_ext_compress(VALUE self, VALUE source_value)
125
105
  {
126
106
  GET_COMPRESSOR(self);
127
107
  DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
128
- GET_STRING(source);
129
-
130
- uint8_t* remaining_source_data = (uint8_t*)source_data;
131
- size_t remaining_source_length = source_length;
108
+ GET_SOURCE_DATA(source_value);
132
109
 
133
110
  lzws_result_t result = lzws_compress(
134
111
  compressor_ptr->state_ptr,
135
- &remaining_source_data,
136
- &remaining_source_length,
137
- &compressor_ptr->remaining_destination_buffer,
138
- &compressor_ptr->remaining_destination_buffer_length);
139
-
140
- VALUE bytes_written = INT2NUM(source_length - remaining_source_length);
112
+ &remaining_source, &remaining_source_length,
113
+ &compressor_ptr->remaining_destination_buffer, &compressor_ptr->remaining_destination_buffer_length);
141
114
 
142
- if (result == LZWS_COMPRESSOR_NEEDS_MORE_SOURCE) {
143
- return rb_ary_new_from_args(2, bytes_written, Qfalse);
144
- }
145
- else if (result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
146
- return rb_ary_new_from_args(2, bytes_written, Qtrue);
147
- }
148
- else {
149
- lzws_ext_raise_error("UnexpectedError", "unexpected error");
115
+ if (
116
+ result != 0 &&
117
+ result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
118
+ lzws_ext_raise_error(LZWS_EXT_ERROR_UNEXPECTED);
150
119
  }
120
+
121
+ VALUE bytes_written = SIZET2NUM(source_length - remaining_source_length);
122
+ VALUE needs_more_destination = result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
123
+
124
+ return rb_ary_new_from_args(2, bytes_written, needs_more_destination);
151
125
  }
152
126
 
153
- VALUE lzws_ext_flush_compressor(VALUE self)
127
+ VALUE lzws_ext_compressor_finish(VALUE self)
154
128
  {
155
129
  GET_COMPRESSOR(self);
156
130
  DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
157
131
 
158
- lzws_result_t result = lzws_flush_compressor(
132
+ lzws_result_t result = lzws_compressor_finish(
159
133
  compressor_ptr->state_ptr,
160
- &compressor_ptr->remaining_destination_buffer,
161
- &compressor_ptr->remaining_destination_buffer_length);
134
+ &compressor_ptr->remaining_destination_buffer, &compressor_ptr->remaining_destination_buffer_length);
162
135
 
163
- if (result == 0) {
164
- return Qfalse;
165
- }
166
- else if (result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
167
- return Qtrue;
168
- }
169
- else {
170
- lzws_ext_raise_error("UnexpectedError", "unexpected error");
136
+ if (
137
+ result != 0 &&
138
+ result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
139
+ lzws_ext_raise_error(LZWS_EXT_ERROR_UNEXPECTED);
171
140
  }
141
+
142
+ VALUE needs_more_destination = result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
143
+
144
+ return needs_more_destination;
172
145
  }
173
146
 
174
147
  VALUE lzws_ext_compressor_read_result(VALUE self)
@@ -176,19 +149,19 @@ VALUE lzws_ext_compressor_read_result(VALUE self)
176
149
  GET_COMPRESSOR(self);
177
150
  DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
178
151
 
179
- uint8_t* destination_buffer = compressor_ptr->destination_buffer;
180
- size_t destination_buffer_length = compressor_ptr->destination_buffer_length;
181
- size_t remaining_destination_buffer_length = compressor_ptr->remaining_destination_buffer_length;
152
+ lzws_ext_byte_t* destination_buffer = compressor_ptr->destination_buffer;
153
+ size_t destination_buffer_length = compressor_ptr->destination_buffer_length;
154
+ size_t remaining_destination_buffer_length = compressor_ptr->remaining_destination_buffer_length;
182
155
 
183
- const char* result_data = (const char*)destination_buffer;
156
+ const char* result = (const char*)destination_buffer;
184
157
  size_t result_length = destination_buffer_length - remaining_destination_buffer_length;
185
158
 
186
- VALUE result = rb_str_new(result_data, result_length);
159
+ VALUE result_value = rb_str_new(result, result_length);
187
160
 
188
161
  compressor_ptr->remaining_destination_buffer = destination_buffer;
189
162
  compressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
190
163
 
191
- return result;
164
+ return result_value;
192
165
  }
193
166
 
194
167
  VALUE lzws_ext_compressor_close(VALUE self)
@@ -203,7 +176,7 @@ VALUE lzws_ext_compressor_close(VALUE self)
203
176
  compressor_ptr->state_ptr = NULL;
204
177
  }
205
178
 
206
- uint8_t* destination_buffer = compressor_ptr->destination_buffer;
179
+ lzws_ext_byte_t* destination_buffer = compressor_ptr->destination_buffer;
207
180
  if (destination_buffer != NULL) {
208
181
  free(destination_buffer);
209
182
 
@@ -215,3 +188,17 @@ VALUE lzws_ext_compressor_close(VALUE self)
215
188
 
216
189
  return Qnil;
217
190
  }
191
+
192
+ void lzws_ext_compressor_exports(VALUE root_module)
193
+ {
194
+ VALUE module = rb_define_module_under(root_module, "Stream");
195
+
196
+ VALUE compressor = rb_define_class_under(module, "NativeCompressor", rb_cObject);
197
+
198
+ rb_define_alloc_func(compressor, lzws_ext_allocate_compressor);
199
+ rb_define_method(compressor, "initialize", lzws_ext_initialize_compressor, 1);
200
+ rb_define_method(compressor, "write", lzws_ext_compress, 1);
201
+ rb_define_method(compressor, "finish", lzws_ext_compressor_finish, 0);
202
+ rb_define_method(compressor, "read_result", lzws_ext_compressor_read_result, 0);
203
+ rb_define_method(compressor, "close", lzws_ext_compressor_close, 0);
204
+ }
@@ -5,23 +5,26 @@
5
5
  #define LZWS_EXT_STREAM_COMPRESSOR_H
6
6
 
7
7
  #include <lzws/compressor/state.h>
8
+ #include <stdlib.h>
8
9
 
10
+ #include "lzws_ext/common.h"
9
11
  #include "ruby.h"
10
12
 
11
13
  typedef struct {
12
14
  lzws_compressor_state_t* state_ptr;
13
- uint8_t* destination_buffer;
15
+ lzws_ext_byte_t* destination_buffer;
14
16
  size_t destination_buffer_length;
15
- uint8_t* remaining_destination_buffer;
17
+ lzws_ext_byte_t* remaining_destination_buffer;
16
18
  size_t remaining_destination_buffer_length;
17
19
  } lzws_ext_compressor_t;
18
20
 
19
21
  VALUE lzws_ext_allocate_compressor(VALUE klass);
20
22
  VALUE lzws_ext_initialize_compressor(VALUE self, VALUE options);
21
- VALUE lzws_ext_compressor_write_magic_header(VALUE self);
22
23
  VALUE lzws_ext_compress(VALUE self, VALUE source);
23
- VALUE lzws_ext_flush_compressor(VALUE self);
24
+ VALUE lzws_ext_compressor_finish(VALUE self);
24
25
  VALUE lzws_ext_compressor_read_result(VALUE self);
25
26
  VALUE lzws_ext_compressor_close(VALUE self);
26
27
 
28
+ void lzws_ext_compressor_exports(VALUE root_module);
29
+
27
30
  #endif // LZWS_EXT_STREAM_COMPRESSOR_H
@@ -1,18 +1,17 @@
1
1
  // Ruby bindings for lzws library.
2
2
  // Copyright (c) 2019 AUTHORS, MIT License.
3
3
 
4
+ #include "lzws_ext/stream/decompressor.h"
5
+
4
6
  #include <lzws/buffer.h>
7
+ #include <lzws/common.h>
5
8
  #include <lzws/decompressor/common.h>
6
- #include <lzws/decompressor/header.h>
7
9
  #include <lzws/decompressor/main.h>
8
10
  #include <lzws/decompressor/state.h>
9
11
 
10
- #include "ruby.h"
11
-
12
12
  #include "lzws_ext/error.h"
13
- #include "lzws_ext/macro.h"
14
13
  #include "lzws_ext/option.h"
15
- #include "lzws_ext/stream/decompressor.h"
14
+ #include "ruby.h"
16
15
 
17
16
  static void free_decompressor(lzws_ext_decompressor_t* decompressor_ptr)
18
17
  {
@@ -21,7 +20,7 @@ static void free_decompressor(lzws_ext_decompressor_t* decompressor_ptr)
21
20
  lzws_decompressor_free_state(state_ptr);
22
21
  }
23
22
 
24
- uint8_t* destination_buffer = decompressor_ptr->destination_buffer;
23
+ lzws_ext_byte_t* destination_buffer = decompressor_ptr->destination_buffer;
25
24
  if (destination_buffer != NULL) {
26
25
  free(destination_buffer);
27
26
  }
@@ -51,34 +50,34 @@ VALUE lzws_ext_allocate_decompressor(VALUE klass)
51
50
  VALUE lzws_ext_initialize_decompressor(VALUE self, VALUE options)
52
51
  {
53
52
  GET_DECOMPRESSOR(self);
53
+ Check_Type(options, T_HASH);
54
54
  LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
55
- LZWS_EXT_UNUSED_VARIABLE(without_magic_header);
55
+ LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
56
56
 
57
- lzws_decompressor_state_t* decompressor_state_ptr;
57
+ lzws_decompressor_state_t* state_ptr;
58
58
 
59
59
  lzws_result_t result = lzws_decompressor_get_initial_state(
60
- &decompressor_state_ptr,
61
- msb, unaligned_bit_groups, quiet);
60
+ &state_ptr,
61
+ without_magic_header, msb, unaligned_bit_groups, quiet);
62
62
 
63
- if (result == LZWS_DECOMPRESSOR_ALLOCATE_FAILED) {
64
- lzws_ext_raise_error("AllocateError", "allocate error");
65
- }
66
- else if (result != 0) {
67
- lzws_ext_raise_error("UnexpectedError", "unexpected error");
63
+ if (result != 0) {
64
+ switch (result) {
65
+ case LZWS_DECOMPRESSOR_ALLOCATE_FAILED:
66
+ lzws_ext_raise_error(LZWS_EXT_ERROR_ALLOCATE_FAILED);
67
+ default:
68
+ lzws_ext_raise_error(LZWS_EXT_ERROR_UNEXPECTED);
69
+ }
68
70
  }
69
71
 
70
- decompressor_ptr->state_ptr = decompressor_state_ptr;
71
-
72
- // -----
73
-
74
- uint8_t* destination_buffer;
75
- size_t destination_buffer_length = buffer_length;
72
+ lzws_ext_byte_t* destination_buffer;
76
73
 
77
- result = lzws_create_buffer_for_decompressor(&destination_buffer, &destination_buffer_length, quiet);
74
+ result = lzws_create_destination_buffer_for_decompressor(&destination_buffer, &destination_buffer_length, quiet);
78
75
  if (result != 0) {
79
- lzws_ext_raise_error("AllocateError", "allocate error");
76
+ lzws_decompressor_free_state(state_ptr);
77
+ lzws_ext_raise_error(LZWS_EXT_ERROR_ALLOCATE_FAILED);
80
78
  }
81
79
 
80
+ decompressor_ptr->state_ptr = state_ptr;
82
81
  decompressor_ptr->destination_buffer = destination_buffer;
83
82
  decompressor_ptr->destination_buffer_length = destination_buffer_length;
84
83
  decompressor_ptr->remaining_destination_buffer = destination_buffer;
@@ -87,77 +86,48 @@ VALUE lzws_ext_initialize_decompressor(VALUE self, VALUE options)
87
86
  return Qnil;
88
87
  }
89
88
 
90
- #define GET_STRING(source) \
91
- Check_Type(source, T_STRING); \
92
- \
93
- const char* source_data = RSTRING_PTR(source); \
94
- size_t source_length = RSTRING_LEN(source);
95
-
96
89
  #define DO_NOT_USE_AFTER_CLOSE(decompressor_ptr) \
97
90
  if (decompressor_ptr->state_ptr == NULL || decompressor_ptr->destination_buffer == NULL) { \
98
- lzws_ext_raise_error("UsedAfterCloseError", "decompressor used after close"); \
91
+ lzws_ext_raise_error(LZWS_EXT_ERROR_USED_AFTER_CLOSE); \
99
92
  }
100
93
 
101
- VALUE lzws_ext_decompressor_read_magic_header(VALUE self, VALUE source)
102
- {
103
- GET_DECOMPRESSOR(self);
104
- DO_NOT_USE_AFTER_CLOSE(decompressor_ptr);
105
- GET_STRING(source);
106
-
107
- uint8_t* remaining_source_data = (uint8_t*)source_data;
108
- size_t remaining_source_length = source_length;
109
-
110
- lzws_result_t result = lzws_decompressor_read_magic_header(
111
- decompressor_ptr->state_ptr,
112
- &remaining_source_data,
113
- &remaining_source_length);
114
-
115
- VALUE bytes_read = INT2NUM(source_length - remaining_source_length);
94
+ #define GET_SOURCE_DATA(source_value) \
95
+ Check_Type(source_value, T_STRING); \
96
+ \
97
+ const char* source = RSTRING_PTR(source_value); \
98
+ size_t source_length = RSTRING_LEN(source_value); \
99
+ lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*)source; \
100
+ size_t remaining_source_length = source_length;
116
101
 
117
- if (result == 0 || result == LZWS_DECOMPRESSOR_NEEDS_MORE_SOURCE) {
118
- return bytes_read;
119
- }
120
- else if (result == LZWS_DECOMPRESSOR_INVALID_MAGIC_HEADER) {
121
- lzws_ext_raise_error("ValidateError", "validate error");
122
- }
123
- else {
124
- lzws_ext_raise_error("UnexpectedError", "unexpected error");
125
- }
126
- }
127
-
128
- VALUE lzws_ext_decompress(VALUE self, VALUE source)
102
+ VALUE lzws_ext_decompress(VALUE self, VALUE source_value)
129
103
  {
130
104
  GET_DECOMPRESSOR(self);
131
105
  DO_NOT_USE_AFTER_CLOSE(decompressor_ptr);
132
- GET_STRING(source);
133
-
134
- uint8_t* remaining_source_data = (uint8_t*)source_data;
135
- size_t remaining_source_length = source_length;
106
+ GET_SOURCE_DATA(source_value);
136
107
 
137
108
  lzws_result_t result = lzws_decompress(
138
109
  decompressor_ptr->state_ptr,
139
- &remaining_source_data,
140
- &remaining_source_length,
141
- &decompressor_ptr->remaining_destination_buffer,
142
- &decompressor_ptr->remaining_destination_buffer_length);
143
-
144
- VALUE bytes_read = INT2NUM(source_length - remaining_source_length);
145
-
146
- if (result == LZWS_DECOMPRESSOR_NEEDS_MORE_SOURCE) {
147
- return rb_ary_new_from_args(2, bytes_read, Qfalse);
148
- }
149
- else if (result == LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
150
- return rb_ary_new_from_args(2, bytes_read, Qtrue);
151
- }
152
- else if (result == LZWS_DECOMPRESSOR_INVALID_MAX_CODE_BIT_LENGTH) {
153
- lzws_ext_raise_error("ValidateError", "validate error");
154
- }
155
- else if (result == LZWS_DECOMPRESSOR_CORRUPTED_SOURCE) {
156
- lzws_ext_raise_error("DecompressorCorruptedSourceError", "decompressor received corrupted source");
157
- }
158
- else {
159
- lzws_ext_raise_error("UnexpectedError", "unexpected error");
160
- }
110
+ &remaining_source, &remaining_source_length,
111
+ &decompressor_ptr->remaining_destination_buffer, &decompressor_ptr->remaining_destination_buffer_length);
112
+
113
+ if (
114
+ result != 0 &&
115
+ result != LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
116
+ switch (result) {
117
+ case LZWS_DECOMPRESSOR_INVALID_MAGIC_HEADER:
118
+ case LZWS_DECOMPRESSOR_INVALID_MAX_CODE_BIT_LENGTH:
119
+ lzws_ext_raise_error(LZWS_EXT_ERROR_VALIDATE_FAILED);
120
+ case LZWS_DECOMPRESSOR_CORRUPTED_SOURCE:
121
+ lzws_ext_raise_error(LZWS_EXT_ERROR_DECOMPRESSOR_CORRUPTED_SOURCE);
122
+ default:
123
+ lzws_ext_raise_error(LZWS_EXT_ERROR_UNEXPECTED);
124
+ }
125
+ }
126
+
127
+ VALUE bytes_read = SIZET2NUM(source_length - remaining_source_length);
128
+ VALUE needs_more_destination = result == LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
129
+
130
+ return rb_ary_new_from_args(2, bytes_read, needs_more_destination);
161
131
  }
162
132
 
163
133
  VALUE lzws_ext_decompressor_read_result(VALUE self)
@@ -165,19 +135,19 @@ VALUE lzws_ext_decompressor_read_result(VALUE self)
165
135
  GET_DECOMPRESSOR(self);
166
136
  DO_NOT_USE_AFTER_CLOSE(decompressor_ptr);
167
137
 
168
- uint8_t* destination_buffer = decompressor_ptr->destination_buffer;
169
- size_t destination_buffer_length = decompressor_ptr->destination_buffer_length;
170
- size_t remaining_destination_buffer_length = decompressor_ptr->remaining_destination_buffer_length;
138
+ lzws_ext_byte_t* destination_buffer = decompressor_ptr->destination_buffer;
139
+ size_t destination_buffer_length = decompressor_ptr->destination_buffer_length;
140
+ size_t remaining_destination_buffer_length = decompressor_ptr->remaining_destination_buffer_length;
171
141
 
172
- const char* result_data = (const char*)destination_buffer;
142
+ const char* result = (const char*)destination_buffer;
173
143
  size_t result_length = destination_buffer_length - remaining_destination_buffer_length;
174
144
 
175
- VALUE result = rb_str_new(result_data, result_length);
145
+ VALUE result_value = rb_str_new(result, result_length);
176
146
 
177
147
  decompressor_ptr->remaining_destination_buffer = destination_buffer;
178
148
  decompressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
179
149
 
180
- return result;
150
+ return result_value;
181
151
  }
182
152
 
183
153
  VALUE lzws_ext_decompressor_close(VALUE self)
@@ -192,7 +162,7 @@ VALUE lzws_ext_decompressor_close(VALUE self)
192
162
  decompressor_ptr->state_ptr = NULL;
193
163
  }
194
164
 
195
- uint8_t* destination_buffer = decompressor_ptr->destination_buffer;
165
+ lzws_ext_byte_t* destination_buffer = decompressor_ptr->destination_buffer;
196
166
  if (destination_buffer != NULL) {
197
167
  free(destination_buffer);
198
168
 
@@ -204,3 +174,16 @@ VALUE lzws_ext_decompressor_close(VALUE self)
204
174
 
205
175
  return Qnil;
206
176
  }
177
+
178
+ void lzws_ext_decompressor_exports(VALUE root_module)
179
+ {
180
+ VALUE module = rb_define_module_under(root_module, "Stream");
181
+
182
+ VALUE decompressor = rb_define_class_under(module, "NativeDecompressor", rb_cObject);
183
+
184
+ rb_define_alloc_func(decompressor, lzws_ext_allocate_decompressor);
185
+ rb_define_method(decompressor, "initialize", lzws_ext_initialize_decompressor, 1);
186
+ rb_define_method(decompressor, "read", lzws_ext_decompress, 1);
187
+ rb_define_method(decompressor, "read_result", lzws_ext_decompressor_read_result, 0);
188
+ rb_define_method(decompressor, "close", lzws_ext_decompressor_close, 0);
189
+ }