FIFOBuferStream and tests (Windows/VS2010 only compiled/tested)

This commit is contained in:
Aleksandar Fabijanic 2012-06-07 03:59:13 +00:00
parent 4bb6e0ff42
commit cfbcce0481
14 changed files with 910 additions and 52 deletions

View File

@ -324,6 +324,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release_static_mt|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="src\Exception.cpp" />
<ClCompile Include="src\FIFOBufferStream.cpp" />
<ClCompile Include="src\Format.cpp" />
<ClCompile Include="src\FPEnvironment.cpp" />
<ClCompile Include="src\FPEnvironment_C99.cpp">
@ -989,6 +990,7 @@
<ClInclude Include="include\Poco\Environment_WIN32U.h" />
<ClInclude Include="include\Poco\Exception.h" />
<ClInclude Include="include\Poco\FIFOBuffer.h" />
<ClInclude Include="include\Poco\FIFOBufferStream.h" />
<ClInclude Include="include\Poco\Format.h" />
<ClInclude Include="include\Poco\Foundation.h" />
<ClInclude Include="include\Poco\FPEnvironment.h" />

View File

@ -876,6 +876,9 @@
<ClCompile Include="src\Windows1251Encoding.cpp">
<Filter>Text\Source Files</Filter>
</ClCompile>
<ClCompile Include="src\FIFOBufferStream.cpp">
<Filter>Streams\Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\Poco\Any.h">
@ -1802,6 +1805,9 @@
<ClInclude Include="include\Poco\FIFOBuffer.h">
<Filter>Core\Header Files</Filter>
</ClInclude>
<ClInclude Include="include\Poco\FIFOBufferStream.h">
<Filter>Streams\Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="src\pocomsg.rc">

View File

