/[MITgcm]/MITgcm/tools/mpack-1.6/part.c
ViewVC logotype

Contents of /MITgcm/tools/mpack-1.6/part.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (show annotations) (download)
Tue Feb 26 17:05:00 2008 UTC (16 years, 1 month ago) by jmc
Branch: MAIN
CVS Tags: checkpoint64y, checkpoint64x, checkpoint64z, checkpoint64q, checkpoint64p, checkpoint64s, checkpoint64r, checkpoint64u, checkpoint64t, checkpoint64w, checkpoint64v, checkpoint64i, checkpoint64h, checkpoint64k, checkpoint64j, checkpoint64m, checkpoint64l, checkpoint64o, checkpoint64n, checkpoint64a, checkpoint64c, checkpoint64b, checkpoint64e, checkpoint64d, checkpoint64g, checkpoint64f, checkpoint63p, checkpoint63q, checkpoint63r, checkpoint63s, checkpoint63l, checkpoint63m, checkpoint63n, checkpoint63o, checkpoint63h, checkpoint63i, checkpoint63j, checkpoint63k, checkpoint63d, checkpoint63e, checkpoint63f, checkpoint63g, checkpoint63a, checkpoint63b, checkpoint63c, checkpoint64, checkpoint65, checkpoint60, checkpoint61, checkpoint62, checkpoint63, checkpoint66g, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, checkpoint66n, checkpoint66m, checkpoint66l, checkpoint66k, checkpoint66j, checkpoint66i, checkpoint66h, checkpoint65z, checkpoint65x, checkpoint65y, checkpoint65r, checkpoint65s, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint65j, checkpoint65k, checkpoint65h, checkpoint65i, checkpoint65n, checkpoint65o, checkpoint65l, checkpoint65m, checkpoint65b, checkpoint65c, checkpoint65a, checkpoint65f, checkpoint65g, checkpoint65d, checkpoint65e, checkpoint59q, checkpoint59p, checkpoint59r, checkpoint59o, checkpoint62c, checkpoint62b, checkpoint62a, checkpoint62g, checkpoint62f, checkpoint62e, checkpoint62d, checkpoint62k, checkpoint62j, checkpoint62i, checkpoint62h, checkpoint62o, checkpoint62n, checkpoint62m, checkpoint62l, checkpoint62s, checkpoint62r, checkpoint62q, checkpoint62p, checkpoint62w, checkpoint62v, checkpoint62u, checkpoint62t, checkpoint62z, checkpoint62y, checkpoint62x, checkpoint61f, checkpoint61g, checkpoint61d, checkpoint61e, checkpoint61b, checkpoint61c, checkpoint61a, checkpoint61n, checkpoint61o, checkpoint61l, checkpoint61m, checkpoint61j, checkpoint61k, checkpoint61h, checkpoint61i, checkpoint61v, checkpoint61w, checkpoint61t, checkpoint61u, checkpoint61r, checkpoint61s, checkpoint61p, checkpoint61q, checkpoint61z, checkpoint61x, checkpoint61y, HEAD
Changes since 1.3: +4 -5 lines
File MIME type: text/plain
put again new version (1.6-4, see MITgcm_contrib/mpack_src) of mpack sources.
among others:
 - fix MD5 code on some 64 bit platforms.
 - fix lot of compilation warnings.

