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

流媒体/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 FileDescriptor_cxx_Version = 
  51.     "$Id: FileDescriptor.cxx,v 1.3 2001/06/29 05:36:28 bko Exp $";
  52. #include "FileDescriptor.hxx"
  53. #include "VLog.hxx"
  54. #include "SystemException.hxx"
  55. #include "SystemStatus.hxx"
  56. #include "VocalCommon.hxx"
  57. #include <unistd.h>
  58. #include <fcntl.h>
  59. #include <cerrno>
  60. using Vocal::IO::FileDescriptor;
  61. using Vocal::IO::file_descriptor_t;
  62. using Vocal::Logging::VLog;
  63. using Vocal::SUCCESS;
  64. const file_descriptor_t     FileDescriptor::INVALID = -1;
  65. FileDescriptor::FileDescriptor(file_descriptor_t fd)
  66.     : fd_(fd)
  67. {
  68. }
  69. FileDescriptor::~FileDescriptor()
  70. {
  71.     if ( fd_ != INVALID )
  72.     {
  73.         try
  74.         {
  75.          close();
  76.         }
  77.         catch ( ... )
  78.         {
  79.         }
  80.     }
  81. }
  82. void
  83. FileDescriptor::setFD(file_descriptor_t fd)
  84. {
  85.     if ( fd_ != INVALID )
  86.     {
  87.      close();
  88.     }
  89.     fd_ = fd;
  90. }
  91. file_descriptor_t   
  92. FileDescriptor::getFD() const
  93. {
  94.     return ( fd_ );
  95. }
  96. void       
  97. FileDescriptor::setBlocking()
  98. throw ( Vocal::SystemException )
  99. {
  100.     const string    fn("FileDescriptor::setBlocking");
  101.     VLog         log(fn);
  102. #if defined(WIN32)
  103.     VERR(log) << "not implemented under Win32" << VERR_END(log);
  104.     assert(0);
  105. #else
  106.     
  107.     int flags = fcntl(fd_, F_GETFL);
  108.     
  109.     if (   flags < 0 
  110.      ||  fcntl(fd_, F_SETFL, flags & ~O_NONBLOCK) <  0
  111.      )
  112.     {
  113.      throw Vocal::SystemException(fn + " on fcntl(): " + strerror(errno), 
  114.                __FILE__, __LINE__, errno);
  115.     }
  116.     VDEBUG(log) << (fn + ": fd = ") << fd_ << VDEBUG_END(log);
  117. #endif
  118. }
  119. void       
  120. FileDescriptor::setNonblocking()
  121. throw ( Vocal::SystemException )
  122. {
  123.     const string    fn("FileDescriptor::setNonblocking");
  124.     VLog         log(fn);
  125. #if defined(WIN32)
  126.     VERR(log) << "not implemented under Win32" << VERR_END(log);
  127.     assert(0);
  128. #else
  129.     int flags = fcntl(fd_, F_GETFL);
  130.     
  131.     if  (   flags < 0 
  132.      ||  fcntl(fd_, F_SETFL, flags | O_NONBLOCK) < 0
  133.      )
  134.     {
  135.      throw Vocal::SystemException(fn + " on fcntl(): " + strerror(errno), 
  136.                __FILE__, __LINE__, errno);
  137.     }
  138.     VDEBUG(log) << (fn + ": fd = ") << fd_ << VDEBUG_END(log);
  139. #endif
  140. }
  141. int 
  142. FileDescriptor::write(const string & stuff)
  143. throw ( Vocal::SystemException, Vocal::SystemStatus )
  144. {
  145.     if ( stuff.size() == 0 )
  146.     {
  147.      return ( 0 );
  148.     }
  149.     
  150.     void * s = reinterpret_cast<void *>(const_cast<char *>(stuff.c_str()));
  151.     
  152.     return ( writeToFD(s, stuff.size()) );
  153. }
  154. int 
  155. FileDescriptor::write(const char * stuff)
  156. throw ( Vocal::SystemException, Vocal::SystemStatus )
  157. {
  158.     size_t  size = ( stuff ? strlen(stuff) : 0 );
  159.     
  160.     if ( size == 0 )
  161.     {
  162.      return ( 0 );
  163.     }
  164.     void * s = reinterpret_cast<void *>(const_cast<char *>(stuff));
  165.     
  166.     return ( writeToFD(s, size) );
  167. }
  168. int 
  169. FileDescriptor::write(const vector<u_int8_t> & stuff)
  170. throw ( Vocal::SystemException, Vocal::SystemStatus )
  171. {
  172.     if ( stuff.size() == 0 )
  173.     {
  174.      return ( 0 );
  175.     }
  176.     void * s = reinterpret_cast<void *>(const_cast<u_int8_t *>(&stuff[0]));
  177.     return ( writeToFD(s, stuff.size()) );
  178. }
  179. int 
  180. FileDescriptor::write(const u_int8_t * stuff, size_t size)
  181. throw ( Vocal::SystemException, Vocal::SystemStatus )
  182. {
  183.     if ( stuff == 0 || size == 0 )
  184.     {
  185.      return ( 0 );
  186.     }
  187.     void * s = reinterpret_cast<void *>(const_cast<u_int8_t *>(stuff));
  188.     return ( writeToFD(s, size) );
  189. }
  190. int 
  191. FileDescriptor::read(string & stuff)
  192. throw ( Vocal::SystemException, Vocal::SystemStatus )
  193. {
  194.     void * s = reinterpret_cast<void *>(const_cast<char *>(stuff.data()));
  195.     int bytesRead = readFromFD(s, stuff.size());
  196.     stuff.resize(bytesRead);
  197.         
  198.     return ( bytesRead );
  199. }
  200. int 
  201. FileDescriptor::read(char * stuff, size_t capacity)
  202. throw ( Vocal::SystemException, Vocal::SystemStatus )
  203. {
  204.     if ( stuff == 0 || capacity == 0 )
  205.     {
  206.      return ( 0 );
  207.     }
  208.     
  209.     void * s = reinterpret_cast<void *>(stuff);
  210.     int bytesRead = readFromFD(s, (capacity > 1 ? capacity-1 : 1 ) );
  211.     if ( capacity > 1 )
  212.     {    
  213.      stuff[bytesRead] = '';
  214.     }
  215.     return ( bytesRead );
  216. }
  217. int 
  218. FileDescriptor::read(vector<u_int8_t> & stuff)
  219. throw ( Vocal::SystemException, Vocal::SystemStatus )
  220. {
  221.     stuff.clear();
  222.     
  223.     void * s = reinterpret_cast<void *>(&stuff[0]);
  224.     int bytesRead = readFromFD(s, stuff.size());
  225.     stuff.resize(bytesRead);
  226.     
  227.     return ( bytesRead );
  228. }
  229. int 
  230. FileDescriptor::read(u_int8_t * stuff, size_t capacity) 
  231. throw ( Vocal::SystemException, Vocal::SystemStatus )
  232. {
  233.     if ( stuff == 0 || capacity == 0 )
  234.     {
  235.      return ( 0 );
  236.     }
  237.     
  238.     void * s = reinterpret_cast<void *>(stuff);
  239.     int bytesRead = readFromFD(s, capacity);
  240.     
  241.     return ( bytesRead );
  242. }
  243. void       
  244. FileDescriptor::close()
  245. throw ( Vocal::SystemException )
  246. {
  247.     const string    fn("FileDescriptor::close");
  248.     VLog         log(fn);
  249.     if ( ::close(fd_) < 0 )
  250.     {
  251.      fd_ = INVALID;
  252.      throw Vocal::SystemException(fn + " on std::close(): " + strerror(errno), 
  253.                __FILE__, __LINE__, errno);
  254.     }
  255.     VDEBUG(log) << (fn + ": fd = ") << fd_ << VDEBUG_END(log);
  256.     fd_ = INVALID;
  257. }
  258. bool          
  259. FileDescriptor::operator==(const FileDescriptor & rhs) const
  260. {
  261.     return ( fd_ == rhs.fd_ );
  262. }
  263. bool          
  264. FileDescriptor::operator!=(const FileDescriptor & rhs) const
  265. {
  266.     return ( fd_ != rhs.fd_ );
  267. }
  268. bool          
  269. FileDescriptor::operator<(const FileDescriptor & rhs) const
  270. {
  271.     return ( fd_ < rhs.fd_ );
  272. }
  273. bool          
  274. FileDescriptor::operator<=(const FileDescriptor & rhs) const
  275. {
  276.     return ( fd_ <= rhs.fd_ );
  277. }
  278. bool          
  279. FileDescriptor::operator>(const FileDescriptor & rhs) const
  280. {
  281.     return ( fd_ > rhs.fd_ );
  282. }
  283. bool          
  284. FileDescriptor::operator>=(const FileDescriptor & rhs) const
  285. {
  286.     return ( fd_ >= rhs.fd_ );
  287. }
  288. ostream &       
  289. FileDescriptor::writeTo(ostream & out) const
  290. {
  291.     return ( out << "fd = " << fd_ );
  292. }
  293. int 
  294. FileDescriptor::writeToFD(void * stuff, int size)
  295. throw ( Vocal::SystemException, Vocal::SystemStatus )
  296. {
  297.     const string    fn("FileDescriptor::writeToFD");
  298.     VLog         log(fn);
  299.     int bytesWritten = 0;
  300.     
  301.     bytesWritten = ::write( fd_, 
  302.               stuff, 
  303.     size);
  304.     if ( bytesWritten < SUCCESS )
  305.     {
  306.      int error = errno;
  307.      // If the socket is set nonblocking, we can get an EAGAIN
  308. // here, without sending the packet. If the socket is set 
  309. // blocking we can get an EINTR here, without sending the packet.
  310. // 
  311. if ( error == EAGAIN || error == EINTR )
  312. {
  313.          throw Vocal::SystemStatus(fn + " on write(): " + strerror(error),
  314.                __FILE__, __LINE__, error);
  315.      }
  316.      throw Vocal::SystemException(fn + " on write(): " + strerror(error), 
  317.                __FILE__, __LINE__, error);
  318.     }
  319.     VDEBUG(log) << fn << ": written on " << *this
  320. << ", bytes written: " << bytesWritten
  321. << ", of total: " << size
  322. << VDEBUG_END(log);
  323.     return ( bytesWritten );
  324. }
  325. int 
  326. FileDescriptor::readFromFD(void * stuff, int capacity)
  327. throw ( Vocal::SystemException, Vocal::SystemStatus )
  328. {
  329.     const string    fn("FileDescriptor::readFromFD");
  330.     VLog         log(fn);
  331.     int bytesRead = 0;
  332.     bytesRead = ::read( fd_, 
  333.           stuff, 
  334. capacity);
  335.     if ( bytesRead < SUCCESS )
  336.     {
  337.      int error = errno;
  338.      // If the socket is set nonblocking, we can get an EAGAIN
  339. // here, without receiving the packet. If the socket is set 
  340. // blocking we can get an EINTR here, without receiving the packet.
  341. // 
  342. if ( error == EAGAIN || error == EINTR )
  343. {
  344.          throw Vocal::SystemStatus(fn + " on read(): " + strerror(error),
  345.                __FILE__, __LINE__, error);
  346.      }
  347.      throw Vocal::SystemException(fn + " on read(): " + strerror(error), 
  348.                __FILE__, __LINE__, error);
  349.     }
  350.     VDEBUG(log) << fn << ": read on " << *this
  351. << ", bytes read: " << bytesRead
  352. << ", of capacity: " << capacity
  353. << VDEBUG_END(log);
  354.     return ( bytesRead );
  355. }