@ -61,16 +61,46 @@ public:
Buffer(std::size_t capacity):
_capacity(capacity),
_used(capacity),
_ptr(new T[capacity])
_ptr(new T[capacity]),
_ownMem(true)
/// Creates and allocates the Buffer.
{
}
explicit Buffer(T* pMem, std::size_t length):
_capacity(length),
_used(length),
_ptr(pMem),
_ownMem(false)
/// Creates the Buffer. Length argument specifies the length
/// of the supplied memory pointed to by pMem in the number
/// of elements of type T. Supplied pointer is considered
/// blank and not owned by Buffer, so in this case Buffer
/// only acts as a wrapper around externally supplied
/// (and lifetime-managed) memory.
{
}
explicit Buffer(const T* pMem, std::size_t length):
_capacity(length),
_used(length),
_ptr(new T[length]),
_ownMem(true)
/// Creates and allocates the Buffer; copies the contents of
/// the supplied memory into the buffer. Length argument specifies
/// the length of the supplied memory pointed to by pMem in the
/// number of elements of type T.
{
if (_used)
std::memcpy(_ptr, pMem, _used * sizeof(T));
}
Buffer(const Buffer& other):
/// Copy constructor.
_capacity(other._used),
_used(other._used),
_ptr(new T[other._used])
_ptr(new T[other._used]),
_ownMem(true)
{
if (_used)
std::memcpy(_ptr, other._ptr, _used * sizeof(T));
@ -91,15 +121,21 @@ public:
~Buffer()
/// Destroys the Buffer.
{
delete [] _ptr;
if (_ownMem) delete [] _ptr;
}
void resize(std::size_t newCapacity, bool preserveContent = true)
/// Resizes the buffer. If preserveContent is true,
/// the content of the old buffer is copied over to the
/// new buffer. The new capacity can be larger or smaller than
/// the current one, but it must not be 0.
/// the current one, but it must not be 0.
/// Buffers only wrapping externally owned storage can not be
/// resized. If resize is attempted on those, IllegalAccessException
/// is thrown.
{
if (!_ownMem)
throw InvalidAccessException("Cannot resize buffer which does not own its storage.");
poco_assert(newCapacity);
if (newCapacity > _capacity)
@ -116,11 +152,20 @@ public:
_used = newCapacity;
}
void assign(const T* buf, std::size_t sz)
/// Assigns the argument buffer to this buffer.
/// If necessary, resizes the buffer.
{
if (0 == sz) return;
if (sz > _capacity) resize(sz, false);
std::memcpy(_ptr, buf, sz);
_used = sz;
}
void append(const T* buf, std::size_t sz)
/// Resizes this buffer and appends the argument buffer.
{
if (0 == sz)
return;
if (0 == sz) return;
std::size_t oldSize = _used;
resize(_used + sz, true);
std::memcpy(_ptr + oldSize, buf, sz);
@ -234,6 +279,7 @@ private:
std::size_t _capacity;
std::size_t _used;
T* _ptr;
bool _ownMem;
};

View File

@ -67,7 +67,7 @@ public:
mutable Poco::BasicEvent<bool> writable;
/// Event indicating "writability" of the buffer,
/// triggerred as follows:
/// triggered as follows:
///
/// * when buffer transitions from non-full to full,
/// Writable event observers are notified, with
@ -79,7 +79,7 @@ public:
mutable Poco::BasicEvent<bool> readable;
/// Event indicating "readability" of the buffer,
/// triggerred as follows:
/// triggered as follows:
///
/// * when buffer transitions from non-empty to empty,
/// Readable event observers are notified, with false
@ -94,7 +94,25 @@ public:
_begin(0),
_used(0),
_notify(notify)
/// Creates and allocates the FIFOBuffer.
/// Creates the FIFOBuffer.
{
}
explicit BasicFIFOBuffer(T* pBuffer, std::size_t size, bool notify = false):
_buffer(pBuffer, size),
_begin(0),
_used(0),
_notify(notify)
/// Creates the FIFOBuffer.
{
}
explicit BasicFIFOBuffer(const T* pBuffer, std::size_t size, bool notify = false):
_buffer(pBuffer, size),
_begin(0),
_used(size),
_notify(notify)
/// Creates the FIFOBuffer.
{
}
@ -123,24 +141,64 @@ public:
if (_notify) notify(usedBefore);
}
std::size_t peek(T* pBuffer, std::size_t length) const
/// Peeks into the data currently in the FIFO
/// without actually extracting it.
/// If length is zero, the return is immediate.
/// If length is greater than used length,
/// it is substituted with the the current FIFO
/// used length.
///
/// Returns the number of elements copied in the
/// supplied buffer.
{
if (0 == length) return 0;
Mutex::ScopedLock lock(_mutex);
if (length > _used) length = _used;
std::memcpy(pBuffer, _buffer.begin() + _begin, length * sizeof(T));
return length;
}
std::size_t peek(Poco::Buffer<T>& buffer, std::size_t length = 0) const
/// Peeks into the data currently in the FIFO
/// without actually extracting it.
/// Resizes the supplied buffer to the size of
/// data written to it. If length is not
/// supplied by the caller, the current FIFO used length
/// is substituted for it.
/// supplied by the caller or is greater than length
/// of currently used data, the current FIFO used
/// data length is substituted for it.
///
/// Returns the number of elements copied in the
/// supplied buffer.
{
Mutex::ScopedLock lock(_mutex);
if (0 == length || length > _used) length = _used;
buffer.resize(length);
return peek(buffer.begin(), length);
}
std::size_t read(T* pBuffer, std::size_t length)
/// Copies the data currently in the FIFO
/// into the supplied buffer.
/// Resizes the supplied buffer to the size of
/// data written to it.
///
/// Returns the reference to the buffer.
{
Mutex::ScopedLock lock(_mutex);
if (0 == length || length > _used) length = _used;
poco_assert (length <= _buffer.size());
buffer.resize(length);
std::memcpy(buffer.begin(), _buffer.begin() + _begin, length * sizeof(T));
if (0 == _used) return 0;
return length;
std::size_t usedBefore = _used;
std::size_t readLen = peek(pBuffer, length);
poco_assert (_used >= readLen);
_used -= readLen;
if (0 == _used) _begin = 0;
else _begin += length;
if (_notify) notify(usedBefore);
return readLen;
}
std::size_t read(Poco::Buffer<T>& buffer, std::size_t length = 0)
@ -167,6 +225,38 @@ public:
return readLen;
}
std::size_t write(const T* pBuffer, std::size_t length)
/// Writes data from supplied buffer to the FIFO buffer.
/// If there is no sufficient space for the whole
/// buffer to be written, data up to available
/// length is written.
/// The length of data to be written is determined from the
/// length argument. Function does nothing and returns zero
/// if length argument is equal to zero.
///
/// Returns the length of data written.
{
if (0 == length || isFull()) return 0;
Mutex::ScopedLock lock(_mutex);
if (_buffer.size() - (_begin + _used) < length)
{
std::memmove(_buffer.begin(), _buffer.begin() + _begin, _used);
_begin = 0;
}
std::size_t usedBefore = _used;
std::size_t available = _buffer.size() - _used - _begin;
std::size_t len = length > available ? available : length;
std::memcpy(_buffer.begin() + _begin + _used, pBuffer, len * sizeof(T));
_used += len;
poco_assert (_used <= _buffer.size());
if (_notify) notify(usedBefore);
return len;
}
std::size_t write(const Buffer<T>& buffer, std::size_t length = 0)
/// Writes data from supplied buffer to the FIFO buffer.
/// If there is no sufficient space for the whole
@ -178,25 +268,11 @@ public:
///
/// Returns the length of data written.
{
Mutex::ScopedLock lock(_mutex);
if (isFull()) return 0;
if (0 == length || length > buffer.size()) length = buffer.size();
if (_buffer.size() - (_begin + _used) < length)
{
std::memmove(_buffer.begin(), _buffer.begin() + _begin, _used);
_begin = 0;
}
std::size_t usedBefore = _used;
std::size_t available = _buffer.size() - _used - _begin;
std::size_t len = length > available ? available : length;
std::memcpy(_buffer.begin() + _begin + _used, buffer.begin(), len * sizeof(T));
_used += len;
poco_assert (_used <= _buffer.size());
if (_notify) notify(usedBefore);
return len;
return write(buffer.begin(), length);
}
std::size_t size() const
@ -310,6 +386,24 @@ public:
return 0 == _used;
}
bool isFull() const
/// Returns true is buffer is full, false otherwise.
{
return size() == _used;
}
void setNotify(bool notify = true)
/// Enables/disables notifications.
{
_notify = notify;
}
bool getNotify() const
/// Returns true if notifications are enabled, false otherwise.
{
return _notify;
}
private:
void notify(std::size_t usedBefore)
{

View File

@ -0,0 +1,176 @@
//
// FIFOBufferStream.h
//
// $Id: //poco/1.4/Foundation/include/Poco/FIFOBufferStream.h#1 $
//
// Library: Foundation
// Package: Streams
// Module: FIFOBufferStream
//
// Definition of the FIFOBufferStream class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#ifndef Foundation_FIFOBufferStream_INCLUDED
#define Foundation_FIFOBufferStream_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/FIFOBuffer.h"
#include "Poco/BufferedBidirectionalStreamBuf.h"
#include <istream>
#include <ostream>
namespace Poco {
class Foundation_API FIFOBufferStreamBuf: public BufferedBidirectionalStreamBuf
/// This is the streambuf class used for reading from and writing to a FIFOBuffer.
/// FIFOBuffer is enabled for emtpy/non-empty/full state transitions notifications.
{
public:
FIFOBufferStreamBuf();
/// Creates a FIFOBufferStreamBuf.
explicit FIFOBufferStreamBuf(FIFOBuffer& fifoBuffer);
/// Creates a FIFOBufferStreamBuf and assigns the given buffer to it.
explicit FIFOBufferStreamBuf(char* pBuffer, std::size_t length);
/// Creates a FIFOBufferStreamBuf and assigns the given buffer to it.
explicit FIFOBufferStreamBuf(const char* pBuffer, std::size_t length);
/// Creates a FIFOBufferStreamBuf and assigns the given buffer to it.
explicit FIFOBufferStreamBuf(std::size_t length);
/// Creates a FIFOBufferStreamBuf of the given length.
~FIFOBufferStreamBuf();
/// Destroys the FIFOBufferStreamBuf.
FIFOBuffer& fifoBuffer();
/// Returns the underlying FIFO buffer reference.
protected:
int readFromDevice(char* buffer, std::streamsize length);
int writeToDevice(const char* buffer, std::streamsize length);
private:
enum
{
STREAM_BUFFER_SIZE = 1024
};
FIFOBuffer* _pFIFOBuffer;
FIFOBuffer& _fifoBuffer;
};
class Foundation_API FIFOIOS: public virtual std::ios
/// The base class for FIFOBufferInputStream and
/// FIFOBufferStream.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
explicit FIFOIOS(FIFOBuffer& buffer);
/// Creates a FIFOIOS and assigns the given buffer to it.
explicit FIFOIOS(char* pBuffer, std::size_t length);
/// Creates a FIFOIOS and assigns the given buffer to it.
explicit FIFOIOS(const char* pBuffer, std::size_t length);
/// Creates a FIFOIOS and assigns the given buffer to it.
explicit FIFOIOS(std::size_t length);
/// Creates a FIFOIOS of the given length.
~FIFOIOS();
/// Destroys the FIFOIOS.
///
/// Flushes the buffer.
FIFOBufferStreamBuf* rdbuf();
/// Returns a pointer to the internal FIFOBufferStreamBuf.
void close();
/// Flushes the stream.
protected:
FIFOBufferStreamBuf _buf;
};
class Foundation_API FIFOBufferStream: public FIFOIOS, public std::iostream
/// An output stream for writing to a FIFO.
{
public:
Poco::BasicEvent<bool>& writable;
Poco::BasicEvent<bool>& readable;
explicit FIFOBufferStream(FIFOBuffer& buffer);
/// Creates the FIFOBufferStream with supplied buffer as initial value.
explicit FIFOBufferStream(char* pBuffer, std::size_t length);
/// Creates a FIFOBufferStream and assigns the given buffer to it.
explicit FIFOBufferStream(const char* pBuffer, std::size_t length);
/// Creates a FIFOBufferStream and assigns the given buffer to it.
explicit FIFOBufferStream(std::size_t length);
/// Creates a FIFOBufferStream of the given length.
~FIFOBufferStream();
/// Destroys the FIFOBufferStream.
///
/// Flushes the buffer.
private:
FIFOBufferStream();
FIFOBufferStream(const FIFOBufferStream& other);
FIFOBufferStream& operator =(const FIFOBufferStream& other);
};
///
/// inlines
///
FIFOBuffer& FIFOBufferStreamBuf::fifoBuffer()
{
return _fifoBuffer;
}
} // namespace Poco
#endif // Foundation_FIFOBufferStream_INCLUDED

