1 #include "../../include/freenet/fcpv2.h"
\r
10 #include <ws2tcpip.h>
\r
13 #include <netinet/in.h>
\r
25 Message::Message():m_name("")
\r
30 Message::Message(const std::string &name):m_name(name)
\r
35 Message::Message(const std::string &name, const int fieldcount, ...):m_name(name)
\r
37 const char *field=0;
\r
40 va_start(args,fieldcount);
\r
42 for(int i=0; i<fieldcount; i++)
\r
44 field=va_arg(args,const char *);
\r
45 val=va_arg(args,const char *);
\r
49 m_fields[field]=val;
\r
57 const std::string Message::GetFCPString() const
\r
59 std::string rval=m_name;
\r
61 for(std::map<std::string,std::string>::const_iterator i=m_fields.begin(); i!=m_fields.end(); i++)
\r
64 rval+="="+(*i).second;
\r
67 if(m_name=="AllData")
\r
73 rval+="EndMessage\n";
\r
89 bool Connection::m_wsastartup=false;
\r
92 Connection::Connection():m_socket(-1),m_tempbuffer(65535,0)
\r
95 if(m_wsastartup==false)
\r
98 WSAStartup(MAKEWORD(2,2),&wsadata);
\r
104 Connection::Connection(const int sock):m_socket(sock),m_tempbuffer(65535,0)
\r
107 if(m_wsastartup==false)
\r
110 WSAStartup(MAKEWORD(2,2),&wsadata);
\r
116 Connection::~Connection()
\r
124 const bool Connection::Connect(const std::string &fcphost, const int fcpport)
\r
127 m_sendbuffer.clear();
\r
128 m_receivebuffer.clear();
\r
130 if(IsConnected()==true)
\r
136 std::ostringstream portstring;
\r
137 addrinfo hint,*result,*current;
\r
140 portstring << fcpport;
\r
141 std::memset(&hint,0,sizeof(hint));
\r
142 hint.ai_socktype=SOCK_STREAM;
\r
144 rval=getaddrinfo(fcphost.c_str(),portstring.str().c_str(),&hint,&result);
\r
148 for(current=result; current!=0 && m_socket==-1; current=current->ai_next)
\r
151 m_socket=socket(current->ai_family,current->ai_socktype,current->ai_protocol);
\r
155 rval=connect(m_socket,current->ai_addr,current->ai_addrlen);
\r
164 freeaddrinfo(result);
\r
178 const bool Connection::Disconnect()
\r
180 m_sendbuffer.clear();
\r
181 m_receivebuffer.clear();
\r
185 closesocket(m_socket);
\r
194 void Connection::DoReceive()
\r
198 int len=recv(m_socket,&m_tempbuffer[0],m_tempbuffer.size(),0);
\r
201 m_receivebuffer.insert(m_receivebuffer.end(),m_tempbuffer.begin(),m_tempbuffer.begin()+len);
\r
210 void Connection::DoSend()
\r
212 if(IsConnected() && m_sendbuffer.size()>0)
\r
214 int len=send(m_socket,&m_sendbuffer[0],m_sendbuffer.size(),0);
\r
217 m_sendbuffer.erase(m_sendbuffer.begin(),m_sendbuffer.begin()+len);
\r
226 const bool Connection::MessageReady() const
\r
228 std::vector<char>::const_iterator tempi;
\r
229 std::vector<char>::size_type temp;
\r
230 return MessageReady(tempi,temp);
\r
233 const bool Connection::MessageReady(std::vector<char>::const_iterator &endpos, std::vector<char>::size_type &endlen) const
\r
235 static std::string alldatastring="AllData\n";
\r
236 static std::string datastring="\nData\n"; // need the \n at the beginning to differentiate from AllData\n
\r
237 static std::string endmessagestring="EndMessage\n";
\r
238 std::vector<char>::const_iterator tempendpos=m_receivebuffer.end();
\r
239 std::vector<char>::size_type tempendlen=0;
\r
241 if(m_receivebuffer.size()>0)
\r
243 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),alldatastring.begin(),alldatastring.end());
\r
244 if(tempendpos==m_receivebuffer.begin())
\r
246 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),datastring.begin(),datastring.end());
\r
247 if(tempendpos!=m_receivebuffer.end())
\r
250 tempendlen=datastring.size()-1;
\r
255 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),endmessagestring.begin(),endmessagestring.end());
\r
256 tempendlen=endmessagestring.size();
\r
259 if(tempendpos!=m_receivebuffer.end())
\r
271 const bool Connection::MessageReady(std::vector<char>::iterator &endpos, std::vector<char>::size_type &endlen)
\r
273 static std::string alldatastring="AllData\n";
\r
274 static std::string datastring="\nData\n"; // need the \n at the beginning to differentiate from AllData\n
\r
275 static std::string endmessagestring="EndMessage\n";
\r
276 std::vector<char>::iterator tempendpos=m_receivebuffer.end();
\r
277 std::vector<char>::size_type tempendlen=0;
\r
279 if(m_receivebuffer.size()>0)
\r
281 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),alldatastring.begin(),alldatastring.end());
\r
282 if(tempendpos==m_receivebuffer.begin())
\r
284 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),datastring.begin(),datastring.end());
\r
285 if(tempendpos!=m_receivebuffer.end())
\r
288 tempendlen=datastring.size()-1;
\r
293 tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),endmessagestring.begin(),endmessagestring.end());
\r
294 tempendlen=endmessagestring.size();
\r
297 if(tempendpos!=m_receivebuffer.end())
\r
309 const bool Connection::Receive(Message &message)
\r
311 std::vector<char>::iterator endpos;
\r
312 std::vector<char>::size_type endlen;
\r
313 if(MessageReady(endpos,endlen)==true)
\r
315 std::vector<std::string> fields;
\r
317 Split(std::string(m_receivebuffer.begin(),endpos),"\n=",fields);
\r
318 m_receivebuffer.erase(m_receivebuffer.begin(),endpos+endlen);
\r
322 if(fields.size()>0)
\r
324 message.SetName(fields[0]);
\r
327 if(fields.size()>1)
\r
329 for(std::vector<std::string>::iterator i=fields.begin()+1; i!=fields.end();)
\r
331 if(i+1!=fields.end())
\r
333 message.GetFields()[(*i)]=(*(i+1));
\r
347 const bool Connection::Receive(std::vector<char> &data, const std::vector<char>::size_type len)
\r
349 if(m_receivebuffer.size()>=len && len>=0)
\r
351 data.insert(data.end(),m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
352 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
361 const bool Connection::Receive(char *data, const size_t len)
\r
363 if(m_receivebuffer.size()>=len && len>=0)
\r
365 std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,data);
\r
366 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
375 const bool Connection::ReceiveIgnore(const size_t len)
\r
377 if(m_receivebuffer.size()>=len && len>=0)
\r
379 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
388 const bool Connection::Send(const Message &message)
\r
390 if(message.GetName()!="")
\r
392 std::string fcpstring=message.GetFCPString();
\r
393 m_sendbuffer.insert(m_sendbuffer.end(),fcpstring.begin(),fcpstring.end());
\r
399 const bool Connection::Send(const std::vector<char> &data)
\r
401 m_sendbuffer.insert(m_sendbuffer.end(),data.begin(),data.end());
\r
405 const bool Connection::Send(const char *data, const size_t len)
\r
409 m_sendbuffer.insert(m_sendbuffer.end(),data[0],data[0]+len);
\r
415 void Connection::Split(const std::string &str, const std::string &separators, std::vector<std::string> &elements)
\r
417 std::string::size_type offset = 0;
\r
418 std::string::size_type delimIndex = 0;
\r
420 delimIndex = str.find_first_of(separators, offset);
\r
422 while (delimIndex != std::string::npos)
\r
424 elements.push_back(str.substr(offset, delimIndex - offset));
\r
425 offset += delimIndex - offset + 1;
\r
426 delimIndex = str.find_first_of(separators, offset);
\r
429 elements.push_back(str.substr(offset));
\r
432 const bool Connection::Update(const unsigned long ms)
\r
436 m_timeval.tv_sec=ms/1000;
\r
437 m_timeval.tv_usec=(ms%1000)*1000;
\r
439 FD_ZERO(&m_readfs);
\r
440 FD_ZERO(&m_writefs);
\r
442 FD_SET(m_socket,&m_readfs);
\r
444 if(m_sendbuffer.size()>0)
\r
446 FD_SET(m_socket,&m_writefs);
\r
449 select(m_socket+1,&m_readfs,&m_writefs,0,&m_timeval);
\r
451 if(FD_ISSET(m_socket,&m_readfs))
\r
455 if(IsConnected() && FD_ISSET(m_socket,&m_writefs))
\r
473 const bool Connection::WaitForBytes(const unsigned long ms, const size_t len)
\r
475 while(IsConnected() && m_receivebuffer.size()<len)
\r
480 if(IsConnected() && m_receivebuffer.size()>=len)
\r