|
From: Christian P. <cp...@us...> - 2005-01-14 14:56:13
|
Update of /cvsroot/pclasses/pclasses2/src/Net In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21205/src/Net Added Files: RTSPSocket.cpp RTSPHeader.cpp Log Message: Migrating RTSP standalone lib based on P1 --- NEW FILE: RTSPSocket.cpp --- /*************************************************************************** * Copyright (C) 2004 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "pclasses/IO/IOStream.h" #include "pclasses/Net/RTSPSocket.h" #include <sstream> namespace P { namespace Net { extern Socket::Domain AddrFamily2Domain(int family); RTSPRequest::RTSPRequest(Method method) : _method(method), _url(), _urlValid(false) { } RTSPRequest::RTSPRequest(Method method, const IO::URL& url) : _method(method), _url(url), _urlValid(true) { } RTSPRequest::~RTSPRequest() throw() { } RTSPRequest::Method RTSPRequest::method() const throw() { return _method; } void RTSPRequest::setUrl(const IO::URL& url) throw() { _url = url; } const IO::URL& RTSPRequest::url() const throw() { return _url; } void RTSPRequest::clearUrl() throw() { _urlValid = false; _url = IO::URL(); } bool RTSPRequest::hasUrl() const throw() { return _urlValid; } const RTSPRequestHeader& RTSPRequest::header() const throw() { return _header; } RTSPRequestHeader& RTSPRequest::header() throw() { return _header; } RTSPResponse::RTSPResponse(RTSPSocket& socket, const std::string& protoVer, int code, const std::string& reason) : _socket(&socket), _protoVer(protoVer), _statusCode(code), _reason(reason), _bytesRead(0), _contentLength(0) { setAccess(Read); setValid(true); setEof(false); } RTSPResponse::~RTSPResponse() throw() { try { close(); } catch(...) { } } const RTSPResponseHeader& RTSPResponse::header() const throw() { return _header; } RTSPResponseHeader& RTSPResponse::header() throw() { return _header; } const std::string& RTSPResponse::protocolVersion() const throw() { return _protoVer; } int RTSPResponse::statusCode() const throw() { return _statusCode; } const std::string& RTSPResponse::reason() const throw() { return _reason; } void RTSPResponse::_close() throw(IO::IOError) { setValid(false); setAccess(None); setEof(true); _socket = 0; } size_t RTSPResponse::_write(const char* buffer, size_t count) throw(IO::IOError) { return 0; } size_t RTSPResponse::_read(char* buffer, size_t count) throw(IO::IOError) { if(!_bytesRead) { RTSPHeader::const_iterator i = _header.find("Content-Length"); if(i != _header.end()) { std::istringstream is(i->second); is >> _contentLength; } } size_t ret; // we know the size of the response body ... if(_contentLength > 0) { if(_bytesRead == _contentLength) { setEof(true); return 0; } size_t bytesLeft = _contentLength - _bytesRead; if(count > bytesLeft) count = bytesLeft; ret = _socket->read(buffer, count); _bytesRead += ret; if(!ret) setEof(true); } // we do not know the size of the response body ... // the connection will probably be closed after receiving // the body // XXXX RTSP requires !!! the presence of the Content-Length field else { ret = _socket->read(buffer, count); _bytesRead += ret; if(!ret) setEof(true); } return ret; } RTSPSocket::RTSPSocket() : StreamSocket() { } RTSPSocket::RTSPSocket(Domain d) : StreamSocket() { open(d); } RTSPSocket::RTSPSocket(const NetworkAddress& addr, port_t port) : StreamSocket() { open(AddrFamily2Domain(addr.family())); connect(addr, port); } RTSPSocket::~RTSPSocket() throw() { } void RTSPSocket::open(Domain d) throw(IO::IOError) { Socket::open(d, Stream, 0); } void RTSPSocket::sendRequest(RTSPRequest& req) throw(IO::IOError) { IO::IOStream reqs(*this); switch(req.method()) { case RTSPRequest::DESCRIBE: reqs << "DESCRIBE "; break; case RTSPRequest::ANNOUNCE: reqs << "ANNOUNCE "; break; case RTSPRequest::GET_PARAMETER: reqs << "GET_PARAMETER "; break; case RTSPRequest::OPTIONS: reqs << "OPTIONS "; break; case RTSPRequest::PAUSE: reqs << "PAUSE "; break; case RTSPRequest::PLAY: reqs << "PLAY "; break; case RTSPRequest::RECORD: reqs << "RECORD "; break; case RTSPRequest::REDIRECT: reqs << "REDIRECT "; break; case RTSPRequest::SETUP: reqs << "SETUP "; break; case RTSPRequest::SET_PARAMETER: reqs << "SET_PARAMETER "; break; case RTSPRequest::TEARDOWN: reqs << "TEARDOWN "; break; default: throw RuntimeError("RTSP request not implemented",P_SOURCEINFO); } // send URL .. if(req.hasUrl()) reqs << req.url().path(); else reqs << "*"; // send protocol version .. reqs << " RTSP/1.0\r\n"; // send header lines ... RTSPHeader::const_iterator i = req.header().begin(); bool hostFound = false; while(i != req.header().end()) { if(i->first == "Host") hostFound = true; reqs << i->first << ": " << i->second << "\r\n"; ++i; } if(!hostFound) reqs << "Host: " << req.url().host() << "\r\n"; // terminate request and flush stream reqs << "\r\n"; reqs.sync(); } RTSPResponse RTSPSocket::readResponse() throw(IO::IOError) { std::string line1 = readLine(); std::string rtspProto, rtspResponse; int rtspResponseCode; std::string tmp; std::istringstream is(line1); is >> rtspProto; is >> rtspResponseCode; is >> rtspResponse; RTSPResponse resp(*this, rtspProto, rtspResponseCode, rtspResponse); while(1) { tmp = readLine(); // response header terminated ? if(tmp == "\r\n" || tmp == "\n") break; size_t pos = tmp.find(':'); if(pos != std::string::npos && tmp.size() > 4) { std::string headName = tmp.substr(0, pos); std::string headVal = tmp.substr(pos+2, tmp.size()-(pos+4)); std::cerr << headName << '=' << headVal << std::endl; resp.header().set(headName, headVal); } } return resp; } } // !namespace Net } // !namespace P --- NEW FILE: RTSPHeader.cpp --- /*************************************************************************** * Copyright (C) 2004 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "pclasses/Net/RTSPHeader.h" namespace P { namespace Net { RTSPHeader::RTSPHeader() { } RTSPHeader::~RTSPHeader() { } RTSPRequestHeader::RTSPRequestHeader() { } RTSPRequestHeader::~RTSPRequestHeader() { } RTSPResponseHeader::RTSPResponseHeader() { } RTSPResponseHeader::~RTSPResponseHeader() { } } // !namespace Net } // !namespace P |