View File

@ -58,7 +58,7 @@ class BasicMemoryStreamBuf: public std::basic_streambuf<ch, tr>
/// stream buffer for reading and writing from a memory area.
///
/// This streambuf only supports unidirectional streams.
/// In other words, the BasicBufferedStreamBuf can be
/// In other words, the BasicMemoryStreamBuf can be
/// used for the implementation of an istream or an
/// ostream, but not for an iostream.
{

View File

@ -93,17 +93,17 @@ public:
{
if (_ispb)
{
return _pb;
return _pb;
}
else
{
int_type c = readFromDevice();
if (c != char_traits::eof())
{
_ispb = true;
_pb = c;
}
return c;
int_type c = readFromDevice();
if (c != char_traits::eof())
{
_ispb = true;
_pb = c;
}
return c;
}
}
@ -116,12 +116,12 @@ public:
}
else
{
int_type c = readFromDevice();
if (c != char_traits::eof())
{
_pb = c;
}
return c;
int_type c = readFromDevice();
if (c != char_traits::eof())
{
_pb = c;
}
return c;
}
}
@ -129,13 +129,13 @@ public:
{
if (_ispb)
{
return char_traits::eof();
return char_traits::eof();
}
else
{
_ispb = true;
_pb = c;
return c;
_ispb = true;
_pb = c;
return c;
}
}

