C++ zlib inflate failed - перевод исправления С#?

Я пытаюсь раздуть строку с помощью zlib deflate, но это не удается, по-видимому, потому, что у нее нет правильного заголовка. Я читал в другом месте, что решение этой проблемы на С#:

public static byte[] FlateDecode(byte[] inp, bool strict) {
    MemoryStream stream = new MemoryStream(inp);
    InflaterInputStream zip = new InflaterInputStream(stream);
    MemoryStream outp = new MemoryStream();
    byte[] b = new byte[strict ? 4092 : 1];
    try {
        int n;
        while ((n = zip.Read(b, 0, b.Length)) > 0) {
            outp.Write(b, 0, n);
        }
        zip.Close();
        outp.Close();
        return outp.ToArray();
    }
    catch {
        if (strict)
            return null;
        return outp.ToArray();
    }
}

Но я ничего не знаю о C#. Я могу предположить, что все, что он делает, это добавляет префикс к строке, но что это за префикс, я понятия не имею. Сможет ли кто-нибудь сформулировать эту функцию (или даже просто создание заголовка и конкатенацию строк) на С++?

Данные, которые я пытаюсь раздуть, взяты из PDF-файла с использованием дефляции zlib.

Спасибо миллион, Вятт


person wyatt    schedule 14.12.2010    source источник
comment
вы можете отформатировать свой код, выбрав его и нажав значок «101010». Я сделал это на этот раз.   -  person Steve Townsend    schedule 14.12.2010
comment
Извините, просто оплошность. Научи меня работать в четыре утра.   -  person wyatt    schedule 14.12.2010
comment
Во-первых, попробуйте на самом деле выкачать некоторые случайные данные с помощью zlib. Если ваш код может раздуть его обратно, значит, проблема в имеющихся у вас данных. В противном случае опубликуйте свой код C++, чтобы мы могли вместе искать возможные ошибки.   -  person Sergei Tachenov    schedule 14.12.2010
comment
Код приходит напрямую от разработчика - работает нормально. Я считаю, что проблема заключается в необязательных верхнем и, возможно, нижнем колонтитуле, которые формат pdf либо добавляет, либо исключает, но люди не обсуждают это подробно.   -  person wyatt    schedule 14.12.2010


Ответы (2)


Мне больше повезло с использованием SharpZipLib для zlib взаимодействия, чем с собственными классами .Net Framework. Это правильно обрабатывает потоки из C++ (zlib native) и из классов сжатия Java без каких-либо забавных действий.

person Steve Townsend    schedule 14.12.2010
comment
Спасибо за это, и я буду иметь это в виду на будущее. К сожалению, в настоящее время я не использую .NET. Знаете ли вы какое-либо альтернативное решение, которое будет работать с mingw? - person wyatt; 14.12.2010
comment
@wyatt - я вижу, что мой ответ упустил вашу мысль. Почему бы вам не опубликовать свой код C++, который не работает, и взять его оттуда? Вы можете отредактировать код C++ в вопросе. zlib в C++ должен быть данком, в зависимости от того, откуда пришел поток (какая информация также должна быть включена в вопрос). - person Steve Townsend; 14.12.2010
comment
Если вы не используете .NET, какова цель этого вопроса? Если ваш вопрос касается кода C++, это может помочь НЕ публиковать код C# и задавать вопрос .NET. - person Security Hound; 14.12.2010
comment
@Ramhound - я думаю, проблема в чтении потока с использованием zlib в C++. Предположение заключалось в том, что логика С# в вопросе может решить проблему, но в этом нет необходимости. Если это необходимо, то версия C++ не должна быть слишком сложной для разработки. - person Steve Townsend; 14.12.2010
comment
@ Стив - я снова прочитал вопрос, и теперь цель вопроса имеет смысл. - person Security Hound; 14.12.2010
comment
Дефлированный код взят из pdf, я добавлю это к вопросу через секунду. Код, который я использую, взят прямо с сайта zlib по адресу zlib.net/zpipe.c описано на zlib.net/zlib_how.html - person wyatt; 14.12.2010

Я не вижу никаких префиксов, извините. Вот как выглядит логика; извините, это не на С++:

MemoryStream stream = new MemoryStream(inp);
InflaterInputStream zip = new InflaterInputStream(stream);

Создайте поток раздувания из переданных данных

MemoryStream outp = new MemoryStream();

Создайте поток буфера памяти для вывода

byte[] b = new byte[strict ? 4092 : 1];
try {
    int n;
    while ((n = zip.Read(b, 0, b.Length)) > 0) {

Если вы используете строгий режим, прочитайте до 4092 байт — или 1 в не- строгий режим - в байтовый буфер

        outp.Write(b, 0, n);

Запишите все декодированные байты (может быть меньше 4092) в поток выходного буфера памяти.

    zip.Close();
    outp.Close();
    return outp.ToArray();

Очистите и верните поток выходного буфера памяти в виде массива.

Однако я немного запутался: почему бы просто не вырезать массив b из n элементов и не вернуть его, а не использовать MemoryStream? Код также должен действительно позаботиться об очистке потоков памяти и zip при исключении (например, с использованием using), поскольку все они IDisposable, но я думаю, что это не очень важно, поскольку они не соответствуют дескрипторам файлов ввода-вывода, только структуры памяти.

person Rup    schedule 14.12.2010