version 0.3.28
[fms.git] / src / freenet / fcpv2.cpp
index 16a7348..ecd81e7 100644 (file)
@@ -1,8 +1,8 @@
 #include "../../include/freenet/fcpv2.h"\r
-#include <cstdio>\r
-#include <cstdarg>\r
+\r
 #include <sstream>\r
-#include <cstring>\r
+#include <algorithm>\r
+#include <cstdarg>\r
 \r
 #ifdef _WIN32\r
        #include <ws2tcpip.h>\r
        #include <netinet/in.h>\r
 #endif\r
 \r
-/* XMEM doesn't play nice with strtok - should replace strtok with something else anyway\r
-#ifdef XMEM\r
-       #include <xmem.h>\r
-#endif\r
+namespace FCPv2\r
+{\r
+\r
+/*\r
+\r
+       Message Methods\r
+\r
 */\r
 \r
-#ifdef _WIN32\r
-       bool FCPv2::m_wsastartup=false;\r
-#endif\r
+Message::Message():m_name("")\r
+{\r
 \r
+}\r
 \r
+Message::Message(const std::string &name):m_name(name)\r
+{\r
+       \r
+}\r
 \r
-FCPv2::FCPv2()\r
+Message::Message(const std::string &name, const int fieldcount, ...):m_name(name)\r
+{\r
+       const char *field=0;\r
+       const char *val=0;\r
+       va_list args;\r
+       va_start(args,fieldcount);\r
+\r
+       for(int i=0; i<fieldcount; i++)\r
+       {\r
+               field=va_arg(args,const char *);\r
+               val=va_arg(args,const char *);\r
+\r
+               if(field && val)\r
+               {\r
+                       m_fields[field]=val;\r
+               }\r
+       }\r
+\r
+       va_end(args);\r
+\r
+}\r
+\r
+const std::string Message::GetFCPString() const\r
+{\r
+       std::string rval=m_name;\r
+       rval+="\r\n";\r
+       for(std::map<std::string,std::string>::const_iterator i=m_fields.begin(); i!=m_fields.end(); i++)\r
+       {\r
+               rval+=(*i).first;\r
+               rval+="="+(*i).second;\r
+               rval+="\n";\r
+       }\r
+       if(m_name=="AllData")\r
+       {\r
+               rval+="Data\n";\r
+       }\r
+       else\r
+       {\r
+               rval+="EndMessage\n";\r
+       }\r
+       return rval;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+/*\r
+       \r
+       Connection Methods\r
+\r
+*/\r
+\r
+#ifdef _WIN32\r
+       bool Connection::m_wsastartup=false;\r
+#endif\r
+\r
+Connection::Connection():m_socket(-1),m_tempbuffer(65535,0)\r
 {\r
 #ifdef _WIN32\r
        if(m_wsastartup==false)\r
@@ -33,68 +97,66 @@ FCPv2::FCPv2()
                m_wsastartup=true;\r
        }\r
 #endif\r
-\r
-       // initialize socket to server\r
-       m_serversocket=-1;\r
-\r
-       // initialize buffers\r
-       m_tempbuffer=new char[65535];\r
-\r
 }\r
 \r
+Connection::Connection(const int sock):m_socket(sock),m_tempbuffer(65535,0)\r
+{\r
+#ifdef _WIN32\r
+       if(m_wsastartup==false)\r
+       {\r
+               WSAData wsadata;\r
+               WSAStartup(MAKEWORD(2,2),&wsadata);\r
+               m_wsastartup=true;\r
+       }\r
+#endif\r
+}\r
 \r
-FCPv2::~FCPv2()\r
+Connection::~Connection()\r
 {\r
        Disconnect();\r
 #ifdef _WIN32\r
        WSACleanup();\r
 #endif\r
-\r
-       delete [] m_tempbuffer;\r
-\r
 }\r
 \r