View File

@ -0,0 +1,208 @@
//
// FIFOBufferStream.cpp
//
// $Id: //poco/1.4/Foundation/src/FIFOBufferStream.cpp#1 $
//
// Library: Foundation
// Package: Streams
// Module: FIFOBufferStream
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#include "Poco/FIFOBufferStream.h"
namespace Poco {
//
// FIFOBufferStreamBuf
//
FIFOBufferStreamBuf::FIFOBufferStreamBuf():
BufferedBidirectionalStreamBuf(STREAM_BUFFER_SIZE + 4, std::ios::in | std::ios::out),
_pFIFOBuffer(new FIFOBuffer(STREAM_BUFFER_SIZE, true)),
_fifoBuffer(*_pFIFOBuffer)
{
}
FIFOBufferStreamBuf::FIFOBufferStreamBuf(FIFOBuffer& fifoBuffer):
BufferedBidirectionalStreamBuf(fifoBuffer.size() + 4, std::ios::in | std::ios::out),
_pFIFOBuffer(0),
_fifoBuffer(fifoBuffer)
{
fifoBuffer.setNotify(true);
}
FIFOBufferStreamBuf::FIFOBufferStreamBuf(char* pBuffer, std::size_t length):
BufferedBidirectionalStreamBuf(length + 4, std::ios::in | std::ios::out),
_pFIFOBuffer(new FIFOBuffer(pBuffer, length, true)),
_fifoBuffer(*_pFIFOBuffer)
{
}
FIFOBufferStreamBuf::FIFOBufferStreamBuf(const char* pBuffer, std::size_t length):
BufferedBidirectionalStreamBuf(length + 4, std::ios::in | std::ios::out),
_pFIFOBuffer(new FIFOBuffer(pBuffer, length, true)),
_fifoBuffer(*_pFIFOBuffer)
{
}
FIFOBufferStreamBuf::FIFOBufferStreamBuf(std::size_t length):
BufferedBidirectionalStreamBuf(length + 4, std::ios::in | std::ios::out),
_pFIFOBuffer(new FIFOBuffer(length, true)),
_fifoBuffer(*_pFIFOBuffer)
{
}
FIFOBufferStreamBuf::~FIFOBufferStreamBuf()
{
delete _pFIFOBuffer;
}
int FIFOBufferStreamBuf::readFromDevice(char* buffer, std::streamsize length)
{
poco_assert (length > 0);
return _fifoBuffer.read(buffer, static_cast<std::size_t>(length));
}
int FIFOBufferStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
{
poco_assert (length > 0);
return _fifoBuffer.write(buffer, static_cast<std::size_t>(length));
}
//
// FIFOIOS
//
FIFOIOS::FIFOIOS(FIFOBuffer& fifoBuffer): _buf(fifoBuffer)
{
poco_ios_init(&_buf);
}
FIFOIOS::FIFOIOS(char* pBuffer, std::size_t length): _buf(pBuffer, length)
{
poco_ios_init(&_buf);
}
FIFOIOS::FIFOIOS(const char* pBuffer, std::size_t length): _buf(pBuffer, length)
{
poco_ios_init(&_buf);
}
FIFOIOS::FIFOIOS(std::size_t length): _buf(length)
{
poco_ios_init(&_buf);
}
FIFOIOS::~FIFOIOS()
{
try
{
_buf.sync();
}
catch (...)
{
}
}
FIFOBufferStreamBuf* FIFOIOS::rdbuf()
{
return &_buf;
}
void FIFOIOS::close()
{
_buf.sync();
}
//
// FIFOBufferStream
//
FIFOBufferStream::FIFOBufferStream(FIFOBuffer& fifoBuffer):
FIFOIOS(fifoBuffer),
readable(_buf.fifoBuffer().readable),
writable(_buf.fifoBuffer().writable),
std::iostream(&_buf)
{
}
FIFOBufferStream::FIFOBufferStream(char* pBuffer, std::size_t length):
FIFOIOS(pBuffer, length),
readable(_buf.fifoBuffer().readable),
writable(_buf.fifoBuffer().writable),
std::iostream(&_buf)
{
}
FIFOBufferStream::FIFOBufferStream(const char* pBuffer, std::size_t length):
FIFOIOS(pBuffer, length),
readable(_buf.fifoBuffer().readable),
writable(_buf.fifoBuffer().writable),
std::iostream(&_buf)
{
}
FIFOBufferStream::FIFOBufferStream(std::size_t length):
FIFOIOS(length),
readable(_buf.fifoBuffer().readable),
writable(_buf.fifoBuffer().writable),
std::iostream(&_buf)
{
}
FIFOBufferStream::~FIFOBufferStream()
{
}
} // namespace Poco

