GDTR registration error codes

This commit is contained in:
Pavel Kirienko
2014-02-28 12:26:46 +04:00
parent 61a9adb369
commit eb573ce04e
4 changed files with 79 additions and 29 deletions
+1
View File
@@ -118,6 +118,7 @@ public:
bool match(DataTypeKind kind, const char* name) const;
bool match(DataTypeKind kind, uint16_t id) const;
bool match(const char* name) const { return match(kind_, name); }
std::string toString() const;
@@ -41,6 +41,16 @@ class GlobalDataTypeRegistry : Noncopyable
}
};
public:
enum RegistResult
{
RegistResultOk,
RegistResultCollision,
RegistResultInvalidParams,
RegistResultFrozen
};
private:
typedef LinkedListRoot<Entry> List;
List msgs_;
List srvs_;
@@ -51,25 +61,29 @@ class GlobalDataTypeRegistry : Noncopyable
const List* selectList(DataTypeKind kind) const;
List* selectList(DataTypeKind kind);
void remove(Entry* dtd);
bool add(Entry* dtd);
RegistResult remove(Entry* dtd);
RegistResult registImpl(Entry* dtd);
public:
static GlobalDataTypeRegistry& instance();
/// Last call wins
template <typename Type>
bool assign(uint16_t id)
RegistResult regist(uint16_t id)
{
if (isFrozen())
return false;
return RegistResultFrozen;
static Entry entry;
remove(&entry);
const RegistResult remove_res = remove(&entry);
if (remove_res != RegistResultOk)
return remove_res;
entry = Entry(DataTypeKind(Type::DataTypeKind), id, Type::getDataTypeSignature(), Type::getDataTypeName());
return add(&entry);
return registImpl(&entry);
}
/// Further calls to add() will fail
/// Further calls to regist<>() will fail
void freeze() { frozen_ = true; }
bool isFrozen() const { return frozen_; }
@@ -101,7 +115,10 @@ struct DefaultDataTypeRegistrator
{
DefaultDataTypeRegistrator()
{
if (!GlobalDataTypeRegistry::instance().assign<Type>(Type::DefaultDataTypeID))
const GlobalDataTypeRegistry::RegistResult res =
GlobalDataTypeRegistry::instance().regist<Type>(Type::DefaultDataTypeID);
if (res != GlobalDataTypeRegistry::RegistResultOk)
{
#if UAVCAN_EXCEPTIONS
throw std::logic_error("Type registration failed");
+24 -13
View File
@@ -33,15 +33,19 @@ GlobalDataTypeRegistry::List* GlobalDataTypeRegistry::selectList(DataTypeKind ki
}
}
void GlobalDataTypeRegistry::remove(Entry* dtd)
GlobalDataTypeRegistry::RegistResult GlobalDataTypeRegistry::remove(Entry* dtd)
{
assert(dtd);
if (!dtd)
{
assert(0);
return RegistResultInvalidParams;
}
if (isFrozen())
return;
return RegistResultFrozen;
List* list = selectList(dtd->descriptor.getKind());
if (!list)
return;
return RegistResultInvalidParams;
Entry* p = list->get();
while (p)
@@ -51,24 +55,31 @@ void GlobalDataTypeRegistry::remove(Entry* dtd)
list->remove(dtd);
p = next;
}
return RegistResultOk;
}
bool GlobalDataTypeRegistry::add(Entry* dtd)
GlobalDataTypeRegistry::RegistResult GlobalDataTypeRegistry::registImpl(Entry* dtd)
{
assert(dtd);
if (!dtd || (dtd->descriptor.getID() > DataTypeDescriptor::MaxDataTypeID))
{
assert(0);
return RegistResultInvalidParams;
}
if (isFrozen())
return false;
return RegistResultFrozen;
List* list = selectList(dtd->descriptor.getKind());
if (!list)
return false;
return RegistResultInvalidParams;
{ // Collision check
Entry* p = list->get();
while (p)
{
if (p->descriptor.getID() == dtd->descriptor.getID()) // ID collision
return false;
return RegistResultCollision;
if (p->descriptor.match(dtd->descriptor.getName())) // Name collision
return RegistResultCollision;
p = p->getNextListNode();
}
}
@@ -90,7 +101,7 @@ bool GlobalDataTypeRegistry::add(Entry* dtd)
}
}
#endif
return true;
return RegistResultOk;
}
GlobalDataTypeRegistry& GlobalDataTypeRegistry::instance()
@@ -102,7 +113,7 @@ GlobalDataTypeRegistry& GlobalDataTypeRegistry::instance()
const DataTypeDescriptor* GlobalDataTypeRegistry::find(DataTypeKind kind, const char* name) const
{
const List* list = selectList(kind);
if (list == NULL)
if (!list)
{
assert(0);
return NULL;
@@ -123,7 +134,7 @@ DataTypeSignature GlobalDataTypeRegistry::computeAggregateSignature(DataTypeKind
assert(isFrozen()); // Computing the signature if the registry is not frozen is pointless
const List* list = selectList(kind);
if (list == NULL)
if (!list)
{
assert(0);
return DataTypeSignature();
@@ -174,7 +185,7 @@ void GlobalDataTypeRegistry::getDataTypeIDMask(DataTypeKind kind, DataTypeIDMask
{
mask.reset();
const List* list = selectList(kind);
if (list == NULL)
if (!list)
{
assert(0);
return;
+29 -8
View File
@@ -47,6 +47,14 @@ namespace
static const char* getDataTypeName() { return "foo.DataTypeD"; }
};
struct DataTypeBNameCollision
{
enum { DefaultDataTypeID = 999 };
enum { DataTypeKind = uavcan::DataTypeKindMessage };
static uavcan::DataTypeSignature getDataTypeSignature() { return uavcan::DataTypeSignature(963); }
static const char* getDataTypeName() { return "my_namespace.DataTypeB"; }
};
template <typename Type>
uavcan::DataTypeDescriptor extractDescriptor(uint16_t dtid = Type::DefaultDataTypeID)
@@ -94,7 +102,8 @@ TEST(GlobalDataTypeRegistry, Basic)
/*
* Runtime registrations
*/
ASSERT_TRUE(GlobalDataTypeRegistry::instance().assign<DataTypeAService>(DataTypeAService::DefaultDataTypeID));
ASSERT_EQ(GlobalDataTypeRegistry::RegistResultOk,
GlobalDataTypeRegistry::instance().regist<DataTypeAService>(DataTypeAService::DefaultDataTypeID));
ASSERT_EQ(2, GlobalDataTypeRegistry::instance().getNumMessageTypes());
ASSERT_EQ(1, GlobalDataTypeRegistry::instance().getNumServiceTypes());
@@ -107,8 +116,8 @@ TEST(GlobalDataTypeRegistry, Basic)
/*
* Runtime re-registration
*/
ASSERT_TRUE(GlobalDataTypeRegistry::instance().assign<DataTypeAService>(147));
ASSERT_TRUE(GlobalDataTypeRegistry::instance().assign<DataTypeB>(741));
ASSERT_EQ(GlobalDataTypeRegistry::RegistResultOk, GlobalDataTypeRegistry::instance().regist<DataTypeAService>(147));
ASSERT_EQ(GlobalDataTypeRegistry::RegistResultOk, GlobalDataTypeRegistry::instance().regist<DataTypeB>(741));
ASSERT_EQ(2, GlobalDataTypeRegistry::instance().getNumMessageTypes());
ASSERT_EQ(1, GlobalDataTypeRegistry::instance().getNumServiceTypes());
@@ -127,8 +136,15 @@ TEST(GlobalDataTypeRegistry, Basic)
/*
* These types will be necessary for the aggregate signature test
*/
ASSERT_FALSE(GlobalDataTypeRegistry::instance().assign<DataTypeC>(741)); // COLLISION - error
ASSERT_TRUE(GlobalDataTypeRegistry::instance().assign<DataTypeC>(DataTypeC::DefaultDataTypeID));
ASSERT_EQ(GlobalDataTypeRegistry::RegistResultCollision,
GlobalDataTypeRegistry::instance().regist<DataTypeC>(741)); // ID COLLISION
ASSERT_EQ(GlobalDataTypeRegistry::RegistResultCollision,
GlobalDataTypeRegistry::instance().regist<DataTypeBNameCollision>(
DataTypeBNameCollision::DefaultDataTypeID)); // NAME COLLISION
ASSERT_EQ(GlobalDataTypeRegistry::RegistResultOk,
GlobalDataTypeRegistry::instance().regist<DataTypeC>(DataTypeC::DefaultDataTypeID));
uavcan::DefaultDataTypeRegistrator<DataTypeD> reg_DataTypeD;
GlobalDataTypeRegistry::instance().getDataTypeIDMask(uavcan::DataTypeKindMessage, dtmask);
@@ -149,9 +165,14 @@ TEST(GlobalDataTypeRegistry, Basic)
*/
GlobalDataTypeRegistry::instance().freeze();
ASSERT_FALSE(GlobalDataTypeRegistry::instance().assign<DataTypeAService>(555)); // Rejected
ASSERT_FALSE(GlobalDataTypeRegistry::instance().assign<DataTypeAMessage>(999)); // Rejected
ASSERT_FALSE(GlobalDataTypeRegistry::instance().assign<DataTypeB>(888)); // Rejected
ASSERT_EQ(GlobalDataTypeRegistry::RegistResultFrozen,
GlobalDataTypeRegistry::instance().regist<DataTypeAService>(555)); // Rejected
ASSERT_EQ(GlobalDataTypeRegistry::RegistResultFrozen,
GlobalDataTypeRegistry::instance().regist<DataTypeAMessage>(999)); // Rejected
ASSERT_EQ(GlobalDataTypeRegistry::RegistResultFrozen,
GlobalDataTypeRegistry::instance().regist<DataTypeB>(888)); // Rejected
/*
* Searching