flatten 20260225
This commit is contained in:
294
tjp/core/pipe/Pipe.inl
Executable file
294
tjp/core/pipe/Pipe.inl
Executable file
@@ -0,0 +1,294 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
#include "Pipe.h"
|
||||
#include <tjp/core/assert/debug_assert.h>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
Pipe<Packet,Mutex>::Pipe () :
|
||||
offset(0),
|
||||
size_(0),
|
||||
open(true)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
Pipe<Packet,Mutex>::~Pipe ()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
void Pipe<Packet,Mutex>::close()
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
|
||||
open = false;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
bool Pipe<Packet,Mutex>::isOpen() const
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
return open;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::write_no_lock (Packet &&packet)
|
||||
{
|
||||
debug_assert(mutex.locked_by_caller());
|
||||
|
||||
if (packet.size() == 0)
|
||||
return size_;
|
||||
|
||||
size_ += packet.size();
|
||||
pipe.emplace_back(std::move(packet));
|
||||
|
||||
return size_;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::write (Packet &&packet)
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
|
||||
return write_no_lock(std::move(packet));
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
Packet Pipe<Packet,Mutex>::read_no_lock ()
|
||||
{
|
||||
debug_assert(!pipe.empty());
|
||||
debug_assert(offset == 0);
|
||||
debug_assert(mutex.locked_by_caller());
|
||||
|
||||
auto p = std::move(pipe.front());
|
||||
pipe.pop_front();
|
||||
|
||||
debug_assert(size_ >= p.size());
|
||||
size_ -= p.size();
|
||||
offset = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
Packet Pipe<Packet,Mutex>::read ()
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
|
||||
return read_no_lock();
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
bool Pipe<Packet,Mutex>::empty_no_lock() const
|
||||
{
|
||||
return pipe.empty();
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
bool Pipe<Packet,Mutex>::empty() const
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
|
||||
return empty_no_lock();
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::peek_no_lock (char *buffer, size_t size) const
|
||||
{
|
||||
debug_assert(mutex.locked_by_caller());
|
||||
|
||||
size_t ptr = 0;
|
||||
size_t offset = this->offset;
|
||||
|
||||
auto &buffers = pipe;
|
||||
|
||||
typename PacketList::const_iterator i=buffers.begin();
|
||||
while (i!=buffers.end() && (size > 0))
|
||||
{
|
||||
auto chunksize = i->size() - offset;
|
||||
size_t newoffset = 0;
|
||||
|
||||
if (chunksize > size)
|
||||
{
|
||||
newoffset = offset + size;
|
||||
chunksize = size;
|
||||
}
|
||||
|
||||
if (buffer)
|
||||
memcpy (buffer + ptr, i->data() + offset, chunksize);
|
||||
|
||||
ptr += chunksize;
|
||||
size -= chunksize;
|
||||
offset = newoffset;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::peek (char *buffer, size_t size) const
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
|
||||
return peek_no_lock(buffer, size);
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::read_no_lock (char *buffer, size_t requestedSize)
|
||||
{
|
||||
auto size = requestedSize;
|
||||
size_t ptr = 0;
|
||||
|
||||
auto &buffers = pipe;
|
||||
|
||||
while (!buffers.empty() && (size > 0))
|
||||
{
|
||||
auto chunksize = buffers.front().size() - offset;
|
||||
size_t newoffset = 0;
|
||||
|
||||
if (chunksize > size)
|
||||
{
|
||||
newoffset = offset + size;
|
||||
chunksize = size;
|
||||
}
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
debug_assert(ptr + chunksize <= requestedSize);
|
||||
memcpy (buffer + ptr, buffers.front().data() + offset, chunksize);
|
||||
}
|
||||
|
||||
ptr += chunksize;
|
||||
size -= chunksize;
|
||||
offset = newoffset;
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
size_ -= buffers.front().size();
|
||||
buffers.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
sizeReadRequested += requestedSize;
|
||||
sizeRead += ptr;
|
||||
|
||||
return ptr;
|
||||
} ;
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
void Pipe<Packet,Mutex>::clearSizeRead ()
|
||||
{
|
||||
sizeReadRequested = sizeRead = 0;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::read (char *buffer, size_t requestedSize)
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
return read_no_lock(buffer, requestedSize);
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::write (const char *buffer, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return size;
|
||||
|
||||
write(Packet(buffer, buffer+size));
|
||||
return size;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::skip_no_lock(size_t size)
|
||||
{
|
||||
return read_no_lock(nullptr, size);
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::skip(size_t size)
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
|
||||
return skip_no_lock(size);
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::size () const
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
return size_ - offset;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
void Pipe<Packet,Mutex>::clear ()
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
|
||||
pipe.clear();
|
||||
size_ = offset = 0;
|
||||
flush_ = false;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
size_t Pipe<Packet,Mutex>::resize (size_t maximumSize)
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
if (size_ > maximumSize)
|
||||
{
|
||||
skip_no_lock(size_ - maximumSize);
|
||||
}
|
||||
|
||||
return size_;
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
const Packet *Pipe<Packet,Mutex>::peek() const
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
|
||||
if (pipe.empty())
|
||||
return nullptr;
|
||||
|
||||
return &pipe.front();
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
bool Pipe<Packet,Mutex>::eos() const
|
||||
{
|
||||
return !open && empty();
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
bool Pipe<Packet,Mutex>::finishing() const
|
||||
{
|
||||
return !open && !empty();
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
bool Pipe<Packet,Mutex>::flushing() const
|
||||
{
|
||||
return flush_ && !empty();
|
||||
}
|
||||
|
||||
template<typename Packet, typename Mutex>
|
||||
bool Pipe<Packet,Mutex>::flushed()
|
||||
{
|
||||
if (!flush_)
|
||||
return false;
|
||||
|
||||
if (!empty())
|
||||
return false;
|
||||
|
||||
flush_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user