⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncbi_connection.c

📁 ncbi源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    CONN_NOT_NULL(Flush);    if (conn->state == eCONN_Unusable)        return eIO_InvalidArg;    /* perform open, if not opened yet */    if (conn->state != eCONN_Open  &&  (status = s_Open(conn)) != eIO_Success)        return status;    assert(conn->state == eCONN_Open  &&  conn->meta.list != 0);    /* call current connector's "FLUSH" method */    if ( !conn->meta.flush )        return eIO_Success;    status = conn->meta.flush(conn->meta.c_flush,                              conn->w_timeout == kDefaultTimeout ?                              conn->meta.default_timeout : conn->w_timeout);    if (status != eIO_Success)        CONN_LOG(eLOG_Warning, "[CONN_Flush]  Cannot flush data");    return status;}/* Read or peek data from the input queue, see CONN_Read() */static EIO_Status s_CONN_Read(CONN        conn, void*       buf, size_t      size, size_t*     n_read, int/*bool*/ peek){    EIO_Status status;    assert(*n_read == 0);    /* check if the read method is specified at all */    if ( !conn->meta.read ) {        status = eIO_NotSupported;        CONN_LOG(eLOG_Error, "[CONN_Read]  Unable to read data");        return status;    }    /* read data from the internal peek buffer, if any */    *n_read = peek        ? BUF_Peek(conn->buf, buf, size) : BUF_Read(conn->buf, buf, size);    if (*n_read == size)        return eIO_Success;    buf = (char*) buf + *n_read;    /* read data from the connection */    {{        size_t x_read = 0;        /* call current connector's "READ" method */        status = conn->meta.read(conn->meta.c_read, buf, size- *n_read,&x_read,                                 conn->r_timeout == kDefaultTimeout ?                                 conn->meta.default_timeout : conn->r_timeout);        *n_read += x_read;        if (peek  &&  x_read)  /* save data in the internal peek buffer */            verify(BUF_Write(&conn->buf, buf, x_read));    }}    if (status != eIO_Success) {        if ( *n_read ) {            CONN_LOG(eLOG_Trace, "[CONN_Read]  Read error");            status = eIO_Success;        } else if ( size ) {            CONN_LOG(status == eIO_Closed  ? eLOG_Trace   :                     status == eIO_Timeout ? eLOG_Warning : eLOG_Error,                     "[CONN_Read]  Cannot read data");        }    }    return status;}/* Persistently read data from the input queue, see CONN_Read() */static EIO_Status s_CONN_ReadPersist(CONN    conn, void*   buf, size_t  size, size_t* n_read){    EIO_Status status;    assert(*n_read == 0);    for (;;) {        size_t x_read = 0;        status = s_CONN_Read(conn, (char*) buf + *n_read,                             size - *n_read, &x_read, 0/*no peek*/);        *n_read += x_read;        if (*n_read == size  ||  status != eIO_Success)            break;        /* flush the unwritten output data (if any) */        if ( conn->meta.flush ) {            conn->meta.flush(conn->meta.c_flush,                             conn->r_timeout == kDefaultTimeout ?                             conn->meta.default_timeout : conn->r_timeout);        }    }    return status;}extern EIO_Status CONN_Read(CONN           conn, void*          buf, size_t         size, size_t*        n_read, EIO_ReadMethod how){    EIO_Status status;    if (!n_read)        return eIO_InvalidArg;    *n_read = 0;    if (size && !buf)        return eIO_InvalidArg;    CONN_NOT_NULL(Read);    if (conn->state == eCONN_Unusable)        return eIO_InvalidArg;    /* perform open, if not opened yet */    if (conn->state != eCONN_Open  &&  (status = s_Open(conn)) != eIO_Success)        return status;    assert(conn->state == eCONN_Open  &&  conn->meta.list != 0);    /* flush the unwritten output data (if any) */    if ( conn->meta.flush ) {        conn->meta.flush(conn->meta.c_flush,                         conn->r_timeout == kDefaultTimeout ?                         conn->meta.default_timeout : conn->r_timeout);    }    /* now do read */    switch (how) {    case eIO_ReadPlain:        return s_CONN_Read(conn, buf, size, n_read, 0/*no peek*/);    case eIO_ReadPeek:        return s_CONN_Read(conn, buf, size, n_read, 1/*peek*/);    case eIO_ReadPersist:        return s_CONN_ReadPersist(conn, buf, size, n_read);    default:        break;    }    return eIO_Unknown;}extern EIO_Status CONN_ReadLine(CONN    conn, char*   line, size_t  size, size_t* n_read ){    EIO_Status status = eIO_Success;    char       w[1024];    size_t     len;    if (!n_read)        return eIO_InvalidArg;    *n_read = 0;    if (size && !line)        return eIO_InvalidArg;    CONN_NOT_NULL(ReadLine);    /* perform open, if not opened yet */    if (conn->state != eCONN_Open  &&  (status = s_Open(conn)) != eIO_Success)        return status;    assert(conn->state == eCONN_Open  &&  conn->meta.list != 0);    /* flush the unwritten output data (if any) */    if ( conn->meta.flush ) {        conn->meta.flush(conn->meta.c_flush,                         conn->r_timeout == kDefaultTimeout ?                         conn->meta.default_timeout : conn->r_timeout);    }    len = 0;    while (len < size) {        size_t i;        size_t x_read = 0;        size_t x_size = BUF_Size(conn->buf);        char*  buf = size - len < sizeof(w) ? w : &line[len];        if (x_size == 0 || x_size > sizeof(w))            x_size = sizeof(w);        status = s_CONN_Read(conn, buf, x_size, &x_read, 0);        for (i = 0; i < x_read; i++) {            if (buf == w)                line[len] = buf[i];            if (buf[i] == '\n') {                line[len] = '\0';                i++;                break;            } else if (++len >= size) {                i++;                break;            }        }        if (i < x_read) {            if (!BUF_PushBack(&conn->buf, &buf[i], x_read - i))                status = eIO_Unknown;            break;        } else if (status != eIO_Success) {            if (len < size)                line[len] = '\0';            break;        }    }    *n_read = len;    return status;}extern EIO_Status CONN_Status(CONN conn, EIO_Event dir){    CONN_NOT_NULL(Status);    if (conn->state == eCONN_Unusable  ||  !conn->meta.list)        return eIO_Unknown;    if (dir != eIO_Read  &&  dir != eIO_Write)        return eIO_InvalidArg;    if (conn->state == eCONN_Closed)        return eIO_Closed;    if ( !conn->meta.status )        return eIO_NotSupported;    return conn->meta.status(conn->meta.c_status, dir);}extern EIO_Status CONN_Close(CONN conn){    FConnCallback func = 0;    void*         data = 0;    CONN_NOT_NULL(Close);    if (conn->state != eCONN_Unusable) {        func = conn->cbs[eCONN_OnClose].func;        data = conn->cbs[eCONN_OnClose].data;    }    /* allow close CB only once */    memset(&conn->cbs[eCONN_OnClose], 0, sizeof(conn->cbs[eCONN_OnClose]));    /* call it! */    if ( func )        (*func)(conn, eCONN_OnClose, data);    /* now close the connection - this also makes it "eCONN_Unusable" */    if ( conn->meta.list )        CONN_ReInit(conn, 0);    BUF_Destroy(conn->buf);    conn->buf = 0;    free(conn);    return eIO_Success;}extern EIO_Status CONN_SetCallback(CONN                  conn, ECONN_Callback        type, const SCONN_Callback* new_cb, SCONN_Callback*       old_cb){    int i = (int) type;    if (i >= CONN_N_CALLBACKS)        return eIO_InvalidArg;    CONN_NOT_NULL(SetCallback);    if ( old_cb )        *old_cb = conn->cbs[i];    if ( new_cb )        conn->cbs[i] = *new_cb;    return eIO_Success;}#ifdef IMPLEMENTED__CONN_WaitAsync/* Internal handler(wrapper for the user-provided handler) for CONN_WaitAsync() */static void s_ConnectorAsyncHandler(SConnectorAsyncHandler* data, EIO_Event               event, EIO_Status              status){    /* handle the async. event */    data->handler(data->conn, event, status, data->data);    /* reset */    verify(CONN_WaitAsync(data->conn, eIO_ReadWrite, 0, 0, 0) == eIO_Success);}extern EIO_Status CONN_WaitAsync(CONN              conn, EIO_Event         event, FConnAsyncHandler handler, void*             data, FConnAsyncCleanup cleanup){    EIO_Status status;    CONNECTOR  x_connector = conn->connector;    SConnectorAsyncHandler* x_data = &conn->async_data;    CONN_NOT_NULL(WaitAsync);    /* perform connect, if not connected yet */    if (!conn->connected  &&  (status = s_Connect(conn)) != eIO_Success)        return status;    /* reset previous handler, cleanup its data */    /* (call current connector's "WAIT_ASYNC" method with NULLs) */    status = x_connector->vtable.wait_async ?        x_connector->vtable.wait_async(x_connector->handle, 0, 0) :        eIO_NotSupported;    if (status != eIO_Success) {        CONN_LOG(eLOG_Error, "[CONN_WaitAsync]  Cannot reset the handler");        return status;    }    if ( x_data->cleanup )        x_data->cleanup(x_data->data);    memset(x_data, '\0', sizeof(*x_data));    /* set new handler, if specified */    /* (call current connector's "WAIT_ASYNC" method with new handler/data) */    if ( !handler )        return eIO_Success;    x_data->conn       = conn;    x_data->wait_event = event;    x_data->handler    = handler;    x_data->data       = data;    x_data->cleanup    = cleanup;    status = x_connector->vtable.wait_async(x_connector->handle,                                            s_ConnectorAsyncHandler, x_data);    if (status != eIO_Success) {        CONN_LOG(eLOG_Error, "[CONN_WaitAsync]  Cannot set new handler");    }    return status;}#endif /* IMPLEMENTED__CONN_WaitAsync *//* * -------------------------------------------------------------------------- * $Log: ncbi_connection.c,v $ * Revision 1000.3  2004/06/01 18:44:48  gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.42 * * Revision 6.42  2004/05/26 16:00:06  lavr * Minor status fixes in CONN_SetTimeout() and CONN_ReadLine() * * Revision 6.41  2004/05/24 20:19:19  lavr * Fix eIO_InvalidArg conditions (size and no buffer) * * Revision 6.40  2004/05/24 19:54:59  lavr * +CONN_ReadLine() * * Revision 6.39  2004/03/23 02:27:37  lavr * Code formatting * * Revision 6.38  2004/02/23 15:23:39  lavr * New (last) parameter "how" added in CONN_Write() API call * * Revision 6.37  2003/08/25 14:40:53  lavr * Employ new k..Timeout constants * * Revision 6.36  2003/05/31 05:18:26  lavr * Optimize on calling flush; do not require to have flush method * * Revision 6.35  2003/05/21 17:53:06  lavr * Better check for {0,0} timeout in CONN_Read() * * Revision 6.34  2003/05/20 21:21:45  lavr * CONN_Write(): log with different log levels on write errors * * Revision 6.33  2003/05/19 16:43:40  lavr * Bugfix in CONN_SetTimeout();  better close callback sequence * * Revision 6.32  2003/05/14 03:51:16  lavr * +CONN_Description() * * Revision 6.31  2003/05/12 18:33:21  lavr * Names of timeout variables uniformed * * Revision 6.30  2003/01/28 15:16:37  lavr * Fix "NULL" message not to contain double quotes in call names * * Revision 6.29  2003/01/17 19:44:46  lavr * Reduce dependencies * * Revision 6.28  2003/01/15 19:51:17  lavr * +CONN_PushBack() * * Revision 6.27  2002/09/19 19:43:46  lavr * Add more assert()'s and do not rely on CONN_Flush() to open in CONN_Read() * * Revision 6.26  2002/09/06 15:43:20  lavr * Bug fixes of late assignments in Read and Write; Flush changed to open * connection if not yet open; more error logging * * Revision 6.25  2002/08/07 16:32:32  lavr * Changed EIO_ReadMethod enums accordingly; log moved to end * * Revision 6.24  2002/04/26 16:30:26  lavr * Checks for kDefaultTimeout and use of default_timeout of meta-connector * * Revision 6.23  2002/04/24 21:18:04  lavr * Beautifying: pup open check before buffer check in CONN_Wait() * * Revision 6.22  2002/04/22 19:30:01  lavr * Do not put trace message on polling wait (tmo={0,0}) * More effective CONN_Read w/o repeatitive checkings for eIO_ReadPersist * * Revision 6.21  2002/03/22 22:17:01  lavr * Better check when formally timed out but technically polled in CONN_Wait() * * Revision 6.20  2002/02/05 22:04:12  lavr * Included header files rearranged * * Revision 6.19  2002/01/30 20:10:56  lavr * Remove *n_read = 0 assignment in s_CONN_Read; replace it with assert() * * Revision 6.18  2001/08/20 20:13:15  vakatov * CONN_ReInit() -- Check connection handle for NULL (it was missed in R6.17) * * Revision 6.17  2001/08/20 20:00:43  vakatov * CONN_SetTimeout() to return "EIO_Status". * CONN_***() -- Check connection handle for NULL. * * Revision 6.16  2001/07/10 15:08:35  lavr * Edit for style * * Revision 6.15  2001/06/29 21:06:46  lavr * BUGFIX: CONN_LOG now checks for non-NULL get_type virtual function * * Revision 6.14  2001/06/28 22:00:48  lavr * Added function: CONN_SetCallback * Added callback: eCONN_OnClose * * Revision 6.13  2001/06/07 17:54:36  lavr * Modified exit branch in s_CONN_Read() * * Revision 6.12  2001/05/30 19:42:44  vakatov * s_CONN_Read() -- do not issue warning if requested zero bytes * (by A.Lavrentiev) * * Revision 6.11  2001/04/24 21:29:04  lavr * kDefaultTimeout is used everywhere when timeout is not set explicitly * * Revision 6.10  2001/02/26 22:52:44  kans * Initialize x_read in s_CONN_Read * * Revision 6.9  2001/02/26 16:32:01  kans * Including string.h instead of cstring * * Revision 6.8  2001/02/25 21:41:50  kans * Include <cstring> on Mac to get memset * * Revision 6.7  2001/02/09 17:34:18  lavr * CONN_GetType added; severities of some messages changed * * Revision 6.6  2001/01/25 16:55:48  lavr * CONN_ReInit bugs fixed * * Revision 6.5  2001/01/23 23:10:53  lavr * Typo corrected in description of connection structure * * Revision 6.4  2001/01/12 23:51:38  lavr * Message logging modified for use LOG facility only * * Revision 6.3  2001/01/03 22:29:59  lavr * CONN_Status implemented * * Revision 6.2  2000/12/29 17:52:59  lavr * Adapted to use new connector structure; modified to have * Internal tri-state {Unusable | Open | Closed }. * * Revision 6.1  2000/03/24 22:53:34  vakatov * Initial revision * * Revision 6.4  1999/11/01 16:14:23  vakatov * s_CONN_Read() -- milder error levels when hitting EOF * * Revision 6.3  1999/04/05 15:32:53  vakatov * CONN_Wait():  be more mild and discrete about the posted error severity * * Revision 6.1  1999/04/01 21:48:09  vakatov * Fixed for the change in spec:  "n_written/n_read" args in * CONN_Write/Read to be non-NULL and "*n_written / *n_read" := 0 * * Revision 6.0  1999/03/25 23:04:57  vakatov * Initial revision * * ========================================================================== */

⌨️ 快捷键说明

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