blob: 3f4970c1126a7df5d3cfa2c63dfbbd476797d539 [file] [log] [blame]
Thomas Klausnerea8ba492014-09-23 16:54:47 +02001/*
2 zip_io_util.c -- I/O helper functions
3 Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
4
5 This file is part of libzip, a library to manipulate ZIP archives.
6 The authors can be contacted at <libzip@nih.at>
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in
15 the documentation and/or other materials provided with the
16 distribution.
17 3. The names of the authors may not be used to endorse or promote
18 products derived from this software without specific prior
19 written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <errno.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include "zipint.h"
39
40zip_uint16_t
41_zip_get_16(const zip_uint8_t **a)
42{
43 zip_uint16_t ret;
44
45 ret = (zip_uint16_t)((*a)[0]+((*a)[1]<<8));
46 *a += 2;
47
48 return ret;
49}
50
51
52zip_uint32_t
53_zip_get_32(const zip_uint8_t **a)
54{
55 zip_uint32_t ret;
56
57 ret = ((((((zip_uint32_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0];
58 *a += 4;
59
60 return ret;
61}
62
63
64zip_uint64_t
65_zip_get_64(const zip_uint8_t **a)
66{
67 zip_uint64_t x, y;
68
69 x = ((((((zip_uint64_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0];
70 *a += 4;
71 y = ((((((zip_uint64_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0];
72 *a += 4;
73
74 return x+(y<<32);
75}
76
77int
78_zip_read(struct zip_source *src, zip_uint8_t *b, zip_uint64_t length, struct zip_error *error)
79{
80 zip_int64_t n;
81
82 if (length > ZIP_INT64_MAX) {
83 zip_error_set(error, ZIP_ER_INTERNAL, 0);
84 return -1;
85 }
86
87 if ((n = zip_source_read(src, b, length)) < 0) {
88 zip_error_set_from_source(error, src);
89 return -1;
90 }
91
92 if (n < (zip_int64_t)length) {
93 zip_error_set(error, ZIP_ER_EOF, 0);
94 return -1;
95 }
96
97 return 0;
98}
99
100
101zip_uint8_t *
102_zip_read_data(const zip_uint8_t **buf, struct zip_source *src, size_t len, int nulp, struct zip_error *error)
103{
104 zip_uint8_t *r;
105
106 if (len == 0 && nulp == 0)
107 return NULL;
108
109 r = (zip_uint8_t *)malloc(nulp ? len+1 : len);
110 if (!r) {
111 zip_error_set(error, ZIP_ER_MEMORY, 0);
112 return NULL;
113 }
114
115 if (buf) {
116 memcpy(r, *buf, len);
117 *buf += len;
118 }
119 else {
120 if (_zip_read(src, r, len, error) < 0) {
121 free(r);
122 return NULL;
123 }
124 }
125
126 if (nulp) {
127 zip_uint8_t *o;
128 /* replace any in-string NUL characters with spaces */
129 r[len] = 0;
130 for (o=r; o<r+len; o++)
131 if (*o == '\0')
132 *o = ' ';
133 }
134
135 return r;
136}
137
138
139struct zip_string *
140_zip_read_string(const zip_uint8_t **buf, struct zip_source *src, zip_uint16_t len, int nulp, struct zip_error *error)
141{
142 zip_uint8_t *raw;
143 struct zip_string *s;
144
145 if ((raw=_zip_read_data(buf, src, len, nulp, error)) == NULL)
146 return NULL;
147
148 s = _zip_string_new(raw, len, ZIP_FL_ENC_GUESS, error);
149 free(raw);
150 return s;
151}
152
153
154
155
156void
157_zip_put_16(zip_uint8_t **p, zip_uint16_t i)
158{
159 *((*p)++) = i&0xff;
160 *((*p)++) = (i>>8)&0xff;
161}
162
163
164void
165_zip_put_32(zip_uint8_t **p, zip_uint32_t i)
166{
167 *((*p)++) = i&0xff;
168 *((*p)++) = (i>>8)&0xff;
169 *((*p)++) = (i>>16)&0xff;
170 *((*p)++) = (i>>24)&0xff;
171}
172
173
174void
175_zip_put_64(zip_uint8_t **p, zip_uint64_t i)
176{
177 *((*p)++) = i&0xff;
178 *((*p)++) = (i>>8)&0xff;
179 *((*p)++) = (i>>16)&0xff;
180 *((*p)++) = (i>>24)&0xff;
181 *((*p)++) = (i>>32)&0xff;
182 *((*p)++) = (i>>40)&0xff;
183 *((*p)++) = (i>>48)&0xff;
184 *((*p)++) = (i>>56)&0xff;
185}
186
187
188void
189_zip_put_data(zip_uint8_t **p, const char *s, size_t len)
190{
191 memcpy(*p, s, len);
192 *p += len;
193}
194
195
196int
197_zip_write(struct zip *za, const void *data, zip_uint64_t length)
198{
199 zip_int64_t n;
200
201 if ((n = zip_source_write(za->src, data, length)) < 0) {
202 zip_error_set_from_source(&za->error, za->src);
203 return -1;
204 }
205 if ((zip_uint64_t)n != length) {
206 zip_error_set(&za->error, ZIP_ER_WRITE, EINTR);
207 return -1;
208 }
209
210 return 0;
211}