Попытка сжать в формате zlib с низким уровнем доступа к потоку - PullRequest
0 голосов
/ 07 февраля 2011

Я пытаюсь реализовать спецификацию Microsoft для формата message.rpmsg (здесь: http://msdn.microsoft.com/en-us/library/ee625343(v=EXCHG.80).aspx).. Спецификация - странная комбинация сжатого потока zlib, упакованного в пакеты. Для каждого пакета мне нужно поместить в заголовок пакетаколичество байтов в несжатом потоке (должно быть 4096, в противном случае Outlook кашляет, несмотря на спецификации), размер сжатого буфера и магический маркер.

Мой код находится в .net, и желательноЯ ищу полностью управляемую библиотеку.

Просмотр различных библиотек (SharpZlibLib, zlib.NET, пространство имен Microsoft Compression.Deflate) - я не смог найти общедоступные записи, которые для каждой операции «Запись»сделает: - вернет количество сжатых байтов; - гарантирует границу BYTE (FLUSH_SYNC); - в идеале, без подмены или слишком большого изменения кода

У библиотек, на которые я смотрел, есть поток вывода, из которого можно прочитать(весь сжатый поток) - но не предоставляют доступ к самим пакетам.

ПокаЯ использую исходную библиотеку zlib и нативный zlib1.dll после многих модификаций contrib / dotzlib - однако я бы хотел избежать очевидных проблем с производительностью и развертыванием моего текущего обходного пути

Поэтому я ищу библиотеку, которая позволит мне указать режим FLUSH и дать мне доступ к размеру каждого пакета.

Кроме того, если кто-то может оценить различные библиотеки (zlib.net, SharpZipLib кажетсябыть самым вездесущим - что-нибудь еще?), и такие области, как производительность / качество / поддержка

Большое спасибо Uri

1 Ответ

0 голосов
/ 07 февраля 2011

Не проверено, но с использованием zlib.net Я бы ожидал, что сработает что-то подобное ниже;обратите внимание, что я использую MemoryStream здесь, чтобы избежать необходимости искать (поскольку это не может быть универсально поддержано - так как длина блока составляет максимум 4 КБ, меня это совсем не беспокоит), но если вы знаю вы можете искать, вы можете написать фиктивную 0 для сжатой длины, затем записать данные, затем искать в обратном направлении, чтобы обновить сжатую длину, и снова искать вперед до конца:

static void WriteBlock(Stream destination, byte[] arr, int offset, int length)
{
    using (var ms = new MemoryStream())
    {
        using (var zlib = new zlib.ZOutputStream(ms))
        {
            zlib.Write(arr, offset, length);
        }
        WriteInt32LittleEndian(destination, 0x00000FA0);
        WriteInt32LittleEndian(destination, length);
        WriteInt32LittleEndian(destination, (int)ms.Length);
        destination.Write(ms.GetBuffer(), 0, (int)ms.Length);

    }
}
static void WriteInt32LittleEndian(Stream destination, int value)
{
    destination.WriteByte((byte)value);
    destination.WriteByte((byte)(value >> 8));
    destination.WriteByte((byte)(value >> 16));
    destination.WriteByte((byte)(value >> 24));
}
...