-\r
-const bool FCPv2::Connect(const char *host, const int port)\r
+const bool Connection::Connect(const std::string &fcphost, const int fcpport)\r
 {\r
-       // disconnect socket to server if it is currently open\r
-       if(Connected())\r
+\r
+       m_sendbuffer.clear();\r
+       m_receivebuffer.clear();\r
+\r
+       if(IsConnected()==true)\r
        {\r
                Disconnect();\r
        }\r
 \r
        int rval=-1;\r
-       struct sockaddr_storage m_serveraddr;\r
-\r
        std::ostringstream portstring;\r
        addrinfo hint,*result,*current;\r
-       result=NULL;\r
-       portstring << port;\r
 \r
-       memset(&hint,0,sizeof(addrinfo));\r
+       result=current=0;\r
+       portstring << fcpport;\r
+       std::memset(&hint,0,sizeof(hint));\r
        hint.ai_socktype=SOCK_STREAM;\r
-       rval=getaddrinfo(host,portstring.str().c_str(),&hint,&result);\r
 \r
-       // erase any data in buffers\r
-       m_sendbuffer.clear();\r
-       m_receivebuffer.clear();\r
+       rval=getaddrinfo(fcphost.c_str(),portstring.str().c_str(),&hint,&result);\r
 \r
        if(result)\r
        {\r
-               for(current=result; current!=NULL && m_serversocket==-1; current=current->ai_next)\r
+               for(current=result; current!=0 && m_socket==-1; current=current->ai_next)\r
                {\r
-                       memset(&m_serveraddr,0,sizeof(struct sockaddr_storage));\r
 \r
-                       m_serversocket=socket(current->ai_family,current->ai_socktype,current->ai_protocol);\r
+                       m_socket=socket(current->ai_family,current->ai_socktype,current->ai_protocol);\r
 \r
-                       if(m_serversocket!=-1)\r
+                       if(m_socket!=-1)\r
                        {\r
-                               rval=connect(m_serversocket,current->ai_addr,current->ai_addrlen);\r
+                               rval=connect(m_socket,current->ai_addr,current->ai_addrlen);\r
                                if(rval==-1)\r
                                {\r
                                        Disconnect();\r
                                }\r
                        }\r
+\r
                }\r
 \r
                freeaddrinfo(result);\r
@@ -111,333 +173,293 @@ const bool FCPv2::Connect(const char *host, const int port)
 \r
 }\r
 \r
-const bool FCPv2::Disconnect()\r
+const bool Connection::Disconnect()\r
 {\r
-       if(Connected())\r
+       m_sendbuffer.clear();\r
+       m_receivebuffer.clear();\r
+       if(IsConnected())\r
        {\r
        #ifdef _WIN32\r
-               closesocket(m_serversocket);\r
+               closesocket(m_socket);\r
        #else\r
-               close(m_serversocket);\r
+               close(m_socket);\r
        #endif\r
-               m_serversocket=-1;\r
+               m_socket=-1;\r
        }\r
        return true;\r
 }\r
 \r
-int FCPv2::FindOnReceiveBuffer(const char *text)\r
+void Connection::DoReceive()\r
 {\r
-       bool found;\r
-       std::vector<char>::size_type i,j;\r
-       size_t tlen=strlen(text);\r
-\r
-       if(m_receivebuffer.size()>=tlen)\r
+       if(IsConnected())\r
        {\r
-               for(i=0; i<=m_receivebuffer.size()-tlen; i++)\r
+               int len=recv(m_socket,&m_tempbuffer[0],m_tempbuffer.size(),0);\r
+               if(len>0)\r
                {\r
-                       found=true;\r
-                       for(j=0; j<tlen; j++)\r
-                       {\r
-                               if(m_receivebuffer[i+j]!=text[j])\r
-                               {\r
-                                       found=false;\r
-                                       j=tlen;\r
-                               }\r
-                       }\r
-                       if(found==true)\r
-                       {\r
-                               return i;\r
-                       }\r
+                       m_receivebuffer.insert(m_receivebuffer.end(),m_tempbuffer.begin(),m_tempbuffer.begin()+len);\r
+               }\r
+               else\r
+               {\r
+                       Disconnect();\r
                }\r
        }\r
+}\r
 \r
-       return -1;\r
+void Connection::DoSend()\r
+{\r
+       if(IsConnected() && m_sendbuffer.size()>0)\r
+       {\r
+               int len=send(m_socket,&m_sendbuffer[0],m_sendbuffer.size(),0);\r
+               if(len>0)\r
+               {\r
+                       m_sendbuffer.erase(m_sendbuffer.begin(),m_sendbuffer.begin()+len);\r
+               }\r
+               else\r
+               {\r
+                       Disconnect();\r
+               }\r
+       }\r
 }\r
 \r
-FCPMessage FCPv2::ReceiveMessage()\r
+const bool Connection::MessageReady() const\r
 {\r
-       int field=0;\r
-       int len=0;\r
-       int endlen=0;\r
-       int endmessage=-1;\r
-       char *buffpos;\r
-       char *prevpos;\r
-       char *buffer;\r
+       std::vector<char>::const_iterator tempi;\r
+       std::vector<char>::size_type temp;\r
+       return MessageReady(tempi,temp);\r
+}\r
 \r
-       FCPMessage message;\r
+const bool Connection::MessageReady(std::vector<char>::const_iterator &endpos, std::vector<char>::size_type &endlen) const\r
+{\r
+       static std::string alldatastring="AllData\n";\r
+       static std::string datastring="\nData\n";       // need the \n at the beginning to differentiate from AllData\n\r
+       static std::string endmessagestring="EndMessage\n";\r
+       std::vector<char>::const_iterator tempendpos=m_receivebuffer.end();\r
+       std::vector<char>::size_type tempendlen=0;\r
 \r
-       // there is data on the receive buffer\r
        if(m_receivebuffer.size()>0)\r
        {\r
-\r
-               // find Data on a line by itself following AllData\r
-               if(FindOnReceiveBuffer("AllData\n")==0)\r
+               tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),alldatastring.begin(),alldatastring.end());\r
+               if(tempendpos==m_receivebuffer.begin())\r
                {\r
-                       endmessage=FindOnReceiveBuffer("\nData\n");\r
-                       if(endmessage!=-1)\r
+                       tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),datastring.begin(),datastring.end());\r
+                       if(tempendpos!=m_receivebuffer.end())\r
                        {\r
-                               endmessage++;\r
-                               endlen=5;\r
+                               tempendpos+=1;\r
+                               tempendlen=datastring.size()-1;\r
                        }\r
                }\r
