1 #include "../../include/freenet/fcpv2.h"
\r
8 #include <ws2tcpip.h>
\r
11 #include <netinet/in.h>
\r
23 Message::Message():m_name("")
\r
28 Message::Message(const std::string &name):m_name(name)
\r
33 Message::Message(const std::string &name, const int fieldcount, ...):m_name(name)
\r
35 const char *field=0;
\r
38 va_start(args,fieldcount);
\r
40 for(int i=0; i<fieldcount; i++)
\r
42 field=va_arg(args,const char *);
\r
43 val=va_arg(args,const char *);
\r
47 m_fields[field]=val;
\r
55 const std::string Message::GetFCPString() const
\r
57 std::string rval=m_name;
\r
59 for(std::map<std::string,std::string>::const_iterator i=m_fields.begin(); i!=m_fields.end(); i++)
\r
62 rval+="="+(*i).second;
\r
65 if(m_name=="AllData")
\r
71 rval+="EndMessage\n";
\r
87 bool Connection::m_wsastartup=false;
\r
90 Connection::Connection():m_socket(-1),m_tempbuffer(65535,0)
\r
93 if(m_wsastartup==false)
\r
96 WSAStartup(MAKEWORD(2,2),&wsadata);
\r
102 Connection::Connection(const int sock):m_socket(sock),m_tempbuffer(65535,0)
\r
105 if(m_wsastartup==false)
\r
108 WSAStartup(MAKEWORD(2,2),&wsadata);
\r
114 Connection::~Connection()
\r
122 const bool Connection::Connect(const std::string &fcphost, const int fcpport)
\r
125 m_sendbuffer.clear();
\r
126 m_receivebuffer.clear();
\r
128 if(IsConnected()==true)
\r
134 std::ostringstream portstring;
\r
135 addrinfo hint,*result,*current;
\r
138 portstring << fcpport;
\r
139 std::memset(&hint,0,sizeof(hint));
\r
140 hint.ai_socktype=SOCK_STREAM;
\r
142 rval=getaddrinfo(fcphost.c_str(),portstring.str().c_str(),&hint,&result);
\r
146 for(current=result; current!=0 && m_socket==-1; current=current->ai_next)
\r
149 m_socket=socket(current->ai_family,current->ai_socktype,current->ai_protocol);
\r
153 rval=connect(m_socket,current->ai_addr,current->ai_addrlen);
\r
162 freeaddrinfo(result);
\r
176 const bool Connection::Disconnect()
\r
178 m_sendbuffer.clear();
\r
179 m_receivebuffer.clear();
\r
183 closesocket(m_socket);
\r
192 void Connection::DoReceive()
\r
196 int len=recv(m_socket,&m_tempbuffer[0],m_tempbuffer.size(),0);
\r
199 m_receivebuffer.insert(m_receivebuffer.end(),m_tempbuffer.begin(),m_tempbuffer.begin()+len);
\r
208 void Connection::DoSend()
\r
210 if(IsConnected() && m_sendbuffer.size()>0)
\r
212 int len=send(m_socket,&m_sendbuffer[0],m_sendbuffer.size(),0);
\r
215 m_sendbuffer.erase(m_sendbuffer.begin(),m_sendbuffer.begin()+len);
\r
224 const bool Connection::MessageReady() const
\r
226 std::vector<char>::const_iterator tempi;
\r
227 std::vector<char>::size_type temp;
\r
228 return MessageReady(tempi,temp);
\r
231 const bool Connection::MessageReady(std::vector<char>::const_iterator &endpos, std::vector<char>::size_type &endlen) const
\r
233 static std::string alldatastring="AllData\n";
\r
234 static std::string datastring="\nData\n"; // need the \n at the beginning to differentiate from AllData\n
\r
235 static std::string endmessagestring="EndMessage\n";
\r
236 std::vector<char>::const_iterator tempendpos=m_receivebuffer.end();
\r
237 std::vector<char>::size_type tempendlen=0;
\r
239 if(m_receivebuffer.size()>0)
\r
241 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),alldatastring.begin(),alldatastring.end());
\r
242 if(tempendpos==m_receivebuffer.begin())
\r
244 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),datastring.begin(),datastring.end());
\r
245 if(tempendpos!=m_receivebuffer.end())
\r
248 tempendlen=datastring.size()-1;
\r
253 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),endmessagestring.begin(),endmessagestring.end());
\r
254 tempendlen=endmessagestring.size();
\r
257 if(tempendpos!=m_receivebuffer.end())
\r
269 const bool Connection::MessageReady(std::vector<char>::iterator &endpos, std::vector<char>::size_type &endlen)
\r
271 static std::string alldatastring="AllData\n";
\r
272 static std::string datastring="\nData\n"; // need the \n at the beginning to differentiate from AllData\n
\r
273 static std::string endmessagestring="EndMessage\n";
\r
274 std::vector<char>::iterator tempendpos=m_receivebuffer.end();
\r
275 std::vector<char>::size_type tempendlen=0;
\r
277 if(m_receivebuffer.size()>0)
\r
279 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),alldatastring.begin(),alldatastring.end());
\r
280 if(tempendpos==m_receivebuffer.begin())
\r
282 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),datastring.begin(),datastring.end());
\r
283 if(tempendpos!=m_receivebuffer.end())
\r
286 tempendlen=datastring.size()-1;
\r
291 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),endmessagestring.begin(),endmessagestring.end());
\r
292 tempendlen=endmessagestring.size();
\r
295 if(tempendpos!=m_receivebuffer.end())
\r
307 const bool Connection::Receive(Message &message)
\r
309 std::vector<char>::iterator endpos;
\r
310 std::vector<char>::size_type endlen;
\r
311 if(MessageReady(endpos,endlen)==true)
\r
313 std::vector<std::string> fields;
\r
315 Split(std::string(m_receivebuffer.begin(),endpos),"\n=",fields);
\r
316 m_receivebuffer.erase(m_receivebuffer.begin(),endpos+endlen);
\r
320 if(fields.size()>0)
\r
322 message.SetName(fields[0]);
\r
325 if(fields.size()>1)
\r
327 for(std::vector<std::string>::iterator i=fields.begin()+1; i!=fields.end();)
\r
329 if(i+1!=fields.end())
\r
331 message.GetFields()[(*i)]=(*(i+1));
\r
345 const bool Connection::Receive(std::vector<char> &data, const std::vector<char>::size_type len)
\r
347 if(m_receivebuffer.size()>=len && len>=0)
\r
349 data.insert(data.end(),m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
350 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
359 const bool Connection::Receive(char *data, const size_t len)
\r
361 if(m_receivebuffer.size()>=len && len>=0)
\r
363 std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,data);
\r
364 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
373 const bool Connection::ReceiveIgnore(const size_t len)
\r
375 if(m_receivebuffer.size()>=len && len>=0)
\r
377 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
386 const bool Connection::Send(const Message &message)
\r
388 if(message.GetName()!="")
\r
390 std::string fcpstring=message.GetFCPString();
\r
391 m_sendbuffer.insert(m_sendbuffer.end(),fcpstring.begin(),fcpstring.end());
\r
397 const bool Connection::Send(const std::vector<char> &data)
\r
399 m_sendbuffer.insert(m_sendbuffer.end(),data.begin(),data.end());
\r
403 const bool Connection::Send(const char *data, const size_t len)
\r
407 m_sendbuffer.insert(m_sendbuffer.end(),data[0],data[0]+len);
\r
413 void Connection::Split(const std::string &str, const std::string &separators, std::vector<std::string> &elements)
\r
415 std::string::size_type offset = 0;
\r
416 std::string::size_type delimIndex = 0;
\r
418 delimIndex = str.find_first_of(separators, offset);
\r
420 while (delimIndex != std::string::npos)
\r
422 elements.push_back(str.substr(offset, delimIndex - offset));
\r
423 offset += delimIndex - offset + 1;
\r
424 delimIndex = str.find_first_of(separators, offset);
\r
427 elements.push_back(str.substr(offset));
\r
430 const bool Connection::Update(const unsigned long ms)
\r
434 m_timeval.tv_sec=ms/1000;
\r
435 m_timeval.tv_usec=(ms%1000)*1000;
\r
437 FD_ZERO(&m_readfs);
\r
438 FD_ZERO(&m_writefs);
\r
440 FD_SET(m_socket,&m_readfs);
\r
442 if(m_sendbuffer.size()>0)
\r
444 FD_SET(m_socket,&m_writefs);
\r
447 select(m_socket+1,&m_readfs,&m_writefs,0,&m_timeval);
\r
449 if(FD_ISSET(m_socket,&m_readfs))
\r
453 if(IsConnected() && FD_ISSET(m_socket,&m_writefs))
\r
471 const bool Connection::WaitForBytes(const unsigned long ms, const size_t len)
\r
473 while(IsConnected() && m_receivebuffer.size()<len)
\r
478 if(IsConnected() && m_receivebuffer.size()>=len)
\r