async-ruby-zip 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ #ifndef ASYNC_ZIP_CALLBACK_H
2
+ #define ASYNC_ZIP_CALLBACK_H
3
+
4
+ #include "archive_data.h"
5
+
6
+ void az_add_to_event_qeueue(archive_data_t* tdata);
7
+ void init_async_zip_event_thread(void);
8
+
9
+ #endif
@@ -0,0 +1,219 @@
1
+ #include "carchive.h"
2
+ #include "carray.h"
3
+ #include "cfilesystem.h"
4
+ #include "cerror.h"
5
+ #include <zip.h>
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+ #include <stdint.h>
11
+
12
+
13
+ // Format error message from ZIP-archive
14
+ void cerror_zip_asprintf(char** ppmsg, struct zip* z, const char* text)
15
+ {
16
+ if(!z)
17
+ return;
18
+
19
+ if(text)
20
+ {
21
+ cerror_asprintf(ppmsg, "%s: %s", text, zip_strerror(z));
22
+ }
23
+ else
24
+ {
25
+ cerror_asprintf(ppmsg, "%s", zip_strerror(z));
26
+ }
27
+ }
28
+
29
+
30
+ // Put files to the archive
31
+ cerror_t carchive_create(const char* zip_path, const carray_str_t* parr)
32
+ {
33
+ cerror_t result = { 0 };
34
+
35
+ cfilesystem_remove(zip_path);
36
+
37
+ int err = 0;
38
+ struct zip* z = zip_open(zip_path, ZIP_CREATE, &err);
39
+ if(!z)
40
+ {
41
+ result.code = CERROR_E_ZIP_OPEN_FAILED;
42
+ cerror_asprintf(&result.message, "cannot open zip archive for writing: '%s'", zip_path);
43
+ return result;
44
+ }
45
+
46
+ size_t i;
47
+ for(i = 0; i != parr->size; ++i)
48
+ {
49
+ const char* filepath = carray_str_get(parr, i);
50
+ if(!cfilesystem_exists(filepath))
51
+ {
52
+ result.code = CERROR_E_ZIP_FILE_NOT_FOUND;
53
+ cerror_asprintf(&result.message, "file not found: '%s'", filepath);
54
+ break;
55
+ }
56
+
57
+ struct zip_source* s = zip_source_file(z, filepath, 0, -1);
58
+ if(!s)
59
+ {
60
+ result.code = CERROR_E_ZIP_CREATE_DATA_SOURCE;
61
+ cerror_zip_asprintf(&result.message, z, "cannot create data source");
62
+ break;
63
+ }
64
+
65
+ char* filename = cfilesystem_filename(filepath);
66
+ err = zip_add(z, filename, s);
67
+ if(err < 0)
68
+ {
69
+ result.code = CERROR_E_ZIP_ADD_FILE;
70
+ cerror_zip_asprintf(&result.message, z, "cannot add file to archive");
71
+ free(filename);
72
+ break;
73
+ }
74
+
75
+ free(filename);
76
+ }
77
+
78
+ if(cerror_is_error(&result))
79
+ {
80
+ zip_unchange_all(z);
81
+ zip_close(z);
82
+ }
83
+ else
84
+ {
85
+ err = zip_close(z);
86
+ if(err < 0)
87
+ {
88
+ result.code = CERROR_E_ZIP_CLOSE_ARCHIVE;
89
+ cerror_zip_asprintf(&result.message, z, "cannot close zip archive");
90
+ }
91
+ }
92
+
93
+ return result;
94
+ }
95
+
96
+
97
+ // Extract files from the archive
98
+ cerror_t carchive_extract(const char* zip_path, const char* dest_path, carray_str_t** pparr)
99
+ {
100
+ cerror_t result = { 0 };
101
+
102
+ int err = 0;
103
+ struct zip* z = zip_open(zip_path, 0, &err);
104
+ if(!z)
105
+ {
106
+ result.code = CERROR_E_ZIP_OPEN_FAILED;
107
+ cerror_asprintf(&result.message, "cannot open zip archive for reading: '%s'", zip_path);
108
+ return result;
109
+ }
110
+
111
+ uint64_t num = zip_get_num_entries(z, 0);
112
+ if(num == (uint64_t)-1)
113
+ {
114
+ result.code = CERROR_E_ZIP_ENTRY_COUNT;
115
+ cerror_zip_asprintf(&result.message, z, "cannot get the number of entities in archive");
116
+ }
117
+ else
118
+ {
119
+ if(!cfilesystem_exists(dest_path))
120
+ cfilesystem_create_directories(dest_path);
121
+
122
+ *pparr = carray_str_create((size_t)num);
123
+
124
+ struct zip_stat st = { 0 };
125
+ uint64_t i;
126
+ for(i = 0; i != num; ++i)
127
+ {
128
+ zip_stat_init(&st);
129
+ err = zip_stat_index(z, i, 0, &st);
130
+ if(err < 0)
131
+ {
132
+ result.code = CERROR_E_ZIP_ENTRY_READ_STATS;
133
+ cerror_zip_asprintf(&result.message, z, "cannot read statistics for entry");
134
+ break;
135
+ }
136
+
137
+ if(st.valid & ZIP_STAT_SIZE)
138
+ {
139
+ struct zip_file* f = zip_fopen_index(z, i, 0);
140
+ if(!f)
141
+ {
142
+ result.code = CERROR_E_ZIP_ENTRY_READ_ENTRY;
143
+ cerror_zip_asprintf(&result.message, z, "cannot read entry");
144
+ break;
145
+ }
146
+
147
+ char* filename = (st.valid & ZIP_STAT_NAME ? strdup(st.name) : cfilesystem_tempfilename());
148
+ char* dest_filepath = cfilesystem_combine(dest_path, filename);
149
+
150
+ carray_str_set(*pparr, (size_t)i, dest_filepath);
151
+
152
+ FILE* fp = fopen(dest_filepath, "w");
153
+ if(!fp)
154
+ {
155
+ result.code = CERROR_E_FILE_CREATE;
156
+ cerror_asprintf(&result.message, "cannot create file for writing: '%s', [%s]", dest_filepath, strerror(errno));
157
+ free(filename);
158
+ free(dest_filepath);
159
+ break;
160
+ }
161
+
162
+ char* bytes = (char*)malloc(st.size);
163
+ err = zip_fread(f, bytes, st.size);
164
+ if(err < 0)
165
+ {
166
+ result.code = CERROR_E_ZIP_ENTRY_READ_BYTES;
167
+ cerror_zip_asprintf(&result.message, z, "cannot read entry byts");
168
+ free(bytes);
169
+ free(filename);
170
+ free(dest_filepath);
171
+ fclose(fp);
172
+ break;
173
+ }
174
+
175
+ err = fwrite(bytes, st.size, 1, fp);
176
+ if(!err)
177
+ {
178
+ result.code = CERROR_E_FILE_WRITE;
179
+ cerror_asprintf(&result.message, "cannot writing data to file: '%s', [%s]", dest_filepath, strerror(errno));
180
+ free(bytes);
181
+ free(filename);
182
+ free(dest_filepath);
183
+ fclose(fp);
184
+ break;
185
+ }
186
+
187
+ fclose(fp);
188
+
189
+ free(bytes);
190
+ free(filename);
191
+ free(dest_filepath);
192
+
193
+ err = zip_fclose(f);
194
+ if(err)
195
+ {
196
+ result.code = CERROR_E_ZIP_ENTRY_CLOSE;
197
+ cerror_zip_asprintf(&result.message, z, "cannot close zip entry");
198
+ break;
199
+ }
200
+ }
201
+ }
202
+ }
203
+
204
+ if(cerror_is_error(&result))
205
+ {
206
+ zip_close(z);
207
+ }
208
+ else
209
+ {
210
+ err = zip_close(z);
211
+ if(err < 0)
212
+ {
213
+ result.code = CERROR_E_ZIP_CLOSE_ARCHIVE;
214
+ cerror_zip_asprintf(&result.message, z, "cannot close zip archive");
215
+ }
216
+ }
217
+
218
+ return result;
219
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef EXTRA_CARCHIVE_H
2
+ #define EXTRA_CARCHIVE_H
3
+
4
+ #include "carray.h"
5
+ #include "cerror.h"
6
+
7
+ cerror_t carchive_create(const char* zip_path, const carray_str_t* parr);
8
+ cerror_t carchive_extract(const char* zip_path, const char* dest_path, carray_str_t** pparr);
9
+
10
+ #endif
@@ -0,0 +1,80 @@
1
+ #include "carray.h"
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+
5
+ //
6
+ carray_str_t* carray_str_create(size_t count)
7
+ {
8
+ carray_str_t* parr = (carray_str_t*)malloc(sizeof(carray_str_t));
9
+ if(parr)
10
+ {
11
+ parr->ptr = (char**)malloc(sizeof(char*) * count);
12
+ parr->size = count;
13
+
14
+ memset(parr->ptr, 0, sizeof(char*) * count);
15
+ }
16
+
17
+ return parr;
18
+ }
19
+
20
+ //
21
+ void carray_str_destroy(carray_str_t* parr)
22
+ {
23
+ if(parr)
24
+ {
25
+ size_t i;
26
+ for(i = 0; i != parr->size; ++i)
27
+ free(parr->ptr[i]);
28
+
29
+ free(parr->ptr);
30
+ free(parr);
31
+ }
32
+ }
33
+
34
+ //
35
+ size_t carray_str_size(const carray_str_t* arr)
36
+ {
37
+ if(!arr)
38
+ return 0;
39
+
40
+ return arr->size;
41
+ }
42
+
43
+ //
44
+ const char* carray_str_get(const carray_str_t* arr, size_t index)
45
+ {
46
+ if(index >= arr->size)
47
+ return NULL;
48
+
49
+ return arr->ptr[index];
50
+ }
51
+
52
+ //
53
+ char* carray_str_set(carray_str_t* arr, size_t index, const char* data)
54
+ {
55
+ if(index >= arr->size)
56
+ return NULL;
57
+
58
+ if(arr->ptr)
59
+ carray_str_unset(arr, index);
60
+
61
+ if(data)
62
+ {
63
+ arr->ptr[index] = strdup(data);
64
+ }
65
+
66
+ return arr->ptr[index];
67
+ }
68
+
69
+ //
70
+ void carray_str_unset(carray_str_t* arr, size_t index)
71
+ {
72
+ if(index >= arr->size)
73
+ return;
74
+
75
+ if(arr->ptr[index])
76
+ {
77
+ free(arr->ptr[index]);
78
+ arr->ptr[index] = NULL;
79
+ }
80
+ }
@@ -0,0 +1,28 @@
1
+ #ifndef EXTRA_CARRAY_H
2
+ #define EXTRA_CARRAY_H
3
+
4
+ #include <stddef.h>
5
+ #include <stdio.h>
6
+
7
+ /* CARRAY for strings*/
8
+ typedef struct
9
+ {
10
+ char** ptr;
11
+ size_t size;
12
+ } carray_str_t;
13
+
14
+ /* Creation & Destruction */
15
+ carray_str_t* carray_str_create(size_t count);
16
+ void carray_str_destroy(carray_str_t* arr);
17
+
18
+ /* Utilities */
19
+ size_t carray_str_size(const carray_str_t* arr);
20
+
21
+ /* Accessors */
22
+ const char* carray_str_get(const carray_str_t* arr, size_t index);
23
+ char* carray_str_set(carray_str_t* arr, size_t index, const char* data);
24
+
25
+ void carray_str_unset(carray_str_t* arr, size_t index);
26
+
27
+
28
+ #endif
@@ -0,0 +1,74 @@
1
+ #include "cerror.h"
2
+ #include <stdlib.h>
3
+ #include <stdio.h>
4
+ #include <string.h>
5
+ #include <stdarg.h>
6
+
7
+ //
8
+ cerror_t* cerror_create(int code, const char* text)
9
+ {
10
+ cerror_t* perr = (cerror_t*)malloc(sizeof(cerror_t));
11
+ perr->code = code;
12
+
13
+ if(text)
14
+ {
15
+ perr->message = (char*)malloc(strlen(text) + 1);
16
+ strcpy(perr->message, text);
17
+ }
18
+ else
19
+ {
20
+ perr->message = NULL;
21
+ }
22
+
23
+ return perr;
24
+ }
25
+
26
+ //
27
+ void cerror_destroy(cerror_t* perr)
28
+ {
29
+ if(perr)
30
+ {
31
+ if(perr->message)
32
+ {
33
+ free(perr->message);
34
+ perr->message = NULL;
35
+ }
36
+
37
+ free(perr);
38
+ }
39
+ }
40
+
41
+ //
42
+ int cerror_asprintf(char** ppasz, const char* format, ...)
43
+ {
44
+ char buffer[384];
45
+ int n;
46
+
47
+ va_list ap;
48
+ va_start(ap, format);
49
+
50
+ n = vsprintf(buffer, format, ap);
51
+ if(n)
52
+ {
53
+ *ppasz = strdup(buffer);
54
+ }
55
+
56
+ return n;
57
+ }
58
+
59
+
60
+ //
61
+ void cerror_free_message(cerror_t* perr)
62
+ {
63
+ if(perr->message)
64
+ {
65
+ free(perr->message);
66
+ perr->message = NULL;
67
+ }
68
+ }
69
+
70
+ //
71
+ int cerror_is_error(cerror_t* perr)
72
+ {
73
+ return (perr->code > 0 ? 1 : 0);
74
+ }
@@ -0,0 +1,35 @@
1
+ #ifndef EXTRA_CERROR_H
2
+ #define EXTRA_CERROR_H
3
+
4
+ #define CERROR_E_ZIP_OPEN_FAILED 1
5
+ #define CERROR_E_ZIP_FILE_NOT_FOUND 2
6
+ #define CERROR_E_ZIP_CREATE_DATA_SOURCE 3
7
+ #define CERROR_E_ZIP_ADD_FILE 4
8
+ #define CERROR_E_ZIP_CLOSE_ARCHIVE 5
9
+ #define CERROR_E_ZIP_ENTRY_COUNT 6
10
+ #define CERROR_E_ZIP_ENTRY_READ_STATS 7
11
+ #define CERROR_E_ZIP_ENTRY_READ_ENTRY 8
12
+ #define CERROR_E_ZIP_ENTRY_READ_BYTES 9
13
+ #define CERROR_E_ZIP_ENTRY_CLOSE 10
14
+ #define CERROR_E_FILE_CREATE 16
15
+ #define CERROR_E_FILE_WRITE 17
16
+
17
+
18
+
19
+ /* Structure for error reporting */
20
+ typedef struct
21
+ {
22
+ int code;
23
+ char* message;
24
+ } cerror_t;
25
+
26
+ /* Create & Destroy */
27
+ cerror_t* cerror_create(int code, const char* text);
28
+ void cerror_destroy(cerror_t* perr);
29
+
30
+ int cerror_asprintf(char** ppasz, const char* format, ...);
31
+ void cerror_free_message(cerror_t* perr);
32
+
33
+ int cerror_is_error(cerror_t* perr);
34
+
35
+ #endif