Type safe DataTypeID class

This commit is contained in:
Pavel Kirienko
2014-03-11 21:29:35 +04:00
parent befea376c2
commit 62ea9e2746
11 changed files with 73 additions and 46 deletions
+34 -7
View File
@@ -23,6 +23,36 @@ enum DataTypeKind
NumDataTypeKinds
};
class DataTypeID
{
uint16_t value_;
public:
enum { Max = 1023 };
DataTypeID() : value_(0xFFFF) { }
DataTypeID(uint16_t id)
: value_(id)
{
assert(isValid());
}
bool isValid() const { return value_ <= Max; }
uint16_t get() const { return value_; }
bool operator==(DataTypeID rhs) const { return value_ == rhs.value_; }
bool operator!=(DataTypeID rhs) const { return value_ != rhs.value_; }
bool operator<(DataTypeID rhs) const { return value_ < rhs.value_; }
bool operator>(DataTypeID rhs) const { return value_ > rhs.value_; }
bool operator<=(DataTypeID rhs) const { return value_ <= rhs.value_; }
bool operator>=(DataTypeID rhs) const { return value_ >= rhs.value_; }
};
/**
* CRC-64-WE
* Description: http://reveng.sourceforge.net/crc-catalogue/17plus.htm#crc.cat-bits.64
@@ -89,39 +119,36 @@ public:
class DataTypeDescriptor
{
DataTypeKind kind_;
uint16_t id_;
DataTypeID id_;
DataTypeSignature signature_;
const char* full_name_;
public:
enum { MaxDataTypeID = 1023 };
enum { MaxFullNameLen = 80 };
DataTypeDescriptor()
: kind_(DataTypeKind(0))
, id_(0)
, full_name_("")
{ }
DataTypeDescriptor(DataTypeKind kind, uint16_t id, const DataTypeSignature& signature, const char* name)
DataTypeDescriptor(DataTypeKind kind, DataTypeID id, const DataTypeSignature& signature, const char* name)
: kind_(kind)
, id_(id)
, signature_(signature)
, full_name_(name)
{
assert(id <= MaxDataTypeID);
assert(kind < NumDataTypeKinds);
assert(name);
assert(std::strlen(name) <= MaxFullNameLen);
}
DataTypeKind getKind() const { return kind_; }
uint16_t getID() const { return id_; }
DataTypeID getID() const { return id_; }
const DataTypeSignature& getSignature() const { return signature_; }
const char* getFullName() const { return full_name_; }
bool match(DataTypeKind kind, const char* name) const;
bool match(DataTypeKind kind, uint16_t id) const;
bool match(DataTypeKind kind, DataTypeID id) const;
std::string toString() const;
@@ -19,7 +19,7 @@
namespace uavcan
{
typedef std::bitset<DataTypeDescriptor::MaxDataTypeID + 1> DataTypeIDMask;
typedef std::bitset<DataTypeID::Max + 1> DataTypeIDMask;
class GlobalDataTypeRegistry : Noncopyable
{
@@ -29,14 +29,14 @@ class GlobalDataTypeRegistry : Noncopyable
Entry() { }
Entry(DataTypeKind kind, uint16_t id, const DataTypeSignature& signature, const char* name)
Entry(DataTypeKind kind, DataTypeID id, const DataTypeSignature& signature, const char* name)
: descriptor(kind, id, signature, name)
{ }
};
struct EntryInsertionComparator
{
const uint16_t id;
const DataTypeID id;
EntryInsertionComparator(Entry* dtd) : id(dtd->descriptor.getID()) { }
bool operator()(const Entry* entry) const
{
@@ -73,7 +73,7 @@ public:
/// Last call wins
template <typename Type>
RegistResult regist(uint16_t id)
RegistResult regist(DataTypeID id)
{
if (isFrozen())
return RegistResultFrozen;
@@ -26,9 +26,9 @@ class Dispatcher : Noncopyable
class DataTypeIDInsertionComparator
{
const uint16_t id_;
const DataTypeID id_;
public:
DataTypeIDInsertionComparator(uint16_t id) : id_(id) { }
DataTypeIDInsertionComparator(DataTypeID id) : id_(id) { }
bool operator()(const TransferListenerBase* listener) const
{
assert(listener);
@@ -20,7 +20,7 @@ class Frame
{
uint8_t payload_[sizeof(CanFrame::data)];
TransferType transfer_type_;
uint_fast16_t data_type_id_;
DataTypeID data_type_id_;
uint_fast8_t payload_len_;
NodeID src_node_id_;
NodeID dst_node_id_;
@@ -33,14 +33,13 @@ public:
Frame()
: transfer_type_(TransferType(NumTransferTypes)) // That is invalid value
, data_type_id_(0)
, payload_len_(0)
, frame_index_(0)
, transfer_id_(0)
, last_frame_(false)
{ }
Frame(uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id,
Frame(DataTypeID data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id,
uint_fast8_t frame_index, TransferID transfer_id, bool last_frame = false)
: transfer_type_(transfer_type)
, data_type_id_(data_type_id)
@@ -52,7 +51,7 @@ public:
, last_frame_(last_frame)
{
assert((transfer_type == TransferTypeMessageBroadcast) == dst_node_id.isBroadcast());
assert(data_type_id <= DataTypeDescriptor::MaxDataTypeID);
assert(data_type_id.isValid());
assert(src_node_id != dst_node_id);
assert(frame_index <= MaxIndex);
}
@@ -64,7 +63,7 @@ public:
const uint8_t* getPayloadPtr() const { return payload_; }
TransferType getTransferType() const { return transfer_type_; }
uint_fast16_t getDataTypeID() const { return data_type_id_; }
DataTypeID getDataTypeID() const { return data_type_id_; }
NodeID getSrcNodeID() const { return src_node_id_; }
NodeID getDstNodeID() const { return dst_node_id_; }
TransferID getTransferID() const { return transfer_id_; }
@@ -17,17 +17,16 @@ namespace uavcan
UAVCAN_PACKED_BEGIN
class OutgoingTransferRegistryKey
{
uint16_t data_type_id_;
DataTypeID data_type_id_;
uint8_t transfer_type_;
NodeID destination_node_id_; ///< Not applicable for message broadcasting
public:
OutgoingTransferRegistryKey()
: data_type_id_(0xFFFF)
, transfer_type_(0xFF)
: transfer_type_(0xFF)
{ }
OutgoingTransferRegistryKey(uint16_t data_type_id, TransferType transfer_type, NodeID destination_node_id)
OutgoingTransferRegistryKey(DataTypeID data_type_id, TransferType transfer_type, NodeID destination_node_id)
: data_type_id_(data_type_id)
, transfer_type_(transfer_type)
, destination_node_id_(destination_node_id)
+3 -2
View File
@@ -45,7 +45,7 @@ bool DataTypeDescriptor::match(DataTypeKind kind, const char* name) const
return (kind_ == kind) && !std::strcmp(full_name_, name);
}
bool DataTypeDescriptor::match(DataTypeKind kind, uint16_t id) const
bool DataTypeDescriptor::match(DataTypeKind kind, DataTypeID id) const
{
return (kind_ == kind) && (id_ == id);
}
@@ -61,7 +61,8 @@ std::string DataTypeDescriptor::toString() const
}
std::ostringstream os;
os << full_name_ << ":" << id_ << kindch << ":" << std::hex << std::setfill('0') << std::setw(16) << signature_.get();
os << full_name_ << ":" << id_.get() << kindch << ":" << std::hex
<< std::setfill('0') << std::setw(16) << signature_.get();
return os.str();
}
+10 -9
View File
@@ -62,7 +62,7 @@ GlobalDataTypeRegistry::RegistResult GlobalDataTypeRegistry::remove(Entry* dtd)
GlobalDataTypeRegistry::RegistResult GlobalDataTypeRegistry::registImpl(Entry* dtd)
{
if (!dtd || (dtd->descriptor.getID() > DataTypeDescriptor::MaxDataTypeID))
if (!dtd || (dtd->descriptor.getID() > DataTypeID::Max))
{
assert(0);
return RegistResultInvalidParams;
@@ -93,12 +93,12 @@ GlobalDataTypeRegistry::RegistResult GlobalDataTypeRegistry::registImpl(Entry* d
int id = -1;
while (p)
{
if (id >= p->descriptor.getID())
if (id >= p->descriptor.getID().get())
{
assert(0);
std::abort();
}
id = p->descriptor.getID();
id = p->descriptor.getID().get();
p = p->getNextListNode();
}
}
@@ -158,8 +158,9 @@ DataTypeSignature GlobalDataTypeRegistry::computeAggregateSignature(DataTypeKind
while (p)
{
const DataTypeDescriptor& desc = p->descriptor;
const int dtid = desc.getID().get();
if (inout_id_mask[desc.getID()])
if (inout_id_mask[dtid])
{
if (signature_initialized)
signature.extend(desc.getSignature());
@@ -168,16 +169,16 @@ DataTypeSignature GlobalDataTypeRegistry::computeAggregateSignature(DataTypeKind
signature_initialized = true;
}
assert(prev_dtid < desc.getID()); // Making sure that list is ordered properly
assert(prev_dtid < dtid); // Making sure that list is ordered properly
prev_dtid++;
while (prev_dtid < desc.getID())
while (prev_dtid < dtid)
inout_id_mask[prev_dtid++] = false; // Erasing bits for missing types
assert(prev_dtid == desc.getID());
assert(prev_dtid == dtid);
p = p->getNextListNode();
}
prev_dtid++;
while (prev_dtid <= DataTypeDescriptor::MaxDataTypeID)
while (prev_dtid <= DataTypeID::Max)
inout_id_mask[prev_dtid++] = false;
return signature;
@@ -196,7 +197,7 @@ void GlobalDataTypeRegistry::getDataTypeIDMask(DataTypeKind kind, DataTypeIDMask
while (p)
{
assert(p->descriptor.getKind() == kind);
mask[p->descriptor.getID()] = true;
mask[p->descriptor.getID().get()] = true;
p = p->getNextListNode();
}
}
+4 -4
View File
@@ -122,7 +122,7 @@ bool Frame::compile(CanFrame& out_can_frame) const
bitpack<4, 6>(frame_index_) |
bitpack<10, 7>(src_node_id_.get()) |
bitpack<17, 2>(transfer_type_) |
bitpack<19, 10>(data_type_id_);
bitpack<19, 10>(data_type_id_.get());
switch (transfer_type_)
{
@@ -159,7 +159,7 @@ bool Frame::isValid() const
((transfer_type_ == TransferTypeMessageBroadcast) != dst_node_id_.isBroadcast()) ||
(transfer_type_ >= NumTransferTypes) ||
(payload_len_ > getMaxPayloadLen()) ||
(data_type_id_ > DataTypeDescriptor::MaxDataTypeID);
(!data_type_id_.isValid());
return !invalid;
}
@@ -192,8 +192,8 @@ std::string Frame::toString() const
static const int BUFLEN = 100;
char buf[BUFLEN];
int ofs = std::snprintf(buf, BUFLEN, "dtid=%i tt=%i snid=%i dnid=%i idx=%i last=%i tid=%i payload=[",
int(data_type_id_), int(transfer_type_), int(src_node_id_.get()), int(dst_node_id_.get()),
int(frame_index_), int(last_frame_), int(transfer_id_.get()));
int(data_type_id_.get()), int(transfer_type_), int(src_node_id_.get()),
int(dst_node_id_.get()), int(frame_index_), int(last_frame_), int(transfer_id_.get()));
for (int i = 0; i < payload_len_; i++)
{
+1 -1
View File
@@ -96,7 +96,7 @@ TEST(DataTypeSignature, Correctness)
TEST(DataTypeDescriptor, ToString)
{
uavcan::DataTypeDescriptor desc;
ASSERT_EQ(":0s:0000000000000000", desc.toString());
ASSERT_EQ(":65535s:0000000000000000", desc.toString());
desc = uavcan::DataTypeDescriptor(uavcan::DataTypeKindMessage, 123,
uavcan::DataTypeSignature(0xdeadbeef1234), "Bar");
+7 -7
View File
@@ -43,7 +43,7 @@ TEST(Frame, FrameParseCompile)
EXPECT_EQ(29, frame.getIndex());
EXPECT_EQ(uavcan::NodeID(42), frame.getSrcNodeID());
EXPECT_EQ(uavcan::TransferTypeMessageBroadcast, frame.getTransferType());
EXPECT_EQ(456, frame.getDataTypeID());
EXPECT_EQ(456, frame.getDataTypeID().get());
EXPECT_EQ(payload_string.length(), frame.getPayloadLen());
EXPECT_TRUE(std::equal(frame.getPayloadPtr(), frame.getPayloadPtr() + frame.getPayloadLen(),
@@ -100,7 +100,7 @@ TEST(Frame, FrameParsing)
ASSERT_EQ(0, frame.getIndex());
ASSERT_EQ(NodeID(42), frame.getSrcNodeID());
ASSERT_EQ(NodeID::Broadcast, frame.getDstNodeID());
ASSERT_EQ(456, frame.getDataTypeID());
ASSERT_EQ(456, frame.getDataTypeID().get());
ASSERT_EQ(TransferID(2), frame.getTransferID());
ASSERT_EQ(uavcan::TransferTypeMessageBroadcast, frame.getTransferType());
ASSERT_EQ(sizeof(CanFrame::data), frame.getMaxPayloadLen());
@@ -125,7 +125,7 @@ TEST(Frame, FrameParsing)
ASSERT_EQ(0, frame.getIndex());
ASSERT_EQ(NodeID(42), frame.getSrcNodeID());
ASSERT_EQ(NodeID(127), frame.getDstNodeID());
ASSERT_EQ(456, frame.getDataTypeID());
ASSERT_EQ(456, frame.getDataTypeID().get());
ASSERT_EQ(TransferID(2), frame.getTransferID());
ASSERT_EQ(uavcan::TransferTypeMessageUnicast, frame.getTransferType());
ASSERT_EQ(sizeof(CanFrame::data) - 1, frame.getMaxPayloadLen());
@@ -199,7 +199,7 @@ TEST(Frame, RxFrameParse)
ASSERT_TRUE(rx_frame.parse(can_rx_frame));
ASSERT_EQ(123, rx_frame.getMonotonicTimestamp().toUSec());
ASSERT_EQ(2, rx_frame.getIfaceIndex());
ASSERT_EQ(456, rx_frame.getDataTypeID());
ASSERT_EQ(456, rx_frame.getDataTypeID().get());
ASSERT_EQ(uavcan::TransferTypeMessageBroadcast, rx_frame.getTransferType());
}
@@ -211,10 +211,10 @@ TEST(Frame, FrameToString)
// RX frame default
RxFrame rx_frame;
EXPECT_EQ("dtid=0 tt=4 snid=255 dnid=255 idx=0 last=0 tid=0 payload=[] ts_m=0.000000 ts_utc=0.000000 iface=0", rx_frame.toString());
EXPECT_EQ("dtid=65535 tt=4 snid=255 dnid=255 idx=0 last=0 tid=0 payload=[] ts_m=0.000000 ts_utc=0.000000 iface=0", rx_frame.toString());
// RX frame max len
rx_frame = RxFrame(Frame(uavcan::DataTypeDescriptor::MaxDataTypeID, uavcan::TransferTypeMessageUnicast,
rx_frame = RxFrame(Frame(uavcan::DataTypeID::Max, uavcan::TransferTypeMessageUnicast,
uavcan::NodeID::Max, uavcan::NodeID::Max - 1, Frame::MaxIndex,
uavcan::TransferID::Max, true),
uavcan::MonotonicTime::getMax(), uavcan::UtcTime::getMax(), 3);
@@ -230,7 +230,7 @@ TEST(Frame, FrameToString)
// Plain frame default
Frame frame;
EXPECT_EQ("dtid=0 tt=4 snid=255 dnid=255 idx=0 last=0 tid=0 payload=[]", frame.toString());
EXPECT_EQ("dtid=65535 tt=4 snid=255 dnid=255 idx=0 last=0 tid=0 payload=[]", frame.toString());
// Plain frame max len
frame = rx_frame;
@@ -98,7 +98,7 @@ struct Transfer
<< " tid=" << int(transfer_id.get())
<< " snid=" << int(src_node_id.get())
<< " dnid=" << int(dst_node_id.get())
<< " dtid=" << int(data_type.getID())
<< " dtid=" << int(data_type.getID().get())
<< "\n\t'" << payload << "'";
return os.str();
}