-               // otherwise this is a regular message - search for EndMessage\r
                else\r
                {\r
-                       endmessage=FindOnReceiveBuffer("EndMessage\n");\r
-                       endlen=11;\r
+                       tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),endmessagestring.begin(),endmessagestring.end());\r
+                       tempendlen=endmessagestring.size();\r
                }\r
 \r
-               // continue if we found "EndMessage\n" or "Data\n"\r
-               if(endmessage!=-1)\r
+               if(tempendpos!=m_receivebuffer.end())\r
                {\r
-                       // total length of message (including ending \n)\r
-                       len=endmessage+endlen;\r
-\r
-                       // allocate space for message\r
-                       buffer=new char[len+1];\r
-\r
-                       // copy message from receive buffer to message buffer\r
-                       std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,buffer);\r
-                       buffer[len]='\0';\r
-\r
-                       // remove from receive buffer\r
-                       m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);\r
-\r
-                       // set buffer position\r
-                       buffpos=buffer;\r
-\r
-                       // find message name\r
-                       buffpos=strtok(buffer,"\n");\r
-                       message.SetName(buffer);\r
-\r
-                       do\r
-                       {\r
-                               // find next field\r
-                               prevpos=buffpos;\r
-                               buffpos=strtok(NULL,"=");\r
-\r
-                               // continue if we aren't at the end of a regular message, or at Data for an AllData message\r
-                               if(strncmp(buffpos,"EndMessage\n",11)!=0 && strncmp(buffpos,"Data\n",5)!=0)     //!(strncmp(message->MessageName,"AllData",7)==0 && strncmp(buffpos,"Data\n",5)==0))\r
-                               {\r
-\r
-                                       // find next value\r
-                                       prevpos=buffpos;\r
-                                       buffpos=strtok(NULL,"\n");\r
-\r
-                                       if(prevpos && buffpos)\r
-                                       {\r
-                                               message[prevpos]=buffpos;\r
-                                       }\r
-\r
-                                       field++;\r
-                               }\r
-                               else\r
-                               {\r
-                                       buffpos=0;\r
-                               }\r
-\r
-                       }while(buffpos!=0);\r
-\r
-                       delete [] buffer;\r
-\r
+                       endpos=tempendpos;\r
+                       endlen=tempendlen;\r
+                       return true;\r
                }\r
