libarchive-ruby-fs 0.2.1 → 0.2.2

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.
@@ -1,246 +1,267 @@
1
- #include "libarchive_internal.h"
2
-
3
- extern VALUE rb_mArchive;
4
- VALUE rb_cArchiveWriter;
5
- extern VALUE rb_eArchiveError;
6
- extern VALUE rb_cArchiveEntry;
7
-
8
- static void rb_libarchive_writer_close0(struct rb_libarchive_archive_container *p) {
9
- archive_write_close(p->ar);
10
- archive_write_finish(p->ar);
11
- p->ar = NULL;
12
- }
13
-
14
- /* */
15
- static VALUE rb_libarchive_writer_close(VALUE self) {
16
- struct rb_libarchive_archive_container *p;
17
- Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
18
- Check_Archive(p);
19
- rb_libarchive_writer_close0(p);
20
- return Qnil;
21
- }
22
-
23
- static VALUE rb_libarchive_writer_s_open0(int (*archive_open)(struct rb_libarchive_archive_container *, void *), void *arg, int compression, int format, const char *cmd) {
24
- VALUE writer;
25
- struct rb_libarchive_archive_container *p;
26
- int r;
27
- writer = rb_funcall(rb_cArchiveWriter, rb_intern("new"), 0);
28
- Data_Get_Struct(writer, struct rb_libarchive_archive_container, p);
29
-
30
- if ((p->ar = archive_write_new()) == NULL) {
31
- rb_raise(rb_eArchiveError, "Open writer failed: %s", strerror(errno));
32
- }
33
-
34
- if (cmd != NULL) {
35
- r = archive_write_set_compression_program(p->ar, cmd);
36
- } else {
37
- r = archive_write_set_compression(p->ar, compression);
38
- }
39
-
40
- if (r != ARCHIVE_OK) {
41
- char error_string[BUFSIZ];
42
- archive_copy_error_string(p->ar, error_string, BUFSIZ);
43
- rb_libarchive_writer_close0(p);
44
- rb_raise(rb_eArchiveError, "Set compression failed: %s", error_string);
45
- }
46
-
47
- if (archive_write_set_format(p->ar, format) != ARCHIVE_OK) {
48
- char error_string[BUFSIZ];
49
- archive_copy_error_string(p->ar, error_string, BUFSIZ);
50
- rb_libarchive_writer_close0(p);
51
- rb_raise(rb_eArchiveError, "Set format failed: %s", error_string);
52
- }
53
-
54
- if (archive_open(p, arg) != ARCHIVE_OK) {
55
- char error_string[BUFSIZ];
56
- archive_copy_error_string(p->ar, error_string, BUFSIZ);
57
- rb_libarchive_writer_close0(p);
58
- rb_raise(rb_eArchiveError, "Open writer failed: %s", error_string);
59
- }
60
-
61
- if (rb_block_given_p()) {
62
- VALUE retval;
63
- int status;
64
- retval = rb_protect(rb_yield, writer, &status);
65
- rb_libarchive_writer_close0(p);
66
-
67
- if (status != 0) {
68
- rb_jump_tag(status);
69
- }
70
-
71
- return retval;
72
- } else {
73
- return writer;
74
- }
75
- }
76
-
77
- static int rb_libarchive_writer_s_open_filename0(struct rb_libarchive_archive_container *p, void *arg) {
78
- const char *filename = (const char *) arg;
79
- return archive_write_open_filename(p->ar, filename);
80
- }
81
-
82
- /* */
83
- static VALUE rb_libarchive_writer_s_open_filename(VALUE self, VALUE v_filename, VALUE v_compression, VALUE v_format) {
84
- const char *filename = NULL;
85
- int compression, format;
86
- const char *cmd = NULL;
87
- Check_Type(v_filename, T_STRING);
88
-
89
- if (RSTRING_LEN(v_filename) < 1) {
90
- rb_raise(rb_eArchiveError, "Open writer failed: No such file or directory");
91
- }
92
-
93
- filename = RSTRING_PTR(v_filename);
94
-
95
- if (T_STRING == TYPE(v_compression)) {
96
- compression = -1;
97
- cmd = RSTRING_PTR(v_compression);
98
- } else {
99
- compression = NUM2INT(v_compression);
100
- }
101
-
102
-
103
- format = NUM2INT(v_format);
104
- return rb_libarchive_writer_s_open0(rb_libarchive_writer_s_open_filename0, (void *) filename, compression, format, cmd);
105
- }
106
-
107
- static int rb_libarchive_writer_s_open_memory0(struct rb_libarchive_archive_container *p, void *arg) {
108
- VALUE str = (VALUE) arg;
109
- p->memory = str;
110
- return archive_write_open_rb_str(p->ar, str);
111
- }
112
-
113
- /* */
114
- static VALUE rb_libarchive_writer_s_open_memory(VALUE self, VALUE v_memory, VALUE v_compression, VALUE v_format) {
115
- int compression, format;
116
- const char *cmd = NULL;
117
- Check_Type(v_memory, T_STRING);
118
-
119
- if (T_STRING == TYPE(v_compression)) {
120
- compression = -1;
121
- cmd = RSTRING_PTR(v_compression);
122
- } else {
123
- compression = NUM2INT(v_compression);
124
- }
125
-
126
- format = NUM2INT(v_format);
127
- return rb_libarchive_writer_s_open0(rb_libarchive_writer_s_open_memory0, (void *) v_memory, compression, format, cmd);
128
- }
129
-
130
- /* */
131
- static VALUE rb_libarchive_writer_new_entry(VALUE self) {
132
- VALUE entry;
133
- struct rb_libarchive_archive_container *p;
134
- struct archive_entry *ae;
135
- Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
136
- Check_Archive(p);
137
-
138
- if ((ae = archive_entry_new()) == NULL) {
139
- rb_raise(rb_eArchiveError, "New entry failed: %s", strerror(errno));
140
- }
141
-
142
- entry = rb_libarchive_entry_new(ae, 1);
143
-
144
- if (rb_block_given_p()) {
145
- VALUE retval;
146
- int status;
147
- retval = rb_protect(rb_yield, entry, &status);
148
- rb_libarchive_entry_close(entry);
149
-
150
- if (status != 0) {
151
- rb_jump_tag(status);
152
- }
153
-
154
- return retval;
155
- } else {
156
- return entry;
157
- }
158
- }
159
-
160
- /* */
161
- static VALUE rb_libarchive_writer_write_header(VALUE self, VALUE v_entry) {
162
- struct rb_libarchive_archive_container *pa;
163
- struct rb_libarchive_entry_container *pae;
164
- Check_Class(v_entry, rb_cArchiveEntry);
165
- Data_Get_Struct(self, struct rb_libarchive_archive_container, pa);
166
- Check_Archive(pa);
167
- Data_Get_Struct(v_entry, struct rb_libarchive_entry_container, pae);
168
- Check_Entry(pae);
169
-
170
- if (archive_write_header(pa->ar, pae->ae) != ARCHIVE_OK) {
171
- rb_raise(rb_eArchiveError, "Write header failed: %s", archive_error_string(pa->ar));
172
- }
173
-
174
- return Qnil;
175
- }
176
-
177
- static ssize_t rb_libarchive_writer_write_data0(struct archive *ar, VALUE v_buff) {
178
- const char *buff;
179
- size_t size;
180
- ssize_t n;
181
-
182
- if (NIL_P(v_buff)) {
183
- return 0;
184
- }
185
-
186
- Check_Type(v_buff, T_STRING);
187
- buff = RSTRING_PTR(v_buff);
188
- size = RSTRING_LEN(v_buff);
189
-
190
- if (size < 1) {
191
- return 0;
192
- }
193
-
194
- if ((n = archive_write_data(ar, buff, size)) < 0) {
195
- rb_raise(rb_eArchiveError, "Write data failed: %s", archive_error_string(ar));
196
- }
197
-
198
- return n;
199
- }
200
-
201
- /* */
202
- static VALUE rb_libarchive_writer_write_data(int argc, VALUE *argv, VALUE self) {
203
- struct rb_libarchive_archive_container *p;
204
- Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
205
- Check_Archive(p);
206
-
207
- if (rb_block_given_p()) {
208
- ssize_t len = 0;
209
-
210
- if (argc > 0) {
211
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
212
- }
213
-
214
- while(1) {
215
- VALUE retval;
216
- ssize_t n;
217
- retval = rb_yield(Qnil);
218
-
219
- if ((n = rb_libarchive_writer_write_data0(p->ar, retval)) < 1) {
220
- return LONG2NUM(len);
221
- }
222
-
223
- len += n;
224
- }
225
- } else {
226
- VALUE v_buff;
227
- ssize_t n;
228
- rb_scan_args(argc, argv, "10", &v_buff);
229
- n = rb_libarchive_writer_write_data0(p->ar, v_buff);
230
- return LONG2NUM(n);
231
- }
232
- }
233
-
234
- void Init_libarchive_writer() {
235
- rb_cArchiveWriter = rb_define_class_under(rb_mArchive, "Writer", rb_cObject);
236
- rb_define_alloc_func(rb_cArchiveWriter, rb_libarchive_archive_alloc);
237
- rb_funcall(rb_cArchiveWriter, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("new")));
238
- rb_define_singleton_method(rb_cArchiveWriter, "open_filename", rb_libarchive_writer_s_open_filename, 3);
239
- rb_define_singleton_method(rb_mArchive, "write_open_filename", rb_libarchive_writer_s_open_filename, 3);
240
- rb_define_singleton_method(rb_cArchiveWriter, "open_memory", rb_libarchive_writer_s_open_memory, 3);
241
- rb_define_singleton_method(rb_mArchive, "write_open_memory", rb_libarchive_writer_s_open_memory, 3);
242
- rb_define_method(rb_cArchiveWriter, "close", rb_libarchive_writer_close, 0);
243
- rb_define_method(rb_cArchiveWriter, "new_entry", rb_libarchive_writer_new_entry, 0);
244
- rb_define_method(rb_cArchiveWriter, "write_header", rb_libarchive_writer_write_header, 1);
245
- rb_define_method(rb_cArchiveWriter, "write_data", rb_libarchive_writer_write_data, -1);
246
- }
1
+ #include "libarchive_internal.h"
2
+
3
+ extern VALUE rb_mArchive;
4
+ VALUE rb_cArchiveWriter;
5
+ extern VALUE rb_eArchiveError;
6
+ extern VALUE rb_cArchiveEntry;
7
+
8
+ static void rb_libarchive_writer_close0(struct rb_libarchive_archive_container *p) {
9
+ archive_write_close(p->ar);
10
+ archive_write_finish(p->ar);
11
+ p->ar = NULL;
12
+ }
13
+
14
+ /* */
15
+ static VALUE rb_libarchive_writer_close(VALUE self) {
16
+ struct rb_libarchive_archive_container *p;
17
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
18
+ Check_Archive(p);
19
+ rb_libarchive_writer_close0(p);
20
+ return Qnil;
21
+ }
22
+
23
+ static VALUE rb_libarchive_writer_s_open0(int (*archive_open)(struct rb_libarchive_archive_container *, void *), void *arg, int compression, int format, const char *cmd) {
24
+ VALUE writer;
25
+ struct rb_libarchive_archive_container *p;
26
+ int r;
27
+ writer = rb_funcall(rb_cArchiveWriter, rb_intern("new"), 0);
28
+ Data_Get_Struct(writer, struct rb_libarchive_archive_container, p);
29
+
30
+ if ((p->ar = archive_write_new()) == NULL) {
31
+ rb_raise(rb_eArchiveError, "Open writer failed: %s", strerror(errno));
32
+ }
33
+
34
+ if (cmd != NULL) {
35
+ r = archive_write_set_compression_program(p->ar, cmd);
36
+ } else {
37
+ r = archive_write_set_compression(p->ar, compression);
38
+ }
39
+
40
+ if (r != ARCHIVE_OK) {
41
+ char error_string[BUFSIZ];
42
+ archive_copy_error_string(p->ar, error_string, BUFSIZ);
43
+ rb_libarchive_writer_close0(p);
44
+ rb_raise(rb_eArchiveError, "Set compression failed: %s", error_string);
45
+ }
46
+
47
+ if (archive_write_set_format(p->ar, format) != ARCHIVE_OK) {
48
+ char error_string[BUFSIZ];
49
+ archive_copy_error_string(p->ar, error_string, BUFSIZ);
50
+ rb_libarchive_writer_close0(p);
51
+ rb_raise(rb_eArchiveError, "Set format failed: %s", error_string);
52
+ }
53
+
54
+ if (archive_open(p, arg) != ARCHIVE_OK) {
55
+ char error_string[BUFSIZ];
56
+ archive_copy_error_string(p->ar, error_string, BUFSIZ);
57
+ rb_libarchive_writer_close0(p);
58
+ rb_raise(rb_eArchiveError, "Open writer failed: %s", error_string);
59
+ }
60
+
61
+ if (rb_block_given_p()) {
62
+ VALUE retval;
63
+ int status;
64
+ retval = rb_protect(rb_yield, writer, &status);
65
+ rb_libarchive_writer_close0(p);
66
+
67
+ if (status != 0) {
68
+ rb_jump_tag(status);
69
+ }
70
+
71
+ return retval;
72
+ } else {
73
+ return writer;
74
+ }
75
+ }
76
+
77
+ static int rb_libarchive_writer_s_open_filename0(struct rb_libarchive_archive_container *p, void *arg) {
78
+ const char *filename = (const char *) arg;
79
+ return archive_write_open_filename(p->ar, filename);
80
+ }
81
+
82
+ /* */
83
+ static VALUE rb_libarchive_writer_s_open_filename(VALUE self, VALUE v_filename, VALUE v_compression, VALUE v_format) {
84
+ const char *filename = NULL;
85
+ int compression, format;
86
+ const char *cmd = NULL;
87
+ Check_Type(v_filename, T_STRING);
88
+
89
+ if (RSTRING_LEN(v_filename) < 1) {
90
+ rb_raise(rb_eArchiveError, "Open writer failed: No such file or directory");
91
+ }
92
+
93
+ filename = RSTRING_PTR(v_filename);
94
+
95
+ if (T_STRING == TYPE(v_compression)) {
96
+ compression = -1;
97
+ cmd = RSTRING_PTR(v_compression);
98
+ } else {
99
+ compression = NUM2INT(v_compression);
100
+ }
101
+
102
+
103
+ format = NUM2INT(v_format);
104
+ return rb_libarchive_writer_s_open0(rb_libarchive_writer_s_open_filename0, (void *) filename, compression, format, cmd);
105
+ }
106
+
107
+ static int rb_libarchive_writer_s_open_memory0(struct rb_libarchive_archive_container *p, void *arg) {
108
+ VALUE str = (VALUE) arg;
109
+ p->memory = str;
110
+ return archive_write_open_rb_str(p->ar, str);
111
+ }
112
+
113
+ /* */
114
+ static VALUE rb_libarchive_writer_s_open_memory(VALUE self, VALUE v_memory, VALUE v_compression, VALUE v_format) {
115
+ int compression, format;
116
+ const char *cmd = NULL;
117
+ Check_Type(v_memory, T_STRING);
118
+
119
+ if (T_STRING == TYPE(v_compression)) {
120
+ compression = -1;
121
+ cmd = RSTRING_PTR(v_compression);
122
+ } else {
123
+ compression = NUM2INT(v_compression);
124
+ }
125
+
126
+ format = NUM2INT(v_format);
127
+ return rb_libarchive_writer_s_open0(rb_libarchive_writer_s_open_memory0, (void *) v_memory, compression, format, cmd);
128
+ }
129
+
130
+ /* */
131
+ static VALUE rb_libarchive_writer_new_entry(VALUE self) {
132
+ VALUE entry;
133
+ struct rb_libarchive_archive_container *p;
134
+ struct archive_entry *ae;
135
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
136
+ Check_Archive(p);
137
+
138
+ if ((ae = archive_entry_new()) == NULL) {
139
+ rb_raise(rb_eArchiveError, "New entry failed: %s", strerror(errno));
140
+ }
141
+
142
+ entry = rb_libarchive_entry_new(ae, 1);
143
+
144
+ if (rb_block_given_p()) {
145
+ VALUE retval;
146
+ int status;
147
+ retval = rb_protect(rb_yield, entry, &status);
148
+ rb_libarchive_entry_close(entry);
149
+
150
+ if (status != 0) {
151
+ rb_jump_tag(status);
152
+ }
153
+
154
+ return retval;
155
+ } else {
156
+ return entry;
157
+ }
158
+ }
159
+
160
+ /* */
161
+ static VALUE rb_libarchive_writer_write_header(VALUE self, VALUE v_entry) {
162
+ struct rb_libarchive_archive_container *pa;
163
+ struct rb_libarchive_entry_container *pae;
164
+ Check_Class(v_entry, rb_cArchiveEntry);
165
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, pa);
166
+ Check_Archive(pa);
167
+ Data_Get_Struct(v_entry, struct rb_libarchive_entry_container, pae);
168
+ Check_Entry(pae);
169
+
170
+ if (archive_write_header(pa->ar, pae->ae) != ARCHIVE_OK) {
171
+ rb_raise(rb_eArchiveError, "Write header failed: %s", archive_error_string(pa->ar));
172
+ }
173
+
174
+ return Qnil;
175
+ }
176
+
177
+ typedef struct _archive_write_data_p {
178
+ struct archive* ar;
179
+ const char* buff;
180
+ ssize_t size;
181
+ int bytes_written;
182
+ } archive_write_data_p;
183
+
184
+ static void* rb_libarchive_writer_write_data1(void* _params)
185
+ {
186
+ archive_write_data_p* params = (archive_write_data_p*) _params;
187
+ params->bytes_written = archive_write_data(params->ar, params->buff, params->size);
188
+ return NULL;
189
+ }
190
+
191
+ static ssize_t rb_libarchive_writer_write_data0(struct archive *ar, VALUE v_buff) {
192
+ archive_write_data_p params = { ar, NULL, 0, -1 };
193
+
194
+ if (NIL_P(v_buff)) {
195
+ return 0;
196
+ }
197
+
198
+ Check_Type(v_buff, T_STRING);
199
+ params.buff = RSTRING_PTR(v_buff);
200
+ params.size = RSTRING_LEN(v_buff);
201
+
202
+ if (params.size < 1) {
203
+ return 0;
204
+ }
205
+
206
+ /*
207
+ * Let's only release the GIL when the buffer has a reasonable size.
208
+ * Re-acquiring the GIL is expensive.
209
+ */
210
+ if (params.size > 65536)
211
+ rb_thread_call_without_gvl(rb_libarchive_writer_write_data1, (void*) &params, NULL, NULL);
212
+ else
213
+ rb_libarchive_writer_write_data1((void*) &params);
214
+
215
+ if (params.bytes_written < 0) {
216
+ rb_raise(rb_eArchiveError, "Write data failed: %s", archive_error_string(ar));
217
+ }
218
+
219
+ return params.bytes_written;
220
+ }
221
+
222
+ /* */
223
+ static VALUE rb_libarchive_writer_write_data(int argc, VALUE *argv, VALUE self) {
224
+ struct rb_libarchive_archive_container *p;
225
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
226
+ Check_Archive(p);
227
+
228
+ if (rb_block_given_p()) {
229
+ ssize_t len = 0;
230
+
231
+ if (argc > 0) {
232
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
233
+ }
234
+
235
+ while(1) {
236
+ VALUE retval;
237
+ ssize_t n;
238
+ retval = rb_yield(Qnil);
239
+
240
+ if ((n = rb_libarchive_writer_write_data0(p->ar, retval)) < 1) {
241
+ return LONG2NUM(len);
242
+ }
243
+
244
+ len += n;
245
+ }
246
+ } else {
247
+ VALUE v_buff;
248
+ ssize_t n;
249
+ rb_scan_args(argc, argv, "10", &v_buff);
250
+ n = rb_libarchive_writer_write_data0(p->ar, v_buff);
251
+ return LONG2NUM(n);
252
+ }
253
+ }
254
+
255
+ void Init_libarchive_writer() {
256
+ rb_cArchiveWriter = rb_define_class_under(rb_mArchive, "Writer", rb_cObject);
257
+ rb_define_alloc_func(rb_cArchiveWriter, rb_libarchive_archive_alloc);
258
+ rb_funcall(rb_cArchiveWriter, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("new")));
259
+ rb_define_singleton_method(rb_cArchiveWriter, "open_filename", rb_libarchive_writer_s_open_filename, 3);
260
+ rb_define_singleton_method(rb_mArchive, "write_open_filename", rb_libarchive_writer_s_open_filename, 3);
261
+ rb_define_singleton_method(rb_cArchiveWriter, "open_memory", rb_libarchive_writer_s_open_memory, 3);
262
+ rb_define_singleton_method(rb_mArchive, "write_open_memory", rb_libarchive_writer_s_open_memory, 3);
263
+ rb_define_method(rb_cArchiveWriter, "close", rb_libarchive_writer_close, 0);
264
+ rb_define_method(rb_cArchiveWriter, "new_entry", rb_libarchive_writer_new_entry, 0);
265
+ rb_define_method(rb_cArchiveWriter, "write_header", rb_libarchive_writer_write_header, 1);
266
+ rb_define_method(rb_cArchiveWriter, "write_data", rb_libarchive_writer_write_data, -1);
267
+ }