MicoleBus.cpp

Go to the documentation of this file.
00001 /*
00002  * This file is part of Micole Architecture
00003  *
00004  * Copyright (C) 2007 Micole partners
00005  *
00006  * Micole Architecture is free software: you can redistribute it 
00007  * and/or modify it under the terms of the GNU Lesser General 
00008  * Public License as published by the Free Software Foundation, 
00009  * either version 3 of the License, or (at your option) any 
00010  * later version.
00011  *
00012  * Micole Architecture is distributed in the hope that it will be 
00013  * useful, * but WITHOUT ANY WARRANTY; without even the implied 
00014  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00015  * PURPOSE.  See the GNU Lesser General Public License for more 
00016  * details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with Micole Architecture.  If not, see
00020  * <http://www.gnu.org/licenses/>.
00021  */
00022 
00023 #include "stdafx.h"
00024 #include "MicoleBus.h"
00025 #include "MicoleAgent.h"
00026 #include "NetworkAgent.h"
00027 
00028 #include "MicoleStringStream.h"
00029 
00030 #include "Lo2kThread.h"
00031 
00032 using namespace std;
00033 
00034 
00035 MicoleBus::MicoleBus(bool sync = true)
00036 {
00037         _semLock = CreateSemaphore( NULL, MAXREADERS, MAXREADERS, NULL );
00038         _isWriting = CreateSemaphore( NULL, 1, 1, NULL );
00039         _regexpNumber = 0;
00040         _bindNumber = 0;
00041         _run = true;
00042         _sync = sync;
00043 
00044         if (!_sync)
00045                 start();
00046 }
00047 
00048 MicoleBus::~MicoleBus()
00049 {
00050 }
00051 
00052 void MicoleBus::run()
00053 {
00054 
00055         while(_run) 
00056         {
00057                 #ifdef _FULL_DEBUG
00058 /*              char *buffer = new char[10];
00059                 _itoa_s(_buffer.size(),buffer,9,10);
00060                 OutputDebugString((string(buffer)+"\n").c_str());
00061                 delete []buffer;*/
00062                 #endif
00063                 
00064                 while (_buffer.size() > 0)  //while buffer is not empty
00065                 {
00066                         //retrieve first message
00067                         string message;
00068                         lo2k::CriticalSection * cs = lo2k::CriticalSection::get(); //put critical section
00069                         cs->enter();
00070                         //remove first element from stl list
00071                         message = _buffer.front(); 
00072                         _buffer.pop();
00073                         cs->leave();    
00074 
00075                         //intepretation of message
00076                         this->interpret(message); 
00077                 }
00078         }
00079 }
00080 
00081 void MicoleBus::interpret(string message)
00082 {
00087         lockSlot();
00088         for (map<string,MicoleBusRegexp>::iterator i = _regexpList.begin(); i != _regexpList.end(); i++)
00089         {
00090                 #ifdef _FULL_DEBUG
00091                 //OutputDebugString(((*i).second._regexp+"\n").c_str());
00092                 #endif  
00093 
00094                 //create a  cmatch objet (see boost regexp usage)
00095                 cmatch what;
00096                 if(regex_match(message.c_str(), what, (*i).second._regexp))
00097                 {
00098                         int whatSize = (int) what.size();
00099                         char **  pArgv = new char*[whatSize];
00100                         
00101                         //foreach catched string by regular expression
00102                         for (int j = 1; j < whatSize; j++)
00103                         {
00104                                 //allocate arg
00105                                 int argvSize = what[j].second - what[j].first + 1;
00106                                 pArgv[j - 1] = (char *) malloc(sizeof(char) * argvSize);
00107                                 
00108                                 //extract parsed chain
00109                                 memcpy(pArgv[j-1],what[j].first,argvSize-1);
00110                                 pArgv[j-1][argvSize-1]=0; //add 0 terminal value
00111                         }
00112 
00113                         //apply to all callback
00114                         for (list<MicoleCallback*>::iterator k = (*i).second._cbList.begin() ; k != (*i).second._cbList.end() ; k++)
00115                                 (*k)->execute(this, whatSize - 1, (const char **)pArgv);
00116                         
00117                         //free
00118                         for (int j = 1; j < whatSize; j++)
00119                                 free(pArgv[j-1]);
00120                         
00121                         delete []pArgv;
00122                 }
00123         }
00124         unlockSlot();
00125 }
00126 
00127 void MicoleBus::stop()
00128 {
00129         _run = false;
00130 }
00131 
00135 MicoleBus::MicoleBus (const MicoleBus &mb)
00136 {
00137 }
00138 
00139 int MicoleBus::bindMsg(string regexp, MicoleCallback * cb)
00140 {
00141         lo2k::CriticalSection * cs = lo2k::CriticalSection::get();
00142         
00143         lockAllSlots();
00144         if(_regexpList.find(regexp) == _regexpList.end())
00145         {
00146                 MicoleBusRegexp elt;
00147                 elt._regexp = regex(regexp);
00148                 elt._cbList.push_back(cb);
00149         
00150                 cs->enter();
00151                 _regexpList[regexp]=elt;
00152                 cs->leave();
00153                 _regexpNumber++;
00154                 _bindNumber++;
00155         }
00156         else //entry already exist, add callback to callback list
00157         {
00158                 _regexpList[regexp]._cbList.push_back(cb);
00159                 _bindNumber++;
00160         }
00161         unlockAllSlots();
00162 
00163         MicoleStringStream ms;
00164         ms << "bind number:" << _bindNumber << " regexp number: " << _regexpNumber << " regexp: " << regexp <<"\n";
00165 
00166         OutputDebugStringA(ms.str().c_str());
00167         return 0;
00168 }
00169 
00170 void MicoleBus::unbindMsg(MicoleCallback * cb) {
00171         lockAllSlots();
00172         for (map<string,MicoleBusRegexp>::iterator i = _regexpList.begin() ; i != _regexpList.end() ; i++)
00173                 (*i).second._cbList.remove(cb);
00174 
00175         unlockAllSlots();
00176 }
00177 
00178 void MicoleBus::sendMsg(string s) 
00179 {
00180         if (_sync)  
00181                 this->interpret(s);
00182         else
00183         {
00184                 lo2k::CriticalSection * cs = lo2k::CriticalSection::get();
00185                 cs->enter();
00186                 _buffer.push(s);
00187                 cs->leave();
00188         }
00189 }

Generated on Tue Oct 16 17:10:42 2007 for Micole by  doxygen 1.4.7