View File

@ -308,6 +308,7 @@
<ClCompile Include="src\CoreTest.cpp" />
<ClCompile Include="src\CoreTestSuite.cpp" />
<ClCompile Include="src\DynamicFactoryTest.cpp" />
<ClCompile Include="src\FIFOBufferStreamTest.cpp" />
<ClCompile Include="src\FormatTest.cpp" />
<ClCompile Include="src\FPETest.cpp" />
<ClCompile Include="src\MemoryPoolTest.cpp" />
@ -439,6 +440,7 @@
<ClInclude Include="src\CoreTest.h" />
<ClInclude Include="src\CoreTestSuite.h" />
<ClInclude Include="src\DynamicFactoryTest.h" />
<ClInclude Include="src\FIFOBufferStreamTest.h" />
<ClInclude Include="src\FormatTest.h" />
<ClInclude Include="src\FPETest.h" />
<ClInclude Include="src\MemoryPoolTest.h" />

View File

@ -567,6 +567,9 @@
<ClCompile Include="src\ArrayTest.cpp">
<Filter>Core\Source Files</Filter>
</ClCompile>
<ClCompile Include="src\FIFOBufferStreamTest.cpp">
<Filter>Streams\Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\AnyTest.h">
@ -953,5 +956,8 @@
<ClInclude Include="src\ArrayTest.h">
<Filter>Core\Source Files</Filter>
</ClInclude>
<ClInclude Include="src\FIFOBufferStreamTest.h">
<Filter>Streams\Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -258,7 +258,25 @@ void CoreTest::testBuffer()
g.append("hello", 5);
assert (g.size() == 10);
assert ( !memcmp(g.begin(), "hellohello", 10) );
assert ( !std::memcmp(g.begin(), "hellohello", 10) );
char h[10];
Buffer<char> i(h, 10);
try
{
i.append("hello", 5);
fail ("must fail");
}
catch (InvalidAccessException&) { }
i.assign("hello", 5);
assert ( !std::memcmp(&h[0], "hello", 5) );
const char j[10] = "hello";
Buffer<char> k(j, 5);
k.append("hello", 5);
assert ( !std::memcmp(&j[0], "hello", 5) );
assert ( !std::memcmp(k.begin(), "hellohello", 10) );
}
@ -267,6 +285,10 @@ void CoreTest::testFIFOBufferChar()
typedef FIFOBuffer::Type T;
FIFOBuffer f(20, true);
assert (f.isEmpty());
assert (!f.isFull());
Buffer<T> b(10);
std::vector<T> v;
@ -423,6 +445,7 @@ void CoreTest::testFIFOBufferChar()
assert(2 == _readableToNot);
assert(0 == _notToWritable);
assert(1 == _writableToNot);
assert (f.isFull());
f.read(b);
assert(3 == _notToReadable);
@ -545,6 +568,7 @@ void CoreTest::testFIFOBufferChar()
assert(6 == _readableToNot);
assert(1 == _notToWritable);
assert(2 == _writableToNot);
assert (f.isFull());
assert (10 == f.size());
assert (10 == f.used());

