zipruby 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of zipruby might be problematic. Click here for more details.

data/ext/zipruby.h CHANGED
@@ -1,7 +1,7 @@
1
1
  #ifndef __ZIPRUBY_H__
2
2
  #define __ZIPRUBY_H__
3
3
 
4
- #define VERSION "0.1.0"
4
+ #define VERSION "0.1.1"
5
5
  #define ERRSTR_BUFSIZE 256
6
6
 
7
7
  void Init_zipruby();
@@ -1,3 +1,5 @@
1
+ #include <errno.h>
2
+
1
3
  #include "zip.h"
2
4
  #include "zipruby.h"
3
5
  #include "zipruby_archive.h"
@@ -15,10 +17,13 @@ static VALUE zipruby_archive_get_stat(int argc, VALUE *argv, VALUE self);
15
17
  static VALUE zipruby_archive_add_buffer(VALUE self, VALUE name, VALUE source);
16
18
  static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self);
17
19
  static VALUE zipruby_archive_add_filep(int argc, VALUE *argv, VALUE self);
18
- static VALUE zipruby_archive_add_zip(VALUE self, VALUE srcarchive);
19
20
  static VALUE zipruby_archive_replace_buffer(VALUE self, VALUE index, VALUE source);
20
21
  static VALUE zipruby_archive_replace_file(VALUE self, VALUE index, VALUE fname);
21
22
  static VALUE zipruby_archive_replace_filep(VALUE self, VALUE index, VALUE file);
23
+ static VALUE zipruby_archive_add_or_replace_buffer(VALUE self, VALUE name, VALUE source);
24
+ static VALUE zipruby_archive_add_or_replace_file(int argc, VALUE *argv, VALUE self);
25
+ static VALUE zipruby_archive_add_or_replace_filep(int argc, VALUE *argv, VALUE self);
26
+ static VALUE zipruby_archive_update(VALUE self, VALUE srcarchive);
22
27
  static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self);
23
28
  static VALUE zipruby_archive_set_comment(VALUE self, VALUE comment);
24
29
  static VALUE zipruby_archive_locate_name(int argc, VALUE *argv, VALUE self);
