|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/connect/ncbi_file_connector.c |
source navigation diff markup identifier search freetext search file search |
1 /* $Id: ncbi_file_connector.c,v 6.14 2006/01/11 20:21:22 lavr Exp $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Vladimir Alekseyev, Denis Vakatov, Anton Lavrentiev
27 *
28 * File Description:
29 * Implement CONNECTOR for a FILE stream
30 *
31 * See in "connectr.h" for the detailed specification of the underlying
32 * connector("CONNECTOR", "SConnectorTag") methods and structures.
33 *
34 */
35
36 #include "ncbi_ansi_ext.h"
37 #include <connect/ncbi_file_connector.h>
38 #include <assert.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41
42
43 /***********************************************************************
44 * INTERNAL -- Auxiliary types and static functions
45 ***********************************************************************/
46
47 /* All internal data necessary to perform the (re)connect and i/o
48 */
49 typedef struct {
50 char* inp_file_name;
51 char* out_file_name;
52 FILE* finp;
53 FILE* fout;
54 SFileConnAttr attr;
55 } SFileConnector;
56
57
58 /***********************************************************************
59 * INTERNAL -- "s_VT_*" functions for the "virt. table" of connector methods
60 ***********************************************************************/
61
62 #ifdef __cplusplus
63 extern "C" {
64 #endif /* __cplusplus */
65 static const char* s_VT_GetType (CONNECTOR connector);
66 static EIO_Status s_VT_Open (CONNECTOR connector,
67 const STimeout* timeout);
68 static EIO_Status s_VT_Wait (CONNECTOR connector,
69 EIO_Event event,
70 const STimeout* timeout);
71 static EIO_Status s_VT_Write (CONNECTOR connector,
72 const void* buf,
73 size_t size,
74 size_t* n_written,
75 const STimeout* timeout);
76 static EIO_Status s_VT_Flush (CONNECTOR connector,
77 const STimeout* timeout);
78 static EIO_Status s_VT_Read (CONNECTOR connector,
79 void* buf,
80 size_t size,
81 size_t* n_read,
82 const STimeout* timeout);
83 static EIO_Status s_VT_Status (CONNECTOR connector,
84 EIO_Event dir);
85 static EIO_Status s_VT_Close (CONNECTOR connector,
86 const STimeout* timeout);
87 static void s_Setup (SMetaConnector* meta,
88 CONNECTOR connector);
89 static void s_Destroy (CONNECTOR connector);
90 # ifdef IMPLEMENTED__CONN_WaitAsync
91 static EIO_Status s_VT_WaitAsync(void* connector,
92 FConnectorAsyncHandler func,
93 SConnectorAsyncHandler* data);
94 # endif
95 #ifdef __cplusplus
96 } /* extern "C" */
97 #endif /* __cplusplus */
98
99
100 /*ARGSUSED*/
101 static const char* s_VT_GetType
102 (CONNECTOR connector)
103 {
104 return "FILE";
105 }
106
107
108 /*ARGSUSED*/
109 static EIO_Status s_VT_Open
110 (CONNECTOR connector,
111 const STimeout* timeout)
112 {
113 SFileConnector* xxx = (SFileConnector*) connector->handle;
114 const char* mode = 0;
115
116 /* if connected already, and trying to reconnect */
117 if (xxx->finp && xxx->fout)
118 return eIO_Success;
119
120 /* open file for output */
121 switch ( xxx->attr.w_mode ) {
122 case eFCM_Truncate:
123 mode = "wb"; break;
124 case eFCM_Seek: /* mode = "rb+"; break; */
125 case eFCM_Append:
126 mode = "ab"; break;
127 }
128
129 if (!xxx->out_file_name ||
130 !(xxx->fout = fopen(xxx->out_file_name, mode))) {
131 return eIO_Unknown;
132 }
133
134 /* open file for input */
135 if (!xxx->inp_file_name ||
136 !(xxx->finp = fopen(xxx->inp_file_name, "rb"))) {
137 fclose(xxx->fout);
138 xxx->fout = 0;
139 return eIO_Unknown;
140 }
141
142 /* Due to shortage of portable 'fseek' call ignore positioning for now;
143 * only 0/EOF are in use for writing, and only 0 for reading
144 */
145 return eIO_Success;
146 }
147
148
149 /*ARGSUSED*/
150 static EIO_Status s_VT_Write
151 (CONNECTOR connector,
152 const void* buf,
153 size_t size,
154 size_t* n_written,
155 const STimeout* timeout)
156 {
157 SFileConnector* xxx = (SFileConnector*) connector->handle;
158
159 if ( !size ) {
160 *n_written = 0;
161 return eIO_Success;
162 }
163
164 *n_written = fwrite(buf, 1, size, xxx->fout);
165 if ( !*n_written ) {
166 return eIO_Unknown;
167 }
168
169 return eIO_Success;
170 }
171
172
173 /*ARGSUSED*/
174 static EIO_Status s_VT_Read
175 (CONNECTOR connector,
176 void* buf,
177 size_t size,
178 size_t* n_read,
179 const STimeout* timeout)
180 {
181 SFileConnector* xxx = (SFileConnector*) connector->handle;
182
183 if ( !size ) {
184 *n_read = 0;
185 return eIO_Success;
186 }
187
188 *n_read = fread(buf, 1, size, xxx->finp);
189 if ( !*n_read ) {
190 return feof(xxx->finp) ? eIO_Closed : eIO_Unknown;
191 }
192
193 return eIO_Success;
194 }
195
196
197 /*ARGSUSED*/
198 static EIO_Status s_VT_Wait
199 (CONNECTOR connector,
200 EIO_Event event,
201 const STimeout* timeout)
202 {
203 return eIO_Success;
204 }
205
206
207 /*ARGSUSED*/
208 static EIO_Status s_VT_Flush
209 (CONNECTOR connector,
210 const STimeout* timeout)
211 {
212 SFileConnector* xxx = (SFileConnector*) connector->handle;
213
214 if (fflush(xxx->fout) != 0)
215 return eIO_Unknown;
216
217 return eIO_Success;
218 }
219
220
221 static EIO_Status s_VT_Status
222 (CONNECTOR connector,
223 EIO_Event dir)
224 {
225 SFileConnector* xxx = (SFileConnector*) connector->handle;
226 assert(dir == eIO_Read || dir == eIO_Write);
227 if (dir == eIO_Read)
228 return feof(xxx->finp) ? eIO_Closed :
229 (ferror(xxx->finp) ? eIO_Unknown : eIO_Success);
230 else
231 return ferror(xxx->fout) ? eIO_Unknown : eIO_Success;
232 }
233
234
235 /*ARGSUSED*/
236 static EIO_Status s_VT_Close
237 (CONNECTOR connector,
238 const STimeout* timeout)
239 {
240 SFileConnector* xxx = (SFileConnector*) connector->handle;
241
242 fclose(xxx->finp);
243 xxx->finp = 0;
244 fclose(xxx->fout);
245 xxx->fout = 0;
246 return eIO_Success;
247 }
248
249
250 static void s_Setup
251 (SMetaConnector* meta,
252 CONNECTOR connector)
253 {
254 /* initialize virtual table */
255 CONN_SET_METHOD(meta, get_type, s_VT_GetType, connector);
256 CONN_SET_METHOD(meta, open, s_VT_Open, connector);
257 CONN_SET_METHOD(meta, wait, s_VT_Wait, connector);
258 CONN_SET_METHOD(meta, write, s_VT_Write, connector);
259 CONN_SET_METHOD(meta, flush, s_VT_Flush, connector);
260 CONN_SET_METHOD(meta, read, s_VT_Read, connector);
261 CONN_SET_METHOD(meta, status, s_VT_Status, connector);
262 CONN_SET_METHOD(meta, close, s_VT_Close, connector);
263 #ifdef IMPLEMENTED__CONN_WaitAsync
264 CONN_SET_METHOD(meta, wait_async, s_VT_WaitAsync, connector);
265 #endif
266 meta->default_timeout = 0/*infinite*/;
267 }
268
269
270 static void s_Destroy
271 (CONNECTOR connector)
272 {
273 SFileConnector* xxx = (SFileConnector*) connector->handle;
274
275 free(xxx->inp_file_name);
276 free(xxx->out_file_name);
277 free(xxx);
278 connector->handle = 0;
279 free(connector);
280 }
281
282
283 /***********************************************************************
284 * EXTERNAL -- the connector's "constructors"
285 ***********************************************************************/
286
287 extern CONNECTOR FILE_CreateConnector
288 (const char* inp_file_name,
289 const char* out_file_name)
290 {
291 static const SFileConnAttr def_attr = { 0, eFCM_Truncate, 0 };
292
293 return FILE_CreateConnectorEx(inp_file_name, out_file_name, &def_attr);
294 }
295
296
297 extern CONNECTOR FILE_CreateConnectorEx
298 (const char* inp_file_name,
299 const char* out_file_name,
300 const SFileConnAttr* attr)
301 {
302 CONNECTOR ccc = (SConnector*) malloc(sizeof(SConnector));
303 SFileConnector* xxx = (SFileConnector*) malloc(sizeof(*xxx));
304
305 /* initialize internal data structures */
306 xxx->inp_file_name = strdup(inp_file_name);
307 xxx->out_file_name = strdup(out_file_name);
308 xxx->finp = 0;
309 xxx->fout = 0;
310
311 memcpy(&xxx->attr, attr, sizeof(SFileConnAttr));
312
313 /* initialize connector data */
314 ccc->handle = xxx;
315 ccc->next = 0;
316 ccc->meta = 0;
317 ccc->setup = s_Setup;
318 ccc->destroy = s_Destroy;
319
320 return ccc;
321 }
322
323
324 /*
325 * --------------------------------------------------------------------------
326 * $Log: ncbi_file_connector.c,v $
327 * Revision 6.14 2006/01/11 20:21:22 lavr
328 * Uniform creation/fill-up of connector structures
329 *
330 * Revision 6.13 2005/04/20 18:15:59 lavr
331 * +<assert.h>
332 *
333 * Revision 6.12 2003/05/31 05:14:56 lavr
334 * Add ARGSUSED where args are meant to be unused
335 *
336 * Revision 6.11 2003/05/14 03:55:53 lavr
337 * Slight VT table reformatting
338 *
339 * Revision 6.10 2002/10/28 15:46:20 lavr
340 * Use "ncbi_ansi_ext.h" privately
341 *
342 * Revision 6.9 2002/10/22 15:11:24 lavr
343 * Zero connector's handle to crash if revisited
344 *
345 * Revision 6.8 2002/09/24 15:06:00 lavr
346 * Log moved to end
347 *
348 * Revision 6.7 2002/04/26 16:32:36 lavr
349 * Added setting of default timeout in meta-connector's setup routine
350 *
351 * Revision 6.6 2001/12/04 15:56:35 lavr
352 * Use strdup() instead of explicit strcpy(malloc(...), ...)
353 *
354 * Revision 6.5 2001/01/25 17:04:43 lavr
355 * Reversed:: DESTROY method calls free() to delete connector structure
356 *
357 * Revision 6.4 2001/01/23 23:11:20 lavr
358 * Status virtual method implemented
359 *
360 * Revision 6.3 2001/01/11 16:38:16 lavr
361 * free(connector) removed from s_Destroy function
362 * (now always called from outside, in METACONN_Remove)
363 *
364 * Revision 6.2 2000/12/29 17:55:53 lavr
365 * Adapted for use of new connector structure.
366 *
367 * Revision 6.1 2000/04/12 15:18:13 vakatov
368 * Initial revision
369 *
370 * ==========================================================================
371 */
372 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |