-/*\r
+/**\r
+\r
+ \mainpage FCPv2 library\r
\r
FCPv2 C++ library\r
\r
- link with ws2_32.lib in Windows\r
+ link with ws2_32.lib and iphlpapi.lib in Windows\r
+\r
+*/\r
\r
+/**\r
+ \file fcpv2.h\r
*/\r
\r
#ifndef _fcpv2_\r
#define _fcpv2_\r
\r
+#include <map>\r
+#include <vector>\r
+#include <string>\r
+\r
#ifdef _WIN32\r
#include <winsock2.h>\r
#include <windows.h>\r
#include <arpa/inet.h>\r
#endif\r
\r
-#include <string>\r
-#include <vector>\r
-#include <map>\r
+/**\r
+ \brief %FCPv2 namespace\r
\r
+ This namespace contains the %FCPv2 library\r
+*/\r
+namespace FCPv2\r
+{\r
\r
-class FCPMessage:public std::map<std::string, std::string >\r
+/**\r
+ \brief An FCP message\r
+\r
+ FCP Messages are comprised of a name and zero or more field/value pairs.\r
+*/\r
+class Message\r
{\r
public:\r
- FCPMessage() {};\r
- FCPMessage(const std::string &name) {m_name=name;}\r
+ /**\r
+ \brief Default constructor\r
+ */\r
+ Message();\r
+ /**\r
+ \brief Construct message with a specific name\r
+\r
+ \param name The name of the message\r
+ */\r
+ Message(const std::string &name);\r
+ /**\r
+ \brief Construct message with a specific name and fields\r
\r
- const std::string GetName() const { return m_name; }\r
- void SetName(const std::string &name) { m_name=name; }\r
+ The number of field/value pairs must match the fieldcount parameter.\r
+\r
+ \param name The name of the message\r
+ \param fieldcount The number of field/value pairs that follow\r
+ */\r
+ Message(const std::string &name, const int fieldcount, ...);\r
+\r
+ /**\r
+ \brief Gets the name of the message\r
+\r
+ \return The name of the message\r
+ */\r
+ const std::string &GetName() const { return m_name; }\r
+ /**\r
+ \brief Sets the name of the message\r
+\r
+ \param name The name of the message\r
+ */\r
+ void SetName(const std::string &name) { m_name=name; }\r
+\r
+ /**\r
+ \brief Accesses the field/value pairs\r
+\r
+ \param field The field to access\r
+ \return Reference to the value of the field\r
+ */\r
+ std::string &operator[](const std::string &field) { return m_fields[field]; }\r
+\r
+ /**\r
+ \brief Non-const accessor for field map\r
+\r
+ \return field map\r
+ */\r
+ std::map<std::string,std::string> &GetFields() { return m_fields; }\r
+ /**\r
+ \brief Const accessor for field map\r
+\r
+ \return field map\r
+ */\r
+ const std::map<std::string,std::string> &GetFields() const { return m_fields; }\r
+ \r
+ /**\r
+ \brief Clears the name and fields of the message\r
+ */\r
+ void Clear() { m_name=""; m_fields.clear(); }\r
+ \r
+ const bool operator==(const Message &rhs) const { return (m_name==rhs.m_name && m_fields==rhs.m_fields); }\r
+ const bool operator!=(const Message &rhs) const { return !(*this==rhs); }\r
+ const bool operator<(const Message &rhs) const { return (m_name<rhs.m_name || (m_name==rhs.m_name && m_fields<rhs.m_fields)); }\r
+ const bool operator<=(const Message &rhs) const { return (*this==rhs || *this<rhs); }\r
+ const bool operator>(const Message &rhs) const { return !(*this<=rhs); }\r
+ const bool operator>=(const Message &rhs) const { return !(*this<rhs); }\r
\r
- void Reset() { m_name=""; clear(); }\r
+ /**\r
+ \brief Gets the string representing this message in FCP\r
+\r
+ This string is what is actually sent/received from the node through FCP\r
+ */\r
+ const std::string GetFCPString() const;\r
+\r
+private:\r
\r
-protected:\r
std::string m_name;\r
+ std::map<std::string,std::string> m_fields;\r
+\r
};\r
\r
-class FCPv2\r
+/**\r
+ \brief An FCP connection to a Freenet node\r
+*/\r
+class Connection\r
{\r
public:\r
- FCPv2();\r
- ~FCPv2();\r
+ /**\r
+ \brief Default constructor\r
+ */\r
+ Connection();\r
+ /**\r
+ \brief Construct connection with an existing socket\r
+\r
+ \param sock An existing socket connection to a Freenet node\r
+ */\r
+ Connection(const int sock);\r
+ /**\r
+ \brief Default constructor\r
+\r
+ The deconstructor will close the connection if it is open\r
+ */\r
+ ~Connection();\r
+\r
+ /**\r
+ \brief Creates an FCP connection to a Freenet node\r
+\r
+ If the instaciated object has an existing connection open, it will be closed.\r
+\r
+ \param fcphost The IP Address, hostname, FQDN, or other resolvable name that points to the Freenet node\r
+ \param fcpport The port that the Freenet node is listening for FCP connections on\r
+ \return true if the connection was established, false if it was not\r
+ */\r
+ const bool Connect(const std::string &fcphost, const int fcpport);\r
+ /**\r
+ \brief Checks if the connection is currently connected\r
+\r
+ \return true if there is a connection, false if there is not\r
+ */\r
+ const bool IsConnected() const { return m_socket!=-1; }\r
+ /**\r
+ \brief Disconnects the connection\r
\r
- const bool Connect(const char *host, const int port);\r
+ \return always true\r
+ */\r
const bool Disconnect();\r
+ \r
+ /**\r
+ \brief Sends and receives data on the connection\r
+\r
+ \param ms Maximum number of milliseconds to wait for the send and receive buffers to become available\r
+ \return true if the connection remains connected, false if the connection is disconnected\r
+ */\r
+ const bool Update(const unsigned long ms);\r
\r
- const bool Connected() const { return m_serversocket!=-1 ? true : false ; }\r
+ /**\r
+ \brief Checks if an FCP message is ready to be received\r
\r
- const bool Update(const long waittime);\r
+ \return true if an FCP message is ready to be received, false otherwise\r
+ */\r
+ const bool MessageReady() const;\r
+ \r
+ /**\r
+ \brief Gets the number of bytes on the receive buffer\r
\r
- const int SendMessage(const char *messagename, const int fieldcount, ...);\r
- const int SendMessage(FCPMessage &message);\r
- const int SendRaw(const char *data, const int datalen);\r
- const std::vector<char>::size_type SendBufferSize() const { return m_sendbuffer.size(); }\r
+ \return The number of bytes on the receive buffer\r
+ */\r
+ const std::vector<char>::size_type ReceiveBufferSize() const { return m_receivebuffer.size(); }\r
+ /**\r
+ \brief Receives an FCP message\r
+ \r
+ \param[out] message The FCP message\r
+ \return true if an FCP message was received, false otherwise\r
+ */\r
+ const bool Receive(Message &message);\r
+ /**\r
+ \brief Receives raw data\r
+ \r
+ The received data is inserted at the end of the supplied vector\r
\r
- FCPMessage ReceiveMessage();\r
- const long ReceiveRaw(char *data, long &datalen); // data must be preallocated, with datalen being max length of data. Returns length of data received\r
- const std::vector<char>::size_type ReceiveBufferSize() const { return m_receivebuffer.size(); }\r
+ \param[out] data vector to place received data in\r
+ \param len number of bytes to receive\r
+ \return true if the bytes were received, false otherwise\r
+ */\r
+ const bool Receive(std::vector<char> &data, const std::vector<char>::size_type len);\r
+ /**\r
+ \brief Receives raw data\r
\r
-private:\r
+ \param[out] data char array to place received data in\r
+ \param len number of bytes to receive\r
+ \return true if the bytes were received, false otherwise\r
+ */\r
+ const bool Receive(char *data, const size_t len);\r
+ /**\r
+ \brief Discards data on receive buffer\r
+\r
+ \param len The number of bytes on the receive buffer to discard\r
+ \return true if the bytes were discarded, false otherwise\r
+ */\r
+ const bool ReceiveIgnore(const size_t len);\r
\r
- void SocketReceive();\r
- void SocketSend();\r
+ /**\r
+ \brief Gets the number of bytes waiting to be sent to the node\r
+\r
+ \return The number of bytes waiting to be sent to the node\r
+ */\r
+ const std::vector<char>::size_type SendBufferSize() const { return m_sendbuffer.size(); }\r
+ /**\r
+ \brief Sends an FCP Message\r
+\r
+ \param message The Message to send\r
+ \return true if the Message was buffered for sending successfully, false otherwise\r
+ */\r
+ const bool Send(const Message &message);\r
+ /**\r
+ \brief Sends raw data\r
\r
- void SendBufferedText(const char *text); // puts text on send buffer\r
- void SendBufferedRaw(const char *data, const long len); // puts raw data on send buffer\r
+ \param data A vector of the data to send\r
+ \return true if the data was buffered for sending successfully, false otherwise\r
+ */\r
+ const bool Send(const std::vector<char> &data);\r
+ /**\r
+ \brief Sends raw data\r
\r
- int FindOnReceiveBuffer(const char *text); // finds text string on receive buffer and returns index to first char position, -1 if not found\r
+ \param data A char array of data to send\r
+ \param len The number of bytes on the array to send\r
+ \return true if the data was buffered for sending successfully, false otherwise\r
+ */\r
+ const bool Send(const char *data, const size_t len);\r
\r
+ /**\r
+ \brief Gets the socket identifier of the connection\r
+\r
+ \return The socket identifier. It will be -1 if the socket is invalid.\r
+ */\r
+ const int Socket() { return m_socket; }\r
+ \r
+ /**\r
+ \brief Waits until the receive buffer contains a specified number of bytes\r
+ \r
+ This will continuously call Update until either the specific number of bytes have been received,\r
+ or the connection becomes disconnected\r
+ \r
+ \param ms The number of milliseconds for each call to Update\r
+ \param len The number of bytes to wait for\r
+ \return true if the number of bytes is waiting on the receive buffer, false if the connection was closed\r
+ */\r
+ const bool WaitForBytes(const unsigned long ms, const size_t len);\r
+\r
+private:\r
+ // can't be copied\r
+ Connection(const Connection &connection);\r
+ Connection &operator=(const Connection &connection);\r
+\r
+ const bool MessageReady(std::vector<char>::const_iterator &endpos, std::vector<char>::size_type &endlen) const;\r
+ const bool MessageReady(std::vector<char>::iterator &endpos, std::vector<char>::size_type &endlen);\r
+ void Split(const std::string &str, const std::string &separators, std::vector<std::string> &elements);\r
+\r
+ void DoSend();\r
+ void DoReceive();\r
\r
#ifdef _WIN32\r
static bool m_wsastartup;\r
#endif\r
\r
- int m_serversocket;\r
-\r
- char *m_tempbuffer; // temp buffer used for recv\r
-\r
- std::vector<char> m_sendbuffer;\r
+ int m_socket;\r
std::vector<char> m_receivebuffer;\r
-\r
+ std::vector<char> m_sendbuffer;\r
+ std::vector<char> m_tempbuffer;\r
fd_set m_readfs;\r
fd_set m_writefs;\r
struct timeval m_timeval;\r
-\r
+ \r
};\r
\r
-#endif // _fcpv2_\r
+} // namespace\r
+\r
+#endif // _fcpv2_connection_\r