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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbi_pipe_connector.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 18:45:18  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: ncbi_pipe_connector.cpp,v 1000.2 2004/06/01 18:45:18 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:  Denis Vakatov, Anton Lavrentiev, Vladimir Ivanov
  35.  *
  36.  * File Description:
  37.  *   Implement CONNECTOR for a pipe interprocess communication
  38.  *   (based on the NCBI CPipe).
  39.  *
  40.  *   See in "connectr.h" for the detailed specification of the underlying
  41.  *   connector("CONNECTOR", "SConnectorTag") methods and structures.
  42.  *
  43.  */
  44. #include <ncbi_pch.hpp>
  45. #include <connect/ncbi_pipe_connector.hpp>
  46. USING_NCBI_SCOPE;
  47. /***********************************************************************
  48.  *  INTERNAL -- Auxiliary types and static functions
  49.  ***********************************************************************/
  50. // All internal data necessary to perform the (re)connect and i/o
  51. typedef struct {
  52.     CPipe*              pipe;        // pipe handle; NULL if not connected yet
  53.     string              cmd;         // program to execute
  54.     vector<string>      args;        // program arguments
  55.     CPipe::TCreateFlags flags;       // pipe create flags
  56.     bool                is_open;     // true if pipe is open
  57.     bool                is_own_pipe; // true if pipe was created in constructor
  58. } SPipeConnector;
  59. /***********************************************************************
  60.  *  INTERNAL -- "s_VT_*" functions for the "virt. table" of connector methods
  61.  ***********************************************************************/
  62. extern "C" {
  63. static const char* s_VT_GetType
  64. (CONNECTOR /*connector*/)
  65. {
  66.     return "PIPE";
  67. }
  68. static char* s_VT_Descr(CONNECTOR connector)
  69. {
  70.     SPipeConnector* xxx = (SPipeConnector*) connector->handle;
  71.     string cmd_line(xxx->cmd);
  72.     ITERATE (vector<string>, iter, xxx->args) {
  73.         if ( !cmd_line.empty() ) {
  74.             cmd_line += " ";
  75.         }
  76.         cmd_line += *iter;
  77.     }
  78.     size_t len = cmd_line.length() + 1/*EOL*/;
  79.     char* buf = (char*) malloc(len);
  80.     if (buf) {
  81.         strcpy(buf, cmd_line.c_str());
  82.     }
  83.     return buf;
  84. }
  85. static EIO_Status s_VT_Open
  86. (CONNECTOR       connector,
  87.  const STimeout* /*timeout*/)
  88. {
  89.     SPipeConnector* xxx = (SPipeConnector*) connector->handle;
  90.     if (!xxx->pipe) {
  91.         return eIO_Unknown;
  92.     }
  93.     // If connected, close previous session first
  94.     if (xxx->is_open) {
  95.         if (xxx->pipe->Close() != eIO_Success) {
  96.             return eIO_Unknown;
  97.         }
  98.         xxx->is_open = false;
  99.     }
  100.     // Open new connection
  101.     EIO_Status status = xxx->pipe->Open(xxx->cmd, xxx->args, xxx->flags);
  102.     if (status == eIO_Success) {
  103.         xxx->is_open = true;
  104.     }
  105.     return status;
  106. }
  107. static EIO_Status s_VT_Status
  108. (CONNECTOR connector,
  109.  EIO_Event dir)
  110. {
  111.     SPipeConnector* xxx = (SPipeConnector*) connector->handle;
  112.     return xxx->pipe ? xxx->pipe->Status(dir) : eIO_Success;
  113. }
  114. static EIO_Status s_VT_Wait
  115. (CONNECTOR       /*connector*/,
  116.  EIO_Event       /*event*/,
  117.  const STimeout* /*timeout*/)
  118. {
  119.     /* NB: to be implemented */
  120.     return eIO_Success;
  121. }
  122. static EIO_Status s_VT_Write
  123. (CONNECTOR       connector,
  124.  const void*     buf,
  125.  size_t          size,
  126.  size_t*         n_written,
  127.  const STimeout* timeout)
  128. {
  129.     SPipeConnector* xxx = (SPipeConnector*) connector->handle;
  130.     if (!xxx->is_open) {
  131.         return eIO_Closed;
  132.     }
  133.     if (!xxx->pipe  ||  xxx->pipe->SetTimeout(eIO_Write, timeout) != 
  134.         eIO_Success) {
  135.         return eIO_Unknown;
  136.     }
  137.     return xxx->pipe->Write(buf, size, n_written);
  138. }
  139. static EIO_Status s_VT_Read
  140. (CONNECTOR       connector,
  141.  void*           buf,
  142.  size_t          size,
  143.  size_t*         n_read,
  144.  const STimeout* timeout)
  145. {
  146.     SPipeConnector* xxx = (SPipeConnector*) connector->handle;
  147.     if (!xxx->is_open) {
  148.         return eIO_Closed;
  149.     }
  150.     if (!xxx->pipe  ||  xxx->pipe->SetTimeout(eIO_Read, timeout) !=
  151.         eIO_Success) {
  152.         return eIO_Unknown;
  153.     }
  154.     return xxx->pipe->Read(buf, size, n_read);
  155. }
  156. static EIO_Status s_VT_Close
  157. (CONNECTOR       connector,
  158.  const STimeout* timeout)
  159. {
  160.     SPipeConnector* xxx = (SPipeConnector*) connector->handle;
  161.     EIO_Status status = eIO_Success;
  162.     if (xxx->is_open) {
  163.         xxx->pipe->SetTimeout(eIO_Close, timeout);
  164.         int exitcode = 0;
  165.         status = xxx->pipe->Close(&exitcode);
  166.         xxx->is_open = false;
  167.     }
  168.     return status == eIO_Closed ? eIO_Success : status;
  169. }
  170. #ifdef IMPLEMENTED__CONN_WaitAsync
  171. static EIO_Status s_VT_WaitAsync
  172. (void*                   connector,
  173.  FConnectorAsyncHandler  func,
  174.  SConnectorAsyncHandler* data)
  175. {
  176.     return eIO_NotSupported;
  177. }
  178. #endif
  179. static void s_Setup
  180. (SMetaConnector* meta,
  181.  CONNECTOR       connector)
  182. {
  183.     // Initialize virtual table
  184.     CONN_SET_METHOD(meta, get_type,   s_VT_GetType,   connector);
  185.     CONN_SET_METHOD(meta, descr,      s_VT_Descr,     connector);
  186.     CONN_SET_METHOD(meta, open,       s_VT_Open,      connector);
  187.     CONN_SET_METHOD(meta, wait,       s_VT_Wait,      connector);
  188.     CONN_SET_METHOD(meta, write,      s_VT_Write,     connector);
  189.     CONN_SET_METHOD(meta, flush,      0,              0);
  190.     CONN_SET_METHOD(meta, read,       s_VT_Read,      connector);
  191.     CONN_SET_METHOD(meta, status,     s_VT_Status,    connector);
  192.     CONN_SET_METHOD(meta, close,      s_VT_Close,     connector);
  193. #ifdef IMPLEMENTED__CONN_WaitAsync
  194.     CONN_SET_METHOD(meta, wait_async, s_VT_WaitAsync, connector);
  195. #endif
  196.     meta->default_timeout = 0; // infinite
  197. }
  198. static void s_Destroy(CONNECTOR connector)
  199. {
  200.     SPipeConnector* xxx = (SPipeConnector*) connector->handle;
  201.     if (xxx) {
  202.         if (xxx->is_own_pipe) {
  203.             delete xxx->pipe;
  204.         }
  205.         delete xxx;
  206.     }
  207.     connector->handle = 0;
  208.     free(connector);
  209. }
  210. } /* extern "C" */
  211. BEGIN_NCBI_SCOPE
  212. /***********************************************************************
  213.  *  EXTERNAL -- the connector's "constructors"
  214.  ***********************************************************************/
  215. extern CONNECTOR PIPE_CreateConnector
  216. (const string&         cmd,
  217.  const vector<string>& args,
  218.  CPipe::TCreateFlags   create_flags,
  219.  CPipe*                pipe)
  220. {
  221.     CONNECTOR       ccc = (SConnector*) malloc(sizeof(SConnector));
  222.     SPipeConnector* xxx = new SPipeConnector();
  223.     // Initialize internal data structures
  224.     xxx->pipe        = pipe ? pipe  : new CPipe();
  225.     xxx->cmd         = cmd;
  226.     xxx->args        = args;
  227.     xxx->flags       = create_flags;
  228.     xxx->is_open     = false;
  229.     xxx->is_own_pipe = pipe ? false : true;
  230.     // Initialize connector data
  231.     ccc->handle  = xxx;
  232.     ccc->next    = 0;
  233.     ccc->meta    = 0;
  234.     ccc->setup   = s_Setup;
  235.     ccc->destroy = s_Destroy;
  236.     return ccc;
  237. }
  238. END_NCBI_SCOPE
  239. /*
  240.  * ==========================================================================
  241.  * $Log: ncbi_pipe_connector.cpp,v $
  242.  * Revision 1000.2  2004/06/01 18:45:18  gouriano
  243.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7
  244.  *
  245.  * Revision 1.7  2004/05/17 20:58:13  gorelenk
  246.  * Added include of PCH ncbi_pch.hpp
  247.  *
  248.  * Revision 1.6  2003/11/12 17:46:38  lavr
  249.  * Few (non-functional) rearrangements
  250.  *
  251.  * Revision 1.5  2003/11/12 16:41:36  ivanov
  252.  * Close: return eIO_Success if pipe is already closed
  253.  *
  254.  * Revision 1.4  2003/09/23 21:09:26  lavr
  255.  * Allow to create on top of (unowned) CPipe object
  256.  *
  257.  * Revision 1.3  2003/09/03 14:35:30  ivanov
  258.  * Fixed previous accidentally commited log message
  259.  *
  260.  * Revision 1.2  2003/09/03 14:29:58  ivanov
  261.  * Cosmetic changes
  262.  *
  263.  * Revision 1.1  2003/09/02 20:33:04  ivanov
  264.  * Initial revision
  265.  *
  266.  * ==========================================================================
  267.  */