+\r
        }\r
 \r
-       return message;\r
+       return false;\r
 }\r
 \r
-const long FCPv2::ReceiveRaw(char *data, long &datalen)\r
+const bool Connection::MessageReady(std::vector<char>::iterator &endpos, std::vector<char>::size_type &endlen)\r
 {\r
-       long len=0;\r
-       if(m_receivebuffer.size()>0 && datalen>0)\r
+       static std::string alldatastring="AllData\n";\r
+       static std::string datastring="\nData\n";       // need the \n at the beginning to differentiate from AllData\n\r
+       static std::string endmessagestring="EndMessage\n";\r
+       std::vector<char>::iterator tempendpos=m_receivebuffer.end();\r
+       std::vector<char>::size_type tempendlen=0;\r
+\r
+       if(m_receivebuffer.size()>0)\r
        {\r
-               if(datalen>m_receivebuffer.size())\r
+               tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),alldatastring.begin(),alldatastring.end());\r
+               if(tempendpos==m_receivebuffer.begin())\r
                {\r
-                       len=m_receivebuffer.size();\r
+                       tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),datastring.begin(),datastring.end());\r
+                       if(tempendpos!=m_receivebuffer.end())\r
+                       {\r
+                               tempendpos+=1;\r
+                               tempendlen=datastring.size()-1;\r
+                       }\r
                }\r
                else\r
                {\r
-                       len=datalen;\r
+                       tempendpos=std::search(m_receivebuffer.begin(),m_receivebuffer.end(),endmessagestring.begin(),endmessagestring.end());\r
+                       tempendlen=endmessagestring.size();\r
                }\r
 \r
-               std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,data);\r
-\r
-               // erase bytes from receive buffer\r
-               m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);\r
+               if(tempendpos!=m_receivebuffer.end())\r
+               {\r
+                       endpos=tempendpos;\r
+                       endlen=tempendlen;\r
+                       return true;\r
+               }\r
 \r
        }\r
-       datalen=len;\r
-       return datalen;\r
-}\r
 \r
-void FCPv2::SendBufferedText(const char *text)\r
-{\r
-       unsigned int i;\r
-       for(i=0; i<strlen(text); i++)\r
-       {\r
-               m_sendbuffer.push_back(text[i]);\r
-       }\r
+       return false;\r
 }\r
 \r
-void FCPv2::SendBufferedRaw(const char *data, const long len)\r
+const bool Connection::Receive(Message &message)\r
 {\r
-       int i;\r
-       for(i=0; i<len; i++)\r
+       std::vector<char>::iterator endpos;\r
+       std::vector<char>::size_type endlen;\r
+       if(MessageReady(endpos,endlen)==true)\r
        {\r
-               m_sendbuffer.push_back(data[i]);\r
-       }\r
-}\r
+               std::vector<std::string> fields;\r
 \r
