Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

vos/corelibs/vos/messagecontext.cc

Go to the documentation of this file.
00001 /*
00002     This file is part of the Virtual Object System of
00003     the Interreality project (http://interreality.org).
00004 
00005     Copyright (C) 2001-2003 Peter Amstutz
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00020 
00021     Peter Amstutz <tetron@interreality.org>
00022 */
00023 
00024 #include "messagecontext.hh"
00025 #include "message.hh"
00026 #include "log.hh"
00027 
00028 using namespace VOS;
00029 
00030 MessageContext::MessageContext()
00031     : parentcontext(0)
00032 {
00033 }
00034 
00035 MessageContext::~MessageContext()
00036 {
00037     LOG("refcount", 5, "deleting message context");
00038     for(map<string, Message*>::iterator i = reply_record.begin(); i != reply_record.end(); i++) {
00039         if((*i).second) (*i).second->release(); // acquired by: addToReplyRecord()
00040     }
00041     if(parentcontext) parentcontext->release(); // acquired by: setParentContext()
00042 }
00043 
00044 void MessageContext::setParameter(const string& p, const string& v)
00045 {
00046     parameters[p]=v;
00047 }
00048 
00049 string MessageContext::getParameter(const string& p) throw (NoSuchParameterError)
00050 {
00051     map<string, string>::iterator i = parameters.find(p);
00052     if(i != parameters.end()) return (*i).second;
00053     else {
00054         if(parentcontext) return parentcontext->getParameter(p);
00055         else throw NoSuchParameterError("No parameter");
00056     }
00057 }
00058 
00059 void MessageContext::addToReplyRecord(Message* m)
00060 {
00061     if(parentcontext) parentcontext->addToReplyRecord(m);
00062     else {
00063         m->acquire(); // released by: removeFromReplyRecord() or destructor
00064         LOG("messagecontext", 4, "adding " << m->getNonce() << " to the reply record");
00065         reply_record[m->getNonce()] = m;
00066     }
00067 }
00068 
00069 bool MessageContext::replyRecordContains(const string& nonce)
00070 {
00071     if(parentcontext) return parentcontext->replyRecordContains(nonce);
00072     else {
00073         map<string, Message*>::iterator i = reply_record.find(nonce);
00074         return (i != reply_record.end() && (*i).second);
00075     }
00076 }
00077 
00078 Message* MessageContext::getFromReplyRecord(const string& nonce)
00079 {
00080     if(parentcontext) return parentcontext->getFromReplyRecord(nonce);
00081     else {
00082         map<string, Message*>::iterator i = reply_record.find(nonce);
00083         if(i != reply_record.end()) return (*i).second;
00084         else return 0;
00085     }
00086 }
00087 
00088 void MessageContext::removeFromReplyRecord(Message* m)
00089 {
00090     if(parentcontext) parentcontext->removeFromReplyRecord(m);
00091     {
00092         map<string, Message*>::iterator i = reply_record.find(m->getNonce());
00093         if(i != reply_record.end()) {
00094             (*i).second->release(); // acquired by: addToReplyRecord()
00095             reply_record.erase(i);
00096         }
00097     }
00098 }
00099 
00100 void MessageContext::doSubstitution(string& s, unsigned int p)
00101 {
00102     LOG("messagecontext", 5, "entering dosubst");
00103     for(; p < s.size() && s[p] != ')'; p++) {
00104         if(s[p] == '\\') {
00105             s.replace(p, 2, 1, s[p+1]);
00106             continue;
00107         }
00108         LOG("messagecontext", 5, "looking at " << s[p]);
00109         if(s[p] == '$') {
00110             int d = p++;
00111             string nonce;
00112             while(p < s.size() && s[p] != '(' && s[p] != '$') {
00113                 if(s[p] == '\\') {
00114                     s.replace(p, 2, 1, s[p+1]);
00115                     p++;
00116                 }
00117                 nonce += s[p++];
00118             }
00119 
00120             if(s[p] == '$') {
00121                 doSubstitution(s, p);
00122                 p=d-1;
00123                 continue;
00124             } else p++;
00125             LOG("messagecontext", 5, "recursing, before recurse: " << s);
00126             doSubstitution(s, p);
00127             LOG("messagecontext", 5, "recursing, after recurse: " << s);
00128             unsigned int q;
00129             for(q = p; q < s.size() && s[q] != ')'; q++) {
00130                 if(s[q] == '\\') {
00131                     s.replace(q, 2, 1, s[q+1]);
00132                 }
00133             }
00134 
00135             if(nonce == "") {
00136                 LOG("messagecontext", 5, p << " " << q << " (p - 2) = " << (p-2) << "   (q - p + 3) = " << (q-p+3));
00137                 try {
00138                     string rep = getParameter(s.substr(p, q-p));
00139                     if(parentcontext) parentcontext->doSubstitution(rep);
00140                     s.replace(p - 2, q - p + 3, rep);
00141                 } catch(NoSuchParameterError) {
00142                     LOG("messagecontext", 3, "doSubst: didn't have " << s.substr(p, q-p) << " field substituting into \"" << s << "\"");
00143                     s.replace(p - 2, q - p + 3, "**error**");
00144                 }
00145             } else {
00146                 Message* m = getFromReplyRecord(nonce);
00147                 if(m) {
00148                     try {
00149                         s.replace(p - 2 - nonce.size(), q - p + 3 + nonce.size(), m->getField(s.substr(p, q-p)).value);
00150                     } catch(Message::NoSuchFieldError) {
00151                         LOG("messagecontext", 3, "doSubst: didn't have " << s.substr(p, q-p) << " field in message nonce " << nonce << " substituting into \"" << s << "\"");
00152                         s.replace(p - 2 - nonce.size(), q - p + 3 + nonce.size(), "**error**");
00153                     }
00154                 } else {
00155                     LOG("messagecontext", 3, "doSubst: no caught message nonce " << nonce << " in substitution \"" << s << "\"");
00156                     s.replace(p - 2 - nonce.size(), q - p + 3 + nonce.size(), "**error**");
00157                 }
00158             }
00159             p-=2;
00160         }
00161     }
00162     LOG("messagecontext", 5, "leaving dosubst");
00163 }
00164 
00165 void MessageContext::setParentContext(MessageContext* mc)
00166 {
00167     if(parentcontext) parentcontext->release(); // acquired by: below
00168     if(mc) {
00169         mc->acquire();
00170         parentcontext=mc;
00171     } else parentcontext=0;
00172 }
00173 
00174 MessageContext* MessageContext::getParentContext()
00175 {
00176     parentcontext->acquire();
00177     return parentcontext;
00178 }
00179 

Generated on Tue Aug 12 03:55:40 2003 for Interreality Project - VOS by doxygen 1.3.2