src/core/attribute-list.cc
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 02 Jun 2008 10:30:24 -0700
changeset 3190 51fe9001a679
parent 2965 4b28e9740e3b
child 3892 f985e116b696
permissions -rw-r--r--
add some doxygen, remove a couple of XXX
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2008 INRIA
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License version 2 as
     7  * published by the Free Software Foundation;
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    19  */
    20 #include "attribute-list.h"
    21 #include "string.h"
    22 #include "singleton.h"
    23 
    24 namespace ns3 {
    25 
    26 /*********************************************************************
    27  *         The AttributeList container implementation
    28  *********************************************************************/
    29 
    30 AttributeList::AttributeList ()
    31 {}
    32 
    33 AttributeList::AttributeList (const AttributeList &o)
    34 {
    35   for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
    36     {
    37       struct Attr attr;
    38       attr.checker = i->checker;
    39       attr.value = i->value->Copy ();
    40       m_attributes.push_back (attr);
    41     }
    42 }
    43 AttributeList &
    44 AttributeList::operator = (const AttributeList &o)
    45 {
    46   Reset ();
    47   for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
    48     {
    49       struct Attr attr;
    50       attr.checker = i->checker;
    51       attr.value = i->value->Copy ();
    52       m_attributes.push_back (attr);
    53     }
    54   return *this;
    55 }
    56 AttributeList::~AttributeList ()
    57 {
    58   Reset ();
    59 }
    60 
    61 void
    62 AttributeList::Set (std::string name, const AttributeValue &value)
    63 {
    64   struct TypeId::AttributeInfo info;
    65   bool ok = TypeId::LookupAttributeByFullName (name, &info);
    66   if (!ok)
    67     {
    68       NS_FATAL_ERROR ("Could not find attribute "<<name);
    69     }
    70   ok = DoSet (&info, value);
    71   if (!ok)
    72     {
    73       NS_FATAL_ERROR ("Could not set value for attribute "<<name);
    74     }
    75 }
    76 bool 
    77 AttributeList::SetFailSafe (std::string name, const AttributeValue &value)
    78 {
    79   struct TypeId::AttributeInfo info;
    80   bool ok = TypeId::LookupAttributeByFullName (name, &info);
    81   if (!ok)
    82     {
    83       return false;
    84     }
    85   ok = DoSet (&info, value);
    86   return ok;
    87 }
    88 void
    89 AttributeList::SetWithTid (TypeId tid, std::string name, const AttributeValue & value)
    90 {
    91   struct TypeId::AttributeInfo info;
    92   bool ok = tid.LookupAttributeByName (name, &info);
    93   if (!ok)
    94     {
    95       NS_FATAL_ERROR ("Could not find attribute "<<tid.GetName ()<<"::"<<name);
    96     }
    97   ok = DoSet (&info, value);
    98   if (!ok)
    99     {
   100       NS_FATAL_ERROR ("Could not set value for attribute "<<tid.GetName ()<<"::"<<name);
   101     }
   102 }
   103 
   104 void
   105 AttributeList::DoSetOne (Ptr<const AttributeChecker> checker, const AttributeValue &value)
   106 {
   107   // get rid of any previous value stored in this
   108   // vector of values.
   109   for (Attrs::iterator k = m_attributes.begin (); k != m_attributes.end (); k++)
   110     {
   111       if (k->checker == checker)
   112         {
   113           m_attributes.erase (k);
   114           break;
   115         }
   116     }
   117   // store the new value.
   118   struct Attr attr;
   119   attr.checker = checker;
   120   attr.value = value.Copy ();
   121   m_attributes.push_back (attr);
   122 }
   123 bool
   124 AttributeList::DoSet (struct TypeId::AttributeInfo *info, const AttributeValue &value)
   125 {
   126   if (info->checker == 0)
   127     {
   128       return false;
   129     }
   130   bool ok = info->checker->Check (value);
   131   if (ok)
   132     {
   133       DoSetOne (info->checker, value);
   134       return true;
   135     }
   136 
   137   // attempt to convert to string.
   138   const StringValue *str = dynamic_cast<const StringValue *> (&value);
   139   if (str == 0)
   140     {
   141       return false;
   142     }
   143   // attempt to convert back to value.
   144   Ptr<AttributeValue> v = info->checker->Create ();
   145   ok = v->DeserializeFromString (str->Get (), info->checker);
   146   if (!ok)
   147     {
   148       return false;
   149     }
   150   ok = info->checker->Check (*v);
   151   if (!ok)
   152     {
   153       return false;
   154     }
   155   DoSetOne (info->checker, *v);
   156   return true;
   157 }
   158 void 
   159 AttributeList::Reset (void)
   160 {
   161   m_attributes.clear ();
   162 }
   163 AttributeList *
   164 AttributeList::GetGlobal (void)
   165 {
   166   return Singleton<AttributeList>::Get ();
   167 }
   168 
   169 std::string
   170 AttributeList::LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const
   171 {
   172   for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
   173     {
   174       TypeId tid = TypeId::GetRegistered (i);
   175       for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
   176         {
   177           if (checker == tid.GetAttributeChecker (j))
   178             {
   179               return tid.GetAttributeFullName (j);
   180             }
   181         }
   182     }
   183   NS_FATAL_ERROR ("Could not find requested Accessor.");
   184   // quiet compiler.
   185   return "";
   186 }
   187 
   188 std::string 
   189 AttributeList::SerializeToString (void) const
   190 {
   191   std::ostringstream oss;
   192   for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end ();)
   193     {
   194       std::string name = LookupAttributeFullNameByChecker (i->checker);
   195       oss << name << "=" << i->value->SerializeToString (i->checker);
   196       i++;
   197       if (i != m_attributes.end ())
   198         {
   199           oss << "|";
   200         }
   201     }  
   202   return oss.str ();
   203 }
   204 bool 
   205 AttributeList::DeserializeFromString (std::string str)
   206 {
   207   Reset ();
   208 
   209   std::string::size_type cur;
   210   cur = 0;
   211   do {
   212     std::string::size_type equal = str.find ("=", cur);
   213     if (equal == std::string::npos)
   214       {
   215         NS_FATAL_ERROR ("Error while parsing serialized attribute: \"" << str << "\"");
   216         break;
   217       }
   218     else
   219       {
   220         std::string name = str.substr (cur, equal-cur);
   221         struct TypeId::AttributeInfo info;
   222         if (!TypeId::LookupAttributeByFullName (name, &info))
   223           {
   224             NS_FATAL_ERROR ("Error while parsing serialized attribute: name does not exist: \"" << name << "\"");
   225             break;
   226           }
   227         else
   228           {
   229             std::string::size_type next = str.find ("|", cur);
   230             std::string value;
   231             if (next == std::string::npos)
   232               {
   233                 value = str.substr (equal+1, str.size () - (equal+1));
   234                 cur = str.size ();
   235               }
   236             else
   237               {
   238                 value = str.substr (equal+1, next - (equal+1));
   239                 cur++;
   240               }
   241             Ptr<AttributeValue> val = info.checker->Create ();
   242             bool ok = val->DeserializeFromString (value, info.checker);
   243             if (!ok)
   244               {
   245                 NS_FATAL_ERROR ("Error while parsing serialized attribute: value invalid: \"" << value << "\"");
   246                 break;
   247               }
   248             else
   249               {
   250                 DoSetOne (info.checker, *val);
   251               }
   252           }
   253       }
   254   } while (cur != str.size ());
   255 
   256   return true;
   257 }
   258 
   259 } // namespace ns3