-const int FCPv2::SendMessage(const char *messagename, const int fieldcount, ...)\r
-{\r
-       va_list args;\r
-       const char *field;\r
-       const char *val;\r
-       std::vector<char>::size_type bytecount=0;\r
-       int i;\r
-       std::vector<char>::size_type startlen;\r
+               Split(std::string(m_receivebuffer.begin(),endpos),"\n=",fields);\r
+               m_receivebuffer.erase(m_receivebuffer.begin(),endpos+endlen);\r
 \r
-       startlen=m_sendbuffer.size();\r
+               message.Clear();\r
 \r
-       SendBufferedText(messagename);\r
-       SendBufferedText("\n");\r
-\r
-       va_start(args,fieldcount);\r
+               if(fields.size()>0)\r
+               {\r
+                       message.SetName(fields[0]);\r
+               }\r
 \r
-       for(i=0; i<fieldcount; i++)\r
-       {\r
-               field=va_arg(args,const char *);\r
-               val=va_arg(args,const char *);\r
+               if(fields.size()>1)\r
+               {\r
+                       for(std::vector<std::string>::iterator i=fields.begin()+1; i!=fields.end();)\r
+                       {\r
+                               if(i+1!=fields.end())\r
+                               {\r
+                                       message.GetFields()[(*i)]=(*(i+1));\r
+                                       i+=2;\r
+                               }\r
+                               else\r
+                               {\r
+                                       i++;\r
+                               }\r
+                       }\r
+               }\r
 \r
-               SendBufferedText(field);\r
-               SendBufferedText("=");\r
-               SendBufferedText(val);\r
-               SendBufferedText("\n");\r
        }\r
-\r
-       SendBufferedText("EndMessage\n");\r
-\r
-       bytecount=m_sendbuffer.size()-startlen;\r
-       \r
-       va_end(args);\r
-\r
-       return bytecount;\r
+       return false;\r
 }\r
 \r
-const int FCPv2::SendMessage(FCPMessage &message)\r
+const bool Connection::Receive(std::vector<char> &data, const std::vector<char>::size_type len)\r
 {\r
-       std::vector<char>::size_type bytecount=0;\r
-       std::vector<char>::size_type startlen;\r
-       FCPMessage::iterator i;\r
-\r
-       startlen=m_sendbuffer.size();\r
-\r
-       if(message.GetName()!="")\r
+       if(m_receivebuffer.size()>=len && len>=0)\r
        {\r
-               SendBufferedText(message.GetName().c_str());\r
-               SendBufferedText("\n");\r
-\r
-               for(i=message.begin(); i!=message.end(); i++)\r
-               {\r
-                       SendBufferedText((*i).first.c_str());\r
-                       SendBufferedText("=");\r
-                       SendBufferedText((*i).second.c_str());\r
-                       SendBufferedText("\n");\r
-               }\r
-\r
-               SendBufferedText("EndMessage\n");\r
+               data.insert(data.end(),m_receivebuffer.begin(),m_receivebuffer.begin()+len);\r
+               m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);\r
+               return true;\r
+       }\r
+       else\r
+       {\r
+               return false;\r
        }\r
-\r
-       bytecount=m_sendbuffer.size()-startlen;\r
-\r
-       return bytecount;\r
 }\r
 \r
-\r
-const int FCPv2::SendRaw(const char *data, const int datalen)\r
+const bool Connection::Receive(char *data, const size_t len)\r
 {\r
-       int bytecount=datalen;\r
-\r
-       if(bytecount>0)\r
+       if(m_receivebuffer.size()>=len && len>=0)\r
        {\r
-               SendBufferedRaw(data,datalen);\r
+               std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,data);\r
+               m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);\r
+               return true;\r
+       }\r
+       else\r
+       {\r
+               return false;\r
        }\r
-\r
-       return bytecount;\r
-\r
 }\r
 \r
-void FCPv2::SocketReceive()\r
+const bool Connection::ReceiveIgnore(const size_t len)\r
 {\r
-       int len=0;\r
-\r
-       len=recv(m_serversocket,m_tempbuffer,65535,0);\r
-\r
-       if(len>0)\r
+       if(m_receivebuffer.size()>=len && len>=0)\r
        {\r
-\r
-               m_receivebuffer.resize(m_receivebuffer.size()+len);\r
-               std::copy(m_tempbuffer,&m_tempbuffer[len],m_receivebuffer.end()-len);\r
-\r
+               m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);\r
+               return true;\r
        }\r
-       // there was an error or server closed connection  - disconnect socket\r
        else\r
        {\r
-               Disconnect();\r
+               return false;\r
        }\r
 }\r
 \r
