File: xdrstdio.c

package info (click to toggle)
libhdf4 4.2.10-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 25,488 kB
  • ctags: 12,954
  • sloc: ansic: 146,962; sh: 14,905; fortran: 12,480; makefile: 922; yacc: 680; pascal: 418; lex: 170; csh: 41
file content (347 lines) | stat: -rw-r--r-- 7,405 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
#if !defined(lint)
static char rcsid[] = "$Id: xdrstdio.c 510 1993-05-03 21:27:09Z chouck $";
#endif

/*
 * xdr_stdio.c, XDR implementation on standard i/o file.
 *
 * This set of routines implements a XDR on a stdio stream.
 * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
 * from the stream.
 *
 * Based on Sun sources from the portable distribution:
 *
 * @(#)xdr_stdio.c	1.1 87/11/04 3.9 RPCSRC
 * @(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro
 * Copyright (C) 1984, Sun Microsystems, Inc.
 *
 *  UCAR/Unidata modifications for netcdf:
 *  	_destroy closes the stream.
 *      current stream position cached in x_public
 *			 (assumes caddr_t can hold a long)
 *      last op cached in x_handy
 */

#include <stdio.h>
#include "local_nc.h" /* prototypes for NCadvis, nc_error */
		      /* also obtains <stdio.h>, <rpc/types.h>, &
		       * <rpc/xdr.h> */
#ifdef DOS_FS
#include    <fcntl.h>   /* O_BINARY */
#define USE_BFLAG
#endif

#ifdef USE_XDRNCSTDIO


#define XDRNC_LASTOP(xdrs) (*((enum xdr_op*)&((xdrs)->x_handy)))
#define XDRNC_POS(xdrs) (*((long*)&((xdrs)->x_public)))


static bool_t	xdrNCstdio_getlong();
static bool_t	xdrNCstdio_putlong();
static bool_t	xdrNCstdio_getbytes();
static bool_t	xdrNCstdio_putbytes();
static u_long	xdrNCstdio_getpos();
static bool_t	xdrNCstdio_setpos();
static long *	xdrNCstdio_inline();
static void	xdrNCstdio_destroy();

/*
 * Ops vector for stdio type XDR
 */
static struct xdr_ops	xdrNCstdio_ops = {
	xdrNCstdio_getlong,	/* deserialize a long int */
	xdrNCstdio_putlong,	/* serialize a long int */
	xdrNCstdio_getbytes,	/* deserialize counted bytes */
	xdrNCstdio_putbytes,	/* serialize counted bytes */
	xdrNCstdio_getpos,	/* get offset in the stream */
	xdrNCstdio_setpos,	/* set offset in the stream */
	xdrNCstdio_inline,	/* prime stream for inline macros */
	xdrNCstdio_destroy	/* destroy stream */
};

/*
 * Initialize a stdio xdr stream.
 * Sets the xdr stream handle xdrs for use on the stream file.
 * Operation flag is set to op.
 */
void
xdrNCstdio_create(xdrs, file, op)
	XDR *xdrs;
	FILE *file;
	enum xdr_op op;
{

	xdrs->x_op = op;
	xdrs->x_ops = &xdrNCstdio_ops;
	xdrs->x_private = (caddr_t)file;
	xdrs->x_handy = 0;
	xdrs->x_base = 0;
	XDRNC_LASTOP(xdrs) = XDR_FREE ;
	XDRNC_POS(xdrs) = ftell(file) ;
}

/*
 * Destroy a NCstdio xdr stream.
 * Cleans up the xdr stream handle xdrs previously set up by xdrNCstdio_create.
 * This function closes the stream.
 */
static void
xdrNCstdio_destroy(xdrs)
	XDR *xdrs;
{
	(void)fclose((FILE *)xdrs->x_private);
}

static bool_t
xdrNCstdio_getlong(xdrs, lp)
	XDR *xdrs;
	long *lp;
{
	if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
	{
		XDRNC_POS(xdrs) = ftell((FILE *)xdrs->x_private);
		return (FALSE);
	}
#ifdef SWAP
	*lp = ntohl(*lp);
#endif
	XDRNC_POS(xdrs) += sizeof(long) ;
	return (TRUE);
}

static bool_t
xdrNCstdio_putlong(xdrs, lp)
	XDR *xdrs;
	long *lp;
{
#ifdef SWAP
	long mycopy = htonl(*lp);
	lp = &mycopy;
#endif
	if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
	{
		XDRNC_POS(xdrs) = ftell((FILE *)xdrs->x_private);
		return (FALSE);
	}
	XDRNC_POS(xdrs) += sizeof(long) ;
	return (TRUE);
}

static bool_t
xdrNCstdio_getbytes(xdrs, addr, len)
	XDR *xdrs;
	caddr_t addr;
	u_int len;
{
	if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
	{
		XDRNC_POS(xdrs) = ftell((FILE *)xdrs->x_private);
		return (FALSE);
	}
	XDRNC_POS(xdrs) += len ;
	return (TRUE);
}

static bool_t
xdrNCstdio_putbytes(xdrs, addr, len)
	XDR *xdrs;
	caddr_t addr;
	u_int len;
{
	if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
	{
		XDRNC_POS(xdrs) = ftell((FILE *)xdrs->x_private);
		return (FALSE);
	}
	XDRNC_POS(xdrs) += len ;
	return (TRUE);
}

