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

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

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


Revision 1.4 - (hide annotations) (download)
Tue Feb 26 17:05:00 2008 UTC (16 years, 2 months 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 edhill 1.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 jmc 1.4 #include <stdlib.h>
31 edhill 1.1 #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 jmc 1.4 void part_close(struct part *part)
63 edhill 1.1 {
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 jmc 1.4 void part_addboundary(struct part *part, char *boundary)
82 edhill 1.1 {
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 jmc 1.4 void part_ungets(char *s, struct part *part)
169 edhill 1.1 {
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