the OTP PDU, Much simpler than the ACN PDU.
This commit is contained in:
parent
a5710d1bb5
commit
818a0891a3
|
@ -58,6 +58,8 @@ set(SOURCE_FILES
|
|||
dmx/universe.cpp
|
||||
dmx/universe.h
|
||||
otp/opt.h
|
||||
otp/pdu.h
|
||||
otp/pdu.cpp
|
||||
rdm/controller.h
|
||||
rdm/controller.cpp
|
||||
rdm/device.h
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
otp/pdu.cpp
|
||||
|
||||
Copyright (c) 2021 Kevin Matz (kevin.matz@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "pdu.h"
|
||||
|
||||
namespace OTP::PDU {
|
||||
|
||||
/**
|
||||
* @brief pdu::pdu
|
||||
*/
|
||||
pdu::pdu()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief pdu::~pdu
|
||||
*/
|
||||
pdu::~pdu()
|
||||
{
|
||||
if (data) delete data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief pdu::streamSize
|
||||
* @return
|
||||
*/
|
||||
size_t pdu::streamSize() const
|
||||
{
|
||||
size_t s = 4; // vector + length
|
||||
|
||||
if (data)
|
||||
s += data->streamSize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief pdu::iStream
|
||||
* @param stream
|
||||
*/
|
||||
void pdu::iStream(Stream stream)
|
||||
{
|
||||
uint16_t length;
|
||||
|
||||
*stream >> vector;
|
||||
*stream >> length;
|
||||
|
||||
// length includes the vector and length.
|
||||
// the remainder of the length is data
|
||||
length -= 4;
|
||||
|
||||
// abort if the remaining PDU length isn't available
|
||||
if (!stream->good() || stream->available() < length)
|
||||
return stream->setstate(std::ios_base::failbit);
|
||||
|
||||
// create a stream buffer for the data
|
||||
stream_ = Stream(new ACN::PDU::pdu_stream(stream->data(), length));
|
||||
if (stream_->available() != length)
|
||||
return stream->setstate(std::ios_base::failbit);
|
||||
|
||||
// fast-forward the input stream
|
||||
stream->ignore(length);
|
||||
|
||||
if (!stream->available())
|
||||
return stream->setstate(std::ios_base::eofbit);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief pdu::oStream
|
||||
* @param stream
|
||||
*/
|
||||
void pdu::oStream(Stream stream) const
|
||||
{
|
||||
uint16_t length = streamSize();
|
||||
|
||||
*stream << vector;
|
||||
*stream << length;
|
||||
|
||||
data->oStream(stream);
|
||||
}
|
||||
|
||||
} // namespace OTP::PDU
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
otp/pdu.h
|
||||
|
||||
Copyright (c) 2021 Kevin Matz (kevin.matz@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "acn/pdu-stream.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace OTP {
|
||||
namespace PDU {
|
||||
|
||||
using ACN::PDU::Stream;
|
||||
using ACN::PDU::pdu_stream_object;
|
||||
|
||||
/**
|
||||
* @brief The pdu_data struct
|
||||
*/
|
||||
struct pdu_data : public pdu_stream_object {};
|
||||
|
||||
|
||||
class pdu;
|
||||
using Pdu = std::shared_ptr<pdu>;
|
||||
|
||||
|
||||
template<class T>
|
||||
struct Block
|
||||
: public pdu_data
|
||||
{
|
||||
Block() {
|
||||
static_assert(std::is_base_of<OTP::PDU::pdu, T>::value,
|
||||
"type parameter of ACN::PDU::Block must derive from OTP::PDU::Pdu");
|
||||
}
|
||||
std::shared_ptr<std::vector<std::shared_ptr<T>>> members
|
||||
= std::shared_ptr<std::vector<std::shared_ptr<T>>>
|
||||
(new std::vector<std::shared_ptr<T>>);
|
||||
void setParent(Pdu parent) {
|
||||
for (auto &p : *members)
|
||||
p->parent = parent;
|
||||
}
|
||||
size_t streamSize() const override {
|
||||
size_t s = 0;
|
||||
for (auto &p : *members)
|
||||
s += p->streamSize();
|
||||
return s;
|
||||
}
|
||||
void iStream(Stream s) override {
|
||||
while(s->good()) {
|
||||
std::shared_ptr<T> p(new T());
|
||||
p->iStream(s);
|
||||
if (s->fail()) // stream failed during pdu read
|
||||
break;
|
||||
if (p->stream()->fail()) // pdu buffer failed
|
||||
continue;
|
||||
members->push_back(p); // add to block
|
||||
}
|
||||
}
|
||||
void oStream(Stream s) const override {
|
||||
for ( const auto& p : *members )
|
||||
p->oStream(s);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The OTP::PDU::Pdu class
|
||||
*/
|
||||
class pdu
|
||||
: public std::enable_shared_from_this<pdu>
|
||||
, public pdu_data
|
||||
{
|
||||
public:
|
||||
pdu();
|
||||
~pdu();
|
||||
|
||||
pdu_data* data = nullptr;
|
||||
uint16_t vector = 0;
|
||||
Pdu parent;
|
||||
|
||||
Stream stream() { return stream_; }
|
||||
virtual size_t streamSize() const override;
|
||||
virtual void iStream(Stream) override;
|
||||
virtual void oStream(Stream) const override;
|
||||
|
||||
template<class T>
|
||||
void createData()
|
||||
{
|
||||
data = new T();
|
||||
if (stream_ && stream_->good())
|
||||
data->iStream(stream_);
|
||||
}
|
||||
template<class T>
|
||||
void createDataBlock() {
|
||||
auto block = new PDU::Block<T>();
|
||||
if (stream_)
|
||||
block->iStream(stream_);
|
||||
block->setParent(shared_from_this());
|
||||
data = block;
|
||||
}
|
||||
|
||||
private:
|
||||
Stream stream_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace PDU
|
||||
} // namespace OTP
|
Loading…
Reference in New Issue