diff --git a/include/rogue/interfaces/stream/Slave.h b/include/rogue/interfaces/stream/Slave.h index c730e35ef..6af34787e 100644 --- a/include/rogue/interfaces/stream/Slave.h +++ b/include/rogue/interfaces/stream/Slave.h @@ -126,6 +126,20 @@ class Slave : public rogue::interfaces::stream::Pool, */ uint64_t getByteCount(); + //! Ensure frame is a single buffer + /** This method makes sure the passed frame is composed of a single buffer. + * If the reqNew flag is true and the passed frame is not a single buffer, a + * new frame will be requested and the frame data will be copied, with the passed + * frame pointer being updated. The return value will indicate if the frame is a + * single buffer at the end of the process. A frame lock must be held when this + * method is called. + * + * Not exposed to Python + * @param frame Reference to frame pointer (FramePtr) + * @param rewEn Flag to determine if a new frame should be requested + */ + bool ensureSingleBuffer(std::shared_ptr& frame, bool reqEn); + #ifndef NO_PYTHON //! Support << operator in python diff --git a/src/rogue/interfaces/stream/Slave.cpp b/src/rogue/interfaces/stream/Slave.cpp index 68fa6b323..3ea134b9e 100644 --- a/src/rogue/interfaces/stream/Slave.cpp +++ b/src/rogue/interfaces/stream/Slave.cpp @@ -140,6 +140,35 @@ uint64_t ris::Slave::getByteCount() { return (frameBytes_); } +// Ensure passed frame is a single buffer +bool ris::Slave::ensureSingleBuffer(ris::FramePtr& frame, bool reqEn) { + // Frame is a single buffer + if (frame->bufferCount() == 1) + return true; + + else if (!reqEn) + return false; + + else { + uint32_t size = frame->getPayload(); + ris::FramePtr nFrame = acceptReq(size, true); + + if (nFrame->bufferCount() != 1) + return false; + + else { + nFrame->setPayload(size); + + ris::FrameIterator srcIter = frame->begin(); + ris::FrameIterator dstIter = nFrame->begin(); + + ris::copyFrame(srcIter, size, dstIter); + frame = nFrame; + return true; + } + } +} + void ris::Slave::setup_python() { #ifndef NO_PYTHON