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/messageblock.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 "messageblock.hh"
00025 #include "message.hh"
00026 #include "msglexer.hh"
00027 #include "log.hh"
00028 
00029 #include "parsemessage_parser.h"
00030 
00031 #include <deque>
00032 
00033 using namespace VOS;
00034 
00035 MessageBlock::MessageBlock()
00036     : formattedString(0)
00037 {
00038     parsestate.m=this;
00039     parsestate.chars_read=0;
00040     parsestate.expected_length=0;
00041     parsestate.done=false;
00042     parsestate.extra=0;
00043     parsestate.read_quoted=0;
00044 }
00045 
00046 MessageBlock::~MessageBlock()
00047 {
00048     LOG("refcount", 5, "start deleting messageblock with messages:");
00049     if(formattedString) delete formattedString;
00050     for(deque<Message*>::iterator i = messages.begin(); i != messages.end(); i++) {
00051         LOG("refcount", 5, "msg: [" << (*i)->refcount_debug << "]  count " << (*i)->getCount());
00052         (*i)->release(); // acquired by: insertMessage()
00053     }
00054     LOG("refcount", 5, "done deleting messageblock");
00055 }
00056 
00057 string MessageBlock::getName()
00058 {
00059     return name;
00060 }
00061 
00062 void MessageBlock::setName(const string& n)
00063 {
00064     name=n;
00065 }
00066 
00067 void MessageBlock::insertMessage(int n, Message* m)
00068 {
00069     m->acquire(); // released by: this destructor
00070     if(messages.size() > 0 && n > -1 && (unsigned int)n >= messages.size()) n = n % (int)messages.size();
00071     if(n < 0) n = (int)messages.size() + n + 1;
00072     messages.insert(messages.begin() + n, m);
00073 }
00074 
00075 Message* MessageBlock::getMessage(int n)
00076 {
00077     if(n < 0) n = (int)messages.size() + n + 1;
00078     if(n < 0 || n >= (int)messages.size()) return 0;
00079     messages[n]->acquire(); // released by: the caller of this method
00080     return messages[n];
00081 }
00082 
00083 Message* MessageBlock::lastMessage()
00084 {
00085     if(messages.size() == 0) return 0;
00086     messages.back()->acquire(); // released by: the caller of this method
00087     return messages.back();
00088 }
00089 
00090 int MessageBlock::numMessages()
00091 {
00092     return (int)messages.size();
00093 }
00094 
00095 const string& MessageBlock::getString()
00096 {
00097     if(formattedString) delete formattedString;
00098 
00099     if(messages.size() == 1 && name == "") {
00100         formattedString = new string;
00101         *formattedString = lastMessage()->getFormattedString(true);
00102         return *formattedString;
00103     }
00104 
00105     string* s = new string();
00106 
00107     *s += "<messageblock length=\"\"";
00108     if(name != "") {
00109         *s += " name=\"";
00110         *s += name;
00111         *s += "\"";
00112     }
00113     *s += ">\n";
00114     for(deque<Message*>::const_iterator f = messages.begin();
00115         f != messages.end();
00116         f++) {
00117         *s += (*f)->getFormattedString(false) + "\n";
00118     }
00119     *s += "</messageblock>";
00120 
00121     unsigned int size = (unsigned int)s->size();
00122 
00123     char len[16];
00124     int width = snprintf(len, sizeof(len), "%i", size);
00125     size += (unsigned int)strlen(len);
00126     if(width < snprintf(len, sizeof(len), "%i", size)) snprintf(len, sizeof(len), "%i", size+1);
00127 
00128     // '<messageblock length="' is 22 characters
00129     s->insert(22, len);
00130 
00131     formattedString = s;
00132 
00133     return *s;
00134 }
00135 
00136 int MessageBlock::parseUpdate(const string& s)
00137 {
00138     unsigned int oldsize = (unsigned int)parse_buffer.size();
00139     parse_buffer.append(s);
00140 
00141     LOG("messageblock", 4, "parse_buffer.size() is " << (unsigned int)parse_buffer.size() << " and expected_length is " << parsestate.expected_length);
00142 
00143     if(parse_buffer.size() < parsestate.expected_length) return 0;
00144 
00145     msgFlexLexer fl(&parsestate);
00146     parsestate.extra=&fl;
00147 
00148 #ifdef USE_STRSTREAM
00149     istrstream ss(parse_buffer.c_str(), parse_buffer.length());
00150     char blah[1024];
00151     ostrstream os(blah, sizeof(blah));
00152 #else
00153     istringstream ss(parse_buffer);
00154     string blah;
00155     ostringstream os(blah);
00156 #endif
00157     LOG("parser", 5, "siccing the parser on " << parse_buffer);
00158     if(parse_buffer.size() > 1000) LOG("parser", 5, "ending is  " << parse_buffer.substr(parse_buffer.size() - 1000, 1000));
00159 
00160     parsestate.input = &ss;
00161 
00162     fl.switch_streams(&ss, &os);
00163     parsestate.chars_read=0;
00164     parsestate.read_quoted=0;
00165     msgparse(&parsestate);
00166 
00167     if(parsestate.done) {
00168         parse_buffer.erase(parse_buffer.begin(), parse_buffer.end());
00169         if(formattedString != 0) {
00170             delete formattedString;
00171             formattedString=0;
00172         }
00173         return (parsestate.chars_read - oldsize);
00174     } else {
00175         for(deque<Message*>::iterator i = messages.begin(); i != messages.end(); i++) {
00176             (*i)->release(); // acquired by: this method
00177         }
00178         messages.resize(0);
00179         return 0;
00180     }
00181 }
00182 
00183 int VOS::msglex(char** lvalp, void* extra)
00184 {
00185     struct parse_state_t* ps=(parse_state_t*)extra;
00186 
00187     msgFlexLexer* fl=(msgFlexLexer*)ps->extra;
00188 
00189     if(! ps->done) {
00190         int ret;
00191         *lvalp = 0;
00192         do {
00193             ret=fl->yylex();
00194             if(ret < 255 || ret == SPACE || ret == COMMENT) *lvalp = (char*)fl->YYText();
00195             else *lvalp = strdup(fl->YYText());
00196             //*lvalp = fl->YYText();
00197 
00198             if(! ps->read_quoted) ps->chars_read += fl->YYLeng();
00199 
00200             LOG("lexer", 6, "lexer called, got a " << *lvalp << " (len " << fl->YYLeng()
00201                 << ") and returning " << ret);
00202         } while(ret == COMMENT);
00203         return ret;
00204     }
00205     return 0;
00206 }
00207 
00208 void VOS::msgerror(char* blah)
00209 {
00210     LOG("parser", 4, "Message parse error (probably because entire message has beeen received yet): " << blah);
00211 }

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