00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "object-base.h"
00021 #include "log.h"
00022 #include "trace-source-accessor.h"
00023 #include "attribute-list.h"
00024 #include "string.h"
00025
00026 NS_LOG_COMPONENT_DEFINE ("ObjectBase");
00027
00028 namespace ns3 {
00029
00030 static TypeId
00031 GetObjectIid (void)
00032 {
00033 TypeId tid = TypeId ("ns3::ObjectBase");
00034 tid.SetParent (tid);
00035 return tid;
00036 }
00037
00038 TypeId
00039 ObjectBase::GetTypeId (void)
00040 {
00041 static TypeId tid = GetObjectIid ();
00042 return tid;
00043 }
00044
00045 ObjectBase::~ObjectBase ()
00046 {}
00047
00048 void
00049 ObjectBase::NotifyConstructionCompleted (void)
00050 {}
00051
00052 void
00053 ObjectBase::ConstructSelf (const AttributeList &attributes)
00054 {
00055
00056 TypeId tid = GetInstanceTypeId ();
00057 do {
00058
00059 NS_LOG_DEBUG ("construct tid="<<tid.GetName ()<<", params="<<tid.GetAttributeN ());
00060 for (uint32_t i = 0; i < tid.GetAttributeN (); i++)
00061 {
00062 Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i);
00063 Ptr<const AttributeValue> initial = tid.GetAttributeInitialValue (i);
00064 Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
00065 NS_LOG_DEBUG ("try to construct \""<< tid.GetName ()<<"::"<<
00066 tid.GetAttributeName (i)<<"\"");
00067 if (!(tid.GetAttributeFlags (i) & TypeId::ATTR_CONSTRUCT))
00068 {
00069 continue;
00070 }
00071 bool found = false;
00072
00073 for (AttributeList::Attrs::const_iterator j = attributes.m_attributes.begin ();
00074 j != attributes.m_attributes.end (); j++)
00075 {
00076 if (j->checker == checker)
00077 {
00078
00079 DoSet (accessor, checker, *j->value);
00080 NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
00081 tid.GetAttributeName (i)<<"\"");
00082 found = true;
00083 break;
00084 }
00085 }
00086 if (!found)
00087 {
00088
00089 for (AttributeList::Attrs::const_iterator j = AttributeList::GetGlobal ()->m_attributes.begin ();
00090 j != AttributeList::GetGlobal ()->m_attributes.end (); j++)
00091 {
00092 if (j->checker == checker)
00093 {
00094
00095 DoSet (accessor, checker, *j->value);
00096 NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
00097 tid.GetAttributeName (i)<<"\" from global");
00098 found = true;
00099 break;
00100 }
00101 }
00102 }
00103 if (!found)
00104 {
00105
00106 DoSet (accessor, checker, *initial);
00107 NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
00108 tid.GetAttributeName (i)<<"\" from initial value.");
00109 }
00110 }
00111 tid = tid.GetParent ();
00112 } while (tid != ObjectBase::GetTypeId ());
00113 NotifyConstructionCompleted ();
00114 }
00115
00116 bool
00117 ObjectBase::DoSet (Ptr<const AttributeAccessor> spec,
00118 Ptr<const AttributeChecker> checker,
00119 const AttributeValue &value)
00120 {
00121 bool ok = checker->Check (value);
00122 if (ok)
00123 {
00124 ok = spec->Set (this, value);
00125 return ok;
00126 }
00127
00128 const StringValue *str = dynamic_cast<const StringValue *> (&value);
00129 if (str == 0)
00130 {
00131 return false;
00132 }
00133
00134 Ptr<AttributeValue> v = checker->Create ();
00135 ok = v->DeserializeFromString (str->Get (), checker);
00136 if (!ok)
00137 {
00138 return false;
00139 }
00140 ok = checker->Check (*v);
00141 if (!ok)
00142 {
00143 return false;
00144 }
00145 ok = spec->Set (this, *v);
00146 return ok;
00147 }
00148 void
00149 ObjectBase::SetAttribute (std::string name, const AttributeValue &value)
00150 {
00151 struct TypeId::AttributeInfo info;
00152 TypeId tid = GetInstanceTypeId ();
00153 if (!tid.LookupAttributeByName (name, &info))
00154 {
00155 NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
00156 }
00157 if (!(info.flags & TypeId::ATTR_SET) ||
00158 !info.accessor->HasSetter ())
00159 {
00160 NS_FATAL_ERROR ("Attribute name="<<name<<" is not settable for this object: tid="<<tid.GetName ());
00161 }
00162 if (!DoSet (info.accessor, info.checker, value))
00163 {
00164 NS_FATAL_ERROR ("Attribute name="<<name<<" could not be set for this object: tid="<<tid.GetName ());
00165 }
00166 }
00167 bool
00168 ObjectBase::SetAttributeFailSafe (std::string name, const AttributeValue &value)
00169 {
00170 struct TypeId::AttributeInfo info;
00171 TypeId tid = GetInstanceTypeId ();
00172 if (!tid.LookupAttributeByName (name, &info))
00173 {
00174 return false;
00175 }
00176 if (!(info.flags & TypeId::ATTR_SET) ||
00177 !info.accessor->HasSetter ())
00178 {
00179 return false;
00180 }
00181 return DoSet (info.accessor, info.checker, value);
00182 }
00183
00184 void
00185 ObjectBase::GetAttribute (std::string name, AttributeValue &value) const
00186 {
00187 struct TypeId::AttributeInfo info;
00188 TypeId tid = GetInstanceTypeId ();
00189 if (!tid.LookupAttributeByName (name, &info))
00190 {
00191 NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
00192 }
00193 if (!(info.flags & TypeId::ATTR_GET) ||
00194 !info.accessor->HasGetter ())
00195 {
00196 NS_FATAL_ERROR ("Attribute name="<<name<<" is not gettable for this object: tid="<<tid.GetName ());
00197 }
00198 bool ok = info.accessor->Get (this, value);
00199 if (ok)
00200 {
00201 return;
00202 }
00203 StringValue *str = dynamic_cast<StringValue *> (&value);
00204 if (str == 0)
00205 {
00206 NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": input value is not a string");
00207 }
00208 Ptr<AttributeValue> v = info.checker->Create ();
00209 ok = info.accessor->Get (this, *PeekPointer (v));
00210 if (!ok)
00211 {
00212 NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": could not get value");
00213 }
00214 str->Set (v->SerializeToString (info.checker));
00215 }
00216
00217
00218 bool
00219 ObjectBase::GetAttributeFailSafe (std::string name, AttributeValue &value) const
00220 {
00221 struct TypeId::AttributeInfo info;
00222 TypeId tid = GetInstanceTypeId ();
00223 if (!tid.LookupAttributeByName (name, &info))
00224 {
00225 return false;
00226 }
00227 if (!(info.flags & TypeId::ATTR_GET) ||
00228 !info.accessor->HasGetter ())
00229 {
00230 return false;
00231 }
00232 bool ok = info.accessor->Get (this, value);
00233 if (ok)
00234 {
00235 return true;
00236 }
00237 StringValue *str = dynamic_cast<StringValue *> (&value);
00238 if (str == 0)
00239 {
00240 return false;
00241 }
00242 Ptr<AttributeValue> v = info.checker->Create ();
00243 ok = info.accessor->Get (this, *PeekPointer (v));
00244 if (!ok)
00245 {
00246 return false;
00247 }
00248 str->Set (v->SerializeToString (info.checker));
00249 return true;
00250 }
00251
00252 bool
00253 ObjectBase::TraceConnectWithoutContext (std::string name, const CallbackBase &cb)
00254 {
00255 TypeId tid = GetInstanceTypeId ();
00256 Ptr<const TraceSourceAccessor> accessor = tid.LookupTraceSourceByName (name);
00257 if (accessor == 0)
00258 {
00259 return false;
00260 }
00261 bool ok = accessor->ConnectWithoutContext (this, cb);
00262 return ok;
00263 }
00264 bool
00265 ObjectBase::TraceConnect (std::string name, std::string context, const CallbackBase &cb)
00266 {
00267 TypeId tid = GetInstanceTypeId ();
00268 Ptr<const TraceSourceAccessor> accessor = tid.LookupTraceSourceByName (name);
00269 if (accessor == 0)
00270 {
00271 return false;
00272 }
00273 bool ok = accessor->Connect (this, context, cb);
00274 return ok;
00275 }
00276 bool
00277 ObjectBase::TraceDisconnectWithoutContext (std::string name, const CallbackBase &cb)
00278 {
00279 TypeId tid = GetInstanceTypeId ();
00280 Ptr<const TraceSourceAccessor> accessor = tid.LookupTraceSourceByName (name);
00281 if (accessor == 0)
00282 {
00283 return false;
00284 }
00285 bool ok = accessor->DisconnectWithoutContext (this, cb);
00286 return ok;
00287 }
00288 bool
00289 ObjectBase::TraceDisconnect (std::string name, std::string context, const CallbackBase &cb)
00290 {
00291 TypeId tid = GetInstanceTypeId ();
00292 Ptr<const TraceSourceAccessor> accessor = tid.LookupTraceSourceByName (name);
00293 if (accessor == 0)
00294 {
00295 return false;
00296 }
00297 bool ok = accessor->Disconnect (this, context, cb);
00298 return ok;
00299 }
00300
00301
00302
00303 }