Tiny programs (C, C++, C#, ...)
File detail
Source code
/*
* file: nntp_client.h - NNTP protocol layer encapsulation
* project: nntpbackup (ISA)
* By Kamil Dudka, xdudka00
* mailto: xdudka00@gmail.com
*/
#ifndef NNTP_CLIENT_H
#define NNTP_CLIENT_H
#include "tcp_client.h"
#include <iostream>
#include <string>
/**
* Class stands for TCP layer encapsulation
*/
class TcpConnection {
public:
struct Err {}; ///< General TCP error
struct ErrConnect: Err {}; ///< Error during TCP connect()
struct ErrRead: Err {}; ///< Error while reading from socket
struct ErrWrite: Err {}; ///< Error while writeing to socket
/**
* Create an TCP connection
* \param szAddr Address of server to connect (IPv4 or server name)
* \param uPort Port number to connect to
*/
TcpConnection (const char *szAddr, unsigned uPort);
~TcpConnection ();
/**
* Write ascii text to socket.
* \param szText Zero ended string to write to socket.
* \return Return this. It can be useful for operator concatenation.
*/
TcpConnection &operator<< (const char *szText);
/**
* Read one line (ended with CR-LF) from socket. CR-LF is dropped.
* \param pszText *pszText will point to zero-ended line text (without CR-LF).
* \return Return this. It can be useful for operator concatenation.
*/
TcpConnection &operator>> (const char **pszText);
private:
TSocket _sockfd;
PNetLine _netLine;
};
/**
* NNTP protocol encapsulation.
*/
class NntpProtocol {
public:
struct Err {}; ///< Generic NNTP error
struct ErrConnect: Err {}; ///< Initial server response error
struct ErrNoStatus: Err {}; ///< No status code in server response
struct ErrDot: Err {}; ///< Dot notation error
struct ErrCmd: Err { ///< Error status returned from server
int _iStatus; ///< Errorneous status code
ErrCmd (int iStatus): _iStatus (iStatus) {}
};
/**
* NNTP protocol command abstraction.
*/
struct Cmd {
virtual ~Cmd(); ///< Always use virtual destructor
virtual void handleStatus (int iStatus) =0; ///< Abstract method handling command's status code
std::string _strCmd; ///< Command's string without CR-LF
};
struct CmdGroup: public Cmd { ///< GROUP nntp command
CmdGroup (const char *szGroup); ///< \param szGroup Group name to select.
virtual void handleStatus (int);
};
struct CmdArticle: public Cmd { ///< ARTICLE nntp command
CmdArticle();
virtual void handleStatus (int);
};
struct CmdNext: public Cmd { ///< NEXT nntp command
CmdNext();
virtual void handleStatus (int);
};
struct CmdQuit: public Cmd { ///< QUIT nntp command
CmdQuit();
virtual void handleStatus (int);
};
static const char *const szEndl; ///< CR-LF
static const char *const szEndText; ///< "."
NntpProtocol (TcpConnection &tcp); ///< \param tcp Established tcp connection to nntp server.
~NntpProtocol();
/**
* Send command to server and handle status response.
* Command object will be always deleted by this method. Be careful.
* \param cmd_to_send_and_DELETE Pointer to dynamically allocated Cmd object.
* \return Return this. It can be useful for operator concatenation.
*/
NntpProtocol &operator<< (Cmd *cmd_to_send_and_DELETE);
int getStatus() const { return _iStatus; } ///< \return Return last command status response.
/**
* Read next data line from server. Memory allocation is maintained by lower layers.
* \param pszLine *pszLine will point to zero-ended string containing line text without CR-LF.
* \return Return false if there is no line to read.
*/
bool getLine(const char **pszLine);
private:
TcpConnection &_tcp;
const char *_szLine;
int _iStatus;
void readStatus();
};
/**
* Simple NNTP client class.
* There is no need to use it.
*/
class NntpClient {
public:
static const unsigned DEF_NNTP_PORT= 119; ///< nntp default port number
struct Err {}; ///< Generic client exception
/**
* \param szServer Server address (URL or IP).
* \param uPort Port number. DEF_NNTP_PORT is used by default.
*/
NntpClient (const char *szServer, unsigned uPort=DEF_NNTP_PORT);
~NntpClient ();
/**
* Select group on nntp server.
* \param szGroup Group name to select.
*/
void groupSelect (const char *szGroup);
/**
* Grab next article on server to stream.
* \param streamTo Outpout stream to write to.
* \return Return false if there is no article left in group.
*/
bool readNext (std::ostream &streamTo);
private:
TcpConnection _tcp;
NntpProtocol _nntp;
bool _bEnd;
};
#endif