tags:

views:

585

answers:

5

I'm building an network application that needs to be able to switch from normal network traffic to a zlib compressed stream, mid stream. My thoughts on the matter involve boolean switch that when on will cause the network code to pass all the data through a class that I can feed IEnumerable<byte> into, and then pull out the decompressed stream, passing that on to the already existing protocol parsing code.

Things I've looked at:

  • ZLib.NET - It seems a little... Ecclectic, and not quite what I want. Would still make a decent start to build off though. (Jon Skeet's comments here hardly inspire me either.)
  • SharpZipLib - This doesn't seem to support zlib at all? Can anyone confirm or deny this?

I would very much prefer and all managed solution, but let's have at it... are there any other implementations of this library out there in .NET, that might be better suited to what I want to do, or should I take ZLib.NET and build off that as a start?

PS:

Jon's asked for more detail, so here it is.

I'm trying to implement MCCP 2. This involves a signal being sent in the network stream, and everything after this signal is a zlib compressed data stream. There's links to exactly what they mean by that in the above link. Anyway, to be clear, I'm on the recieving end of this (client, not server), and I have a bunch of data read out of the network stream already, and the toggle will be in the middle of this (in all likelyhood atleast), so any solution needs to be able to have some extra data fed into it, before it takes over the NetworkStream (or I manually feed in the rest of the data).

+2  A: 

Does the accepted answer in this post: Zlib-compatible compression streams, help you at all?

JMD
I'll admit to having seen that, and not having tried GZipStream, but mostly because of the big note on the zlib homepage saying that it wasn't gzip, so I thought I'd ask first anyway.
Matthew Scharley
GZipStream doesn't work, it throws an InvalidDataException, complaining about headers and magic numbers.
Matthew Scharley
A: 

I can recommend you Gerry Shaw's zlib wrapper for .NET:

http://www.organicbit.com/zip/

0xA3
This is prerelease, and I'm building against mono, so I'm tempted to just save the headache and steer clear, but I'll still check it out.
Matthew Scharley
We have been using this in production for more than 2 years now, both with .NET and with Mono. No pain so far.
0xA3
+3  A: 

SharpZipLib does support ZLib. Look at this FAQ entry.

Additionally, have you checked whether the System.IO.Compression namespace supports what you need?

I wouldn't use an IEnumerable<byte> though - streams are designed to be chained together.

EDIT: Okay... it sounds like you need a stream which supports buffering, but with more control than BufferedStream provides. You'd need to "rewind" the stream if you saw the decompression toggle, and then create a GZipStream on top of it. Your buffer would need to be at least as big as your biggest call to Read() so that you could always have enough buffer to rewind.

Jon Skeet
I agree on your point about the IEnumerable thing... but the fact of the matter is, I can't find a way to push data that I've already read into the zlib stream (since this transition happens midstream) before connecting the network stream to it. Any suggestions there?
Matthew Scharley
It's not entirely clear to me what you're doing. Do you have two different output streams, and you want to switch between them? In fact, I don't really "get" whether you're reading or writing. More explanation in the question might yield better ideas :)
Jon Skeet
As requested, more info!
Matthew Scharley
Ok, I wrapped my NetworkStream with a BufferedStream and... Nothing. BeginRead just hangs there doing nothing. Presumably it's waiting for a full buffers worth first, but I as using a 4k read buffer before, and obviously a login screen isn't going to take up that much space.
Matthew Scharley
I did away with the BufferedStream in favour of just reading byte by byte anyway, since my processing function is a byte by byte state machine anyway.
Matthew Scharley
Cool - that makes life a lot simpler :)
Jon Skeet
A: 

As far as I know the ZLib (gzip) library doesn't support listing the files in the header. Assuming that matters to you, but it seems a big shortcoming. This was when I used the sharp zip library a while ago, so I'm willing to delete this :)

Chris S
This is compression over a network for a remote console. There is no filename. So it doesn't quite matter. But as a response to your answer, there's quite a few compressions that don't (gzip and bzip2 come to mind) which is why they are generally used in tandem with tar.
Matthew Scharley
This was actually the .NET library for compression (gzip off the top of my head) that didn't display the filenames
Chris S
Sorry monoxide I should've read the question more clearly...bye bye post in 10 minutes
Chris S
+1  A: 

Included in DotNetZip there is a ZlibStream, for compressing or decompressing zlib streams of data. You didn't ask, but there is also a GZipStream and a DeflateStream. As well as a ZlibCodec class, if that is your thing. (just inflates or deflates buffers, as opposed to streams).

DotNetZip is a fully-managed library with a liberal license. You don't need to use any of the .zip capability to get at the Zlib stuff. And the zlib stuff is packaged as a separate (smaller) DLL just for this purpose.

Cheeso