View File

@ -0,0 +1,222 @@
//
// FIFOBufferStreamTest.cpp
//
// $Id: //poco/1.4/Foundation/testsuite/src/FIFOBufferStreamTest.cpp#2 $
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#include "FIFOBufferStreamTest.h"
#include "CppUnit/TestCaller.h"
#include "CppUnit/TestSuite.h"
#include "Poco/FIFOBuffer.h"
#include "Poco/FIFOBufferStream.h"
#include "Poco/Delegate.h"
using Poco::FIFOBuffer;
using Poco::FIFOBufferStream;
using Poco::delegate;
FIFOBufferStreamTest::FIFOBufferStreamTest(const std::string& name): CppUnit::TestCase(name)
{
}
FIFOBufferStreamTest::~FIFOBufferStreamTest()
{
}
void FIFOBufferStreamTest::testInput()
{
const char* data = "This is a test";
FIFOBuffer fb1(data, 14);
FIFOBufferStream str1(fb1);
assert (str1.rdbuf()->fifoBuffer().isFull());
int c = str1.get();
assert (c == 'T');
c = str1.get();
assert (c == 'h');
std::string str;
str1 >> str;
assert (str == "is");
char buffer[32];
str1.read(buffer, sizeof(buffer));
assert (str1.gcount() == 10);
buffer[str1.gcount()] = 0;
assert (std::string(" is a test") == buffer);
const char* data2 = "123";
FIFOBufferStream str2(data2, 3);
c = str2.get();
assert (c == '1');
assert (str2.good());
c = str2.get();
assert (c == '2');
str2.unget();
c = str2.get();
assert (c == '2');
assert (str2.good());
c = str2.get();
assert (c == '3');
assert (str2.good());
c = str2.get();
assert (c == -1);
assert (str2.eof());
}
void FIFOBufferStreamTest::testOutput()
{
char output[64];
FIFOBufferStream iostr1(output, 64);
iostr1 << "This is a test " << 42 << std::ends << std::flush;
assert (std::string("This is a test 42") == output);
}
void FIFOBufferStreamTest::testNotify()
{
FIFOBuffer fb(18);
FIFOBufferStream iostr(fb);
assert (iostr.rdbuf()->fifoBuffer().isEmpty());
assert (0 == _readableToNot);
assert (0 == _notToReadable);
assert (0 == _writableToNot);
assert (0 == _notToWritable);
iostr.readable += delegate(this, &FIFOBufferStreamTest::onReadable);
iostr.writable += delegate(this, &FIFOBufferStreamTest::onWritable);
iostr << "This is a test " << 42 << std::ends << std::flush;
assert (iostr.rdbuf()->fifoBuffer().isFull());
assert (0 == _readableToNot);
assert (1 == _notToReadable);
assert (1 == _writableToNot);
assert (0 == _notToWritable);
char input[64];
iostr >> input;
assert (std::string("This") == input);
assert (iostr.rdbuf()->fifoBuffer().isEmpty());
assert (1 == _readableToNot);
assert (1 == _notToReadable);
assert (1 == _writableToNot);
assert (1 == _notToWritable);
iostr >> input;
assert (std::string("is") == input);
assert (1 == _readableToNot);
assert (1 == _notToReadable);
assert (1 == _writableToNot);
assert (1 == _notToWritable);
iostr >> input;
assert (std::string("a") == input);
assert (1 == _readableToNot);
assert (1 == _notToReadable);
assert (1 == _writableToNot);
assert (1 == _notToWritable);
iostr >> input;
assert (std::string("test") == input);
assert (1 == _readableToNot);
assert (1 == _notToReadable);
assert (1 == _writableToNot);
assert (1 == _notToWritable);
iostr >> input;
assert (std::string("42") == input);
assert (1 == _readableToNot);
assert (1 == _notToReadable);
assert (1 == _writableToNot);
assert (1 == _notToWritable);
iostr << "This is a test " << 42 << std::ends << std::flush;
assert (iostr.rdbuf()->fifoBuffer().isFull());
assert (1 == _readableToNot);
assert (2 == _notToReadable);
assert (2 == _writableToNot);
assert (1 == _notToWritable);
iostr.readable -= delegate(this, &FIFOBufferStreamTest::onReadable);
iostr.writable -= delegate(this, &FIFOBufferStreamTest::onWritable);
}
void FIFOBufferStreamTest::onReadable(bool& b)
{
if (b) ++_notToReadable;
else ++_readableToNot;
};
void FIFOBufferStreamTest::onWritable(bool& b)
{
if (b) ++_notToWritable;
else ++_writableToNot;
}
void FIFOBufferStreamTest::setUp()
{
_readableToNot = 0;
_notToReadable = 0;
_writableToNot = 0;
_notToWritable = 0;
}
void FIFOBufferStreamTest::tearDown()
{
}
CppUnit::Test* FIFOBufferStreamTest::suite()
{
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("FIFOBufferStreamTest");
CppUnit_addTest(pSuite, FIFOBufferStreamTest, testInput);
CppUnit_addTest(pSuite, FIFOBufferStreamTest, testOutput);
CppUnit_addTest(pSuite, FIFOBufferStreamTest, testNotify);
return pSuite;
}

