src/core/attribute-list.cc
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 04 Jul 2009 08:15:48 +0200
changeset 4654 2eaebe77d66b
parent 4252 c82988c68a35
permissions -rw-r--r--
Added tag ns-3.5 for changeset c975274c9707
     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   while (cur != str.size ())
   212     {
   213       std::string::size_type equal = str.find ("=", cur);
   214       if (equal == std::string::npos)
   215         {
   216           NS_FATAL_ERROR ("Error while parsing serialized attribute: \"" << str << "\"");
   217           break;
   218         }
   219       else
   220         {
   221           std::string name = str.substr (cur, equal-cur);
   222           struct TypeId::AttributeInfo info;
   223           if (!TypeId::LookupAttributeByFullName (name, &info))
   224             {
   225               NS_FATAL_ERROR ("Error while parsing serialized attribute: name does not exist: \"" << name << "\"");
   226               break;
   227             }
   228           else
   229             {
   230               std::string::size_type next = str.find ("|", cur);
   231               std::string value;
   232               if (next == std::string::npos)
   233                 {
   234                   value = str.substr (equal+1, str.size () - (equal+1));
   235                   cur = str.size ();
   236                 }
   237               else
   238                 {
   239                   value = str.substr (equal+1, next - (equal+1));
   240                   cur = next + 1;
   241                 }
   242               Ptr<AttributeValue> val = info.checker->Create ();
   243               bool ok = val->DeserializeFromString (value, info.checker);
   244               if (!ok)
   245                 {
   246                   NS_FATAL_ERROR ("Error while parsing serialized attribute: value invalid: \"" << value << "\"");
   247                   break;
   248                 }
   249               else
   250                 {
   251                   DoSetOne (info.checker, *val);
   252                 }
   253             }
   254         }
   255     }
   256 
   257   return true;
   258 }
   259 
   260 UnsafeAttributeList::UnsafeAttributeList ()
   261 {}
   262 UnsafeAttributeList::UnsafeAttributeList (const UnsafeAttributeList &o)
   263 {
   264   for (uint32_t i = 0; i < o.m_attributes.size (); ++i)
   265     {
   266       Set (o.m_attributes[i].first, *(o.m_attributes[i].second));
   267     }
   268 }
   269 UnsafeAttributeList &
   270 UnsafeAttributeList::operator = (const UnsafeAttributeList &o)
   271 {
   272   m_attributes.clear ();
   273   for (uint32_t i = 0; i < o.m_attributes.size (); ++i)
   274     {
   275       Set (o.m_attributes[i].first, *(o.m_attributes[i].second));
   276     }
   277   return *this;
   278 }
   279 
   280 UnsafeAttributeList::~UnsafeAttributeList ()
   281 {
   282   m_attributes.clear ();
   283 }
   284 void 
   285 UnsafeAttributeList::Set (std::string name, const AttributeValue &param)
   286 {
   287   if (name == "")
   288     {
   289       return;
   290     }
   291   for (uint32_t i = 0; i < m_attributes.size (); ++i)
   292     {
   293       if (m_attributes[i].first == name)
   294         {
   295           m_attributes[i].second = param.Copy ();
   296           return;
   297         }
   298     }
   299   m_attributes.push_back (std::make_pair (name, param.Copy ()));
   300 }
   301 
   302 AttributeList 
   303 UnsafeAttributeList::GetSafe (std::string tidName) const
   304 {
   305   AttributeList list;
   306   for (uint32_t i = 0; i < m_attributes.size (); ++i)
   307     {
   308       TypeId tid = TypeId::LookupByName (tidName);
   309       list.SetWithTid (tid, m_attributes[i].first, *m_attributes[i].second);
   310     }
   311   return list;
   312 }
   313 
   314 
   315 } // namespace ns3