0

我在网上搜索了一种将 TMX 数据转换为某种可用数据的方法,但我似乎无法使用 Zlib 对从 Base64 解码函数返回的数据进行膨胀。我不知道它是否是这样工作的,但是从我环顾四周的情况来看,我猜我应该对代码进行 Deflate,然后用 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 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);
}
}

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

4

1 回答 1

0

为我工作。解码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 流,它在 hex 中没有错误地解码:

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")andfopen(..., "rb")进行二进制写入和读取。

于 2013-07-17T02:20:26.527 回答