1 /*
2 * Read MIME body-part, stopping on boundaries.
3 */
4 /* (C) Copyright 1994 by Carnegie Mellon University
5 * All Rights Reserved.
6 *
7 * Permission to use, copy, modify, distribute, and sell this software
8 * and its documentation for any purpose is hereby granted without
9 * fee, provided that the above copyright notice appear in all copies
10 * and that both that copyright notice and this permission notice
11 * appear in supporting documentation, and that the name of Carnegie
12 * Mellon University not be used in advertising or publicity
13 * pertaining to distribution of the software without specific,
14 * written prior permission. Carnegie Mellon University makes no
15 * representations about the suitability of this software for any
16 * purpose. It is provided "as is" without express or implied
17 * warranty.
18 *
19 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
20 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
21 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
22 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
24 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
25 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26 * SOFTWARE.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "part.h"
34 #include "xmalloc.h"
35
36 #define BUFSIZE 1024 /* must be > PART_MAX_BOUNDARY_LEN */
37 #define GROWBOUNDARY 20
38
39 static int pendingboundary(struct part *part);
40
41 /*
42 * Create, initialize, and return a new struct part pointer
43 * for the input file 'infile'.
44 */
45 struct part *part_init(FILE *infile)
46 {
47 static struct part zeropart;
48 struct part *newpart;
49
50 newpart = (struct part *)xmalloc(sizeof(struct part));
51 *newpart = zeropart;
52 newpart->infile = infile;
53 newpart->buf = (unsigned char *)xmalloc(BUFSIZE);
54 newpart->buf_alloc = BUFSIZE;
55
56 return newpart;
57 }
58
59 /*
60 * Close and free 'part'.
61 */
62 void part_close(struct part *part)
63 {
64 fclose(part->infile);
65 if (part->buf) free(part->buf);
66 if (part->boundary) free(part->boundary);
67 }
68
69 /*
70 * Return the multipart depth of 'part'. Top-level is '0'.
71 */
72 int
73 part_depth(struct part *part)
74 {
75 return part->boundary_num;
76 }
77
78 /*
79 * Add to 'part' the multipart boundary 'boundary'.
80 */
81 void part_addboundary(struct part *part, char *boundary)
82 {
83 /* Grow boundary array if necessary */
84 if (part->boundary_num == part->boundary_alloc) {
85 part->boundary_alloc += GROWBOUNDARY;
86 part->boundary = (char (*)[PART_MAX_BOUNDARY_LEN+1])
87 xrealloc((char *)part->boundary,
88 part->boundary_alloc * (PART_MAX_BOUNDARY_LEN+1));
89 part->boundary_length = (int *)
90 xrealloc((char *)part->boundary_length,
91 part->boundary_alloc * sizeof(int));
92 }
93
94 strncpy(part->boundary[part->boundary_num], boundary,
95 PART_MAX_BOUNDARY_LEN);
96 part->boundary[part->boundary_num][PART_MAX_BOUNDARY_LEN] = '\0';
97 part->boundary_length[part->boundary_num] =
98 strlen(part->boundary[part->boundary_num]);
99 part->boundary_num++;
100 if (part->boundary_seen+1 == part->boundary_num) {
101 part->boundary_seen++;
102 }
103 }
104
105 /*
106 * Private function that is only called from the part_getc() macro.
107 *
108 * Fills the input buffer for 'part' if necessary. Returns the next
109 * input character or EOF if at a boundary or end of file.
110 */
111 int
112 part_fill(struct part *part)
113 {
114 /* part_getc() decremented this before calling us, put it back */
115 part->cnt++;
116
117 /* Return EOF if we saw a boundary */
118 if (part->boundary_seen < part->boundary_num) return EOF;
119
120 /* Fill buffer if it is empty */
121 if (part->cnt == 0) {
122 part->ptr = part->buf;
123 part->cnt = fread(part->buf, 1, part->buf_alloc, part->infile);
124 if (part->cnt == 0) {
125 part->boundary_seen = 0;
126 return EOF;
127 }
128 }
129
130 /* If there is a newline, see if it is followed by a boundary */
131 if (part->ptr[0] == '\n' && pendingboundary(part)) {
132 return EOF;
133 }
134
135 part->cnt--;
136 return *part->ptr++;
137 }
138
139 /*
140 * Read a line into the array 's', of size 'n', from 'part'.
141 * Reads until 'n'-1 characters are read, a newline is read, or
142 * an EOF is encountered. The array is then nul-terminated and returned.
143 * If the first character read is an EOF, then a null pointer is instead
144 * returned.
145 */
146 char *
147 part_gets(char *s, int n, struct part *part)
148 {
149 int c;
150 char *p = s;
151
152 if (n == 0) return 0;
153 n--;
154 while (n-- && (c = part_getc(part)) != EOF) {
155 *p++ = c;
156 if (c == '\n') break;
157 }
158 if (p == s) return 0;
159 *p++ = '\0';
160 return s;
161 }
162
163 /*
164 * Push back the string 's' into the input buffer of 'part'.
165 * Leaves room in the input buffer to push back an additional single
166 * character using the prot_ungetc() macro.
167 */
168 void part_ungets(char *s, struct part *part)
169 {
170 int len = strlen(s);
171 int i;
172
173 /* Grow buffer if necessary */
174 if (part->cnt + len + 1 > part->buf_alloc) {
175 i = part->ptr - part->buf;
176 part->buf_alloc = part->cnt + len + 1;
177 part->buf = (unsigned char *)
178 xrealloc((char *)part->buf, part->buf_alloc);
179 part->ptr = part->buf + i;
180 }
181
182 /* Move current data down to make room for new data if necessary */
183 if (len + 1 > part->ptr - part->buf) {
184 for (i = part->cnt-1; i >= 0; i--) {
185 part->buf[len+1+i] = part->ptr[i];
186 }
187 part->ptr = part->buf + len + 1;
188 }
189
190 /* Copy in the new data */
191 part->ptr -= len;
192 part->cnt += len;
193 for (i = 0; i < len; i++) {
194 part->ptr[i] = s[i];
195 }
196 }
197
198 /*
199 * Reset the saw-boundary state of 'part' and set up to read next
200 * body-part Returns nonzero iff the pending boundary was a final
201 * boundary of the current multipart.
202 */
203 int
204 part_readboundary(struct part *part)
205 {
206 int c;
207 int sawfinal = 0;
208
209 if (part->boundary_seen < part->boundary_num-1) {
210 /* We saw an enclosing boundary. Signal end of multipart, but
211 * don't skip over the boundary.
212 */
213 part->boundary_num--;
214 return 1;
215 }
216
217 /* Deal with EOF on input stream */
218 if (part->cnt == 0) return 1;
219
220 /* Skip over delimiter, reset the "saw boundary" state */
221 part->ptr += part->boundary_length[part->boundary_seen] + 3;
222 part->cnt -= part->boundary_length[part->boundary_seen] + 3;
223 part->boundary_seen = part->boundary_num;
224
225 /* Check for two dashes, which indicate a final delimiter */
226 c = part_getc(part);
227 if (c == '-') {
228 c = part_getc(part);
229 if (c == '-') {
230 sawfinal = 1;
231 part->boundary_num--;
232 }
233 }
234
235 /* Eat rest of the boundary line */
236 while (c != '\n' && c != EOF) {
237 c = part_getc(part);
238 }
239
240 return sawfinal;
241 }
242
243
244 /*
245 * Return nonzero and set the saw-boundary state iff 'part'
246 * is positioned at a boundary.
247 */
248 static int
249 pendingboundary(struct part *part)
250 {
251 int bufleft;
252 int i;
253
254 /* Fill buffer if we don't have enough to do our look ahead */
255 if (part->cnt < 3 ||
256 (part->cnt < PART_MAX_BOUNDARY_LEN+3 && part->ptr[1] == '-' &&
257 part->ptr[2] == '-')) {
258
259 bufleft = part->buf_alloc - part->cnt - (part->ptr - part->buf);
260
261 /* If not enough room, move everything to beginning of buffer */
262 if (part->ptr!=part->buf && bufleft + part->cnt < PART_MAX_BOUNDARY_LEN+3) {
263 for (i = 0; i < part->cnt; i++) {
264 part->buf[i] = part->ptr[i];
265 }
266 part->ptr = part->buf;
267 bufleft = part->buf_alloc - part->cnt;
268 }
269
270 /* Read in more data */
271 part->cnt += fread(part->ptr+part->cnt, 1, bufleft, part->infile);
272 }
273
274 /* If no "--", it's not a boundary */
275 if (part->cnt < 3 || part->ptr[1] != '-' || part->ptr[2] != '-') {
276 return 0;
277 }
278
279 for (i = 0; i < part->boundary_num; i++) {
280 if (part->cnt - 3 >= part->boundary_length[i] &&
281 !strncmp((char *)part->ptr+3, part->boundary[i],
282 part->boundary_length[i])) {
283 break;
284 }
285 }
286
287 if (i == part->boundary_num) return 0;
288
289 /* Saw boundary, index 'i' */
290 part->boundary_seen = i;
291 return 1;
292 }

  ViewVC Help
Powered by ViewVC 1.1.22