/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2011 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 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 General Public License *
* along with this program. If not, see .*
************************************************************************/
//------------------------------------------------------------------------------
// Author: Lukasz Janyst
// Date: 07.07.2010
// File: Descriptor.hh
//------------------------------------------------------------------------------
#ifndef EOS_NS_DESCRIPTOR_HH
#define EOS_NS_DESCRIPTOR_HH
#include
#include
#include
#include
#include
namespace eos
{
//----------------------------------------------------------------------------
//! Socket exception
//----------------------------------------------------------------------------
class DescriptorException
{
public:
//------------------------------------------------------------------------
//! Constructor
//------------------------------------------------------------------------
DescriptorException()
{
}
//------------------------------------------------------------------------
//! Copy constructor
//------------------------------------------------------------------------
DescriptorException( const DescriptorException& ex )
{
pMsg << ex.pMsg.str();
}
//------------------------------------------------------------------------
//! Get the associated stream
//------------------------------------------------------------------------
std::ostringstream &getMessage()
{
return pMsg;
}
private:
std::ostringstream pMsg;
};
//----------------------------------------------------------------------------
//! A Descriptor
//----------------------------------------------------------------------------
class Descriptor
{
public:
//------------------------------------------------------------------------
//! Constructor
//------------------------------------------------------------------------
Descriptor():
pFD( -1 ) {}
//------------------------------------------------------------------------
//! Create a Descriptor from a file descriptor
//------------------------------------------------------------------------
explicit Descriptor( int fd ):
pFD( fd ) {}
//------------------------------------------------------------------------
//! Set descriptor
//------------------------------------------------------------------------
void setDescriptor( int fd )
{
pFD = fd;
}
//------------------------------------------------------------------------
//! Get descriptor
//------------------------------------------------------------------------
int getDescriptor()
{
return pFD;
}
//------------------------------------------------------------------------
//! Seek
//------------------------------------------------------------------------
off_t seek( off_t offset, int whence )
{
return ::lseek( pFD, offset, whence );
}
//------------------------------------------------------------------------
//! Close the descriptor
//------------------------------------------------------------------------
void close();
//------------------------------------------------------------------------
//! Read the buffer from the blocking descriptor (socket, pipe), it won't
//! return until all the requested data is read, or fail if it cannot
//! be read
//!
//! @param buffer buffer pointer
//! @param len length of the buffer
//------------------------------------------------------------------------
void readBlocking( char *buffer, unsigned len );
//------------------------------------------------------------------------
//! Read the buffer from the non-blocking descriptor (file),
//! it won't return until all the requested data is read, when it reaches
//! the end it will wait for new data to be appended
//!
//! @param buffer buffer pointer
//! @param len length of the buffer
//! @param poll poll the descriptor every poll microseconds if the
//! sufficient amount of data is unavailable
//! an exception is thrown it poll is set to 0 and there
//! is no data anymore
//------------------------------------------------------------------------
void readNonBlocking( char *buffer, unsigned len, unsigned poll = 0 );
//------------------------------------------------------------------------
//! Read the buffer from the non-blocking descriptor (file)
//! at given offset, it won't return until all the requested data is read,
//! when it reaches the end it will wait for new data to be appended
//!
//! @param buffer buffer pointer
//! @param len length of the buffer
//! @param offset offset
//! @param poll poll the descriptor every poll microseconds if the
//! sufficient amount of data is unavailable
//! an exception is thrown it poll is set to 0 and there
//! is no data anymore
//------------------------------------------------------------------------
void offsetReadNonBlocking( char *buffer, unsigned len, off_t offset,
unsigned poll = 0 );
//------------------------------------------------------------------------
//! Try to read len bytes at offset
//!
//! @param buffer buffer pointer
//! @param len length of the buffer
//! @param offset offset
//! @return number of available bytes
//------------------------------------------------------------------------
unsigned tryRead( char *buffer, unsigned len, off_t offset );
//------------------------------------------------------------------------
//! Write data to the descriptor
//!
//! @param buffer buffer pointer
//! @param len length of the buffer
//------------------------------------------------------------------------
void write( const char *buffer, unsigned len );
protected:
int pFD;
};
//----------------------------------------------------------------------------
//! A network socket
//----------------------------------------------------------------------------
class Socket: public Descriptor
{
public:
//------------------------------------------------------------------------
//! Protocol
//------------------------------------------------------------------------
enum Protocol
{
TCP = 0,
UDP
};
//------------------------------------------------------------------------
//! Constructor
//------------------------------------------------------------------------
Socket() {}
//------------------------------------------------------------------------
//! Create a socket from a descriptor
//------------------------------------------------------------------------
explicit Socket( int socket ):
Descriptor( socket ) {}
//------------------------------------------------------------------------
//! Initialize the socket
//!
//! @param proto protocol type
//------------------------------------------------------------------------
void init( Protocol proto );
//------------------------------------------------------------------------
//! Connect the socket
//!
//! @param address hostname or ip address of a server
//! @param port port number
//------------------------------------------------------------------------
void connect( const char *address, unsigned port );
//------------------------------------------------------------------------
//! Bind to the port
//------------------------------------------------------------------------
void bind( const char *address, unsigned port );
//------------------------------------------------------------------------
//! Listen to the incomming connections
//!
//! @param queue backlog queue size
//------------------------------------------------------------------------
void listen( unsigned queue = 20 );
//------------------------------------------------------------------------
//! Accept connections, allocates memory, the user takes ownership over
//! The socket object
//------------------------------------------------------------------------
Socket *accept();
//------------------------------------------------------------------------
//! Close the socket
//------------------------------------------------------------------------
void close();
//------------------------------------------------------------------------
//! The same as the ones in the manual
//------------------------------------------------------------------------
void setsockopt( int level, int name, void *value, socklen_t len );
//------------------------------------------------------------------------
//! The same as the ones in the manual
//------------------------------------------------------------------------
void getsockopt( int level, int name, void *value, socklen_t &len );
};
};
#endif // EOS_NS_DESCRIPTOR_HH