使用 Base64 和 Zlib 膨胀 TMX 数据 - C++

Inflating TMX Data using Base64 & Zlib - C++

本文关键字:数据 C++ TMX 膨胀 Base64 Zlib 使用      更新时间:2023-10-16

我在网上搜索了一种将TMX数据转换为某种可用数据的方法,但我似乎无法使用Zlib来扩展我从Base64 Decode函数返回的数据。我不知道它是否就是这样工作的,但从我环顾四周的情况来看,我猜我应该对代码进行通货紧缩,然后用Zlib进行膨胀。

所以:TMX数据->Base64->解码->解码数据->Zlib->充气->可用数据?

这是我的源代码:

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 stdinn", stderr);
    if (ferror(stdout))
        fputs("error writing stdoutn", stderr);
    break;
case Z_STREAM_ERROR:
    fputs("invalid compression leveln", stderr);
    break;
case Z_DATA_ERROR:
    fputs("invalid or incomplete deflate datan", stderr);
    break;
case Z_MEM_ERROR:
    fputs("out of memoryn", stderr);
    break;
case Z_VERSION_ERROR:
    fputs("zlib version mismatch!n", stderr);
}
}

如果有任何帮助,我们将不胜感激,因为我很乐意为我的地图文件使用平铺编辑器。这似乎更令人头疼。

为我工作。解码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")进行二进制写入和读取。