annotate libzip/lib/zip_source_buffer.c @ 4:2306f4b04790

libzip: import 1.1.2
author David Demelier <markand@malikania.fr>
date Wed, 24 Feb 2016 21:19:28 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 zip_source_buffer.c -- create zip data source from buffer
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 This file is part of libzip, a library to manipulate ZIP archives.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 The authors can be contacted at <libzip@nih.at>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
7
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 Redistribution and use in source and binary forms, with or without
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 modification, are permitted provided that the following conditions
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 are met:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 1. Redistributions of source code must retain the above copyright
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 notice, this list of conditions and the following disclaimer.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 2. Redistributions in binary form must reproduce the above copyright
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 notice, this list of conditions and the following disclaimer in
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 the documentation and/or other materials provided with the
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 distribution.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 3. The names of the authors may not be used to endorse or promote
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
18 products derived from this software without specific prior
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 written permission.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
20
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
33
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 #include <stdlib.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 #include <string.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
36
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 #include "zipint.h"
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
38
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 #ifndef WRITE_FRAGMENT_SIZE
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 #define WRITE_FRAGMENT_SIZE 64*1024
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 #endif
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
42
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 struct buffer {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 zip_uint64_t fragment_size; /* size of each fragment */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
45
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 zip_uint8_t **fragments; /* pointers to fragments */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 zip_uint64_t nfragments; /* number of allocated fragments */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 zip_uint64_t fragments_capacity; /* size of fragments (number of pointers) */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 zip_uint64_t size; /* size of data in bytes */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 zip_uint64_t offset; /* current offset */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 int free_data;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 };
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
53
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 typedef struct buffer buffer_t;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
55
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 struct read_data {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 zip_error_t error;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 time_t mtime;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 buffer_t *in;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 buffer_t *out;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 };
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
62
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 static void buffer_free(buffer_t *buffer);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 static buffer_t *buffer_new(zip_uint64_t fragment_size);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 static buffer_t *buffer_new_read(const void *data, zip_uint64_t length, int free_data);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 static buffer_t *buffer_new_write(zip_uint64_t fragment_size);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 static zip_int64_t buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 static int buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
70
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 static zip_int64_t read_data(void *, void *, zip_uint64_t, zip_source_cmd_t);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
72
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
73
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 ZIP_EXTERN zip_source_t *
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, int freep)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 if (za == NULL)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
79
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 return zip_source_buffer_create(data, len, freep, &za->error);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
82
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
83
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 ZIP_EXTERN zip_source_t *
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 struct read_data *ctx;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 zip_source_t *zs;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
89
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 if (data == NULL && len > 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 zip_error_set(error, ZIP_ER_INVAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
94
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 if ((ctx=(struct read_data *)malloc(sizeof(*ctx))) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 zip_error_set(error, ZIP_ER_MEMORY, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
99
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 if ((ctx->in = buffer_new_read(data, len, freep)) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 zip_error_set(error, ZIP_ER_MEMORY, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 free(ctx);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
105
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 ctx->out = NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 ctx->mtime = time(NULL);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 zip_error_init(&ctx->error);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
109
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 if ((zs=zip_source_function_create(read_data, ctx, error)) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 buffer_free(ctx->in);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 free(ctx);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
115
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 return zs;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
118
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
119
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 static zip_int64_t
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
123 struct read_data *ctx = (struct read_data *)state;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
124
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 switch (cmd) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 case ZIP_SOURCE_BEGIN_WRITE:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 if ((ctx->out = buffer_new_write(WRITE_FRAGMENT_SIZE)) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
132
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 case ZIP_SOURCE_CLOSE:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
135
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 case ZIP_SOURCE_COMMIT_WRITE:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 buffer_free(ctx->in);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 ctx->in = ctx->out;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 ctx->out = NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
141
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 case ZIP_SOURCE_ERROR:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 return zip_error_to_data(&ctx->error, data, len);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
144
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 case ZIP_SOURCE_FREE:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 buffer_free(ctx->in);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 buffer_free(ctx->out);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 free(ctx);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
150
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 case ZIP_SOURCE_OPEN:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 ctx->in->offset = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
154
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 case ZIP_SOURCE_READ:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 if (len > ZIP_INT64_MAX) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 return buffer_read(ctx->in, data, len);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
161
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 case ZIP_SOURCE_REMOVE:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 buffer_t *empty = buffer_new_read(NULL, 0, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 if (empty == 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
169
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 buffer_free(ctx->in);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 ctx->in = empty;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
174
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 case ZIP_SOURCE_ROLLBACK_WRITE:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 buffer_free(ctx->out);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 ctx->out = NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
179
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 case ZIP_SOURCE_SEEK:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 return buffer_seek(ctx->in, data, len, &ctx->error);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
182
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 case ZIP_SOURCE_SEEK_WRITE:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 return buffer_seek(ctx->out, data, len, &ctx->error);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
185
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 case ZIP_SOURCE_STAT:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 zip_stat_t *st;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
189
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 if (len < sizeof(*st)) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
194
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 st = (zip_stat_t *)data;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
196
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 zip_stat_init(st);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 st->mtime = ctx->mtime;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 st->size = ctx->in->size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 st->comp_size = st->size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 st->comp_method = ZIP_CM_STORE;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 st->encryption_method = ZIP_EM_NONE;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 st->valid = ZIP_STAT_MTIME|ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
204
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 return sizeof(*st);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
207
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 case ZIP_SOURCE_SUPPORTS:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
210
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 case ZIP_SOURCE_TELL:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 if (ctx->in->offset > ZIP_INT64_MAX) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 return (zip_int64_t)ctx->in->offset;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
217
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
218
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 case ZIP_SOURCE_TELL_WRITE:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 if (ctx->out->offset > ZIP_INT64_MAX) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 return (zip_int64_t)ctx->out->offset;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
225
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 case ZIP_SOURCE_WRITE:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 if (len > ZIP_INT64_MAX) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
230 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 return buffer_write(ctx->out, data, len, &ctx->error);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
232
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 default:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
235 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
238
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
239
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 static void
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 buffer_free(buffer_t *buffer)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
243 if (buffer == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 return;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
246
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
247 if (buffer->free_data) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
248 zip_uint64_t i;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
249
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 for (i=0; i < buffer->nfragments; i++) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 free(buffer->fragments[i]);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
254 free(buffer->fragments);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
255 free(buffer);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
257
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
258
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 static buffer_t *
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 buffer_new(zip_uint64_t fragment_size)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 buffer_t *buffer;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
263
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 if ((buffer = malloc(sizeof(*buffer))) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
267
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 buffer->fragment_size = fragment_size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
269 buffer->offset = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 buffer->free_data = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 buffer->nfragments = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 buffer->fragments_capacity = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 buffer->fragments = NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 buffer->size = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
275
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
276 return buffer;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
278
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
279
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
280 static buffer_t *
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 buffer_new_read(const void *data, zip_uint64_t length, int free_data)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 buffer_t *buffer;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
284
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
285 if ((buffer = buffer_new(length)) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
286 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
288
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
289 buffer->size = length;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
290
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 if (length > 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 buffer_free(buffer);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
295 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
296 buffer->fragments_capacity = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
297
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 buffer->nfragments = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 buffer->fragments[0] = (zip_uint8_t *)data;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 buffer->free_data = free_data;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
301 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
302
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
303 return buffer;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
304 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
305
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
306
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 static buffer_t *
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
308 buffer_new_write(zip_uint64_t fragment_size)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 buffer_t *buffer;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
311
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
312 if ((buffer = buffer_new(fragment_size)) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
315
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
316 if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 buffer_free(buffer);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 return NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
319 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 buffer->fragments_capacity = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
321 buffer->nfragments = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
322 buffer->free_data = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
323
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
324 return buffer;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
325 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
326
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
327
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
328 static zip_int64_t
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
329 buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
330 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
331 zip_uint64_t n, i, fragment_offset;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
332
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
333 length = ZIP_MIN(length, buffer->size - buffer->offset);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
334
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
335 if (length == 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
336 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
337 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
338 if (length > ZIP_INT64_MAX) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
339 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
340 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
341
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
342 i = buffer->offset / buffer->fragment_size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
343 fragment_offset = buffer->offset % buffer->fragment_size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
344 n = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
345 while (n < length) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
346 zip_uint64_t left = ZIP_MIN(length - n, buffer->fragment_size - fragment_offset);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
347
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
348 memcpy(data + n, buffer->fragments[i] + fragment_offset, left);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
349
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
350 n += left;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
351 i++;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
352 fragment_offset = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
353 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
354
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
355 buffer->offset += n;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
356 return (zip_int64_t)n;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
357 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
358
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
359
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
360 static int
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
361 buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
362 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
363 zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, len, error);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
364
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
365 if (new_offset < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
366 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
367 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
368
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
369 buffer->offset = (zip_uint64_t)new_offset;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
370 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
371 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
372
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
373
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
374 static zip_int64_t
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
375 buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
376 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
377 zip_uint64_t n, i, fragment_offset;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
378 zip_uint8_t **fragments;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
379
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
380 if (buffer->offset + length + buffer->fragment_size - 1 < length) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
381 zip_error_set(error, ZIP_ER_INVAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
382 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
383 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
384
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
385 /* grow buffer if needed */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
386 if (buffer->offset + length > buffer->nfragments * buffer->fragment_size) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
387 zip_uint64_t needed_fragments = (buffer->offset + length + buffer->fragment_size - 1) / buffer->fragment_size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
388
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
389 if (needed_fragments > buffer->fragments_capacity) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
390 zip_uint64_t new_capacity = buffer->fragments_capacity;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
391
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
392 while (new_capacity < needed_fragments) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
393 new_capacity *= 2;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
394 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
395
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
396 fragments = realloc(buffer->fragments, new_capacity * sizeof(*fragments));
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
397
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
398 if (fragments == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
399 zip_error_set(error, ZIP_ER_MEMORY, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
400 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
401 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
402
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
403 buffer->fragments = fragments;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
404 buffer->fragments_capacity = new_capacity;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
405 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
406
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
407 while (buffer->nfragments < needed_fragments) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
408 if ((buffer->fragments[buffer->nfragments] = malloc(buffer->fragment_size)) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
409 zip_error_set(error, ZIP_ER_MEMORY, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
410 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
411 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
412 buffer->nfragments++;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
413 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
414 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
415
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
416 i = buffer->offset / buffer->fragment_size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
417 fragment_offset = buffer->offset % buffer->fragment_size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
418 n = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
419 while (n < length) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
420 zip_uint64_t left = ZIP_MIN(length - n, buffer->fragment_size - fragment_offset);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
421
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
422 memcpy(buffer->fragments[i] + fragment_offset, data + n, left);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
423
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
424 n += left;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
425 i++;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
426 fragment_offset = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
427 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
428
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
429 buffer->offset += n;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
430 if (buffer->offset > buffer->size) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
431 buffer->size = buffer->offset;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
432 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
433
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
434 return (zip_int64_t)n;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
435 }