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