#include "streams.h"
#include <security_utilities/memutils.h>
namespace Security {
Source::State Source::state() const
{
return mState;
}
size_t Source::getSize()
{
return unknownSize;
}
void Sink::setSize(size_t)
{
}
void NullSource::produce(void *, size_t &length)
{
length = 0;
}
Source::State NullSource::state() const
{
return endOfData;
}
void NullSink::consume(const void *, size_t)
{
}
void FileSource::produce(void *data, size_t &length)
{
if ((length = read(data, length)) == 0)
mState = endOfData;
}
size_t FileSource::getSize()
{
return fileSize();
}
void FileSink::consume(const void *data, size_t length)
{
write(data, length);
}
void MemorySource::produce(void *data, size_t &length)
{
if (mRemaining < length)
length = mRemaining;
memcpy(data, mData, length);
mData = LowLevelMemoryUtilities::increment(mData, length);
mRemaining -= length;
}
size_t MemorySource::getSize()
{
return mRemaining;
}
Source::State MemorySource::state() const
{
return mRemaining ? producing : endOfData;
}
void MemorySink::consume(const void *data, size_t length)
{
if (mSize + length > mMax)
grow(mSize * 3 / 2);
assert(mSize + length <= mMax);
memcpy(((char *)mBuffer) + mSize, data, length);
mSize += length;
}
void MemorySink::setSize(size_t expectedSize)
{
grow(expectedSize);
}
void MemorySink::grow(size_t newSize)
{
if (void *p = realloc(mBuffer, newSize)) {
mBuffer = p;
mMax = newSize;
} else
UnixError::throwMe();
}
}