@@ -51,10 +56,13 @@ void Init_zipruby_archive() {
51
56
  rb_define_method(Archive, "add_buffer", zipruby_archive_add_buffer, 2);
52
57
  rb_define_method(Archive, "add_file", zipruby_archive_add_file, -1);
53
58
  rb_define_method(Archive, "add_filep", zipruby_archive_add_filep, -1);
54
- rb_define_method(Archive, "add_zip", zipruby_archive_add_zip, 1);
55
59
  rb_define_method(Archive, "replace_buffer", zipruby_archive_replace_buffer, 2);
56
60
  rb_define_method(Archive, "replace_file", zipruby_archive_replace_file, 2);
57
61
  rb_define_method(Archive, "replace_filep", zipruby_archive_replace_filep, 2);
62
+ rb_define_method(Archive, "add_or_replace_buffer", zipruby_archive_add_or_replace_buffer, 2);
63
+ rb_define_method(Archive, "add_or_replace_file", zipruby_archive_add_or_replace_file, -1);
64
+ rb_define_method(Archive, "add_or_replace_filep", zipruby_archive_add_or_replace_filep, -1);
65
+ rb_define_method(Archive, "update", zipruby_archive_update, 1);
58
66
  rb_define_method(Archive, "<<", zipruby_archive_add_filep, -1);
59
67
  rb_define_method(Archive, "get_comment", zipruby_archive_get_comment, -1);
60
68
  rb_define_method(Archive, "comment", zipruby_archive_get_comment, -1);
@@ -173,7 +181,7 @@ static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self) {
173
181
  Check_Archive(p_archive);
174
182
 
175
183
  if ((name = zip_get_name(p_archive->archive, NUM2INT(index), i_flags)) == NULL) {
176
- rb_raise(Error, "Get name failed: %s", zip_strerror(p_archive->archive));
184
+ rb_raise(Error, "Get name failed at %d: %s", index, zip_strerror(p_archive->archive));
177
185
  }
178
186
 
179
187
  return (name != NULL) ? rb_str_new2(name) : Qnil;
@@ -279,6 +287,24 @@ static VALUE zipruby_archive_replace_buffer(VALUE self, VALUE index, VALUE sourc
279
287
  return Qnil;
280
288
  }
281
289
 
290
+ /* */
291
+ static VALUE zipruby_archive_add_or_replace_buffer(VALUE self, VALUE name, VALUE source) {
292
+ struct zipruby_archive *p_archive;
293
+ int index;
294
+
295
+ Check_Type(name, T_STRING);
296
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
297
+ Check_Archive(p_archive);
298
+
299
+ index = zip_name_locate(p_archive->archive, StringValuePtr(name), ZIP_FL_NOCASE);
300
+
301
+ if (index >= 0) {
302
+ return zipruby_archive_replace_buffer(self, INT2NUM(index), source);
303
+ } else {
304
+ return zipruby_archive_add_buffer(self, name, source);
305
+ }
306
+ }
307
+
282
308
  /* */
283
309
  static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self) {
284
310
  VALUE name, fname;
@@ -287,18 +313,18 @@ static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self) {
287
313
 
288
314
  rb_scan_args(argc, argv, "11", &name, &fname);
289
315
 
290
-
291
316
  if (NIL_P(fname)) {
292
317
  fname = name;
293
318
  name = Qnil;
294
319
  }
295
320
 
321
+ Check_Type(fname, T_STRING);
322
+
296
323
  if (NIL_P(name)) {
297
324
  name = rb_funcall(rb_cFile, rb_intern("basename"), 1, fname);
298
325
  }
299
326
 
300
327
  Check_Type(name, T_STRING);
301
- Check_Type(fname, T_STRING);
302
328
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
303
329
  Check_Archive(p_archive);
304
330
 
@@ -340,6 +366,38 @@ static VALUE zipruby_archive_replace_file(VALUE self, VALUE index, VALUE fname)
340
366
  return Qnil;
341
367
  }
342
368
 
369
+ /* */
370
+ static VALUE zipruby_archive_add_or_replace_file(int argc, VALUE *argv, VALUE self) {
371
+ VALUE name, fname;
372
+ struct zipruby_archive *p_archive;
373
+ int index;
374
+
375
+ rb_scan_args(argc, argv, "11", &name, &fname);
376
+
377
+ if (NIL_P(fname)) {
378
+ fname = name;
379
+ name = Qnil;
380
+ }
381
+
382
+ Check_Type(fname, T_STRING);
383
+
384
+ if (NIL_P(name)) {
385
+ name = rb_funcall(rb_cFile, rb_intern("basename"), 1, fname);
386
+ }
387
+
388
+ Check_Type(name, T_STRING);
389
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
390
+ Check_Archive(p_archive);
391
+
392
+ index = zip_name_locate(p_archive->archive, StringValuePtr(name), ZIP_FL_NOCASE);
393
+
394
+ if (index >= 0) {
395
+ return zipruby_archive_replace_file(self, INT2NUM(index), fname);
396
+ } else {
397
+ return zipruby_archive_add_file(argc, argv, self);
398
+ }
399
+ }
400
+
343
401
  /* */
344
402
  static VALUE zipruby_archive_add_filep(int argc, VALUE *argv, VALUE self) {
345
403
  VALUE name, file, source;
@@ -373,31 +431,40 @@ static VALUE zipruby_archive_replace_filep(VALUE self, VALUE index, VALUE file)
373
431
  }
374
432
 
375
433
  /* */
