VNamedPipeFC.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const VNamedPipeFC_cxx_Version =
  51.     "$Id: VNamedPipeFC.cxx,v 1.1 2001/03/30 02:49:21 icahoon Exp $";
  52. #ifndef __vxworks
  53. #include "global.h"
  54. #include "VNamedPipeFC.hxx"
  55. #include "Sptr.hxx"
  56. #include <iostream>
  57. #include <sys/stat.h>
  58. #include <unistd.h>
  59. const int maxNamedPipeFds = 128;
  60. static int make_and_open_named_pipe(const char* pipeName)
  61. {
  62.     struct stat buffer;
  63.     int err = stat(pipeName, &buffer);
  64.     if ((err == -1) || !S_ISFIFO(buffer.st_mode))
  65.     {
  66.         unlink(pipeName);
  67.         mknod(pipeName, S_IFIFO | 0644, 0);
  68.     }
  69.     int fd = open(pipeName, O_RDWR | O_NONBLOCK);
  70.     if (fd <= 0)
  71.     {
  72.         cerr << "error, error, can't open: " << pipeName << endl;
  73.     }
  74.     return fd;
  75. }
  76. VNamedPipeFC::~VNamedPipeFC()
  77. {
  78.     close(inFd);
  79.     close(inCtlFd);
  80.     close(outFd);
  81.     close(outCtlFd);
  82.     string inName = pipeName_ + string(".in");
  83.     string inCtlName = pipeName_ + string(".in.ctl");
  84.     string outName = pipeName_ + string(".out");
  85.     string outCtlName = pipeName_ + string(".out.ctl");
  86.     //    unlink(inName.c_str());
  87.     //    unlink(inCtlName.c_str());
  88.     //    unlink(outName.c_str());
  89.     //    unlink(outCtlName.c_str());
  90. }
  91. VNamedPipeFC::VNamedPipeFC(const char* pipeName)
  92.         : timeoutValid(false),
  93.         pipeName_(pipeName)
  94. {
  95.     string inName = pipeName_ + string(".in");
  96.     string inCtlName = pipeName_ + string(".in.ctl");
  97.     string outName = pipeName_ + string(".out");
  98.     string outCtlName = pipeName_ + string(".out.ctl");
  99.     // create the nodes
  100.     inFd = make_and_open_named_pipe(inName.c_str());
  101.     inCtlFd = make_and_open_named_pipe(inCtlName.c_str());
  102.     outFd = make_and_open_named_pipe(outName.c_str());
  103.     outCtlFd = make_and_open_named_pipe(outCtlName.c_str());
  104. }
  105. void VNamedPipeFC::clearTimeout()
  106. {
  107.     timeoutValid = false;
  108. }
  109. void VNamedPipeFC::setTimeout(const struct timeval& timeout)
  110. {
  111.     localTimeout.tv_sec = timeout.tv_sec;
  112.     localTimeout.tv_usec = timeout.tv_usec;
  113.     timeoutValid = true;
  114. }
  115. string VNamedPipeFC::encodeMsg(const string& msg)
  116. {
  117.     char header[20];
  118.     sprintf(header, "msg %10.10dn", msg.length());
  119.     string o_buf;
  120.     o_buf = header;
  121.     o_buf += msg;
  122.     return o_buf;
  123. }
  124. VNamedPipeFC::VNamedPipeFC()
  125. {
  126.     assert(0);
  127. }
  128. bool VNamedPipeFC::handleInCtl()
  129. {
  130.     int bufSize = 5000;  
  131. #if defined (__SUNPRO_CC)
  132.     char buf[5000];
  133. #else    
  134.     char buf[bufSize];
  135. #endif
  136.     fd_set myReadSet;
  137.     struct timeval timeout;
  138.     bool noMoreData = false;
  139.     while (!noMoreData)
  140.     {
  141.         timeout.tv_sec = 0;
  142.         timeout.tv_usec = 0;
  143.         FD_ZERO(&myReadSet);
  144.         FD_SET(inCtlFd, &myReadSet);
  145.         int selVal = select(maxNamedPipeFds, &myReadSet, 0, 0, &timeout);
  146.         if (selVal == 0)
  147.         {
  148.             noMoreData = true;
  149.         }
  150.         if (selVal < 0)
  151.         {
  152.             // bad news!
  153.             noMoreData = true;
  154.         }
  155.         if (FD_ISSET(inCtlFd, &myReadSet))
  156.         {
  157.             // read
  158.             read(inCtlFd, buf, bufSize);
  159.             // go again
  160.         }
  161.     }
  162.     return false;
  163. }
  164. bool VNamedPipeFC::writeOkBlockOrTimeout()
  165. {
  166.     if (timeoutValid)
  167.     {
  168.         struct timeval timeout;
  169.         timeout.tv_sec = localTimeout.tv_sec;
  170.         timeout.tv_usec = localTimeout.tv_usec;
  171.         return writeOk(&timeout);
  172.     }
  173.     else
  174.     {
  175.         return writeOk(0);
  176.     }
  177. }
  178. bool VNamedPipeFC::writeOkNoBlock()
  179. {
  180.     struct timeval timeout;
  181.     timeout.tv_sec = 0;
  182.     timeout.tv_usec = 0;
  183.     return writeOk(&timeout);
  184. }
  185. bool VNamedPipeFC::writeOk(struct timeval* timeout)
  186. {
  187.     fd_set myReadSet;
  188.     fd_set myWriteSet;
  189.     FD_ZERO(&myReadSet);
  190.     FD_SET(inCtlFd, &myReadSet);
  191.     FD_ZERO(&myWriteSet);
  192.     FD_SET(outFd, &myWriteSet);
  193.     int selVal = select(maxNamedPipeFds, &myReadSet, &myWriteSet, 0, timeout);
  194.     if (selVal < 0)
  195.     {
  196.         // bad news!
  197.         return false;
  198.     }
  199.     if (FD_ISSET(inCtlFd, &myReadSet))
  200.     {
  201.         handleInCtl();
  202.         cerr << "ng" << endl;
  203.         return false;
  204.     }
  205.     if (FD_ISSET(outFd, &myWriteSet))
  206.     {
  207.         // cerr << "good" << endl;
  208.         return true;
  209.     }
  210.     //    cerr << "other" << endl;
  211.     return false;
  212. }
  213. bool VNamedPipeFC::readOkBlockOrTimeout()
  214. {
  215.     if (timeoutValid)
  216.     {
  217.         struct timeval timeout;
  218.         timeout.tv_sec = localTimeout.tv_sec;
  219.         timeout.tv_usec = localTimeout.tv_usec;
  220.         return readOk(&timeout);
  221.     }
  222.     else
  223.     {
  224.         return readOk(0);
  225.     }
  226. }
  227. bool VNamedPipeFC::readOkNoBlock()
  228. {
  229.     struct timeval timeout;
  230.     timeout.tv_sec = 0;
  231.     timeout.tv_usec = 0;
  232.     return readOk(&timeout);
  233. }
  234. bool VNamedPipeFC::readOk(struct timeval* timeout)
  235. {
  236.     fd_set myReadSet;
  237.     FD_ZERO(&myReadSet);
  238.     FD_SET(inCtlFd, &myReadSet);
  239.     FD_SET(inFd, &myReadSet);
  240.     int selVal = select(maxNamedPipeFds, &myReadSet, 0, 0, timeout);
  241.     if (selVal < 0)
  242.     {
  243.         // bad news!
  244.         return false;
  245.     }
  246.     if (FD_ISSET(inCtlFd, &myReadSet))
  247.     {
  248.         handleInCtl();
  249.         cerr << "ng" << endl;
  250.         return false;
  251.     }
  252.     if (FD_ISSET(inFd, &myReadSet))
  253.     {
  254.         // cerr << "go" << endl;
  255.         return true;
  256.     }
  257.     //    cerr << "other" << endl;
  258.     return false;
  259. }
  260. bool VNamedPipeFC::sendMsg(const string& msg)
  261. {
  262.     string encodedMsg = encodeMsg(msg);
  263.     unsigned int total_bytes_written = 0;
  264.     // int bytes_written = 0;
  265.     while (total_bytes_written < encodedMsg.length())
  266.     {
  267.         // select for both write and the control channel
  268.         if (writeOkBlockOrTimeout() == false)
  269.         {
  270.             fsync(outFd);
  271.             return false;
  272.         }
  273.         int bytes_written
  274.         = write(outFd,
  275.                 encodedMsg.c_str() + total_bytes_written,
  276.                 encodedMsg.length() - total_bytes_written);
  277.         total_bytes_written += bytes_written;
  278.     }
  279.     fsync(outFd);
  280.     return true;
  281. }
  282. bool VNamedPipeFC::recMsg(string* msg)
  283. {
  284.     char header_buffer[20];
  285.     const int bytes_to_read = 15;
  286.     int total_bytes_read;
  287.     total_bytes_read = 0;
  288.     while (total_bytes_read < bytes_to_read)
  289.     {
  290.         if (readOkBlockOrTimeout() == false)
  291.         {
  292.             return false;
  293.         }
  294.         int bytes_read = read(inFd, header_buffer + total_bytes_read,
  295.                               bytes_to_read - total_bytes_read);
  296.         total_bytes_read += bytes_read;
  297.     }
  298.     header_buffer[15] = '';
  299.     // now, parse the buffer for the data
  300.     //    cout << "buf: " << header_buffer << endl;
  301.     //bytes_to_read = atoi(header_buffer + 4);
  302.     int nbytes_to_read =  atoi(header_buffer + 4) ;
  303.     //    cout << "reading (" << bytes_to_read << " bytes)" << endl;
  304.     char* buffer = new char[nbytes_to_read+1];
  305.     total_bytes_read = 0;
  306.     while (total_bytes_read < nbytes_to_read)
  307.     {
  308.         if (readOkBlockOrTimeout() == false)
  309.         {
  310.             return false;
  311.         }
  312.         int bytes_read = read(inFd, buffer + total_bytes_read,
  313.                               nbytes_to_read - total_bytes_read);
  314.         total_bytes_read += bytes_read;
  315.     }
  316.     buffer[nbytes_to_read] = '';
  317.     *msg = string(buffer);
  318.     delete [] buffer;
  319.     return true;
  320. }
  321. void VNamedPipeFC::clearCtl()
  322. {
  323.     handleInCtl();
  324. }
  325. #else
  326. // vxworks stuff
  327. static int unused;
  328. #endif