1
0
Fork 0

read from stream by data type, not length

This commit is contained in:
Kevin Matz 2021-06-18 08:46:30 -04:00
parent 2c74470b16
commit 65df669754
12 changed files with 111 additions and 143 deletions

View File

@ -59,7 +59,7 @@ void Appliance::UdpStreamHandler(PDU::Stream stream) {
// the preamble size and postamble size provided. ... ignoring any extra
// octets in the preamble or postamble.
for(int i = RLP::UDP::PREAMBLE_MINIMUM_SIZE; i < preamble.length; i++)
stream->read8();
stream->readType<uint8_t>();
if (!stream->good())
return;

View File

@ -48,11 +48,11 @@ range::range(PDU::Stream stream, data_type t, address_length l) :
uint32_t range::read(PDU::Stream stream, address_length length) {
switch (length) {
case ONE:
return stream->read8();
return stream->readType<uint8_t>();
case TWO:
return stream->read16();
return stream->readType<uint16_t>();
case FOUR:
return stream->read32();
return stream->readType<uint32_t>();
default:
return 0;
}
@ -63,10 +63,10 @@ Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 1) // vectors are 1 octet
{
if (stream->fail()) return;
if (!buffer_->good()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
setHeader(new address_type(buffer_->read8()));
setHeader(new address_type(stream_->readType<uint8_t>()));
if (flags_.hasData) {
switch(vector()) {
@ -82,19 +82,19 @@ Pdu::Pdu(PDU::Stream stream)
void Pdu::readSetData() {
// header may be inherited. check that one exists
if (!header()) {
buffer_->setstate(buffer_->rdstate() | std::ios_base::failbit);
stream_->setstate(stream_->rdstate() | std::ios_base::failbit);
return;
}
auto header = (address_type*)this->header();
auto data = new dmp_set_data();
while(buffer_->good()) {
while(stream_->good()) {
// Property Address
range pr(buffer_, header->type, header->width);
range pr(stream_, header->type, header->width);
if (!buffer_->good() || pr.count * pr.incriment > buffer_->available()) {
buffer_->setstate(buffer_->rdstate() | std::ios_base::failbit);
if (!stream_->good() || pr.count * pr.incriment > stream_->available()) {
stream_->setstate(stream_->rdstate() | std::ios_base::failbit);
break;
}
@ -102,15 +102,15 @@ void Pdu::readSetData() {
std::vector<uint8_t> pd;
pd.resize(pr.address, 0);
for (uint32_t i = 0; i < pr.count * pr.incriment; i ++)
pd.push_back(buffer_->read8());
pd.push_back(stream_->readType<uint8_t>());
// Property Fields
set_property fields(pr, pd);
data->properties.push_back(fields);
//set EOF if buffer insufficient for another property range
if (buffer_->available() < header->width * (header->type == SINGLE? 1 : 3))
buffer_->setstate(buffer_->rdstate() | std::ios_base::eofbit);
if (stream_->available() < header->width * (header->type == SINGLE? 1 : 3))
stream_->setstate(stream_->rdstate() | std::ios_base::eofbit);
}
setData(data);
}

View File

@ -59,8 +59,8 @@ Pdu::Pdu(Stream stream, size_t vector_size)
}
// create a stream buffer for the header and data
buffer_ = Stream(new pdu_stream(stream->data(), len));
if (buffer_->available() != len) {
stream_ = Stream(new pdu_stream(stream->data(), len));
if (stream_->available() != len) {
stream->setstate(stream->rdstate() | std::ios_base::failbit);
return;
}
@ -110,16 +110,16 @@ pdu_data * Pdu::data() {
void Pdu::readLength(Stream stream) {
length_ = stream->read16() & 0x0fff; // high 4 bytes are flags
length_ = stream->readType<uint16_t>() & 0x0fff; // high 4 bytes are flags
if (flags_.hasLength)
length_ = (length_ << 8 ) | stream->read8();
length_ = (length_ << 8 ) | stream->readType<uint8_t>();
}
void Pdu::readVector(uint8_t vector_size) {
vector_ = 0;
for (int o = vector_size - 1; o >= 0; o--)
vector_ |= (buffer_->read8() << (8 * o));
vector_ |= (stream_->readType<uint8_t>() << (8 * o));
}
@ -130,48 +130,5 @@ pdu_flags::pdu_flags(uint8_t val) {
hasData = (val >> 4) & 0b1;
};
uint8_t pdu_stream::read8() {
uint8_t ret = 0;
if (available() < (int)sizeof(ret)) {
setstate(rdstate() | std::ios_base::failbit);
return 0;
}
ret = get();
if (!available())
setstate(rdstate() | std::ios_base::eofbit);
return ret;
}
uint16_t pdu_stream::read16() {
uint16_t ret = 0;
if (available() < (int)sizeof(ret)) {
setstate(rdstate() | std::ios_base::failbit);
return 0;
}
ret |= get() << 8;
ret |= get();
if (!available())
setstate(rdstate() | std::ios_base::eofbit);
return ret;
}
uint32_t pdu_stream::read32() {
uint32_t ret = 0;
if (available() < (int)sizeof(ret)) {
setstate(rdstate() | std::ios_base::failbit);
return 0;
}
ret |= get() << 24;
ret |= get() << 16;
ret |= get() << 6;
ret |= get();
if (!available())
setstate(rdstate() | std::ios_base::eofbit);
return ret;
}
} // PDU
} // ACN

View File

@ -25,7 +25,7 @@
#include <cstdint>
#include <functional>
#include <istream>
#include <iostream>
#include <memory>
#include <vector>
@ -62,23 +62,34 @@ class pdu_buffer
{
public:
pdu_buffer(uint8_t * p, size_t l) { setg(p, p, p + l); };
uint8_t * cur_ptr() { return gptr(); };
uint8_t * in_ptr() { return gptr(); };
};
/**
Input stream of nested PDU
Input/Output stream of nested PDU
*/
class pdu_stream
: public std::basic_istream<uint8_t>
: public std::basic_iostream<uint8_t>
{
public:
pdu_stream(uint8_t * p, size_t l)
: std::basic_istream<uint8_t>(&_buffer)
: std::basic_iostream<uint8_t>(&_buffer)
, _buffer(p, l) { rdbuf(&_buffer); }
uint32_t available() { return _buffer.in_avail(); }
uint8_t * data() { return _buffer.cur_ptr(); };
uint8_t read8 ();
uint16_t read16();
uint32_t read32();
uint8_t * data() { return _buffer.in_ptr(); };
template<typename T> T readType() {
if (available() < sizeof(T)) {
setstate(rdstate() | std::ios_base::failbit);
return 0;
}
T ret = 0;
auto data = reinterpret_cast<uint8_t*>(&ret);
for (int i = sizeof(T); --i >= 0; )
data[i] = get();
if (!available())
setstate(rdstate() | std::ios_base::eofbit);
return ret;
}
private:
pdu_buffer _buffer;
};
@ -108,7 +119,7 @@ public:
pdu_header * header(); // may inherit
pdu_data * data(); // may inherit
shared_ptr<Pdu> parent() {return parent_;}
Stream buffer() {return buffer_;}
Stream stream() {return stream_;}
// setters
void setParent (shared_ptr<Pdu> pdu) {parent_ = pdu;}
@ -120,7 +131,7 @@ protected:
uint32_t vector_;
shared_ptr<Pdu> parent_;
shared_ptr<Pdu> inherit_;
Stream buffer_;
Stream stream_;
// private setters
void setHeader (pdu_header * h) {header_ = h;}
@ -154,7 +165,7 @@ Block<T> readBlock(Stream buffer, shared_ptr<PDU::Pdu> parent = 0) {
shared_ptr<T> pdu(new T(buffer));
if (buffer->fail()) // stream failed during pdu constructor
break;
if (pdu->buffer()->fail()) // pdu buffer errors
if (pdu->stream()->fail()) // pdu buffer errors
continue;
if (parent != 0) // set parent
pdu->setParent(parent);

View File

@ -33,7 +33,7 @@ preamble_t::preamble_t(PDU::Stream stream) {
stream->read(acn_id, sizeof(acn_id));
if (stream->gcount() != 12)
stream->setstate(stream->rdstate() | std::ios_base::failbit);
length = stream->read32();
length = stream->readType<decltype(length)>();
}

View File

@ -30,8 +30,8 @@ namespace RLP {
namespace UDP {
preamble_t::preamble_t(PDU::Stream stream) {
length = stream->read16();
postamble_size = stream->read16();
length = stream->readType<decltype(length)>();
postamble_size = stream->readType<decltype(postamble_size)>();
stream->read(acn_id, 12);
if (stream->gcount() != 12)
stream->setstate(stream->rdstate() | std::ios_base::failbit);

View File

@ -42,10 +42,10 @@ Pdu::Pdu(PDU::Stream stream)
: ACN::PDU::Pdu(stream, 4)
{
if (stream->fail()) return;
if (!buffer_->good()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
setHeader(new rlp_header(buffer_));
setHeader(new rlp_header(stream_));
}
} // RLP

View File

@ -29,19 +29,19 @@ namespace SDT {
namespace UDP {
address_t::address_t(PDU::Stream stream) {
type = stream->read8();
type = stream->readType<decltype(type)>();
if (type != SDT_ADDR_NULL)
port = stream->read16();
port = stream->readType<decltype(port)>();
switch (type) {
case SDT_ADDR_IPV4:
for (unsigned int i = 0; i < sizeof(ipv4); i++)
ipv4[i] = stream->read8();
ipv4[i] = stream->readType<uint8_t>();
break;
case SDT_ADDR_IPV6:
for (unsigned int i = 0; i < sizeof(ipv6); i++)
ipv6[i] = stream->read8();
ipv6[i] = stream->readType<uint8_t>();
break;
case SDT_ADDR_NULL:
default:

View File

@ -28,60 +28,60 @@ namespace ACN {
namespace SDT {
params_t::params_t(PDU::Stream stream) {
Expiry = stream->read8();
reserved = stream->peek() & 0xef;
NAK_Outbound = stream->read8() >> 7;
reserved = stream->read8() & 0xef;
NAKholdoff = stream->read16();
NAKmodulus = stream->read16();
NAKmaxwait = stream->read16();
Expiry = stream->readType<decltype(Expiry)>();
auto packed = stream->readType<uint8_t>();
NAK_Outbound = packed >> 7;
reserved = packed & 0xef;
NAKholdoff = stream->readType<decltype(NAKholdoff)>();
NAKmodulus = stream->readType<decltype(NAKmodulus)>();
NAKmaxwait = stream->readType<decltype(NAKmaxwait)>();
}
join_data_t::join_data_t(PDU::Stream stream) {
mid = stream->read16();
number = stream->read16();
reciprocal = stream->read16();
sequence = stream->read32();
reliable = stream->read32();
mid = stream->readType<decltype(mid)>();
number = stream->readType<decltype(number)>();
reciprocal = stream->readType<decltype(reciprocal)>();
sequence = stream->readType<decltype(sequence)>();
reliable = stream->readType<decltype(reliable)>();
destination = UDP::address_t(stream);
parameters = params_t(stream);
expiry = stream->read8();
expiry = stream->readType<decltype(expiry)>();
}
join_accept_data_t::join_accept_data_t(PDU::Stream stream) {
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
number = stream->read16();
mid = stream->read16();
reliable = stream->read32();
reciprocal = stream->read16();
number = stream->readType<decltype(number)>();
mid = stream->readType<decltype(mid)>();
reliable = stream->readType<decltype(reliable)>();
reciprocal = stream->readType<decltype(reciprocal)>();
}
join_refuse_data_t::join_refuse_data_t(PDU::Stream stream) {
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
number = stream->read16();
mid = stream->read16();
reliable = stream->read32();
code = stream->read8();
number = stream->readType<decltype(number)>();
mid = stream->readType<decltype(mid)>();
reliable = stream->readType<decltype(reliable)>();
code = stream->readType<decltype(code)>();
}
nak_data_t::nak_data_t(PDU::Stream stream) {
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
number = stream->read16();
mid = stream->read16();
reliable = stream->read32();
missed_first = stream->read32();
missed_last = stream->read32();
number = stream->readType<decltype(number)>();
mid = stream->readType<decltype(mid)>();
reliable = stream->readType<decltype(reliable)>();
missed_first = stream->readType<decltype(missed_first)>();
missed_last = stream->readType<decltype(missed_last)>();
}
wrapper_data_t::wrapper_data_t(PDU::Stream stream) {
number = stream->read16();
number = stream->readType<decltype(number)>();
}
@ -151,18 +151,18 @@ Pdu::Pdu(PDU::Stream stream)
}
client_pdu_header_t::client_pdu_header_t(PDU::Stream stream) {
protocol = stream->read32();
association = stream->read16();
protocol = stream->readType<decltype(protocol)>();
association = stream->readType<decltype(association)>();
}
ClientPdu::ClientPdu(PDU::Stream stream)
: PDU::Pdu(stream, 2) // vectors are 2 octets (MID)
{
if (stream->fail()) return;
if (!buffer_->good()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
setHeader(new client_pdu_header_t(buffer_));
setHeader(new client_pdu_header_t(stream_));
}
}; // SDT

View File

@ -31,21 +31,21 @@ frame_header::frame_header(PDU::Stream stream) {
stream->read(source_name, 64);
if (stream->gcount() != 64)
stream->setstate(stream->rdstate() | std::ios_base::failbit);
priority = stream->read8();
sync_address = stream->read16();
sequence_number = stream->read8();
options = stream->read8();
universe = stream->read16();
priority = stream->readType<decltype(priority)>();
sync_address = stream->readType<decltype(sync_address)>();
sequence_number = stream->readType<decltype(sequence_number)>();
options = stream->readType<decltype(options)>();
universe = stream->readType<decltype(universe)>();
}
Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 4) // vectors are 4 octets
{
if (stream->fail()) return;
if (!buffer_->good()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
setHeader(new frame_header(buffer_));
setHeader(new frame_header(stream_));
}
} // DATA

View File

@ -29,8 +29,8 @@ namespace EXTENDED {
frame_sync_header::frame_sync_header(PDU::Stream stream) {
sequence_number = stream->read8();
sync_address = stream->read16();
sequence_number = stream->readType<decltype(sequence_number)>();
sync_address = stream->readType<decltype(sync_address)>();
stream->read(reserved, sizeof(reserved));
if (stream->gcount() != sizeof(reserved))
stream->setstate(stream->rdstate() | std::ios_base::failbit);
@ -51,15 +51,15 @@ Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 4) // vectors are 4 octets
{
if (stream->fail()) return;
if (!buffer_->good()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
switch(vector()) {
case VECTOR_E131_EXTENDED_SYNCHRONIZATION:
setHeader(new frame_sync_header(buffer_));
setHeader(new frame_sync_header(stream_));
break;
case VECTOR_E131_EXTENDED_DISCOVERY:
setHeader(new frame_discovery_header(buffer_));
setHeader(new frame_discovery_header(stream_));
break;
default:
break;
@ -69,8 +69,8 @@ Pdu::Pdu(PDU::Stream stream)
namespace DISCOVERY {
discovery_list_header::discovery_list_header(PDU::Stream stream) {
page = stream->read8();
last_page = stream->read8();
page = stream->readType<decltype(page)>();
last_page = stream->readType<decltype(last_page)>();
}
@ -78,10 +78,10 @@ Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 4) // vectors are 4 octets
{
if (stream->fail()) return;
if (!buffer_->good()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
setHeader(new discovery_list_header(buffer_));
setHeader(new discovery_list_header(stream_));
}
@ -95,7 +95,7 @@ DiscoveredUniverse::DiscoveredUniverse(const std::shared_ptr<EXTENDED::DISCOVERY
auto frame_header = (EXTENDED::frame_discovery_header*)pdu->parent()->header();
description_ = std::string((char*)frame_header->source_name);
universe_ = pdu->buffer()->read16();
universe_ = pdu->stream()->readType<decltype(universe_)>();
}
} // DISCOVERY

View File

@ -80,8 +80,8 @@ Receive VECTOR_ROOT_E131_DATA vector'd packets.
@param root is a shared pointer to the PDU
*/
void Receiver::rootDataHandler(std::shared_ptr<RLP::Pdu> root) {
auto block = PDU::readBlock<DATA::Pdu>(root->buffer(), root);
if (root->buffer()->fail())
auto block = PDU::readBlock<DATA::Pdu>(root->stream(), root);
if (root->stream()->fail())
return;
for(auto const &frame : *block) {
// 6.2.1 E1.31 Data Packet: Vector
@ -105,8 +105,8 @@ Receive VECTOR_ROOT_E131_EXTENDED vector'd packets.
@param root is a shared pointer to the PDU
*/
void Receiver::rootExtendedHandler(std::shared_ptr<RLP::Pdu> root) {
auto block = PDU::readBlock<EXTENDED::Pdu>(root->buffer(), root);
if (root->buffer()->fail())
auto block = PDU::readBlock<EXTENDED::Pdu>(root->stream(), root);
if (root->stream()->fail())
return;
for(auto const &frame : *block) {
switch(frame->vector()) {
@ -126,8 +126,8 @@ void Receiver::rootExtendedHandler(std::shared_ptr<RLP::Pdu> root) {
void Receiver::discoveryPacketHandler(std::shared_ptr<EXTENDED::Pdu> frame) {
auto block = PDU::readBlock<EXTENDED::DISCOVERY::Pdu>(frame->buffer(), frame);
if (frame->buffer()->fail())
auto block = PDU::readBlock<EXTENDED::DISCOVERY::Pdu>(frame->stream(), frame);
if (frame->stream()->fail())
return;
for(auto const &pdu : *block) {
@ -151,11 +151,11 @@ void Receiver::discoveryListHanlder(std::shared_ptr<EXTENDED::DISCOVERY::Pdu> pd
if (!pdu->header())
return;
while(pdu->buffer()->good()) {
while(pdu->stream()->good()) {
auto found = std::shared_ptr<EXTENDED::DISCOVERY::DiscoveredUniverse>
(new EXTENDED::DISCOVERY::DiscoveredUniverse(pdu));
if (pdu->buffer()->fail()) break;
if (!pdu->buffer()->good()) break;
if (pdu->stream()->fail()) break;
if (!pdu->stream()->good()) break;
for (const auto &cb : discoveryCallbacks_)
cb(found);
@ -184,7 +184,7 @@ void Receiver::dataPacketHandler(std::shared_ptr<DATA::Pdu> frame) {
// No priority outside the range of 0 to 200 shall be transmitted on
// the network.
if (source->priority() > 200)
frame->buffer()->setstate(frame->buffer()->rdstate() |
frame->stream()->setstate(frame->stream()->rdstate() |
std::ios_base::failbit);
// 6.2.6 E1.31 Data Packet: Options
@ -238,8 +238,8 @@ void Receiver::dataPacketHandler(std::shared_ptr<DATA::Pdu> frame) {
// TODO: do something with merging and arbitration
// PDU data will be a block of DMP
auto block = PDU::readBlock<DMP::Pdu>(frame->buffer(), frame);
if (frame->buffer()->fail())
auto block = PDU::readBlock<DMP::Pdu>(frame->stream(), frame);
if (frame->stream()->fail())
return;
for (auto const &dmp : *block) {
// 7.2 DMP Layer: Vector