Раздувание данных TMX с использованием Base64 и Zlib - C++

Я искал в Интернете способ преобразования данных TMX в какие-то полезные данные, но я не могу использовать Zlib для надувания данных, которые я получаю от функции декодирования Base64. Я не знаю, так ли это работает, но из того, что я осмотрел, я догадываюсь, что я должен дефлировать код, а затем накачать его с помощью Zlib.

Итак: TMX Data -> Base64 -> Decode -> Decoded Data -> Zlib -> Inflate -> Используемые данные?

Вот мой исходный код:

const std::string EncryptedString = "eJxjZGBgYMSCZYCYHYilccgPNnVqOLAQmjp2PFgPiJmh6iSBWApKI7OlkNTQAgMA4AIDoQ==";

FILE *wfile;
// Will contain decoded data
wfile = fopen("testFile", "w");

fprintf(wfile, base64_decode(EncryptedString).c_str());

Затем я открываю тот же файл с декодированными данными, который:

xœcd```Ä‚e€˜ˆ¥qÈ6uj8°š:v<Xˆ™¡ê$X
J#³¥ÔÐ

И попробуйте накачать его с помощью Zlib, используя функцию надувания Zlib в документе

FILE *source;
// Contains decoded data.
source = fopen("testFile", "r");

FILE *dest;
// We write decompressed data to this file.
dest = fopen("testOutFile", "w");

zerr(Z_Inflate(source, dest));

Тем не менее, Zlib возвращает сообщение об ошибке "Неверные или неполные данные выкачки"

Вот код для функции Zlib:

inline int Z_Inflate(FILE *source, FILE *dest)
{
int ret;
unsigned have;
z_stream strm;
Bytef in[CHUNK];
Bytef out[CHUNK];

/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
    return ret;

/* decompress until deflate stream ends or end of file */
do {
    strm.avail_in = fread(in, 1, CHUNK, source);
    if (ferror(source)) {
        (void)inflateEnd(&strm);
        return Z_ERRNO;
    }
    if (strm.avail_in == 0)
        break;
    strm.next_in = in;

    /* run inflate() on input until output buffer not full */
    do {
        strm.avail_out = CHUNK;
        strm.next_out = out;
        ret = inflate(&strm, Z_NO_FLUSH);
        assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
        switch (ret) {
        case Z_NEED_DICT:
            ret = Z_DATA_ERROR;     /* and fall through */
        case Z_DATA_ERROR:
        case Z_MEM_ERROR:
            (void)inflateEnd(&strm);
            return ret;
        }
        have = CHUNK - strm.avail_out;
        if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
            (void)inflateEnd(&strm);
            return Z_ERRNO;
        }
    } while (strm.avail_out == 0);

    /* done when inflate() says it's done */
} while (ret != Z_STREAM_END);

/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}

/* report a zlib or i/o error */
inline void zerr(int ret)
{
fputs("zpipe: ", stderr);
switch (ret) {
case Z_ERRNO:
    if (ferror(stdin))
        fputs("error reading stdin\n", stderr);
    if (ferror(stdout))
        fputs("error writing stdout\n", stderr);
    break;
case Z_STREAM_ERROR:
    fputs("invalid compression level\n", stderr);
    break;
case Z_DATA_ERROR:
    fputs("invalid or incomplete deflate data\n", stderr);
    break;
case Z_MEM_ERROR:
    fputs("out of memory\n", stderr);
    break;
case Z_VERSION_ERROR:
    fputs("zlib version mismatch!\n", stderr);
}
}

Любая помощь будет принята с благодарностью, так как я хотел бы использовать плиточный редактор для файлов моей карты. Кажется, это больше похоже на головную боль.

1 ответ

Решение

Работал на меня. После декодирования строки base64 я получаю в шестнадцатеричном виде:

78 9c 63 64 60 60 60 c4 82 65 80 98 1d 88 a5 71
c8 0f 36 75 6a 38 b0 10 9a 3a 76 3c 58 0f 88 99
a1 ea 24 81 58 0a 4a 23 b3 a5 90 d4 d0 02 03 00
e0 02 03 a1 

Это допустимый поток zlib, который без ошибок декодируется в шестнадцатеричном виде:

01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 1c 00 00 00 07 00 00 00
1b 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
1c 00 00 00 07 00 00 00 1b 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 1c 00 00 00 07 00 00 00
1b 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
1c 00 00 00 07 00 00 00 1b 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 1c 00 00 00 07 00 00 00
1b 00 00 00 01 00 00 00 26 00 00 00 26 00 00 00
26 00 00 00 26 00 00 00 26 00 00 00 26 00 00 00
12 00 00 00 07 00 00 00 1b 00 00 00 01 00 00 00
07 00 00 00 07 00 00 00 07 00 00 00 07 00 00 00
07 00 00 00 07 00 00 00 07 00 00 00 2e 00 00 00
03 00 00 00 01 00 00 00 19 00 00 00 1a 00 00 00
19 00 00 00 19 00 00 00 1a 00 00 00 19 00 00 00
1a 00 00 00 03 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00

На какой ты машине? Если это Windows (дрожь), вам может потребоваться убедиться, что ваши функции stdio не пытаются выполнять преобразования в конце строки. использование fopen(..., "wb") а также fopen(..., "rb") для двоичного письма и чтения.

Другие вопросы по тегам