View File

@ -0,0 +1,70 @@
//
// FIFOBufferStreamTest.h
//
// $Id: //poco/1.4/Foundation/testsuite/src/FIFOBufferStreamTest.h#1 $
//
// Definition of the FIFOBufferStreamTest class.
//
// Copyright (c) 2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#ifndef FIFOBufferStreamTest_INCLUDED
#define FIFOBufferStreamTest_INCLUDED
#include "Poco/Foundation.h"
#include "CppUnit/TestCase.h"
class FIFOBufferStreamTest: public CppUnit::TestCase
{
public:
FIFOBufferStreamTest(const std::string& name);
~FIFOBufferStreamTest();
void testInput();
void testOutput();
void testNotify();
void setUp();
void tearDown();
static CppUnit::Test* suite();
protected:
void onReadable(bool& b);
void onWritable(bool& b);
private:
int _readableToNot;
int _notToReadable;
int _writableToNot;
int _notToWritable;
};
#endif // FIFOBufferStreamTest_INCLUDED

View File

@ -43,6 +43,7 @@
#include "TeeStreamTest.h"
#include "FileStreamTest.h"
#include "MemoryStreamTest.h"
#include "FIFOBufferStreamTest.h"
CppUnit::Test* StreamsTestSuite::suite()
@ -61,6 +62,7 @@ CppUnit::Test* StreamsTestSuite::suite()
pSuite->addTest(TeeStreamTest::suite());
pSuite->addTest(FileStreamTest::suite());
pSuite->addTest(MemoryStreamTest::suite());
pSuite->addTest(FIFOBufferStreamTest::suite());
return pSuite;
}