static u_long
xdrNCstdio_getpos(xdrs)
	XDR *xdrs;
{
	XDRNC_POS(xdrs) = ftell((FILE *)xdrs->x_private);
	return ((u_long)XDRNC_POS(xdrs));
}

static bool_t
xdrNCstdio_setpos(xdrs, pos) 
	XDR *xdrs;
	u_long pos;
{ 
	if(xdrs->x_op == XDRNC_LASTOP(xdrs) && pos == XDRNC_POS(xdrs))
		return TRUE ;
	/* else */
	XDRNC_LASTOP(xdrs) = xdrs->x_op ;
	if (fseek((FILE *)xdrs->x_private,(long)pos, 0) < 0)
	{
		XDRNC_POS(xdrs) = ftell((FILE *)xdrs->x_private);
		return (FALSE);
	}
	/* else */
	XDRNC_POS(xdrs) = pos ;
	return TRUE ;
}

/*ARGSUSED*/
static long *
xdrNCstdio_inline(xdrs, len)
	XDR *xdrs;
	u_int len;
{

	/*
	 * Must do some work to implement this: must insure
	 * enough data in the underlying stdio buffer,
	 * that the buffer is aligned so that we can indirect through a
	 * long *, and stuff this pointer in xdrs->x_buf.  Doing
	 * a fread or fwrite to a scratch buffer would defeat
	 * most of the gains to be had here and require storage
	 * management on this buffer, so we don't do this.
	 */
	return (NULL);
}
#else

/*
 * Destroy a stdio xdr stream.
 * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
 * This function closes the stream, while the default
 * library function, xdrstdio_destroy() which merely flushes it.
 */
static void
xdrNCstdio_destroy(xdrs)
	XDR *xdrs;
{
	(void)fclose((FILE *)xdrs->x_private);
}

static bool_t
xdrNCstdio_setpos(xdrs, pos) 
	XDR *xdrs;
	u_long pos;
{ 

	static XDR *last = NULL ;
	static enum xdr_op lastop = XDR_FREE ;

	if(xdrs == last && xdrs->x_op == lastop && pos == xdr_getpos(xdrs))
		return TRUE ;
	/* else */
	last = xdrs ;
	lastop = xdrs->x_op ;
	if (fseek((FILE *)xdrs->x_private,(long)pos, 0) < 0)
	{
		return (FALSE);
	}
	/* else */
	return TRUE ;
}

#endif /* USE_XDRNCSTDIO */


/********/

#include <unistd.h> /* access(), F_OK */
#ifndef F_OK
#define F_OK    0
#endif

#include "netcdf.h" /* NC_ */
#include "local_nc.h" /* prototypes for NCadvis, nc_error */

#ifndef USE_BFLAG 	/* Doesn't Understand the "b" (binary flag to fopen) */
#define CREAT_FOPENFLAGS "w+"
#define WRITE_FOPENFLAGS "r+"
#define NOWRITE_FOPENFLAGS "r"
#else
#define CREAT_FOPENFLAGS "w+b"
#define WRITE_FOPENFLAGS "r+b"
#define NOWRITE_FOPENFLAGS "rb"
#endif /* !USE_BFLAG */


/*
 * "sync" (flush) xdr stream.
 */
int
NCxdrfile_sync(xdrs)
	XDR *xdrs;
{
	/* assumes xdrstdio, violates layering */
	FILE *fp = (FILE *)xdrs->x_private ;
	if(fflush(fp) == 0)
		return 0 ; /* success */
	/* else, failure */
	return -1 ; 
}


int
NCxdrfile_create(xdrs, path, ncmode)
XDR *xdrs ;
const char *path ;
int ncmode ;
{
	char *fmode ;
	FILE *fp ;
	enum xdr_op op ;

	switch(ncmode & 0x0f) {
	case NC_NOCLOBBER :
		if( access(path, F_OK) != -1 )
		{
			NCadvise(NC_EEXIST, "\"%s\": File exists", path) ;
			return(-1) ;
		}
		/* fall into */
	case NC_CLOBBER :
		fmode = CREAT_FOPENFLAGS ;
		break ;
	case NC_WRITE :
		fmode = WRITE_FOPENFLAGS ;
		break ;
	case NC_NOWRITE :
		fmode = NOWRITE_FOPENFLAGS ;
		break ;
	default:
		NCadvise(NC_EINVAL, "Bad flag %0x", ncmode & 0x0f) ;
		return(-1) ;
	}

#ifdef DOS_FS
	/*
 	 * set default mode to binary to suppress the expansion of
	 * 0x0f into CRLF
	 */
	if(_fmode != O_BINARY)
		_fmode = O_BINARY ;
#endif
	fp = fopen(path, fmode) ;
	if( fp == NULL )
	{
		nc_serror("filename \"%s\"", path) ;
		return(-1) ;
	} /* else */

	if( ncmode & NC_CREAT )
	{
		op = XDR_ENCODE ;
	} else {
		op = XDR_DECODE ;
	}
	
#ifndef USE_XDRNCSTDIO
	xdrstdio_create(xdrs, fp, op) ;
	xdrs->x_ops->x_destroy = xdrNCstdio_destroy ;
	xdrs->x_ops->x_setpostn = xdrNCstdio_setpos ;
#else
	xdrNCstdio_create(xdrs, fp, op) ;
#endif

	return fileno(fp) ;
}