376
- static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self) {
377
- VALUE flags;
434
+ static VALUE zipruby_archive_add_or_replace_filep(int argc, VALUE *argv, VALUE self) {
435
+ VALUE name, file;
378
436
  struct zipruby_archive *p_archive;
379
- const char *comment;
380
- int lenp, i_flags = 0;
437
+ int index;
381
438
 
382
- rb_scan_args(argc, argv, "01", &flags);
439
+ rb_scan_args(argc, argv, "11", &name, &file);
383
440
 
384
- if (!NIL_P(flags)) {
385
- i_flags = NUM2INT(flags);
441
+ if (NIL_P(file)) {
442
+ file = name;
443
+ name = Qnil;
444
+ }
445
+
446
+ Check_Type(file, T_FILE);
447
+
448
+ if (NIL_P(name)) {
449
+ name = rb_funcall(rb_cFile, rb_intern("basename"), 1, rb_funcall(file, rb_intern("path"), 0));
386
450
  }
387
451
 
452
+ Check_Type(name, T_STRING);
388
453
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
389
454
  Check_Archive(p_archive);
390
455
 
391
- // XXX: How is the error checked?
392
- comment = zip_get_archive_comment(p_archive->archive, &lenp, i_flags);
456
+ index = zip_name_locate(p_archive->archive, StringValuePtr(name), ZIP_FL_NOCASE);
393
457
 
394
- return comment ? rb_str_new(comment, lenp) : Qnil;
458
+ if (index >= 0) {
459
+ return zipruby_archive_replace_filep(self, INT2NUM(index), file);
460
+ } else {
461
+ return zipruby_archive_add_filep(argc, argv, self);
462
+ }
395
463
  }
396
464
 
397
465
  /* */
398
- static VALUE zipruby_archive_add_zip(VALUE self, VALUE srcarchive) {
466
+ static VALUE zipruby_archive_update(VALUE self, VALUE srcarchive) {
399
467
  struct zipruby_archive *p_archive, *p_srcarchive;
400
- struct zip_source *zsource;
401
468
  int i, num_files;
402
469
 
403
470
  if (!rb_obj_is_instance_of(srcarchive, Archive)) {
@@ -412,21 +479,111 @@ static VALUE zipruby_archive_add_zip(VALUE self, VALUE srcarchive) {
412
479
  num_files = zip_get_num_files(p_srcarchive->archive);
413
480
 
414
481
  for (i = 0; i < num_files; i++) {
415
- if ((zsource = zip_source_zip(p_archive->archive, p_srcarchive->archive, i, 0, 0, -1)) == NULL) {
416
- rb_raise(Error, "Add zip failed: %s", zip_strerror(p_archive->archive));
482
+ struct zip_source *zsource;
483
+ struct zip_file *fzip;
484
+ struct zip_stat sb;
485
+ char *buf;
486
+ const char *name;
487
+ int index, error;
488
+
489
+ zip_stat_init(&sb);
490
+
491
+ if (zip_stat_index(p_srcarchive->archive, i, 0, &sb)) {
492
+ zip_unchange_all(p_archive->archive);
493
+ zip_unchange_archive(p_archive->archive);
494
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
495
+ }
496
+
497
+ if ((buf = malloc(sb.size)) == NULL) {
498
+ zip_unchange_all(p_archive->archive);
499
+ zip_unchange_archive(p_archive->archive);
500
+ rb_raise(rb_eRuntimeError, "Update archive failed: Cannot allocate memory");
501
+ }
502
+
503
+ fzip = zip_fopen_index(p_srcarchive->archive, i, 0);
504
+
505
+ if (fzip == NULL) {
506
+ free(buf);
507
+ zip_unchange_all(p_archive->archive);
508
+ zip_unchange_archive(p_archive->archive);
509
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
510
+ }
511
+
512
+ if (zip_fread(fzip, buf, sb.size) == -1) {
513
+ free(buf);
514
+ zip_fclose(fzip);
515
+ zip_unchange_all(p_archive->archive);
516
+ zip_unchange_archive(p_archive->archive);
517
+ rb_raise(Error, "Update archive failed: %s", zip_file_strerror(fzip));
518
+ }
519
+
520
+ if ((error = zip_fclose(fzip)) != 0) {
521
+ char errstr[ERRSTR_BUFSIZE];
522
+ free(buf);
523
+ zip_unchange_all(p_archive->archive);
524
+ zip_unchange_archive(p_archive->archive);
525
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
526
+ rb_raise(Error, "Update archive failed: %s", errstr);
527
+ }
528
+
529
+ if ((zsource = zip_source_buffer(p_archive->archive, buf, sb.size, 1)) == NULL) {
530
+ free(buf);
531
+ zip_unchange_all(p_archive->archive);
532
+ zip_unchange_archive(p_archive->archive);
533
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
417
534
  }
418
535
 
419
- if (zip_add(p_archive->archive, zip_get_name(p_srcarchive->archive, i, 0), zsource) == -1) {
536
+ if ((name = zip_get_name(p_srcarchive->archive, i, 0)) == NULL) {
420
537
  zip_source_free(zsource);
421
538
  zip_unchange_all(p_archive->archive);
422
539
  zip_unchange_archive(p_archive->archive);
423
- rb_raise(Error, "Add zip failed: %s", zip_strerror(p_archive->archive));
540
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
541
+ }
542
+
543
+ index = zip_name_locate(p_archive->archive, name, ZIP_FL_NOCASE);
544
+
545
+ if (index >= 0) {
546
+ if (zip_replace(p_archive->archive, i, zsource) == -1) {
547
+ zip_source_free(zsource);
548
+ zip_unchange_all(p_archive->archive);
549
+ zip_unchange_archive(p_archive->archive);
550
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
551
+ }
552
+ } else {
553
+ if (zip_add(p_archive->archive, name, zsource) == -1) {
554
+ zip_source_free(zsource);
555
+ zip_unchange_all(p_archive->archive);
556
+ zip_unchange_archive(p_archive->archive);
557
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
558
+ }
424
559
  }
425
560
  }
426
561
 
427
562
  return Qnil;
428
563
  }
429
564
 
565
+ /* */
566
+ static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self) {
567
+ VALUE flags;
568
+ struct zipruby_archive *p_archive;
569
+ const char *comment;
570
+ int lenp, i_flags = 0;
571
+
572
+ rb_scan_args(argc, argv, "01", &flags);
573
+
574
+ if (!NIL_P(flags)) {
575
+ i_flags = NUM2INT(flags);
576
+ }
577
+
578
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
579
+ Check_Archive(p_archive);
580
+
581
+ // XXX: How is the error checked?
582
+ comment = zip_get_archive_comment(p_archive->archive, &lenp, i_flags);
583
+
584
+ return comment ? rb_str_new(comment, lenp) : Qnil;
585
+ }
586
+
430
587
  /* */
431
588
  static VALUE zipruby_archive_set_comment(VALUE self, VALUE comment) {
432
589
  struct zipruby_archive *p_archive;
data/ext/zipruby_file.c CHANGED
@@ -124,7 +124,7 @@ static VALUE zipruby_file_initialize(int argc, VALUE *argv, VALUE self) {
124
124
  fzip = zip_fopen_index(p_archive->archive, i_index, i_flags);
125
125
 
126
126
  if (fzip == NULL) {
127
- rb_raise(Error, "Open file failed at %d", i_index, zip_strerror(p_archive->archive));
127
+ rb_raise(Error, "Open file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
128
128
  }
129
129
  }
130
130
 
@@ -149,8 +149,8 @@ static VALUE zipruby_file_close(VALUE self) {
149
149
 
150
150
  if ((error = zip_fclose(p_file->file)) != 0) {
151
151
  char errstr[ERRSTR_BUFSIZE];
152
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
153
152
  zip_unchange(p_file->archive, p_file->sb->index);
153
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
154
154
  rb_raise(Error, "Close file failed: %s", errstr);
155
155
  }
156
156
 
data/zipruby.c CHANGED
@@ -17,6 +17,8 @@ void Init_zipruby() {
17
17
  Init_zipruby_stat();
18
18
  Init_zipruby_error();
19
19
  }
20
+ #include <errno.h>
21
+
20
22
  #include "zip.h"
21
23
  #include "zipruby.h"
22
24
  #include "zipruby_archive.h"
@@ -34,10 +36,13 @@ static VALUE zipruby_archive_get_stat(int argc, VALUE *argv, VALUE self);
34
36
  static VALUE zipruby_archive_add_buffer(VALUE self, VALUE name, VALUE source);
35
37
  static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self);
36
38
  static VALUE zipruby_archive_add_filep(int argc, VALUE *argv, VALUE self);
37
- static VALUE zipruby_archive_add_zip(VALUE self, VALUE srcarchive);
38
39
  static VALUE zipruby_archive_replace_buffer(VALUE self, VALUE index, VALUE source);
39
40
  static VALUE zipruby_archive_replace_file(VALUE self, VALUE index, VALUE fname);
40
41
  static VALUE zipruby_archive_replace_filep(VALUE self, VALUE index, VALUE file);
42
+ static VALUE zipruby_archive_add_or_replace_buffer(VALUE self, VALUE name, VALUE source);
43
+ static VALUE zipruby_archive_add_or_replace_file(int argc, VALUE *argv, VALUE self);
44
+ static VALUE zipruby_archive_add_or_replace_filep(int argc, VALUE *argv, VALUE self);
45
+ static VALUE zipruby_archive_update(VALUE self, VALUE srcarchive);
41
46
  static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self);
42
47
  static VALUE zipruby_archive_set_comment(VALUE self, VALUE comment);
43
48
  static VALUE zipruby_archive_locate_name(int argc, VALUE *argv, VALUE self);
@@ -70,10 +75,13 @@ void Init_zipruby_archive() {
70
75
  rb_define_method(Archive, "add_buffer", zipruby_archive_add_buffer, 2);
71
76
  rb_define_method(Archive, "add_file", zipruby_archive_add_file, -1);
72
77
  rb_define_method(Archive, "add_filep", zipruby_archive_add_filep, -1);
73
- rb_define_method(Archive, "add_zip", zipruby_archive_add_zip, 1);
74
78
  rb_define_method(Archive, "replace_buffer", zipruby_archive_replace_buffer, 2);
75
79
  rb_define_method(Archive, "replace_file", zipruby_archive_replace_file, 2);
76
80
  rb_define_method(Archive, "replace_filep", zipruby_archive_replace_filep, 2);
81
+ rb_define_method(Archive, "add_or_replace_buffer", zipruby_archive_add_or_replace_buffer, 2);
82
+ rb_define_method(Archive, "add_or_replace_file", zipruby_archive_add_or_replace_file, -1);
83
+ rb_define_method(Archive, "add_or_replace_filep", zipruby_archive_add_or_replace_filep, -1);
84
+ rb_define_method(Archive, "update", zipruby_archive_update, 1);
77
85
  rb_define_method(Archive, "<<", zipruby_archive_add_filep, -1);
78
86
  rb_define_method(Archive, "get_comment", zipruby_archive_get_comment, -1);
79
87
  rb_define_method(Archive, "comment", zipruby_archive_get_comment, -1);
@@ -192,7 +200,7 @@ static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self) {
192
200
  Check_Archive(p_archive);
193
201
 
194
202
  if ((name = zip_get_name(p_archive->archive, NUM2INT(index), i_flags)) == NULL) {
195
- rb_raise(Error, "Get name failed: %s", zip_strerror(p_archive->archive));
203
+ rb_raise(Error, "Get name failed at %d: %s", index, zip_strerror(p_archive->archive));
196
204
  }
197
205
 
198
206
  return (name != NULL) ? rb_str_new2(name) : Qnil;
@@ -298,6 +306,24 @@ static VALUE zipruby_archive_replace_buffer(VALUE self, VALUE index, VALUE sourc
298
306
  return Qnil;
299
307
  }
300
308
 
309
+ /* */
310
+ static VALUE zipruby_archive_add_or_replace_buffer(VALUE self, VALUE name, VALUE source) {
311
+ struct zipruby_archive *p_archive;
312
+ int index;
313
+
314
+ Check_Type(name, T_STRING);
315
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
316
+ Check_Archive(p_archive);
317
+
318
+ index = zip_name_locate(p_archive->archive, StringValuePtr(name), ZIP_FL_NOCASE);
319
+
320
+ if (index >= 0) {
321
+ return zipruby_archive_replace_buffer(self, INT2NUM(index), source);
322
+ } else {
323
+ return zipruby_archive_add_buffer(self, name, source);
324
+ }
325
+ }
326
+
301
327
  /* */
302
328
  static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self) {
303
329
  VALUE name, fname;
@@ -306,18 +332,18 @@ static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self) {
306
332
 
307
333
  rb_scan_args(argc, argv, "11", &name, &fname);
308
334
 
309
-
310
335
  if (NIL_P(fname)) {
311
336
  fname = name;
312
337
  name = Qnil;
313
338
  }
314
339
 
340
+ Check_Type(fname, T_STRING);
341
+
315
342
  if (NIL_P(name)) {
316
343
  name = rb_funcall(rb_cFile, rb_intern("basename"), 1, fname);
317
344
  }
318
345
 
319
346
  Check_Type(name, T_STRING);
320
- Check_Type(fname, T_STRING);
321
347
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
322
348
  Check_Archive(p_archive);
323
349
 
@@ -359,6 +385,38 @@ static VALUE zipruby_archive_replace_file(VALUE self, VALUE index, VALUE fname)
359
385
  return Qnil;
360
386
  }
361
387
 
388
+ /* */
389
+ static VALUE zipruby_archive_add_or_replace_file(int argc, VALUE *argv, VALUE self) {
390
+ VALUE name, fname;
391
+ struct zipruby_archive *p_archive;
392
+ int index;
393
+
394
+ rb_scan_args(argc, argv, "11", &name, &fname);
395
+
396
+ if (NIL_P(fname)) {
397
+ fname = name;
398
+ name = Qnil;
399
+ }
400
+
401
+ Check_Type(fname, T_STRING);
402
+
403
+ if (NIL_P(name)) {
404
+ name = rb_funcall(rb_cFile, rb_intern("basename"), 1, fname);
405
+ }
406
+
407
+ Check_Type(name, T_STRING);
408
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
409
+ Check_Archive(p_archive);
410
+
411
+ index = zip_name_locate(p_archive->archive, StringValuePtr(name), ZIP_FL_NOCASE);
412
+
413
+ if (index >= 0) {
414
+ return zipruby_archive_replace_file(self, INT2NUM(index), fname);
415
+ } else {
416
+ return zipruby_archive_add_file(argc, argv, self);
417
+ }
418
+ }
419
+
362
420
  /* */
363
421
  static VALUE zipruby_archive_add_filep(int argc, VALUE *argv, VALUE self) {
364
422
  VALUE name, file, source;
@@ -392,31 +450,40 @@ static VALUE zipruby_archive_replace_filep(VALUE self, VALUE index, VALUE file)
392
450
  }
393
451
 
394
452
  /* */
395
- static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self) {
396
- VALUE flags;
453
+ static VALUE zipruby_archive_add_or_replace_filep(int argc, VALUE *argv, VALUE self) {
454
+ VALUE name, file;
397
455
  struct zipruby_archive *p_archive;
398
- const char *comment;
399
- int lenp, i_flags = 0;
456
+ int index;
400
457
 
401
- rb_scan_args(argc, argv, "01", &flags);
458
+ rb_scan_args(argc, argv, "11", &name, &file);
402
459
 
403
- if (!NIL_P(flags)) {
404
- i_flags = NUM2INT(flags);
460
+ if (NIL_P(file)) {
461
+ file = name;
462
+ name = Qnil;
463
+ }
464
+
465
+ Check_Type(file, T_FILE);
466
+
467
+ if (NIL_P(name)) {
468
+ name = rb_funcall(rb_cFile, rb_intern("basename"), 1, rb_funcall(file, rb_intern("path"), 0));
405
469
  }
406
470
 
471
+ Check_Type(name, T_STRING);
407
472
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
408
473
  Check_Archive(p_archive);
409
474
 
410
- // XXX: How is the error checked?
411
- comment = zip_get_archive_comment(p_archive->archive, &lenp, i_flags);
475
+ index = zip_name_locate(p_archive->archive, StringValuePtr(name), ZIP_FL_NOCASE);
412
476
 
413
- return comment ? rb_str_new(comment, lenp) : Qnil;
477
+ if (index >= 0) {
478
+ return zipruby_archive_replace_filep(self, INT2NUM(index), file);
479
+ } else {
480
+ return zipruby_archive_add_filep(argc, argv, self);
481
+ }
414
482
  }
415
483
 
416
484
  /* */
417
- static VALUE zipruby_archive_add_zip(VALUE self, VALUE srcarchive) {
485
+ static VALUE zipruby_archive_update(VALUE self, VALUE srcarchive) {
418
486
  struct zipruby_archive *p_archive, *p_srcarchive;
419
- struct zip_source *zsource;
420
487
  int i, num_files;
421
488
 
422
489
  if (!rb_obj_is_instance_of(srcarchive, Archive)) {
@@ -431,21 +498,111 @@ static VALUE zipruby_archive_add_zip(VALUE self, VALUE srcarchive) {
431
498
  num_files = zip_get_num_files(p_srcarchive->archive);
432
499
 
433
500
  for (i = 0; i < num_files; i++) {
434
- if ((zsource = zip_source_zip(p_archive->archive, p_srcarchive->archive, i, 0, 0, -1)) == NULL) {
435
- rb_raise(Error, "Add zip failed: %s", zip_strerror(p_archive->archive));
501
+ struct zip_source *zsource;
502
+ struct zip_file *fzip;
503
+ struct zip_stat sb;
504
+ char *buf;
505
+ const char *name;
506
+ int index, error;
507
+
508
+ zip_stat_init(&sb);
509
+
510
+ if (zip_stat_index(p_srcarchive->archive, i, 0, &sb)) {
511
+ zip_unchange_all(p_archive->archive);
512
+ zip_unchange_archive(p_archive->archive);
513
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
514
+ }
515
+
516
+ if ((buf = malloc(sb.size)) == NULL) {
517
+ zip_unchange_all(p_archive->archive);
518
+ zip_unchange_archive(p_archive->archive);
519
+ rb_raise(rb_eRuntimeError, "Update archive failed: Cannot allocate memory");
520
+ }
521
+
522
+ fzip = zip_fopen_index(p_srcarchive->archive, i, 0);
523
+
524
+ if (fzip == NULL) {
525
+ free(buf);
526
+ zip_unchange_all(p_archive->archive);
527
+ zip_unchange_archive(p_archive->archive);
528
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
529
+ }
530
+
531
+ if (zip_fread(fzip, buf, sb.size) == -1) {
532
+ free(buf);
533
+ zip_fclose(fzip);
534
+ zip_unchange_all(p_archive->archive);
535
+ zip_unchange_archive(p_archive->archive);
536
+ rb_raise(Error, "Update archive failed: %s", zip_file_strerror(fzip));
537
+ }
538
+
539
+ if ((error = zip_fclose(fzip)) != 0) {
540
+ char errstr[ERRSTR_BUFSIZE];
541
+ free(buf);
542
+ zip_unchange_all(p_archive->archive);
543
+ zip_unchange_archive(p_archive->archive);
544
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
545
+ rb_raise(Error, "Update archive failed: %s", errstr);
436
546
  }
437
547
 
438
- if (zip_add(p_archive->archive, zip_get_name(p_srcarchive->archive, i, 0), zsource) == -1) {
548
+ if ((zsource = zip_source_buffer(p_archive->archive, buf, sb.size, 1)) == NULL) {
549
+ free(buf);
550
+ zip_unchange_all(p_archive->archive);
551
+ zip_unchange_archive(p_archive->archive);
552
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
553
+ }
554
+
555
+ if ((name = zip_get_name(p_srcarchive->archive, i, 0)) == NULL) {
439
556
  zip_source_free(zsource);
440
557
  zip_unchange_all(p_archive->archive);
441
558
  zip_unchange_archive(p_archive->archive);
442
- rb_raise(Error, "Add zip failed: %s", zip_strerror(p_archive->archive));
559
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
560
+ }
561
+
562
+ index = zip_name_locate(p_archive->archive, name, ZIP_FL_NOCASE);
563
+
564
+ if (index >= 0) {
565
+ if (zip_replace(p_archive->archive, i, zsource) == -1) {
566
+ zip_source_free(zsource);
567
+ zip_unchange_all(p_archive->archive);
568
+ zip_unchange_archive(p_archive->archive);
569
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
570
+ }
571
+ } else {
572
+ if (zip_add(p_archive->archive, name, zsource) == -1) {
573
+ zip_source_free(zsource);
574
+ zip_unchange_all(p_archive->archive);
575
+ zip_unchange_archive(p_archive->archive);
576
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
577
+ }
443
578
  }
444
579
  }
445
580
 
446
581
  return Qnil;
447
582
  }
448
583
 
584
+ /* */
585
+ static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self) {
586
+ VALUE flags;
587
+ struct zipruby_archive *p_archive;
588
+ const char *comment;
589
+ int lenp, i_flags = 0;
590
+
591
+ rb_scan_args(argc, argv, "01", &flags);
592
+
593
+ if (!NIL_P(flags)) {
594
+ i_flags = NUM2INT(flags);
595
+ }
596
+
597
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
598
+ Check_Archive(p_archive);
599
+
600
+ // XXX: How is the error checked?
601
+ comment = zip_get_archive_comment(p_archive->archive, &lenp, i_flags);
602
+
603
+ return comment ? rb_str_new(comment, lenp) : Qnil;
604
+ }
605
+
449
606
  /* */
450
607
  static VALUE zipruby_archive_set_comment(VALUE self, VALUE comment) {
451
608
  struct zipruby_archive *p_archive;
@@ -779,7 +936,7 @@ static VALUE zipruby_file_initialize(int argc, VALUE *argv, VALUE self) {
779
936
  fzip = zip_fopen_index(p_archive->archive, i_index, i_flags);
780
937
 
781
938
  if (fzip == NULL) {
782
- rb_raise(Error, "Open file failed at %d", i_index, zip_strerror(p_archive->archive));
939
+ rb_raise(Error, "Open file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
783
940
  }
784
941
  }
785
942
 
@@ -804,8 +961,8 @@ static VALUE zipruby_file_close(VALUE self) {
804
961
 
805
962
  if ((error = zip_fclose(p_file->file)) != 0) {
806
963
  char errstr[ERRSTR_BUFSIZE];
807
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
808
964
  zip_unchange(p_file->archive, p_file->sb->index);
965
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
809
966
  rb_raise(Error, "Close file failed: %s", errstr);
810
967
  }
811
968
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zipruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - winebarrel