//
//
//
//
// Lab. Calcolo II - Esempio di codice
//
//
//
//
//
//
//
// Example code: Simple C-socketlib based network buffer for use with the
// "C++ in a nutshell" basic_networkbuf
// (20060914 francesco.prelz@mi.infn.it)
//
#ifndef BASIC_NETWORKSTREAM_HPP_INCLUDED
#define BASIC_NETWORKSTREAM_HPP_INCLUDED
#include
#include
#include
#include
extern "C" {
int SHLP_open_and_connect(const char *server, unsigned short port);
int SHLP_listen(unsigned short port, int backlog);
int SHLP_connect(int fd_socket, unsigned int in_timeout,
char *caller_id, int caller_id_size);
int SHLP_listen_and_connect(unsigned short port, unsigned int in_timeout,
char *caller_id, int caller_id_size);
}
template >
class basic_networkstream
{
public:
typedef std::streampos pos_type;
typedef charT char_type;
basic_networkstream();
basic_networkstream(const char *address, std::ios_base::openmode mode);
basic_networkstream(const char *address, const int port, std::ios_base::openmode mode);
bool is_open() { return m_opened; }
void open(int listen_sock, std::ios_base::openmode mode);
void open(const char* address, std::ios_base::openmode mode);
void open(const char* address, const int port, std::ios_base::openmode mode);
void close();
bool good() { return m_good; }
const std::string &caller() const { return m_caller; }
pos_type tellg();
std::streamsize read(char_type *buffer, std::streamsize count);
std::streamsize write(const char_type *buffer, std::streamsize count);
std::streamsize gcount() { return m_gcount; }
void sync();
int &timeout() { return m_timeout; };
private:
int m_s; // The good ol' libC socket.
bool m_good;
bool m_opened;
int m_timeout;
std::string m_caller;
std::streamsize m_gcount;
std::streamsize m_tcount;
};
template
basic_networkstream::basic_networkstream() : m_good(false), m_opened(false), m_timeout(0)
{
}
template
basic_networkstream::basic_networkstream(const char *address, std::ios_base::openmode mode) : m_good(false), m_opened(false), m_timeout(0)
{
open(address,mode);
}
template
basic_networkstream::basic_networkstream(const char *address, const int port, std::ios_base::openmode mode) : m_good(false), m_opened(false), m_timeout(0)
{
open(address,port,mode);
}
template
void basic_networkstream::open(const char* address, std::ios_base::openmode mode)
{
// Try to figure out an address in the format ip:port.
std::string addr_str(address);
std::string::size_type colon_pos = addr_str.rfind(':');
if (colon_pos == std::string::npos)
{
m_good = false;
return;
}
std::istringstream port_ss(addr_str.substr(colon_pos+1));
addr_str.erase(colon_pos);
unsigned int port;
port_ss >> port;
if (port == 0 || port > 65535)
{
m_good = false;
return;
}
return this->open(addr_str.c_str(), port);
}
template
void basic_networkstream::open(const char* address, const int port, std::ios_base::openmode mode)
{
if (m_opened)
{
this->close();
}
m_good = false;
if (mode == std::ios::in)
{
char caller_c[512];
if ((m_s = SHLP_listen_and_connect(port, m_timeout, caller_c, sizeof(caller_c))) >= 0)
{
m_opened = true;
m_good = true;
m_caller = caller_c;
}
}
else if (mode & std::ios::out)
{
if ((m_s = SHLP_open_and_connect(address, port)) >= 0)
{
m_opened = true;
m_good = true;
}
}
if (m_good) m_tcount = 0;
return;
}
template
void basic_networkstream::open(int listen_socket, std::ios_base::openmode mode)
{
if (m_opened)
{
this->close();
}
m_good = false;
if (mode & std::ios::in)
{
char caller_c[512];
if ((m_s = SHLP_connect(listen_socket, m_timeout, caller_c, sizeof(caller_c))) >= 0)
{
m_good = true;
m_opened = true;
m_caller = caller_c;
}
}
if (m_good) m_tcount = 0;
return;
}
template
void basic_networkstream::close()
{
if (::close(m_s) < 0) m_good = false;
else m_good = true;
m_opened = false;
}
template
typename basic_networkstream::pos_type basic_networkstream::tellg()
{
return static_cast::pos_type>(m_tcount);
}
template
std::streamsize basic_networkstream::read(char_type *buffer, std::streamsize count)
{
std::streamsize ret;
ret = ::read(m_s,buffer,count);
if (ret < 0) m_good = false;
else
{
m_tcount += ret;
m_gcount = ret;
}
return ret;
}
template
std::streamsize basic_networkstream::write(const char_type *buffer, std::streamsize count)
{
std::streamsize ret;
ret = ::write(m_s,buffer,count);
if (ret < 0) m_good = false;
else m_tcount += ret;
return ret;
}
template
void basic_networkstream::sync()
{
// NOP on the network.
}
#endif // BASIC_NETWORKSTREAM_HPP_INCLUDED not defined