blob: c00d320b46d335d598cbd4de57eef21dd5e0070b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <decaf/net/SocketFactory.h>
#include <decaf/net/BufferedSocket.h>
#include <decaf/net/TcpSocket.h>
#include <decaf/util/Properties.h>
#include <stdio.h>
using namespace std;
using namespace decaf;
using namespace decaf::util;
using namespace decaf::net;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
////////////////////////////////////////////////////////////////////////////////
Socket* SocketFactory::createSocket(
const std::string& uri,
const Properties& properties)
throw ( SocketException ) {
try {
// Ensure something is actually passed in for the URI
if( uri == "" ) {
throw SocketException( __FILE__, __LINE__,
"SocketTransport::start() - uri not provided" );
}
string dummy = uri;
// Extract the port.
std::size_t portIx = dummy.find( ':' );
if( portIx == string::npos ) {
throw SocketException( __FILE__, __LINE__,
"SocketTransport::start() - uri malformed - port not specified: %s", uri.c_str() );
}
string host = dummy.substr( 0, portIx );
string portString = dummy.substr( portIx + 1 );
int port;
if( sscanf( portString.c_str(), "%d", &port) != 1 ) {
throw SocketException( __FILE__, __LINE__,
"SocketTransport::start() - unable to extract port from uri: %s", uri.c_str() );
}
// Get the read buffer size.
int inputBufferSize = 10000;
dummy = properties.getProperty( "inputBufferSize", "10000" );
sscanf( dummy.c_str(), "%d", &inputBufferSize );
// Get the write buffer size.
int outputBufferSize = 10000;
dummy = properties.getProperty( "outputBufferSize", "10000" );
sscanf( dummy.c_str(), "%d", &outputBufferSize );
// Get the linger flag.
int soLinger = 0;
dummy = properties.getProperty( "soLinger", "0" );
sscanf( dummy.c_str(), "%d", &soLinger );
// Get the keepAlive flag.
bool soKeepAlive =
properties.getProperty( "soKeepAlive", "false" ) == "true";
// Get the socket receive buffer size.
int soReceiveBufferSize = -1;
dummy = properties.getProperty( "soReceiveBufferSize", "-1" );
sscanf( dummy.c_str(), "%d", &soReceiveBufferSize );
// Get the socket send buffer size.
int soSendBufferSize = -1;
dummy = properties.getProperty( "soSendBufferSize", "-1" );
sscanf( dummy.c_str(), "%d", &soSendBufferSize );
// Get the socket TCP_NODELAY flag.
bool tcpNoDelay =
properties.getProperty( "tcpNoDelay", "true" ) == "true";
// Now that we have all the elements that we wanted - let's do it!
// Create a TCP Socket and then Wrap it in a buffered socket
// so that users get the benefit of buffered reads and writes.
// The buffered socket will own the TcpSocket instance, and will
// clean it up when it is cleaned up.
TcpSocket* tcpSocket = new TcpSocket();
try {
// Connect the socket.
tcpSocket->connect( host.c_str(), port );
// Set the socket options.
tcpSocket->setSoLinger( soLinger );
tcpSocket->setKeepAlive( soKeepAlive );
tcpSocket->setTcpNoDelay( tcpNoDelay );
if( soReceiveBufferSize > 0 ){
tcpSocket->setReceiveBufferSize( soReceiveBufferSize );
}
if( soSendBufferSize > 0 ){
tcpSocket->setSendBufferSize( soSendBufferSize );
}
} catch ( SocketException& ex ) {
ex.setMark( __FILE__, __LINE__ );
try{
delete tcpSocket;
} catch( SocketException& ex2 ){ /* Absorb */ }
throw ex;
}
return tcpSocket;
}
DECAF_CATCH_RETHROW( SocketException )
DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
DECAF_CATCHALL_THROW( SocketException )
}