src/core/global-value.cc
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 04 Jul 2009 08:15:48 +0200
changeset 4654 2eaebe77d66b
parent 4214 49039ae7bc3d
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  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    19  */
    20 #include "global-value.h"
    21 #include "fatal-error.h"
    22 #include "attribute.h"
    23 #include "string.h"
    24 #include "ns3/core-config.h"
    25 #ifdef HAVE_STDLIB_H
    26 #include <stdlib.h>
    27 #endif
    28 
    29 namespace ns3 {
    30 
    31 GlobalValue::GlobalValue (std::string name, std::string help,
    32 			  const AttributeValue &initialValue,
    33 			  Ptr<const AttributeChecker> checker)
    34   : m_name (name),
    35     m_help (help),
    36     m_initialValue (initialValue.Copy ()),
    37     m_checker (checker)
    38 {
    39   if (m_checker == 0)
    40     {
    41       NS_FATAL_ERROR ("Checker should not be zero.");
    42     }
    43   GetVector ()->push_back (this);
    44   InitializeFromEnv ();
    45 }
    46 
    47 void
    48 GlobalValue::InitializeFromEnv (void)
    49 {
    50 #ifdef HAVE_GETENV
    51   char *envVar = getenv ("NS_GLOBAL_VALUE");
    52   if (envVar == 0)
    53     {
    54       return;
    55     }
    56   std::string env = std::string (envVar);
    57   std::string::size_type cur = 0;
    58   std::string::size_type next = 0;
    59   while (next != std::string::npos)
    60     {
    61       next = env.find (";", cur);
    62       std::string tmp = std::string (env, cur, next-cur);
    63       std::string::size_type equal = tmp.find ("=");
    64       if (equal != std::string::npos)
    65         {
    66           std::string name = tmp.substr (0, equal);
    67           std::string value = tmp.substr (equal+1, tmp.size () - equal - 1);
    68           if (name == m_name)
    69             {
    70               SetValue (StringValue (value));
    71             }
    72         }
    73       cur = next + 1;
    74     }
    75 #endif /* HAVE_GETENV */
    76 }
    77 
    78 std::string 
    79 GlobalValue::GetName (void) const
    80 {
    81   return m_name;
    82 }
    83 std::string 
    84 GlobalValue::GetHelp (void) const
    85 {
    86   return m_help;
    87 }
    88 void
    89 GlobalValue::GetValue (AttributeValue &value) const
    90 {
    91   bool ok = m_checker->Copy (*m_initialValue, value);
    92   if (ok)
    93     {
    94       return;
    95     }
    96   StringValue *str = dynamic_cast<StringValue *> (&value);
    97   if (str == 0)
    98     {
    99       NS_FATAL_ERROR ("GlobalValue name="<<m_name<<": input value is not a string");
   100     }
   101   str->Set (m_initialValue->SerializeToString (m_checker));
   102 }
   103 Ptr<const AttributeChecker> 
   104 GlobalValue::GetChecker (void) const
   105 {
   106   return m_checker;
   107 }
   108   
   109 bool
   110 GlobalValue::SetValue (const AttributeValue &value)
   111 {
   112   if (m_checker->Check (value))
   113     {
   114       m_initialValue = value.Copy ();
   115       return true;
   116     }
   117   // attempt to convert to string.
   118   const StringValue *str = dynamic_cast<const StringValue *> (&value);
   119   if (str == 0)
   120     {
   121       return false;
   122     }
   123   // attempt to convert back to value.
   124   Ptr<AttributeValue> v = m_checker->Create ();
   125   bool ok = v->DeserializeFromString (str->Get (), m_checker);
   126   if (!ok)
   127     {
   128       return false;
   129     }
   130   ok = m_checker->Check (*v);
   131   if (!ok)
   132     {
   133       return false;
   134     }
   135   m_checker->Copy (*v, *PeekPointer (m_initialValue));
   136   return true;
   137 }
   138 
   139 void 
   140 GlobalValue::Bind (std::string name, const AttributeValue &value)
   141 {
   142   for (Iterator i = Begin (); i != End (); i++)
   143     {
   144       if ((*i)->GetName () == name)
   145 	{
   146 	  if (!(*i)->SetValue (value))
   147 	    {
   148 	      NS_FATAL_ERROR ("Invalid new value for global value: "<<name);
   149 	    }
   150 	  return;
   151 	}
   152     }
   153   NS_FATAL_ERROR ("Non-existant global value: "<<name);
   154 }
   155 bool 
   156 GlobalValue::BindFailSafe (std::string name, const AttributeValue &value)
   157 {
   158   for (Iterator i = Begin (); i != End (); i++)
   159     {
   160       if ((*i)->GetName () == name)
   161 	{
   162 	  return (*i)->SetValue (value);
   163 	}
   164     }
   165   return false;
   166 }
   167 GlobalValue::Iterator 
   168 GlobalValue::Begin (void)
   169 {
   170   return GetVector ()->begin ();
   171 }
   172 GlobalValue::Iterator 
   173 GlobalValue::End (void)
   174 {
   175   return GetVector ()->end ();
   176 }
   177 GlobalValue::Vector *
   178 GlobalValue::GetVector (void)
   179 {
   180   static Vector vector;
   181   return &vector;
   182 }
   183 
   184 } // namespace ns3
   185 
   186 #ifdef RUN_SELF_TESTS
   187 
   188 #include "test.h"
   189 #include "uinteger.h"
   190 
   191 namespace ns3 {
   192 
   193 class GlobalValueTests : public Test
   194 {
   195 public:
   196   GlobalValueTests ();
   197   virtual bool RunTests (void);
   198 private:
   199 };
   200 
   201 GlobalValueTests::GlobalValueTests ()
   202   : Test ("GlobalValue")
   203 {}
   204 bool 
   205 GlobalValueTests::RunTests (void)
   206 {
   207   bool result = true;
   208   GlobalValue uint = GlobalValue ("TestUint", "help text",
   209 				  UintegerValue (10),
   210 				  MakeUintegerChecker<uint32_t> ());
   211 
   212 
   213   UintegerValue v;
   214   uint.GetValue (v);
   215   NS_TEST_ASSERT_EQUAL (10, v.Get ());
   216 
   217   GlobalValue::Vector *vector = GlobalValue::GetVector ();
   218   for (GlobalValue::Vector::iterator i = vector->begin (); i != vector->end (); ++i)
   219     {
   220       if ((*i) == &uint)
   221 	{
   222 	  vector->erase (i);
   223 	  break;
   224 	}
   225     }
   226 
   227   return result;
   228 }
   229 
   230 static GlobalValueTests g_initialValueTests;
   231 
   232 } // namespace ns3
   233 
   234 #endif /* RUN_SELF_TESTS */