mirror of
https://github.com/debauchee/barrier.git
synced 2026-02-08 12:53:53 +08:00
Started over.
This commit is contained in:
107
io/CBufferedInputStream.cpp
Normal file
107
io/CBufferedInputStream.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "CBufferedInputStream.h"
|
||||
#include "CLock.h"
|
||||
#include "CMutex.h"
|
||||
#include "CThread.h"
|
||||
#include "IJob.h"
|
||||
#include "XIO.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
//
|
||||
// CBufferedInputStream
|
||||
//
|
||||
|
||||
CBufferedInputStream::CBufferedInputStream(CMutex* mutex, IJob* closeCB) :
|
||||
m_mutex(mutex),
|
||||
m_empty(mutex, true),
|
||||
m_closeCB(closeCB),
|
||||
m_closed(false),
|
||||
m_hungup(false)
|
||||
{
|
||||
assert(m_mutex != NULL);
|
||||
}
|
||||
|
||||
CBufferedInputStream::~CBufferedInputStream()
|
||||
{
|
||||
delete m_closeCB;
|
||||
}
|
||||
|
||||
void CBufferedInputStream::write(
|
||||
const void* data, UInt32 n) throw()
|
||||
{
|
||||
if (!m_hungup && n > 0) {
|
||||
m_buffer.write(data, n);
|
||||
m_empty = (m_buffer.getSize() == 0);
|
||||
m_empty.broadcast();
|
||||
}
|
||||
}
|
||||
|
||||
void CBufferedInputStream::hangup() throw()
|
||||
{
|
||||
m_hungup = true;
|
||||
m_empty.broadcast();
|
||||
}
|
||||
|
||||
UInt32 CBufferedInputStream::readNoLock(
|
||||
void* dst, UInt32 n) throw(XIO)
|
||||
{
|
||||
if (m_closed) {
|
||||
throw XIOClosed();
|
||||
}
|
||||
|
||||
// wait for data (or hangup)
|
||||
while (!m_hungup && m_empty == true) {
|
||||
m_empty.wait();
|
||||
}
|
||||
|
||||
// read data
|
||||
const UInt32 count = m_buffer.getSize();
|
||||
if (n > count) {
|
||||
n = count;
|
||||
}
|
||||
if (n > 0) {
|
||||
if (dst != NULL) {
|
||||
::memcpy(dst, m_buffer.peek(n), n);
|
||||
}
|
||||
m_buffer.pop(n);
|
||||
}
|
||||
|
||||
// update empty state
|
||||
if (m_buffer.getSize() == 0) {
|
||||
m_empty = true;
|
||||
m_empty.broadcast();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
UInt32 CBufferedInputStream::getSizeNoLock() const throw()
|
||||
{
|
||||
return m_buffer.getSize();
|
||||
}
|
||||
|
||||
void CBufferedInputStream::close() throw(XIO)
|
||||
{
|
||||
CLock lock(m_mutex);
|
||||
if (m_closed) {
|
||||
throw XIOClosed();
|
||||
}
|
||||
|
||||
m_closed = true;
|
||||
if (m_closeCB) {
|
||||
m_closeCB->run();
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 CBufferedInputStream::read(
|
||||
void* dst, UInt32 n) throw(XIO)
|
||||
{
|
||||
CLock lock(m_mutex);
|
||||
return readNoLock(dst, n);
|
||||
}
|
||||
|
||||
UInt32 CBufferedInputStream::getSize() const throw()
|
||||
{
|
||||
CLock lock(m_mutex);
|
||||
return getSizeNoLock();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user