src/core/attribute-list.cc
changeset 2633 a0639de8cd8b
child 2671 7fa114622a4d
equal deleted inserted replaced
2632:e7989e4c674a 2633:a0639de8cd8b
       
     1 #include "attribute-list.h"
       
     2 #include "string.h"
       
     3 #include "singleton.h"
       
     4 
       
     5 namespace ns3 {
       
     6 
       
     7 /*********************************************************************
       
     8  *         The AttributeList container implementation
       
     9  *********************************************************************/
       
    10 
       
    11 AttributeList::AttributeList ()
       
    12 {}
       
    13 
       
    14 AttributeList::AttributeList (const AttributeList &o)
       
    15 {
       
    16   for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
       
    17     {
       
    18       struct Attr attr;
       
    19       attr.checker = i->checker;
       
    20       attr.value = i->value.Copy ();
       
    21       m_attributes.push_back (attr);
       
    22     }
       
    23 }
       
    24 AttributeList &
       
    25 AttributeList::operator = (const AttributeList &o)
       
    26 {
       
    27   Reset ();
       
    28   for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
       
    29     {
       
    30       struct Attr attr;
       
    31       attr.checker = i->checker;
       
    32       attr.value = i->value.Copy ();
       
    33       m_attributes.push_back (attr);
       
    34     }
       
    35   return *this;
       
    36 }
       
    37 AttributeList::~AttributeList ()
       
    38 {
       
    39   Reset ();
       
    40 }
       
    41 
       
    42 void
       
    43 AttributeList::Set (std::string name, Attribute value)
       
    44 {
       
    45   struct TypeId::AttributeInfo info;
       
    46   bool ok = TypeId::LookupAttributeByFullName (name, &info);
       
    47   if (!ok)
       
    48     {
       
    49       NS_FATAL_ERROR ("Could not find attribute "<<name);
       
    50     }
       
    51   ok = DoSet (&info, value);
       
    52   if (!ok)
       
    53     {
       
    54       NS_FATAL_ERROR ("Could not set value for attribute "<<name);
       
    55     }
       
    56 }
       
    57 bool 
       
    58 AttributeList::SetFailSafe (std::string name, Attribute value)
       
    59 {
       
    60   struct TypeId::AttributeInfo info;
       
    61   bool ok = TypeId::LookupAttributeByFullName (name, &info);
       
    62   if (!ok)
       
    63     {
       
    64       return false;
       
    65     }
       
    66   ok = DoSet (&info, value);
       
    67   return ok;
       
    68 }
       
    69 void
       
    70 AttributeList::SetWithTid (TypeId tid, std::string name, Attribute value)
       
    71 {
       
    72   struct TypeId::AttributeInfo info;
       
    73   bool ok = tid.LookupAttributeByName (name, &info);
       
    74   if (!ok)
       
    75     {
       
    76       NS_FATAL_ERROR ("Could not find attribute "<<tid.GetName ()<<"::"<<name);
       
    77     }
       
    78   ok = DoSet (&info, value);
       
    79   if (!ok)
       
    80     {
       
    81       NS_FATAL_ERROR ("Could not set value for attribute "<<tid.GetName ()<<"::"<<name);
       
    82     }
       
    83 }
       
    84 
       
    85 void
       
    86 AttributeList::DoSetOne (Ptr<const AttributeChecker> checker, Attribute value)
       
    87 {
       
    88   // get rid of any previous value stored in this
       
    89   // vector of values.
       
    90   for (Attrs::iterator k = m_attributes.begin (); k != m_attributes.end (); k++)
       
    91     {
       
    92       if (k->checker == checker)
       
    93         {
       
    94           m_attributes.erase (k);
       
    95           break;
       
    96         }
       
    97     }
       
    98   // store the new value.
       
    99   struct Attr attr;
       
   100   attr.checker = checker;
       
   101   attr.value = value.Copy ();
       
   102   m_attributes.push_back (attr);
       
   103 }
       
   104 bool
       
   105 AttributeList::DoSet (struct TypeId::AttributeInfo *info, Attribute value)
       
   106 {
       
   107   if (info->checker == 0)
       
   108     {
       
   109       return false;
       
   110     }
       
   111   bool ok = info->checker->Check (value);
       
   112   if (!ok)
       
   113     {
       
   114       // attempt to convert to string.
       
   115       const StringValue *str = value.DynCast<const StringValue *> ();
       
   116       if (str == 0)
       
   117         {
       
   118           return false;
       
   119         }
       
   120       // attempt to convert back to value.
       
   121       Attribute v = info->checker->Create ();
       
   122       ok = v.DeserializeFromString (str->Get ().Get (), info->checker);
       
   123       if (!ok)
       
   124         {
       
   125           return false;
       
   126         }
       
   127       ok = info->checker->Check (v);
       
   128       if (!ok)
       
   129         {
       
   130           return false;
       
   131         }
       
   132       value = v;
       
   133     }
       
   134   DoSetOne (info->checker, value);
       
   135   return true;
       
   136 }
       
   137 void 
       
   138 AttributeList::Reset (void)
       
   139 {
       
   140   m_attributes.clear ();
       
   141 }
       
   142 AttributeList *
       
   143 AttributeList::GetGlobal (void)
       
   144 {
       
   145   return Singleton<AttributeList>::Get ();
       
   146 }
       
   147 
       
   148 std::string
       
   149 AttributeList::LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const
       
   150 {
       
   151   for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
       
   152     {
       
   153       TypeId tid = TypeId::GetRegistered (i);
       
   154       for (uint32_t j = 0; j < tid.GetAttributeListN (); j++)
       
   155         {
       
   156           if (checker == tid.GetAttributeChecker (j))
       
   157             {
       
   158               return tid.GetAttributeFullName (j);
       
   159             }
       
   160         }
       
   161     }
       
   162   NS_FATAL_ERROR ("Could not find requested Accessor.");
       
   163   // quiet compiler.
       
   164   return "";
       
   165 }
       
   166 
       
   167 std::string 
       
   168 AttributeList::SerializeToString (void) const
       
   169 {
       
   170   std::ostringstream oss;
       
   171   for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end (); i++)
       
   172     {
       
   173       std::string name = LookupAttributeFullNameByChecker (i->checker);
       
   174       oss << name << "=" << i->value.SerializeToString (i->checker);
       
   175       if (i != m_attributes.end ())
       
   176         {
       
   177           oss << "|";
       
   178         }
       
   179     }  
       
   180   return oss.str ();
       
   181 }
       
   182 bool 
       
   183 AttributeList::DeserializeFromString (std::string str)
       
   184 {
       
   185   Reset ();
       
   186 
       
   187   std::string::size_type cur;
       
   188   cur = 0;
       
   189   do {
       
   190     std::string::size_type equal = str.find ("=", cur);
       
   191     if (equal == std::string::npos)
       
   192       {
       
   193         // XXX: invalid attribute.
       
   194         break;
       
   195       }
       
   196     else
       
   197       {
       
   198         std::string name = str.substr (cur, equal-cur);
       
   199         struct TypeId::AttributeInfo info;
       
   200         if (!TypeId::LookupAttributeByFullName (name, &info))
       
   201           {
       
   202             // XXX invalid name.
       
   203             break;
       
   204           }
       
   205         else
       
   206           {
       
   207             std::string::size_type next = str.find ("|", cur);
       
   208             std::string value;
       
   209             if (next == std::string::npos)
       
   210               {
       
   211                 value = str.substr (equal+1, str.size () - (equal+1));
       
   212                 cur = str.size ();
       
   213               }
       
   214             else
       
   215               {
       
   216                 value = str.substr (equal+1, next - (equal+1));
       
   217                 cur++;
       
   218               }
       
   219             Attribute val = info.checker->Create ();
       
   220             bool ok = val.DeserializeFromString (value, info.checker);
       
   221             if (!ok)
       
   222               {
       
   223                 // XXX invalid value
       
   224                 break;
       
   225               }
       
   226             else
       
   227               {
       
   228                 DoSetOne (info.checker, val);
       
   229               }
       
   230           }
       
   231       }
       
   232   } while (cur != str.size ());
       
   233 
       
   234   return true;
       
   235 }
       
   236 
       
   237 } // namespace ns3