libuav original
Dependents: UAVCAN UAVCAN_Subscriber
uc_global_data_type_registry.cpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #include <uavcan/node/global_data_type_registry.hpp> 00006 #include <uavcan/debug.hpp> 00007 #include <cassert> 00008 #include <cstdlib> 00009 00010 namespace uavcan 00011 { 00012 00013 GlobalDataTypeRegistry::List* GlobalDataTypeRegistry::selectList(DataTypeKind kind) const 00014 { 00015 if (kind == DataTypeKindMessage) 00016 { 00017 return &msgs_; 00018 } 00019 else if (kind == DataTypeKindService) 00020 { 00021 return &srvs_; 00022 } 00023 else 00024 { 00025 UAVCAN_ASSERT(0); 00026 return UAVCAN_NULLPTR; 00027 } 00028 } 00029 00030 GlobalDataTypeRegistry::RegistrationResult GlobalDataTypeRegistry::remove(Entry* dtd) 00031 { 00032 if (!dtd) 00033 { 00034 UAVCAN_ASSERT(0); 00035 return RegistrationResultInvalidParams; 00036 } 00037 if (isFrozen()) 00038 { 00039 return RegistrationResultFrozen; 00040 } 00041 00042 List* list = selectList(dtd->descriptor.getKind()); 00043 if (!list) 00044 { 00045 return RegistrationResultInvalidParams; 00046 } 00047 00048 list->remove(dtd); // If this call came from regist<>(), that would be enough 00049 Entry* p = list->get(); // But anyway 00050 while (p) 00051 { 00052 Entry* const next = p->getNextListNode(); 00053 if (p->descriptor.match(dtd->descriptor.getKind(), dtd->descriptor.getFullName())) 00054 { 00055 list->remove(p); 00056 } 00057 p = next; 00058 } 00059 return RegistrationResultOk; 00060 } 00061 00062 GlobalDataTypeRegistry::RegistrationResult GlobalDataTypeRegistry::registImpl(Entry* dtd) 00063 { 00064 if (!dtd || !dtd->descriptor.isValid()) 00065 { 00066 UAVCAN_ASSERT(0); 00067 return RegistrationResultInvalidParams; 00068 } 00069 if (isFrozen()) 00070 { 00071 return RegistrationResultFrozen; 00072 } 00073 00074 List* list = selectList(dtd->descriptor.getKind()); 00075 if (!list) 00076 { 00077 return RegistrationResultInvalidParams; 00078 } 00079 00080 { // Collision check 00081 Entry* p = list->get(); 00082 while (p) 00083 { 00084 if (p->descriptor.getID() == dtd->descriptor.getID()) // ID collision 00085 { 00086 return RegistrationResultCollision; 00087 } 00088 if (!std::strncmp(p->descriptor.getFullName(), dtd->descriptor.getFullName(), 00089 DataTypeDescriptor::MaxFullNameLen)) // Name collision 00090 { 00091 return RegistrationResultCollision; 00092 } 00093 p = p->getNextListNode(); 00094 } 00095 } 00096 #if UAVCAN_DEBUG 00097 const unsigned len_before = list->getLength(); 00098 #endif 00099 list->insertBefore(dtd, EntryInsertionComparator(dtd)); 00100 00101 #if UAVCAN_DEBUG 00102 { // List integrity check 00103 const unsigned len_after = list->getLength(); 00104 if ((len_before + 1) != len_after) 00105 { 00106 UAVCAN_ASSERT(0); 00107 std::abort(); 00108 } 00109 } 00110 { // Order check 00111 Entry* p = list->get(); 00112 int id = -1; 00113 while (p) 00114 { 00115 if (id >= p->descriptor.getID().get()) 00116 { 00117 UAVCAN_ASSERT(0); 00118 std::abort(); 00119 } 00120 id = p->descriptor.getID().get(); 00121 p = p->getNextListNode(); 00122 } 00123 } 00124 #endif 00125 return RegistrationResultOk; 00126 } 00127 00128 GlobalDataTypeRegistry& GlobalDataTypeRegistry::instance() 00129 { 00130 static GlobalDataTypeRegistry singleton; 00131 return singleton; 00132 } 00133 00134 void GlobalDataTypeRegistry::freeze() 00135 { 00136 if (!frozen_) 00137 { 00138 frozen_ = true; 00139 UAVCAN_TRACE("GlobalDataTypeRegistry", "Frozen; num msgs: %u, num srvs: %u", 00140 getNumMessageTypes(), getNumServiceTypes()); 00141 } 00142 } 00143 00144 const DataTypeDescriptor* GlobalDataTypeRegistry::find(const char* name) const 00145 { 00146 const DataTypeDescriptor* desc = find(DataTypeKindMessage, name); 00147 if (desc == UAVCAN_NULLPTR) 00148 { 00149 desc = find(DataTypeKindService, name); 00150 } 00151 return desc; 00152 } 00153 00154 const DataTypeDescriptor* GlobalDataTypeRegistry::find(DataTypeKind kind, const char* name) const 00155 { 00156 if (!name) 00157 { 00158 UAVCAN_ASSERT(0); 00159 return UAVCAN_NULLPTR; 00160 } 00161 const List * list = selectList(kind); 00162 if (!list) 00163 { 00164 UAVCAN_ASSERT(0); 00165 return UAVCAN_NULLPTR; 00166 } 00167 Entry* p = list->get(); 00168 while (p) 00169 { 00170 if (p->descriptor.match(kind, name)) 00171 { 00172 return &p->descriptor; 00173 } 00174 p = p->getNextListNode(); 00175 } 00176 return UAVCAN_NULLPTR; 00177 } 00178 00179 const DataTypeDescriptor* GlobalDataTypeRegistry::find(DataTypeKind kind, DataTypeID dtid) const 00180 { 00181 const List * list = selectList(kind); 00182 if (!list) 00183 { 00184 UAVCAN_ASSERT(0); 00185 return UAVCAN_NULLPTR; 00186 } 00187 Entry* p = list->get(); 00188 while (p) 00189 { 00190 if (p->descriptor.match(kind, dtid)) 00191 { 00192 return &p->descriptor; 00193 } 00194 p = p->getNextListNode(); 00195 } 00196 return UAVCAN_NULLPTR; 00197 } 00198 00199 }
Generated on Tue Jul 12 2022 17:17:35 by 1.7.2