Urbi SDK Remote for C++  2.7.5
umessage.cc
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2011, Gostai S.A.S.
00003  *
00004  * This software is provided "as is" without warranty of any kind,
00005  * either expressed or implied, including but not limited to the
00006  * implied warranties of fitness for a particular purpose.
00007  *
00008  * See the LICENSE file for more information.
00009  */
00010 
00012 
00013 #include <libport/cstdlib>
00014 #include <iomanip>
00015 #include <iostream>
00016 
00017 #include <libport/debug.hh>
00018 #include <libport/escape.hh>
00019 
00020 #include <urbi/umessage.hh>
00021 #include <urbi/uvalue.hh>
00022 
00023 GD_CATEGORY(Urbi.UMessage);
00024 
00025 namespace urbi
00026 {
00027 
00028   UMessage::UMessage(UAbstractClient& client)
00029     : client(client)
00030     , value(0)
00031   {
00032   }
00033 
00034   void
00035   UMessage::init_(const binaries_type& bins)
00036   {
00037     const char* msg = rawMessage.c_str();
00038     GD_FINFO_DUMP("new: \"%s\", client: %p",
00039                   libport::escape(msg), &client);
00040     while (msg[0] == ' ')
00041       ++msg;
00042 
00043     // System and error messages.
00044     if (msg[0] == '*' || msg[0] == '!')
00045     {
00046       type = msg[0] == '*' ? MESSAGE_SYSTEM : MESSAGE_ERROR;
00047       if (4 <= strlen(msg))
00048         message = msg + 4;
00049       return;
00050     }
00051 
00052     // value.
00053     type = MESSAGE_DATA;
00054     value = new UValue();
00055     binaries_type::const_iterator iter = bins.begin();
00056     int p = value->parse(msg, 0, bins, iter);
00057     if (0 <= p)
00058       while (msg[p] == ' ')
00059         ++p;
00060     /* no assertion can be made on message[p] because there is no terminator
00061      * for binaries */
00062     if (p < 0 || /*message[p] ||*/ iter != bins.end())
00063       GD_FERROR("parse error in `%s' at %s", msg, abs(p));
00064   }
00065 
00066   UMessage::UMessage(UAbstractClient& client, int timestamp,
00067                      const char* tag, const char* msg,
00068                      const binaries_type& bins)
00069     : client(client)
00070     , timestamp(timestamp)
00071     , tag(tag)
00072     , value(0)
00073     , rawMessage(msg)
00074   {
00075     init_(bins);
00076   }
00077 
00078   UMessage::UMessage(UAbstractClient& client, int timestamp,
00079                      const std::string& tag, const std::string& msg,
00080                      const binaries_type& bins)
00081     : client(client)
00082     , timestamp(timestamp)
00083     , tag(tag)
00084     , value(0)
00085     , rawMessage(msg)
00086   {
00087     init_(bins);
00088   }
00089 
00090   UMessage::UMessage(const UMessage& b)
00091     : client(b.client)
00092     , timestamp(b.timestamp)
00093     , tag(b.tag)
00094     , type(b.type)
00095     , value(0)
00096     , rawMessage(b.rawMessage)
00097   {
00098     switch (type)
00099     {
00100       case MESSAGE_SYSTEM:
00101       case MESSAGE_ERROR:
00102         message = b.message;
00103         break;
00104       default:
00105         value = new UValue(*b.value);
00106         break;
00107     }
00108   }
00109 
00110 
00111   UMessage::~UMessage()
00112   {
00113     if (type != MESSAGE_SYSTEM && type != MESSAGE_ERROR && value)
00114       delete value;
00115   }
00116 
00117   std::ostream&
00118   UMessage::print(std::ostream &o) const
00119   {
00120     char fill = o.fill('0');
00121     o << '[' << std::setw(8) << timestamp;
00122     o.fill(fill);
00123     if (!tag.empty())
00124       o << ":" << tag;
00125     o << "] ";
00126     switch (type)
00127     {
00128       case MESSAGE_DATA:
00129         o << *value;
00130         break;
00131       case MESSAGE_SYSTEM:
00132         o << "*** " << message;
00133         break;
00134       case MESSAGE_ERROR:
00135         o << "!!! " << message;
00136         break;
00137     }
00138     return o;
00139   }
00140 
00141 
00142 } // namespace urbi