mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Core: FilterStream
git-svn-id: svn://ultimatepp.org/upp/trunk@5830 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
baab578f97
commit
156acf2cbd
6 changed files with 232 additions and 7 deletions
|
|
@ -295,6 +295,8 @@ class JsonIO;
|
|||
#include "Callback.h"
|
||||
#include "Util.h"
|
||||
|
||||
#include "FilterStream.h"
|
||||
|
||||
#include "Format.h"
|
||||
#include "Convert.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ file
|
|||
Stream.h,
|
||||
Stream.cpp optimize_speed,
|
||||
BlockStream.cpp optimize_speed,
|
||||
FilterStream.h,
|
||||
FilterStream.cpp,
|
||||
Profile.h,
|
||||
Diag.h,
|
||||
Log.cpp,
|
||||
|
|
|
|||
158
uppsrc/Core/FilterStream.cpp
Normal file
158
uppsrc/Core/FilterStream.cpp
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
#include "Core.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
InputFilterStream::InputFilterStream()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void InputFilterStream::Init()
|
||||
{
|
||||
static byte h[1];
|
||||
ptr = rdlim = h;
|
||||
in = NULL;
|
||||
eof = false;
|
||||
}
|
||||
|
||||
dword InputFilterStream::Avail()
|
||||
{
|
||||
return dword(rdlim - ptr);
|
||||
}
|
||||
|
||||
bool InputFilterStream::IsOpen() const
|
||||
{
|
||||
return in->IsOpen();
|
||||
}
|
||||
|
||||
int InputFilterStream::_Term()
|
||||
{
|
||||
if(ptr == rdlim)
|
||||
Fetch(1);
|
||||
return ptr == rdlim ? -1 : *ptr;
|
||||
}
|
||||
|
||||
int InputFilterStream::_Get()
|
||||
{
|
||||
if(ptr == rdlim)
|
||||
Fetch(1);
|
||||
return ptr == rdlim ? -1 : *ptr++;
|
||||
}
|
||||
|
||||
dword InputFilterStream::_Get(void *data, dword size)
|
||||
{
|
||||
byte *p = (byte *)data;
|
||||
int nn = 0;
|
||||
for(int pass = 0; size && pass < 2; pass++) {
|
||||
int n = min(size, Avail());
|
||||
memcpy(p, ptr, n);
|
||||
size -= n;
|
||||
p += n;
|
||||
ptr += n;
|
||||
nn += n;
|
||||
if(size)
|
||||
Fetch(size);
|
||||
}
|
||||
return nn;
|
||||
}
|
||||
|
||||
void InputFilterStream::Out(const void *ptr, int size)
|
||||
{
|
||||
int l = buffer.GetCount();
|
||||
buffer.SetCount(l + size);
|
||||
memcpy(buffer.Begin() + l, ptr, size);
|
||||
}
|
||||
|
||||
void InputFilterStream::Fetch(int size)
|
||||
{
|
||||
buffer.Clear();
|
||||
if(eof) {
|
||||
static byte h[1];
|
||||
ptr = rdlim = h;
|
||||
return;
|
||||
}
|
||||
if(More)
|
||||
while(buffer.GetCount() < size && More());
|
||||
else {
|
||||
Buffer<byte> b(4096);
|
||||
while(buffer.GetCount() < size) {
|
||||
int n = in->Get(~b, 4096);
|
||||
if(n == 0) {
|
||||
End();
|
||||
eof = true;
|
||||
break;
|
||||
}
|
||||
Filter(~b, n);
|
||||
}
|
||||
}
|
||||
ptr = buffer.Begin();
|
||||
rdlim = buffer.End();
|
||||
}
|
||||
|
||||
OutputFilterStream::OutputFilterStream()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void OutputFilterStream::Init()
|
||||
{
|
||||
buffer.Alloc(4096);
|
||||
wrlim = ~buffer + 4096;
|
||||
ptr = ~buffer;
|
||||
out = NULL;
|
||||
}
|
||||
|
||||
OutputFilterStream::~OutputFilterStream()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void OutputFilterStream::Close()
|
||||
{
|
||||
if(buffer) {
|
||||
FlushOut();
|
||||
End();
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void OutputFilterStream::FlushOut()
|
||||
{
|
||||
if(ptr != ~buffer) {
|
||||
Filter(~buffer, ptr - ~buffer);
|
||||
ptr = ~buffer;
|
||||
}
|
||||
}
|
||||
|
||||
void OutputFilterStream::_Put(int w)
|
||||
{
|
||||
FlushOut();
|
||||
*ptr++ = w;
|
||||
}
|
||||
|
||||
void OutputFilterStream::_Put(const void *data, dword size)
|
||||
{
|
||||
const byte *p = (const byte *)data;
|
||||
for(;;) {
|
||||
int n = min(Avail(), size);
|
||||
memcpy(ptr, p, n);
|
||||
size -= n;
|
||||
p += n;
|
||||
ptr += n;
|
||||
if(size == 0)
|
||||
return;
|
||||
FlushOut();
|
||||
}
|
||||
}
|
||||
|
||||
bool OutputFilterStream::IsOpen() const
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void OutputFilterStream::Out(const void *ptr, int size)
|
||||
{
|
||||
out->Put(ptr, size);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
68
uppsrc/Core/FilterStream.h
Normal file
68
uppsrc/Core/FilterStream.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
class InputFilterStream : public Stream {
|
||||
public:
|
||||
virtual bool IsOpen() const;
|
||||
|
||||
protected:
|
||||
virtual int _Term();
|
||||
virtual int _Get();
|
||||
virtual dword _Get(void *data, dword size);
|
||||
|
||||
Vector<byte> buffer;
|
||||
bool eof;
|
||||
|
||||
void Init();
|
||||
void Fetch(int size);
|
||||
dword Avail();
|
||||
|
||||
public:
|
||||
Stream *in;
|
||||
Callback2<const void *, int> Filter;
|
||||
Callback End;
|
||||
Gate More;
|
||||
void Out(const void *ptr, int size);
|
||||
|
||||
template <class F>
|
||||
void Set(Stream& in_, F& filter) {
|
||||
in = &in_;
|
||||
filter.WhenOut = callback(this, &InputFilterStream::Out);
|
||||
Filter = callback<F, F, const void *, int>(&filter, &F::Put);
|
||||
End = callback(&filter, &F::End);
|
||||
}
|
||||
|
||||
InputFilterStream();
|
||||
template <class F> InputFilterStream(Stream& in, F& filter) { Init(); Set(in, filter); }
|
||||
};
|
||||
|
||||
class OutputFilterStream : public Stream {
|
||||
public:
|
||||
virtual void Close();
|
||||
virtual bool IsOpen() const;
|
||||
|
||||
protected:
|
||||
virtual void _Put(int w);
|
||||
virtual void _Put(const void *data, dword size);
|
||||
|
||||
Buffer<byte> buffer;
|
||||
|
||||
void FlushOut();
|
||||
dword Avail() { return 4096 - (ptr - ~buffer); }
|
||||
void Init();
|
||||
|
||||
public:
|
||||
Stream *out;
|
||||
Callback2<const void *, int> Filter;
|
||||
Callback End;
|
||||
void Out(const void *ptr, int size);
|
||||
|
||||
template <class F>
|
||||
void Set(Stream& out_, F& filter) {
|
||||
out = &out_;
|
||||
filter.WhenOut = callback(this, &OutputFilterStream::Out);
|
||||
Filter = callback<F, F, const void *, int>(&filter, &F::Put);
|
||||
End = callback(&filter, &F::End);
|
||||
}
|
||||
|
||||
OutputFilterStream();
|
||||
template <class F> OutputFilterStream(Stream& in, F& filter) { Init(); Set(in, filter); }
|
||||
~OutputFilterStream();
|
||||
};
|
||||
|
|
@ -63,11 +63,6 @@ Stream::Stream() {
|
|||
|
||||
Stream::~Stream() {}
|
||||
|
||||
bool Stream::_IsEof() const
|
||||
{
|
||||
return GetPos() >= GetSize();
|
||||
}
|
||||
|
||||
void Stream::LoadError() {
|
||||
SetError(ERROR_LOADING_FAILED);
|
||||
if(style & STRM_THROW)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ private:
|
|||
int _Get16();
|
||||
int _Get32();
|
||||
int64 _Get64();
|
||||
bool _IsEof() const;
|
||||
|
||||
public:
|
||||
virtual void Seek(int64 pos);
|
||||
|
|
@ -73,11 +72,12 @@ public:
|
|||
void ClearError() { style = style & ~STRM_ERROR; errorcode = 0; }
|
||||
|
||||
int64 GetPos() const { return dword(ptr - buffer) + pos; }
|
||||
bool IsEof() const { return ptr >= rdlim && _IsEof(); }
|
||||
int64 GetLeft() const { return GetSize() - GetPos(); }
|
||||
void SeekEnd(int64 rel = 0) { Seek(GetSize() + rel); }
|
||||
void SeekCur(int64 rel) { Seek(GetPos() + rel); }
|
||||
|
||||
bool IsEof() { return ptr >= rdlim && _Term() < 0; }
|
||||
|
||||
void Put(int c) { if(ptr < wrlim) *ptr++ = c; else _Put(c); }
|
||||
int Term() { return ptr < rdlim ? *ptr : _Term(); }
|
||||
int Peek() { return Term(); }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue