ncbi_file_connector.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:11k
源码类别:

生物技术

开发平台:

C/C++

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