gphoto4ruby 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.3.1
2
+
3
+ * Added files_count function and parameter allowing to limit files function
4
+ output
5
+ * Some experimental refactoring to catch memory leaks
6
+
1
7
  == 0.3.0
2
8
 
3
9
  * Fixed memory leak configuration manipulation
data/ext/gphoto2camera.c CHANGED
@@ -27,16 +27,28 @@ VALUE rb_cGPhoto2Camera;
27
27
 
28
28
  VALUE rb_cGPhoto2ConfigurationError;
29
29
 
30
+ #define RESULT_CHECK_LIST(r,l) { \
31
+ if (r < 0) { \
32
+ gp_list_free(l); \
33
+ rb_raise_gp_result(r); \
34
+ } \
35
+ }
36
+
37
+ #define RESULT_CHECK_LIST_FILE(r,l,f) { \
38
+ if (r < 0) { \
39
+ gp_list_free(l); \
40
+ gp_file_free(f); \
41
+ rb_raise_gp_result(r); \
42
+ } \
43
+ }
44
+
30
45
  void camera_mark(GPhoto2Camera *c) {
31
46
  }
32
47
 
33
48
  void camera_free(GPhoto2Camera *c) {
34
49
  gp_result_check(gp_camera_exit(c->camera, c->context));
35
50
  gp_result_check(gp_widget_free(c->config));
36
- gp_result_check(gp_list_free(c->list));
37
- gp_result_check(gp_file_free(c->file));
38
51
  gp_result_check(gp_camera_free(c->camera));
39
- free(c->path);
40
52
  free(c->virtFolder);
41
53
  free(c->context);
42
54
  free(c);
@@ -46,13 +58,10 @@ VALUE camera_allocate(VALUE klass) {
46
58
  GPhoto2Camera *c;
47
59
  c = (GPhoto2Camera*) malloc(sizeof(GPhoto2Camera));
48
60
  c->virtFolder = (char*) malloc(sizeof(char)*1024);
49
- c->path = (CameraFilePath*) malloc(sizeof(CameraFilePath));
50
61
  strcpy(c->virtFolder, "/");
51
62
  c->context = gp_context_new();
52
63
  gp_result_check(gp_camera_new(&(c->camera)));
53
64
  gp_result_check(gp_camera_get_config(c->camera, &(c->config), c->context));
54
- gp_result_check(gp_list_new(&(c->list)));
55
- gp_result_check(gp_file_new(&(c->file)));
56
65
  return Data_Wrap_Struct(klass, camera_mark, camera_free, c);
57
66
  }
58
67
 
@@ -187,6 +196,7 @@ VALUE camera_class_ports(VALUE klass) {
187
196
  */
188
197
  VALUE camera_capture(int argc, VALUE *argv, VALUE self) {
189
198
  GPhoto2Camera *c;
199
+ CameraFilePath path;
190
200
 
191
201
  Data_Get_Struct(self, GPhoto2Camera, c);
192
202
 
@@ -197,9 +207,9 @@ VALUE camera_capture(int argc, VALUE *argv, VALUE self) {
197
207
  return Qnil;
198
208
  }
199
209
 
200
- gp_result_check(gp_camera_capture(c->camera, GP_CAPTURE_IMAGE, c->path, c->context));
201
- printf("captured: %s/%s\n", c->path->folder, c->path->name);
202
- strcpy(c->virtFolder, c->path->folder);
210
+ gp_result_check(gp_camera_capture(c->camera, GP_CAPTURE_IMAGE, &path, c->context));
211
+ // printf("captured: %s/%s\n", path.folder, path.name);
212
+ strcpy(c->virtFolder, path.folder);
203
213
  return self;
204
214
  }
205
215
 
@@ -233,28 +243,50 @@ VALUE camera_capture(int argc, VALUE *argv, VALUE self) {
233
243
  VALUE camera_save(int argc, VALUE *argv, VALUE self) {
234
244
  int i, count;
235
245
  int newName = 0;
236
- CameraFileType fileType = GP_FILE_TYPE_NORMAL;
237
- GPhoto2Camera *c;
238
246
  const char *fData, *key, *val, *name;
239
247
  char *fPath, *newNameStr, *pchNew, *pchSrc;
240
248
  char fName[100], cFileName[100], cFolderName[100];
241
249
  unsigned long int fSize;
242
250
  int fd;
251
+
252
+ GPhoto2Camera *c;
253
+
254
+ CameraFileType fileType = GP_FILE_TYPE_NORMAL;
255
+ CameraList *list;
256
+ CameraFile *file;
257
+
243
258
  VALUE arr, hVal;
244
259
 
245
260
  Data_Get_Struct(self, GPhoto2Camera, c);
246
261
 
262
+ gp_list_new(&list);
263
+
247
264
  strcpy(fName, "");
248
- strcpy(cFileName, c->path->name);
249
- strcpy(cFolderName, c->path->folder);
265
+ strcpy(cFolderName, c->virtFolder);
250
266
 
251
- gp_result_check(gp_filesystem_reset(c->camera->fs));
267
+ RESULT_CHECK_LIST(gp_filesystem_reset(c->camera->fs), list);
268
+ RESULT_CHECK_LIST(gp_camera_folder_list_files(c->camera, c->virtFolder, list, c->context), list);
269
+ count = gp_list_count(list);
270
+ RESULT_CHECK_LIST(count, list);
271
+ if (count == 0) {
272
+ gp_list_free(list);
273
+ return self; // Nothing to save
274
+ } else {
275
+ count -= 1;
276
+ }
277
+ RESULT_CHECK_LIST(gp_list_get_name(list, count, &name), list);
278
+
279
+ strcpy(cFileName, name);
252
280
 
253
281
  switch(argc) {
254
282
  case 0:
255
283
  break;
256
284
  case 1:
257
- Check_Type(argv[0], T_HASH);
285
+ if (TYPE(argv[0]) != T_HASH) {
286
+ gp_list_free(list);
287
+ rb_raise(rb_eTypeError, "Not valid options type");
288
+ return Qnil;
289
+ }
258
290
  arr = rb_funcall(argv[0], rb_intern("keys"), 0);
259
291
  for (i = 0; i < RARRAY(arr)->len; i++) {
260
292
  switch(TYPE(RARRAY(arr)->ptr[i])) {
@@ -265,6 +297,7 @@ VALUE camera_save(int argc, VALUE *argv, VALUE self) {
265
297
  key = rb_id2name(rb_to_id(RARRAY(arr)->ptr[i]));
266
298
  break;
267
299
  default:
300
+ gp_list_free(list);
268
301
  rb_raise(rb_eTypeError, "Not valid key type");
269
302
  return Qnil;
270
303
  }
@@ -287,32 +320,25 @@ VALUE camera_save(int argc, VALUE *argv, VALUE self) {
287
320
  hVal = rb_hash_aref(argv[0], RARRAY(arr)->ptr[i]);
288
321
  Check_Type(hVal, T_SYMBOL);
289
322
  val = rb_id2name(rb_to_id(hVal));
290
- if (strcmp(val, "normal") == 0) {
291
- fileType = GP_FILE_TYPE_NORMAL;
292
- } else if (strcmp(val, "preview") == 0) {
323
+ if (strcmp(val, "preview") == 0) {
293
324
  fileType = GP_FILE_TYPE_PREVIEW;
294
325
  }
295
326
  } else if (strcmp(key, "file") == 0) {
296
327
  hVal = rb_hash_aref(argv[0], RARRAY(arr)->ptr[i]);
297
328
  switch(TYPE(hVal)) {
298
329
  case T_STRING:
299
- strcpy(cFolderName, c->virtFolder);
300
330
  strcpy(cFileName, RSTRING(hVal)->ptr);
301
331
  break;
302
332
  case T_SYMBOL:
303
333
  val = rb_id2name(rb_to_id(hVal));
304
- gp_result_check(gp_camera_folder_list_files(c->camera, c->virtFolder, c->list, c->context));
334
+ RESULT_CHECK_LIST(gp_camera_folder_list_files(c->camera, c->virtFolder, list, c->context), list);
305
335
  if (strcmp(val, "first") == 0) {
306
- count = 0;
307
- } else if (strcmp(val, "last") == 0) {
308
- count = gp_result_check(gp_list_count(c->list)) - 1;
309
- } else {
310
- count = -1;
336
+ RESULT_CHECK_LIST(gp_list_get_name(list, 0, &name), list);
337
+ strcpy(cFileName, name);
311
338
  }
312
- gp_result_check(gp_list_get_name(c->list, count, &name));
313
- strcpy(cFileName, name);
314
339
  break;
315
340
  default:
341
+ gp_list_free(list);
316
342
  rb_raise(rb_eTypeError, "Not valid value type");
317
343
  return Qnil;
318
344
  }
@@ -320,12 +346,14 @@ VALUE camera_save(int argc, VALUE *argv, VALUE self) {
320
346
  }
321
347
  break;
322
348
  default:
349
+ gp_list_free(list);
323
350
  rb_raise(rb_eArgError, "Wrong number of arguments (%d for 0 or 1)", argc);
324
351
  return Qnil;
325
352
  }
326
353
 
327
- gp_result_check(gp_camera_file_get(c->camera, cFolderName, cFileName, fileType, c->file, c->context));
328
- gp_result_check(gp_file_get_data_and_size(c->file, &fData, &fSize));
354
+ gp_file_new(&file);
355
+ RESULT_CHECK_LIST_FILE(gp_camera_file_get(c->camera, cFolderName, cFileName, fileType, file, c->context), list, file);
356
+ RESULT_CHECK_LIST_FILE(gp_file_get_data_and_size(file, &fData, &fSize), list, file);
329
357
  if (newName == 1) {
330
358
  strcat(fName, newNameStr);
331
359
  pchNew = strrchr(newNameStr, '.');
@@ -341,6 +369,8 @@ VALUE camera_save(int argc, VALUE *argv, VALUE self) {
341
369
  fd = open(fName, O_CREAT | O_WRONLY, 0644);
342
370
  write(fd, fData, fSize);
343
371
  close(fd);
372
+ gp_file_free(file);
373
+ gp_list_free(list);
344
374
  return self;
345
375
  }
346
376
 
@@ -363,18 +393,36 @@ VALUE camera_save(int argc, VALUE *argv, VALUE self) {
363
393
  *
364
394
  */
365
395
  VALUE camera_delete(int argc, VALUE *argv, VALUE self) {
366
- int i;
396
+ int i, count;
367
397
  int one = 1;
368
- GPhoto2Camera *c;
369
- const char *key;
398
+ const char *key, *name;
370
399
  char cFileName[100], cFolderName[100];
400
+
401
+ GPhoto2Camera *c;
402
+
403
+ CameraList *list;
404
+
371
405
  VALUE arr;
372
406
 
373
407
  Data_Get_Struct(self, GPhoto2Camera, c);
374
408
 
375
- strcpy(cFileName, c->path->name);
376
- strcpy(cFolderName, c->path->folder);
409
+ gp_list_new(&list);
410
+
411
+ strcpy(cFolderName, c->virtFolder);
377
412
 
413
+ RESULT_CHECK_LIST(gp_filesystem_reset(c->camera->fs), list);
414
+ RESULT_CHECK_LIST(gp_camera_folder_list_files(c->camera, c->virtFolder, list, c->context), list);
415
+ count = gp_list_count(list);
416
+ RESULT_CHECK_LIST(count, list);
417
+ if (count == 0) {
418
+ gp_list_free(list);
419
+ return self; // Nothing to delete
420
+ } else {
421
+ count -= 1;
422
+ }
423
+ RESULT_CHECK_LIST(gp_list_get_name(list, count, &name), list);
424
+ strcpy(cFileName, name);
425
+
378
426
  switch(argc) {
379
427
  case 0:
380
428
  break;
@@ -391,11 +439,11 @@ VALUE camera_delete(int argc, VALUE *argv, VALUE self) {
391
439
  key = rb_id2name(rb_to_id(RARRAY(arr)->ptr[i]));
392
440
  break;
393
441
  default:
442
+ gp_list_free(list);
394
443
  rb_raise(rb_eTypeError, "Not valid key type");
395
444
  return Qnil;
396
445
  }
397
446
  if (strcmp(key, "file") == 0) {
398
- strcpy(cFolderName, c->virtFolder);
399
447
  strcpy(cFileName, RSTRING(rb_hash_aref(argv[0], RARRAY(arr)->ptr[i]))->ptr);
400
448
  }
401
449
  }
@@ -403,24 +451,24 @@ VALUE camera_delete(int argc, VALUE *argv, VALUE self) {
403
451
  case T_SYMBOL:
404
452
  key = rb_id2name(rb_to_id(argv[0]));
405
453
  if (strcmp(key, "all") == 0) {
406
- strcpy(cFolderName, c->virtFolder);
407
454
  one = 0;
408
455
  }
409
456
  break;
410
457
  }
411
458
  break;
412
459
  default:
460
+ gp_list_free(list);
413
461
  rb_raise(rb_eArgError, "Wrong number of arguments (%d for 0 or 1)", argc);
414
462
  return Qnil;
415
463
  }
416
464
 
417
- gp_result_check(gp_filesystem_reset(c->camera->fs));
418
465
  if (one == 1) {
419
- gp_result_check(gp_camera_file_delete(c->camera, cFolderName, cFileName, c->context));
466
+ RESULT_CHECK_LIST(gp_camera_file_delete(c->camera, cFolderName, cFileName, c->context), list);
420
467
  } else {
421
- gp_result_check(gp_camera_folder_delete_all(c->camera, cFolderName, c->context));
468
+ RESULT_CHECK_LIST(gp_camera_folder_delete_all(c->camera, cFolderName, c->context), list);
422
469
  }
423
- gp_result_check(gp_filesystem_reset(c->camera->fs));
470
+ RESULT_CHECK_LIST(gp_filesystem_reset(c->camera->fs), list);
471
+ gp_list_free(list);
424
472
  return self;
425
473
  }
426
474
 
@@ -805,26 +853,36 @@ VALUE camera_folder(VALUE self) {
805
853
  VALUE camera_subfolders(VALUE self) {
806
854
  int i, count;
807
855
  const char *name;
856
+
808
857
  GPhoto2Camera *c;
858
+
859
+ CameraList *list;
860
+
809
861
  VALUE arr;
810
862
 
811
863
  Data_Get_Struct(self, GPhoto2Camera, c);
812
864
 
813
- gp_result_check(gp_camera_folder_list_folders(c->camera, c->virtFolder, c->list, c->context));
814
- count = gp_result_check(gp_list_count(c->list));
865
+ gp_list_new(&list);
866
+
867
+ RESULT_CHECK_LIST(gp_camera_folder_list_folders(c->camera, c->virtFolder, list, c->context), list);
868
+ count = gp_list_count(list);
869
+ RESULT_CHECK_LIST(count, list);
815
870
  arr = rb_ary_new();
816
871
  for (i = 0; i < count; i++) {
817
- gp_result_check(gp_list_get_name(c->list, i, &name));
872
+ RESULT_CHECK_LIST(gp_list_get_name(list, i, &name), list);
818
873
  rb_ary_push(arr, rb_str_new2(name));
819
874
  }
875
+ gp_list_free(list);
820
876
  return arr;
821
877
  }
822
878
 
823
879
  /*
824
880
  * call-seq:
825
881
  * files => array
882
+ * files(num) => array of length num
826
883
  *
827
- * Returns an array of file names in current camera path.
884
+ * Returns an array of file names in current camera path. Or num of last files
885
+ * in current camera path.
828
886
  *
829
887
  * Examples:
830
888
  *
@@ -837,25 +895,82 @@ VALUE camera_subfolders(VALUE self) {
837
895
  * "DSC_0003.JPG", ... ]
838
896
  *
839
897
  */
840
- VALUE camera_files(VALUE self) {
898
+ VALUE camera_files(int argc, VALUE *argv, VALUE self) {
841
899
  int i, count;
900
+ int num = 0;
842
901
  const char *name;
902
+
843
903
  GPhoto2Camera *c;
904
+
905
+ CameraList *list;
906
+
844
907
  VALUE arr;
845
908
 
909
+ if (argc == 1) {
910
+ num = NUM2INT(argv[0]);
911
+ } else if (argc != 0) {
912
+ rb_raise(rb_eArgError, "Wrong number of arguments (%d for 0 or 1)", argc);
913
+ return Qnil;
914
+ }
915
+
846
916
  Data_Get_Struct(self, GPhoto2Camera, c);
847
917
 
848
- gp_result_check(gp_filesystem_reset(c->camera->fs));
849
- gp_result_check(gp_camera_folder_list_files(c->camera, c->virtFolder, c->list, c->context));
850
- count = gp_result_check(gp_list_count(c->list));
918
+ gp_list_new(&list);
919
+
920
+ RESULT_CHECK_LIST(gp_filesystem_reset(c->camera->fs), list);
921
+ RESULT_CHECK_LIST(gp_camera_folder_list_files(c->camera, c->virtFolder, list, c->context), list);
922
+ count = gp_list_count(list);
923
+ RESULT_CHECK_LIST(count, list);
851
924
  arr = rb_ary_new();
852
- for (i = 0; i < count; i++) {
853
- gp_result_check(gp_list_get_name(c->list, i, &name));
925
+ if ((count < num) || (num <= 0)) {
926
+ num = 0;
927
+ } else {
928
+ num = count - num;
929
+ }
930
+ for (i = num; i < count; i++) {
931
+ RESULT_CHECK_LIST(gp_list_get_name(list, i, &name), list);
854
932
  rb_ary_push(arr, rb_str_new2(name));
855
933
  }
934
+ gp_list_free(list);
856
935
  return arr;
857
936
  }
858
937
 
938
+ /*
939
+ * call-seq:
940
+ * files_count => fixnum
941
+ *
942
+ * Returns an count of files in current camera path.
943
+ *
944
+ * Examples:
945
+ *
946
+ * c = GPhoto2::Camera.new
947
+ * # with Nikon DSC D80
948
+ * c.folder #=> "/"
949
+ * c.files_count #=> 0
950
+ * c.capture
951
+ * c.files_count #=> 123
952
+ *
953
+ */
954
+ VALUE camera_files_count(VALUE self) {
955
+ int count;
956
+
957
+ GPhoto2Camera *c;
958
+
959
+ CameraList *list;
960
+
961
+ Data_Get_Struct(self, GPhoto2Camera, c);
962
+
963
+ gp_list_new(&list);
964
+
965
+ RESULT_CHECK_LIST(gp_filesystem_reset(c->camera->fs), list);
966
+ RESULT_CHECK_LIST(gp_camera_folder_list_files(c->camera, c->virtFolder, list, c->context), list);
967
+ count = gp_list_count(list);
968
+ RESULT_CHECK_LIST(count, list);
969
+
970
+ gp_list_free(list);
971
+
972
+ return INT2FIX(count);
973
+ }
859
974
  /*
860
975
  * call-seq:
861
976
  * folder_up => camera
@@ -913,17 +1028,23 @@ VALUE camera_folder_down(VALUE self, VALUE folder) {
913
1028
 
914
1029
  const char *name;
915
1030
  int index;
1031
+
1032
+ CameraList *list;
1033
+
916
1034
  GPhoto2Camera *c;
917
1035
 
918
1036
  Data_Get_Struct(self, GPhoto2Camera, c);
919
1037
 
1038
+ gp_list_new(&list);
1039
+
920
1040
  name = RSTRING(folder)->ptr;
921
- gp_result_check(gp_camera_folder_list_folders(c->camera, c->virtFolder, c->list, c->context));
922
- gp_result_check(gp_list_find_by_name(c->list, &index, name));
1041
+ RESULT_CHECK_LIST(gp_camera_folder_list_folders(c->camera, c->virtFolder, list, c->context), list);
1042
+ RESULT_CHECK_LIST(gp_list_find_by_name(list, &index, name), list);
923
1043
  if (strlen(c->virtFolder) > 1) {
924
1044
  strcat(c->virtFolder, "/");
925
1045
  }
926
1046
  strcat(c->virtFolder, name);
1047
+ gp_list_free(list);
927
1048
  return self;
928
1049
  }
929
1050
 
@@ -1010,9 +1131,7 @@ VALUE camera_wait(int argc, VALUE *argv, VALUE self) {
1010
1131
  case GP_EVENT_FILE_ADDED:
1011
1132
  case GP_EVENT_FOLDER_ADDED:
1012
1133
  ce->path = (CameraFilePath*)evtData;
1013
- free(c->path);
1014
- c->path = ce->path;
1015
- strcpy(c->virtFolder, c->path->folder);
1134
+ strcpy(c->virtFolder, ce->path->folder);
1016
1135
  gp_result_check(gp_camera_wait_for_event(c->camera, 100, &fakeType, &fakeData, c->context));
1017
1136
  break;
1018
1137
  case GP_EVENT_UNKNOWN:
data/ext/gphoto2camera.h CHANGED
@@ -57,7 +57,8 @@ VALUE camera_set_value(VALUE self, VALUE str, VALUE newVal);
57
57
 
58
58
  VALUE camera_folder(VALUE self);
59
59
  VALUE camera_subfolders(VALUE self);
60
- VALUE camera_files(VALUE self);
60
+ VALUE camera_files(int argc, VALUE *argv, VALUE self);
61
+ VALUE camera_files_count(VALUE self);
61
62
  VALUE camera_folder_up(VALUE self);
62
63
  VALUE camera_folder_down(VALUE self, VALUE folder);
63
64
  VALUE camera_create_folder(VALUE self, VALUE folder);
@@ -33,9 +33,6 @@ typedef struct {
33
33
  Camera *camera;
34
34
  CameraWidget *config;
35
35
  CameraWidget *childConfig;
36
- CameraList *list;
37
- CameraFilePath *path;
38
- CameraFile *file;
39
36
  GPContext *context;
40
37
 
41
38
  char *virtFolder;
data/ext/gphoto4ruby.c CHANGED
@@ -79,7 +79,8 @@ void Init_gphoto4ruby() {
79
79
  rb_define_method(rb_cGPhoto2Camera, "delete", camera_delete, -1); /* in gphoto2camera.c */
80
80
  rb_define_method(rb_cGPhoto2Camera, "folder", camera_folder, 0); /* in gphoto2camera.c */
81
81
  rb_define_method(rb_cGPhoto2Camera, "subfolders", camera_subfolders, 0); /* in gphoto2camera.c */
82
- rb_define_method(rb_cGPhoto2Camera, "files", camera_files, 0); /* in gphoto2camera.c */
82
+ rb_define_method(rb_cGPhoto2Camera, "files", camera_files, -1); /* in gphoto2camera.c */
83
+ rb_define_method(rb_cGPhoto2Camera, "files_count", camera_files_count, 0); /* in gphoto2camera.c */
83
84
  rb_define_method(rb_cGPhoto2Camera, "folder_up", camera_folder_up, 0); /* in gphoto2camera.c */
84
85
  rb_define_method(rb_cGPhoto2Camera, "folder_down", camera_folder_down, 1); /* in gphoto2camera.c */
85
86
  rb_define_method(rb_cGPhoto2Camera, "create_folder", camera_create_folder, 1); /* in gphoto2camera.c */
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gphoto4ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - heq4 company
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2008-11-04 00:00:00 +03:00
13
+ date: 2008-11-07 00:00:00 +03:00
14
14
  default_executable:
15
15
  dependencies: []
16
16