1 /*
2  *	Copyright 2018, University Corporation for Atmospheric Research
3  *	See netcdf/COPYRIGHT file for copying and redistribution conditions.
4  */
5 /* $Id: ncio.h,v 1.27 2006/01/03 04:56:28 russ Exp $ */
6 
7 #ifndef _NCIO_H_
8 #define _NCIO_H_
9 
10 #include <stddef.h>	/* size_t */
11 #include <sys/types.h>	/* off_t */
12 #include "netcdf.h"
13 
14 /* Define an internal use only mode flag to signal use of byte ranges.
15    This is temporary until we can re-organize the ncio open/create API.
16 */
17 #define NC_HTTP 0x80000000
18 
19 typedef struct ncio ncio;	/* forward reference */
20 
21 /*
22  * A value which is an invalid off_t
23  */
24 #define OFF_NONE  ((off_t)(-1))
25 
26 /*
27  * Flags used by the region layer,
28  *  'rflags' argument to ncio.rel() and ncio.get().
29  */
30 #define RGN_NOLOCK	0x1	/* Don't lock region.
31 				 * Used when contention control handled
32 				 * elsewhere.
33 				 */
34 #define RGN_NOWAIT	0x2	/* return immediate if can't lock, else wait */
35 
36 #define RGN_WRITE	0x4	/* we intend to modify, else read only */
37 
38 #define RGN_MODIFIED	0x8	/* we did modify, else, discard */
39 
40 
41 /*
42  * The next four typedefs define the signatures
43  * of function pointers in struct ncio below.
44  * They are not used outside of this file and ncio.h,
45  * They just make some casts in the ncio.c more readable.
46  */
47 	/*
48 	 * Indicate that you are done with the region which begins
49 	 * at offset. Only reasonable flag value is RGN_MODIFIED.
50 	 */
51 typedef int ncio_relfunc(ncio *const nciop,
52 		 off_t offset, int rflags);
53 
54 	/*
55 	 * Request that the region (offset, extent)
56 	 * be made available through *vpp.
57 	 */
58 typedef int ncio_getfunc(ncio *const nciop,
59 			off_t offset, size_t extent,
60 			int rflags,
61 			void **const vpp);
62 
63 	/*
64 	 * Like memmove(), safely move possibly overlapping data.
65 	 * Only reasonable flag value is RGN_NOLOCK.
66 	 */
67 typedef int ncio_movefunc(ncio *const nciop, off_t to, off_t from,
68 			size_t nbytes, int rflags);
69 
70 	/*
71 	 * Write out any dirty buffers to disk and
72 	 * ensure that next read will get data from disk.
73 	 */
74 typedef int ncio_syncfunc(ncio *const nciop);
75 
76 /*
77  *  Sync any changes to disk, then truncate or extend file so its size
78  *  is length.  This is only intended to be called before close, if the
79  *  file is open for writing and the actual size does not match the
80  *  calculated size, perhaps as the result of having been previously
81  *  written in NOFILL mode.
82   */
83 typedef int ncio_pad_lengthfunc(ncio* nciop, off_t length);
84 
85 /*
86  *  Get file size in bytes.
87  */
88 typedef int ncio_filesizefunc(ncio *nciop, off_t *filesizep);
89 
90 /* Write out any dirty buffers and
91    ensure that next read will not get cached data.
92    Sync any changes, then close the open file associated with the ncio
93    struct, and free its memory.
94    nciop - pointer to ncio to close.
95    doUnlink - if true, unlink file
96 */
97 typedef int ncio_closefunc(ncio *nciop, int doUnlink);
98 
99 /* Get around cplusplus "const xxx in class ncio without constructor" error */
100 #if defined(__cplusplus)
101 #define NCIO_CONST
102 #else
103 #define NCIO_CONST const
104 #endif
105 
106 /*
107  * netcdf i/o abstraction
108  */
109 struct ncio {
110 	/*
111 	 * A copy of the ioflags argument passed in to ncio_open()
112 	 * or ncio_create().
113 	 */
114 	int ioflags;
115 
116 	/*
117 	 * The file descriptor of the netcdf file.
118 	 * This gets handed to the user as the netcdf id.
119 	 */
120 	NCIO_CONST int fd;
121 
122 	/* member functions do the work */
123 
124 	ncio_relfunc *NCIO_CONST rel;
125 
126 	ncio_getfunc *NCIO_CONST get;
127 
128 	ncio_movefunc *NCIO_CONST move;
129 
130 	ncio_syncfunc *NCIO_CONST sync;
131 
132 	ncio_pad_lengthfunc *NCIO_CONST pad_length;
133 
134 	ncio_filesizefunc *NCIO_CONST filesize;
135 
136 	ncio_closefunc *NCIO_CONST close;
137 
138 	/*
139 	 * A copy of the 'path' argument passed in to ncio_open()
140 	 * or ncio_create(). Used by ncabort() to remove (unlink)
141 	 * the file and by error messages.
142 	 */
143 	const char *path;
144 
145 	/* implementation private stuff */
146 	void *pvt;
147 };
148 
149 #undef NCIO_CONST
150 
151 /* Define wrappers around the ncio dispatch table */
152 
153 extern int ncio_rel(ncio* const, off_t, int);
154 extern int ncio_get(ncio* const, off_t, size_t, int, void** const);
155 extern int ncio_move(ncio* const, off_t, off_t, size_t, int);
156 extern int ncio_sync(ncio* const);
157 extern int ncio_filesize(ncio* const, off_t*);
158 extern int ncio_pad_length(ncio* const, off_t);
159 extern int ncio_close(ncio* const, int);
160 
161 extern int ncio_create(const char *path, int ioflags, size_t initialsz,
162                        off_t igeto, size_t igetsz, size_t *sizehintp,
163 		       void* parameters, /* new */
164                        ncio** nciopp, void** const mempp);
165 
166 extern int ncio_open(const char *path, int ioflags,
167                      off_t igeto, size_t igetsz, size_t *sizehintp,
168 		     void* parameters, /* new */
169                      ncio** nciopp, void** const mempp);
170 
171 /* With the advent of diskless io, we need to provide
172    for multiple ncio packages at the same time,
173    so we have multiple versions of ncio_create.
174    If you create a new package, the you must do the following.
175    1. add an extern definition for it in ncio.c
176    2. modify ncio_create and ncio_open in ncio.c to invoke
177       the new package when appropriate.
178 */
179 
180 #endif /* _NCIO_H_ */
181