-void FCPv2::SocketSend()\r
+const bool Connection::Send(const Message &message)\r
 {\r
-       int len=0;\r
-       if(m_sendbuffer.size()>0)\r
+       if(message.GetName()!="")\r
        {\r
-               len=send(m_serversocket,&m_sendbuffer[0],m_sendbuffer.size(),0);\r
-               if(len>0)\r
-               {\r
-                       // move remaining data in buffer to beginning of buffer (erase the bytes we just sent)\r
-                       m_sendbuffer.erase(m_sendbuffer.begin(),m_sendbuffer.begin()+len);\r
-               }\r
-               // there was an error with send - disconnect socket\r
-               else\r
-               {\r
-                       Disconnect();\r
-               }\r
+               std::string fcpstring=message.GetFCPString();\r
+               m_sendbuffer.insert(m_sendbuffer.end(),fcpstring.begin(),fcpstring.end());\r
+               return true;\r
        }\r
+       return false;\r
 }\r
 \r
+const bool Connection::Send(const std::vector<char> &data)\r
+{\r
+       m_sendbuffer.insert(m_sendbuffer.end(),data.begin(),data.end());\r
+       return true;\r
+}\r
 \r
-const bool FCPv2::Update(const long waittime)\r
+const bool Connection::Send(const char *data, const size_t len)\r
 {\r
+       if(data)\r
+       {\r
+               m_sendbuffer.insert(m_sendbuffer.end(),data[0],data[0]+len);\r
+               return true;    \r
+       }\r
+       return false;\r
+}\r
 \r
-       if(Connected())\r
+void Connection::Split(const std::string &str, const std::string &separators, std::vector<std::string> &elements)\r
+{\r
+       std::string::size_type offset = 0;\r
+       std::string::size_type delimIndex = 0;\r
+    \r
+       delimIndex = str.find_first_of(separators, offset);\r
+\r
+    while (delimIndex != std::string::npos)\r
+    {\r
+        elements.push_back(str.substr(offset, delimIndex - offset));\r
+        offset += delimIndex - offset + 1;\r
+        delimIndex = str.find_first_of(separators, offset);\r
+    }\r
+\r
+    elements.push_back(str.substr(offset));\r
+}\r
+\r
+const bool Connection::Update(const unsigned long ms)\r
+{\r
+       if(IsConnected())\r
        {\r
-               m_timeval.tv_sec=waittime;\r
-               m_timeval.tv_usec=0;\r
+               m_timeval.tv_sec=ms/1000;\r
+               m_timeval.tv_usec=(ms%1000)*1000;\r
 \r
                FD_ZERO(&m_readfs);\r
                FD_ZERO(&m_writefs);\r
 \r
-               FD_SET(m_serversocket,&m_readfs);\r
-               \r
+               FD_SET(m_socket,&m_readfs);\r
+\r
                if(m_sendbuffer.size()>0)\r
                {\r
-                       FD_SET(m_serversocket,&m_writefs);\r
+                       FD_SET(m_socket,&m_writefs);\r
                }\r
 \r
-               select(m_serversocket+1,&m_readfs,&m_writefs,0,&m_timeval);\r
+               select(m_socket+1,&m_readfs,&m_writefs,0,&m_timeval);\r
 \r
-               if(FD_ISSET(m_serversocket,&m_readfs))\r
+               if(FD_ISSET(m_socket,&m_readfs))\r
                {\r
-                       SocketReceive();\r
+                       DoReceive();\r
                }\r
-               if(Connected() && FD_ISSET(m_serversocket,&m_writefs))\r
+               if(IsConnected() && FD_ISSET(m_socket,&m_writefs))\r
                {\r
-                       SocketSend();\r
+                       DoSend();\r
                }\r
 \r
-               return true;\r
+       }\r
 \r
+       if(IsConnected())\r
+       {\r
+               return true;\r
        }\r
        else\r
        {\r
@@ -445,3 +467,22 @@ const bool FCPv2::Update(const long waittime)
        }\r
 \r
 }\r
+\r
+const bool Connection::WaitForBytes(const unsigned long ms, const size_t len)\r
+{\r
+       while(IsConnected() && m_receivebuffer.size()<len)\r
+       {\r
+               Update(ms);\r
+       }\r
+       \r
+       if(IsConnected() && m_receivebuffer.size()>=len)\r
+       {\r
+               return true;    \r
+       }\r
+       else\r
+       {\r
+               return false;   \r
+       }\r
+}\r
+\r
+}      // namespace\r