ncbi_file_connector.c

来自「ncbi源码」· C语言 代码 · 共 378 行

C
378
字号
/* * =========================================================================== * PRODUCTION $Log: ncbi_file_connector.c,v $ * PRODUCTION Revision 1000.0  2003/10/29 16:36:42  gouriano * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R6.12 * PRODUCTION * =========================================================================== *//*  $Id: ncbi_file_connector.c,v 1000.0 2003/10/29 16:36:42 gouriano Exp $ * =========================================================================== * *                            PUBLIC DOMAIN NOTICE *               National Center for Biotechnology Information * *  This software/database is a "United States Government Work" under the *  terms of the United States Copyright Act.  It was written as part of *  the author's official duties as a United States Government employee and *  thus cannot be copyrighted.  This software/database is freely available *  to the public for use. The National Library of Medicine and the U.S. *  Government have not placed any restriction on its use or reproduction. * *  Although all reasonable efforts have been taken to ensure the accuracy *  and reliability of the software and data, the NLM and the U.S. *  Government do not and cannot warrant the performance or results that *  may be obtained by using this software or data. The NLM and the U.S. *  Government disclaim all warranties, express or implied, including *  warranties of performance, merchantability or fitness for any particular *  purpose. * *  Please cite the author in any work or product based on this material. * * =========================================================================== * * Author:  Vladimir Alekseyev, Denis Vakatov, Anton Lavrentiev * * File Description: *   Implement CONNECTOR for a FILE stream * *   See in "connectr.h" for the detailed specification of the underlying *   connector("CONNECTOR", "SConnectorTag") methods and structures. * */#include "ncbi_ansi_ext.h"#include <connect/ncbi_file_connector.h>#include <stdio.h>#include <stdlib.h>/*********************************************************************** *  INTERNAL -- Auxiliary types and static functions ***********************************************************************//* All internal data necessary to perform the (re)connect and i/o */typedef struct {    char*         inp_file_name;    char*         out_file_name;    FILE*         finp;    FILE*         fout;    SFileConnAttr attr;} SFileConnector;/*********************************************************************** *  INTERNAL -- "s_VT_*" functions for the "virt. table" of connector methods ***********************************************************************/#ifdef __cplusplusextern "C" {#endif /* __cplusplus */    static const char* s_VT_GetType (CONNECTOR       connector);    static EIO_Status  s_VT_Open    (CONNECTOR       connector,                                     const STimeout* timeout);    static EIO_Status  s_VT_Wait    (CONNECTOR       connector,                                     EIO_Event       event,                                     const STimeout* timeout);    static EIO_Status  s_VT_Write   (CONNECTOR       connector,                                     const void*     buf,                                     size_t          size,                                     size_t*         n_written,                                     const STimeout* timeout);    static EIO_Status  s_VT_Flush   (CONNECTOR       connector,                                     const STimeout* timeout);    static EIO_Status  s_VT_Read    (CONNECTOR       connector,                                     void*           buf,                                     size_t          size,                                     size_t*         n_read,                                     const STimeout* timeout);    static EIO_Status  s_VT_Status  (CONNECTOR       connector,                                     EIO_Event       dir);    static EIO_Status  s_VT_Close   (CONNECTOR       connector,                                     const STimeout* timeout);    static void        s_Setup      (SMetaConnector* meta,                                     CONNECTOR       connector);    static void        s_Destroy    (CONNECTOR       connector);#  ifdef IMPLEMENTED__CONN_WaitAsync    static EIO_Status s_VT_WaitAsync(void*                   connector,                                     FConnectorAsyncHandler  func,                                     SConnectorAsyncHandler* data);#  endif#ifdef __cplusplus} /* extern "C" */#endif /* __cplusplus *//*ARGSUSED*/static const char* s_VT_GetType(CONNECTOR connector){    return "FILE";}/*ARGSUSED*/static EIO_Status s_VT_Open(CONNECTOR       connector, const STimeout* timeout){    SFileConnector* xxx = (SFileConnector*) connector->handle;    const char*     mode = 0;    /* if connected already, and trying to reconnect */    if (xxx->finp  &&  xxx->fout)        return eIO_Success;    /* open file for output */    switch ( xxx->attr.w_mode ) {    case eFCM_Truncate:        mode = "wb";  break;    case eFCM_Seek: /* mode = "rb+"; break; */    case eFCM_Append:        mode = "ab";  break;    }    xxx->fout = fopen(xxx->out_file_name, mode);    if ( !xxx->fout ) {        return eIO_Unknown;    }    /* open file for input */    xxx->finp = fopen(xxx->inp_file_name, "rb");    if ( !xxx->finp ) {        fclose(xxx->fout);        xxx->fout = 0;        return eIO_Unknown;    }    /* Due to the shortage of portable 'fseek' call     * ignore read/write positions so far;     * only 0/EOF are in use for writing, and only 0 for reading     */    return eIO_Success;}/*ARGSUSED*/static EIO_Status s_VT_Write(CONNECTOR       connector, const void*     buf, size_t          size, size_t*         n_written, const STimeout* timeout){    SFileConnector* xxx = (SFileConnector*) connector->handle;    if ( !size ) {        *n_written = 0;        return eIO_Success;    }    *n_written = fwrite(buf, 1, size, xxx->fout);    if ( !*n_written ) {        return eIO_Unknown;    }    return eIO_Success;}/*ARGSUSED*/static EIO_Status s_VT_Read(CONNECTOR       connector, void*           buf, size_t          size, size_t*         n_read, const STimeout* timeout){    SFileConnector* xxx = (SFileConnector*) connector->handle;    if ( !size ) {        *n_read = 0;        return eIO_Success;    }    *n_read = fread(buf, 1, size, xxx->finp);    if ( !*n_read ) {        return feof(xxx->finp) ? eIO_Closed : eIO_Unknown;    }    return eIO_Success;}/*ARGSUSED*/static EIO_Status s_VT_Wait(CONNECTOR       connector, EIO_Event       event, const STimeout* timeout){    return eIO_Success;}/*ARGSUSED*/static EIO_Status s_VT_Flush(CONNECTOR       connector, const STimeout* timeout){    SFileConnector* xxx = (SFileConnector*) connector->handle;    if (fflush(xxx->fout) != 0)        return eIO_Unknown;    return eIO_Success;}static EIO_Status s_VT_Status(CONNECTOR connector, EIO_Event dir){    SFileConnector* xxx = (SFileConnector*) connector->handle;    assert(dir == eIO_Read || dir == eIO_Write);    if (dir == eIO_Read)        return feof(xxx->finp) ? eIO_Closed :        (ferror(xxx->finp) ? eIO_Unknown : eIO_Success);    else        return ferror(xxx->fout) ?  eIO_Unknown : eIO_Success;}/*ARGSUSED*/static EIO_Status s_VT_Close(CONNECTOR       connector, const STimeout* timeout){    SFileConnector* xxx = (SFileConnector*) connector->handle;    fclose(xxx->finp);    xxx->finp = 0;    fclose(xxx->fout);    xxx->fout = 0;    return eIO_Success;}static void s_Setup(SMetaConnector* meta, CONNECTOR       connector){    /* initialize virtual table */    CONN_SET_METHOD(meta, get_type,   s_VT_GetType,   connector);    CONN_SET_METHOD(meta, open,       s_VT_Open,      connector);    CONN_SET_METHOD(meta, wait,       s_VT_Wait,      connector);    CONN_SET_METHOD(meta, write,      s_VT_Write,     connector);    CONN_SET_METHOD(meta, flush,      s_VT_Flush,     connector);    CONN_SET_METHOD(meta, read,       s_VT_Read,      connector);    CONN_SET_METHOD(meta, status,     s_VT_Status,    connector);    CONN_SET_METHOD(meta, close,      s_VT_Close,     connector);#ifdef IMPLEMENTED__CONN_WaitAsync    CONN_SET_METHOD(meta, wait_async, s_VT_WaitAsync, connector);#endif    meta->default_timeout = 0/*infinite*/;}static void s_Destroy(CONNECTOR connector){    SFileConnector* xxx = (SFileConnector*) connector->handle;        free(xxx->inp_file_name);    free(xxx->out_file_name);    free(xxx);    connector->handle = 0;    free(connector);}/*********************************************************************** *  EXTERNAL -- the connector's "constructors" ***********************************************************************/extern CONNECTOR FILE_CreateConnector(const char* inp_file_name, const char* out_file_name){    static const SFileConnAttr def_attr = { 0, eFCM_Truncate, 0 };    return FILE_CreateConnectorEx(inp_file_name, out_file_name, &def_attr);}extern CONNECTOR FILE_CreateConnectorEx(const char*          inp_file_name, const char*          out_file_name, const SFileConnAttr* attr){    CONNECTOR       ccc = (SConnector*) malloc(sizeof(SConnector));    SFileConnector* xxx = (SFileConnector*) malloc(sizeof(SFileConnector));    /* initialize internal data structures */    xxx->inp_file_name = strdup(inp_file_name);    xxx->out_file_name = strdup(out_file_name);    xxx->finp          = 0;    xxx->fout          = 0;    memcpy(&xxx->attr, attr, sizeof(SFileConnAttr));    /* initialize connector data */    ccc->handle  = xxx;    ccc->next    = 0;    ccc->meta    = 0;    ccc->setup   = s_Setup;    ccc->destroy = s_Destroy;    return ccc;}/* * -------------------------------------------------------------------------- * $Log: ncbi_file_connector.c,v $ * Revision 1000.0  2003/10/29 16:36:42  gouriano * PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R6.12 * * Revision 6.12  2003/05/31 05:14:56  lavr * Add ARGSUSED where args are meant to be unused * * Revision 6.11  2003/05/14 03:55:53  lavr * Slight VT table reformatting * * Revision 6.10  2002/10/28 15:46:20  lavr * Use "ncbi_ansi_ext.h" privately * * Revision 6.9  2002/10/22 15:11:24  lavr * Zero connector's handle to crash if revisited * * Revision 6.8  2002/09/24 15:06:00  lavr * Log moved to end * * Revision 6.7  2002/04/26 16:32:36  lavr * Added setting of default timeout in meta-connector's setup routine * * Revision 6.6  2001/12/04 15:56:35  lavr * Use strdup() instead of explicit strcpy(malloc(...), ...) * * Revision 6.5  2001/01/25 17:04:43  lavr * Reversed:: DESTROY method calls free() to delete connector structure * * Revision 6.4  2001/01/23 23:11:20  lavr * Status virtual method implemented * * Revision 6.3  2001/01/11 16:38:16  lavr * free(connector) removed from s_Destroy function * (now always called from outside, in METACONN_Remove) * * Revision 6.2  2000/12/29 17:55:53  lavr * Adapted for use of new connector structure. * * Revision 6.1  2000/04/12 15:18:13  vakatov * Initial revision * * ========================================================================== */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?