Home » U++ Library support » U++ Core » InFilterStream::Out() is buggy: a possible bugfix
InFilterStream::Out() is buggy: a possible bugfix [message #56758] |
Mon, 12 April 2021 02:54 |
zsolt
Messages: 697 Registered: December 2005 Location: Budapest, Hungary
|
Contributor |
|
|
The problem is, that it does not set some variables in the base class at a point.
The correct code would be:
void InFilterStream::Out(const void *p, int size)
{
const byte *s = (byte *)p;
if(todo) {
dword sz = min(todo, (dword)size);
memcpy8(t, s, sz);
t += sz;
s += sz;
todo -= sz;
size -= sz;
pos += sz;
}
if(size) {
int l = buffer.GetCount();
buffer.SetCountR(l + size);
memcpy8(buffer.begin() + l, s, size);
Stream::buffer = ptr = buffer.begin();
rdlim = buffer.end();
}
WhenOut();
}
The added two lines are:
+ Stream::buffer = ptr = buffer.begin();
+ rdlim = buffer.end();
I hope, it will not break any other things in code.
I found it, when I wanted to use that as a gzip input filter to read from an uncompressed stream in gzipped format:
class MyGzipInStream : public InFilterStream {
Zlib z;
public:
void Open(Stream& in) { Set(in, z); z.Compress(); }
Zlib& GetZlib() { return z; }
MyGzipInStream() { z.GZip().Header(); }
~MyGzipInStream() { Close(); }
};
[Updated on: Wed, 14 April 2021 01:29] Report message to a moderator
|
|
|
Re: InFilterStream::Out() is buggy: a possible bugfix [message #56800 is a reply to message #56758] |
Sat, 17 April 2021 06:09 |
|
mirek
Messages: 13975 Registered: November 2005
|
Ultimate Member |
|
|
zsolt wrote on Mon, 12 April 2021 02:54The problem is, that it does not set some variables in the base class at a point.
The correct code would be:
void InFilterStream::Out(const void *p, int size)
{
const byte *s = (byte *)p;
if(todo) {
dword sz = min(todo, (dword)size);
memcpy8(t, s, sz);
t += sz;
s += sz;
todo -= sz;
size -= sz;
pos += sz;
}
if(size) {
int l = buffer.GetCount();
buffer.SetCountR(l + size);
memcpy8(buffer.begin() + l, s, size);
Stream::buffer = ptr = buffer.begin();
rdlim = buffer.end();
}
WhenOut();
}
The added two lines are:
+ Stream::buffer = ptr = buffer.begin();
+ rdlim = buffer.end();
I hope, it will not break any other things in code.
I found it, when I wanted to use that as a gzip input filter to read from an uncompressed stream in gzipped format:
class MyGzipInStream : public InFilterStream {
Zlib z;
public:
void Open(Stream& in) { Set(in, z); z.Compress(); }
Zlib& GetZlib() { return z; }
MyGzipInStream() { z.GZip().Header(); }
~MyGzipInStream() { Close(); }
};
I wonder what is wrong with current code; this is how I believe it is supposed to work:
- there are no more data in buffer, call Fetch
- Fetch pushes data to Filter
- Filter pushes processed (e.g. decompressed) data back through Out
- Fetch then sets those variables that you suggest to set in Out
Filter is not called from anywhere else. So the only place where something could go bad is WhenOut event. Is that what is causing the problem? Are you using WhenOut?
-
|
|
|
Re: InFilterStream::Out() is buggy: a possible bugfix [message #56804 is a reply to message #56800] |
Sat, 17 April 2021 06:27 |
zsolt
Messages: 697 Registered: December 2005 Location: Budapest, Hungary
|
Contributor |
|
|
Zlib uses WhenOut to push the gzip header, so it is missing from the output:
void Zlib::Compress()
{
Begin();
if(deflateInit2(&z, compression_level, Z_DEFLATED,
hdr && !gzip ? MAX_WBITS : -MAX_WBITS, DEF_MEM_LEVEL,
Z_DEFAULT_STRATEGY) != Z_OK)
Panic("deflateInit2 failed");
mode = DEFLATE;
if(gzip)
WhenOut(sGZip_header, 10);
}
[Updated on: Sat, 17 April 2021 06:29] Report message to a moderator
|
|
|
|
|
|
Goto Forum:
Current Time: Sat Apr 27 02:52:02 CEST 2024
Total time taken to generate the page: 0.69794 seconds
|