NCBI C Toolkit Cross Reference

C/connect/ncbi_file_connector.c


  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 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.