00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include "util.h"
00012 #include "bufferedsocketdevice.h"
00013 #include "upnputil.h"
00014 #include "mythcontext.h"
00015
00017
00019
00020 BufferedSocketDevice::BufferedSocketDevice( int nSocket )
00021 {
00022 m_pSocket = new QSocketDevice();
00023
00024 m_pSocket->setSocket ( nSocket, QSocketDevice::Stream );
00025 m_pSocket->setBlocking ( false );
00026 m_pSocket->setAddressReusable( true );
00027
00028 struct linger ling = {1, 1};
00029
00030 if ( setsockopt( socket(), SOL_SOCKET, SO_LINGER, &ling, sizeof( ling )) < 0)
00031 VERBOSE(VB_IMPORTANT, QString( "BufferedSocketDevice: setsockopt - SO_LINGER Error" ));
00032
00033 m_bufWrite.setAutoDelete( TRUE );
00034
00035 m_nDestPort = 0;
00036
00037 m_nMaxReadBufferSize = 0;
00038 m_nWriteSize = 0;
00039 m_nWriteIndex = 0;
00040 m_bHandleSocketDelete= true;
00041 }
00042
00044
00046
00047 BufferedSocketDevice::BufferedSocketDevice( QSocketDevice *pSocket ,
00048 bool bTakeOwnership )
00049 {
00050
00051 m_bufWrite.setAutoDelete( TRUE );
00052
00053 m_pSocket = pSocket;
00054
00055 m_nDestPort = 0;
00056
00057 m_nMaxReadBufferSize = 0;
00058 m_nWriteSize = 0;
00059 m_nWriteIndex = 0;
00060 m_bHandleSocketDelete= bTakeOwnership;
00061
00062 }
00063
00065
00067
00068 BufferedSocketDevice::~BufferedSocketDevice()
00069 {
00070 Close();
00071 }
00072
00074
00076
00077 void BufferedSocketDevice::Close()
00078 {
00079 Flush();
00080 ReadBytes();
00081
00082 m_bufRead.clear();
00083 m_bufWrite.clear();
00084
00085 if (m_pSocket != NULL)
00086 {
00087 if (m_pSocket->isValid())
00088 m_pSocket->close();
00089
00090 if (m_bHandleSocketDelete)
00091 delete m_pSocket;
00092
00093 m_pSocket = NULL;
00094 }
00095
00096 }
00097
00099
00101
00102 bool BufferedSocketDevice::Connect( const QHostAddress &addr, Q_UINT16 port )
00103 {
00104 if (m_pSocket == NULL)
00105 return false;
00106
00107 return m_pSocket->connect( addr, port );
00108 }
00109
00111
00113
00114 QSocketDevice *BufferedSocketDevice::SocketDevice()
00115 {
00116 return( m_pSocket );
00117 }
00118
00120
00122
00123 void BufferedSocketDevice::SetSocketDevice( QSocketDevice *pSocket )
00124 {
00125 if ((m_bHandleSocketDelete) && (m_pSocket != NULL))
00126 delete m_pSocket;
00127
00128 m_bHandleSocketDelete = false;
00129
00130 m_pSocket = pSocket;
00131 }
00132
00134
00136
00137 void BufferedSocketDevice::SetDestAddress( QHostAddress hostAddress, Q_UINT16 nPort )
00138 {
00139 m_DestHostAddress = hostAddress;
00140 m_nDestPort = nPort;
00141 }
00142
00144
00146
00147 void BufferedSocketDevice::SetReadBufferSize( Q_ULONG bufSize )
00148 {
00149 m_nMaxReadBufferSize = bufSize;
00150 }
00151
00153
00155
00156 Q_ULONG BufferedSocketDevice::ReadBufferSize() const
00157 {
00158 return m_nMaxReadBufferSize;
00159 }
00160
00162
00164
00165 int BufferedSocketDevice::ReadBytes()
00166 {
00167 if (m_pSocket == NULL)
00168 return m_bufRead.size();
00169
00170 Q_LONG maxToRead = 0;
00171
00172 if ( m_nMaxReadBufferSize > 0 )
00173 {
00174 maxToRead = m_nMaxReadBufferSize - m_bufRead.size();
00175
00176 if ( maxToRead <= 0 )
00177 return m_bufRead.size();
00178 }
00179
00180 Q_LONG nbytes = m_pSocket->bytesAvailable();
00181 Q_LONG nread;
00182
00183 QByteArray *a = 0;
00184
00185 if ( nbytes > 0 )
00186 {
00187 a = new QByteArray( nbytes );
00188
00189 nread = m_pSocket->readBlock( a->data(), maxToRead ? QMIN( nbytes, maxToRead ) : nbytes );
00190
00191 if (( nread > 0 ) && ( nread != (int)a->size() ))
00192 {
00193
00194 a->resize( nread );
00195 }
00196 }
00197
00198 if (a)
00199 {
00200
00201
00202
00203 m_bufRead.append( a );
00204 }
00205
00206 return m_bufRead.size();
00207 }
00208
00210
00212
00213 bool BufferedSocketDevice::ConsumeWriteBuf( Q_ULONG nbytes )
00214 {
00215 if ( nbytes <= 0 || nbytes > m_nWriteSize )
00216 return FALSE;
00217
00218 m_nWriteSize -= nbytes;
00219
00220 for ( ;; )
00221 {
00222 QByteArray *a = m_bufWrite.first();
00223
00224 if ( m_nWriteIndex + nbytes >= a->size() )
00225 {
00226 nbytes -= a->size() - m_nWriteIndex;
00227 m_bufWrite.remove();
00228
00229 m_nWriteIndex = 0;
00230
00231 if ( nbytes == 0 )
00232 break;
00233 }
00234 else
00235 {
00236 m_nWriteIndex += nbytes;
00237 break;
00238 }
00239 }
00240
00241 return TRUE;
00242 }
00243
00245
00247
00248 void BufferedSocketDevice::Flush()
00249 {
00250
00251 if ((m_pSocket == NULL) || !m_pSocket->isValid())
00252 return;
00253
00254 bool osBufferFull = FALSE;
00255 int consumed = 0;
00256
00257 while ( !osBufferFull && ( m_nWriteSize > 0 ) && m_pSocket->isValid())
00258 {
00259 QByteArray *a = m_bufWrite.first();
00260
00261 int nwritten = 0;
00262 int i = 0;
00263
00264 if ( (int)a->size() - m_nWriteIndex < 1460 )
00265 {
00266 QByteArray out( 65536 );
00267
00268 int j = m_nWriteIndex;
00269 int s = a->size() - j;
00270
00271 while ( a && i+s < (int)out.size() )
00272 {
00273 memcpy( out.data()+i, a->data()+j, s );
00274 j = 0;
00275 i += s;
00276 a = m_bufWrite.next();
00277 s = a ? a->size() : 0;
00278 }
00279
00280 if (m_nDestPort != 0)
00281 nwritten = m_pSocket->writeBlock( out.data(), i, m_DestHostAddress, m_nDestPort );
00282 else
00283 nwritten = m_pSocket->writeBlock( out.data(), i );
00284 }
00285 else
00286 {
00287
00288 i = a->size() - m_nWriteIndex;
00289
00290 if (m_nDestPort != 0)
00291 nwritten = m_pSocket->writeBlock( a->data() + m_nWriteIndex, i, m_DestHostAddress, m_nDestPort );
00292 else
00293 nwritten = m_pSocket->writeBlock( a->data() + m_nWriteIndex, i );
00294 }
00295
00296 if ( nwritten > 0 )
00297 {
00298 if ( ConsumeWriteBuf( nwritten ) )
00299
00300 consumed += nwritten;
00301 }
00302
00303 if ( nwritten < i )
00304 osBufferFull = TRUE;
00305 }
00306 }
00307
00308
00310
00312
00313 QIODevice::Offset BufferedSocketDevice::Size()
00314 {
00315 return (QIODevice::Offset)BytesAvailable();
00316 }
00317
00319
00321
00322 QIODevice::Offset BufferedSocketDevice::At()
00323 {
00324 return( 0 );
00325 }
00326
00328
00330
00331 bool BufferedSocketDevice::At( QIODevice::Offset index )
00332 {
00333 ReadBytes();
00334
00335 if ( index > m_bufRead.size() )
00336 return FALSE;
00337
00338 m_bufRead.consumeBytes( (Q_ULONG)index, 0 );
00339
00340 return TRUE;
00341 }
00342
00344
00346
00347 bool BufferedSocketDevice::AtEnd()
00348 {
00349 if ( !m_pSocket->isValid() )
00350 return TRUE;
00351
00352 ReadBytes();
00353
00354 return m_bufRead.size() == 0;
00355
00356 }
00357
00359
00361
00362 Q_ULONG BufferedSocketDevice::BytesAvailable()
00363 {
00364 if ( !m_pSocket->isValid() )
00365 return 0;
00366
00367 return ReadBytes();
00368 }
00369
00371
00373
00374 Q_ULONG BufferedSocketDevice::WaitForMore( int msecs, bool *pTimeout )
00375 {
00376 bool bTimeout = false;
00377
00378 if ( !m_pSocket->isValid() )
00379 return 0;
00380
00381 Q_LONG nBytes = BytesAvailable();
00382
00383 if (nBytes == 0)
00384 {
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 msecs = 1000;
00410
00411 nBytes = m_pSocket->waitForMore( msecs, &bTimeout );
00412
00413 if (pTimeout != NULL)
00414 *pTimeout = bTimeout;
00415 }
00416
00417 return nBytes;
00418 }
00419
00421
00423
00424 Q_ULONG BufferedSocketDevice::BytesToWrite() const
00425 {
00426 return m_nWriteSize;
00427
00428 }
00429
00431
00433
00434 void BufferedSocketDevice::ClearPendingData()
00435 {
00436 m_bufWrite.clear();
00437 m_nWriteIndex = m_nWriteSize = 0;
00438 }
00439
00441
00443
00444 void BufferedSocketDevice::ClearReadBuffer()
00445 {
00446 m_bufRead.clear();
00447 }
00448
00450
00452
00453 Q_LONG BufferedSocketDevice::ReadBlock( char *data, Q_ULONG maxlen )
00454 {
00455 if ( data == 0 && maxlen != 0 )
00456 return -1;
00457
00458 if ( !m_pSocket->isOpen() )
00459 return -1;
00460
00461 ReadBytes();
00462
00463 if ( maxlen >= m_bufRead.size() )
00464 maxlen = m_bufRead.size();
00465
00466 m_bufRead.consumeBytes( maxlen, data );
00467
00468 return maxlen;
00469
00470 }
00471
00473
00475
00476 Q_LONG BufferedSocketDevice::WriteBlock( const char *data, Q_ULONG len )
00477 {
00478 if ( len == 0 )
00479 return 0;
00480
00481 QByteArray *a = m_bufWrite.last();
00482
00483 bool writeNow = ( m_nWriteSize + len >= 1400 || len > 512 );
00484
00485 if ( a && a->size() + len < 128 )
00486 {
00487
00488 int i = a->size();
00489
00490 a->resize( i+len );
00491 memcpy( a->data()+i, data, len );
00492 }
00493 else
00494 {
00495
00496 a = new QByteArray( len );
00497 memcpy( a->data(), data, len );
00498
00499 m_bufWrite.append( a );
00500 }
00501
00502 m_nWriteSize += len;
00503
00504 if ( writeNow )
00505 Flush();
00506
00507 return len;
00508 }
00509
00511
00513
00514 Q_LONG BufferedSocketDevice::WriteBlockDirect( const char *data, Q_ULONG len )
00515 {
00516 Q_LONG nWritten = 0;
00517
00518
00519
00520 Flush();
00521
00522 if (m_nDestPort != 0)
00523 nWritten = m_pSocket->writeBlock( data, len, m_DestHostAddress, m_nDestPort );
00524 else
00525 nWritten = m_pSocket->writeBlock( data, len );
00526
00527 return nWritten;
00528 }
00529
00531
00533
00534 int BufferedSocketDevice::Getch()
00535 {
00536 if ( m_pSocket->isOpen() )
00537 {
00538 ReadBytes();
00539
00540 if (m_bufRead.size() > 0 )
00541 {
00542 uchar c;
00543
00544 m_bufRead.consumeBytes( 1, (char*)&c );
00545
00546 return c;
00547 }
00548 }
00549
00550 return -1;
00551 }
00552
00554
00556
00557 int BufferedSocketDevice::Putch( int ch )
00558 {
00559 char buf[2];
00560
00561 buf[0] = ch;
00562
00563 return WriteBlock(buf, 1) == 1 ? ch : -1;
00564 }
00565
00567
00569
00570 int BufferedSocketDevice::Ungetch(int ch )
00571 {
00572 return m_bufRead.ungetch( ch );
00573 }
00574
00576
00578
00579 bool BufferedSocketDevice::CanReadLine()
00580 {
00581 ReadBytes();
00582
00583 if (( BytesAvailable() > 0 ) && m_bufRead.scanNewline( 0 ) )
00584 return TRUE;
00585
00586 return FALSE;
00587 }
00588
00590
00592
00593 QString BufferedSocketDevice::ReadLine()
00594 {
00595 QByteArray a(256);
00596
00597 ReadBytes();
00598
00599 bool nl = m_bufRead.scanNewline( &a );
00600
00601 QString s;
00602
00603 if ( nl )
00604 {
00605 At( a.size() );
00606
00607 s = QString( a );
00608 }
00609
00610 return s;
00611 }
00612
00614
00616
00617 QString BufferedSocketDevice::ReadLine( int msecs )
00618 {
00619 MythTimer timer;
00620 QString sLine;
00621
00622 if ( CanReadLine() )
00623 return( ReadLine() );
00624
00625
00626
00627
00628
00629
00630 if ( msecs > 0)
00631 {
00632 bool bTimeout = false;
00633
00634 timer.start();
00635
00636 while ( !CanReadLine() && !bTimeout )
00637 {
00638
00639
00640 WaitForMore( msecs, &bTimeout );
00641
00642 if ( timer.elapsed() >= msecs )
00643 {
00644 bTimeout = true;
00645 VERBOSE( VB_UPNP, "BufferedSocketDeviceRequest::ReadLine - Exceeded Total Elapsed Wait Time." );
00646 }
00647
00648 }
00649
00650 if (CanReadLine())
00651 sLine = ReadLine();
00652 }
00653
00654 return( sLine );
00655 }
00656
00658
00660
00661 Q_UINT16 BufferedSocketDevice::Port() const
00662 {
00663 if (m_pSocket)
00664 return( m_pSocket->port() );
00665
00666 return 0;
00667 }
00668
00670
00672
00673 Q_UINT16 BufferedSocketDevice::PeerPort() const
00674 {
00675 if (m_pSocket)
00676 return( m_pSocket->peerPort() );
00677
00678 return 0;
00679 }
00680
00682
00684
00685 QHostAddress BufferedSocketDevice::Address() const
00686 {
00687 if (m_pSocket)
00688 return( m_pSocket->address() );
00689
00690 QHostAddress tmp;
00691
00692 return tmp;
00693 }
00694
00696
00698
00699 QHostAddress BufferedSocketDevice::PeerAddress() const
00700 {
00701 if (m_pSocket)
00702 return( m_pSocket->peerAddress() );
00703
00704 QHostAddress tmp;
00705
00706 return tmp;
00707 }
00708