forked from clickteam-plugin/TileMap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTMOStream.h
107 lines (90 loc) · 2.84 KB
/
TMOStream.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#pragma once
#include <iostream>
#define MINIZ_HEADER_FILE_ONLY 1
#include "miniz.c"
class TMOStream : public std::ofstream {
int compressionLevel;
unsigned blockBeginPos;
unsigned char * compressionBuffer;
unsigned compressionBufferSize;
public:
TMOStream(const char * fileName, int compressionLevel)
: std::ofstream(fileName, std::ofstream::out | std::ofstream::binary),
compressionLevel(compressionLevel), blockBeginPos(0), compressionBuffer(0),
compressionBufferSize(0)
{
}
~TMOStream() { delete[] compressionBuffer; }
// Begins a block (Map, Layer, Tileset)
void beginBlock(unsigned id)
{
// 4-byte identifier
*this << id;
// Write the current position so we can go back and update the block
// size
blockBeginPos = tellp();
// Dummy block size
*this << 0;
}
// Ends a block by writing its size to the block header
void endBlock()
{
unsigned currentPos = tellp();
seekp(blockBeginPos);
*this << (unsigned int)(currentPos - blockBeginPos - sizeof(unsigned));
seekp(currentPos);
}
// Writes z-lib compressed data preceded by the size
void writeCompressedData(unsigned char * data, unsigned size)
{
// Invalid data - write length 0 and quit
if (!data || !size) {
*this << 0;
return;
}
// Buffer size needed to compress the data
mz_ulong allocSize = mz_compressBound(size);
// Buffer already exists, but is too small...
if (compressionBuffer && compressionBufferSize < allocSize) {
delete[] compressionBuffer;
compressionBuffer = 0;
}
if (!compressionBuffer) {
compressionBuffer = new (std::nothrow) unsigned char[allocSize];
compressionBufferSize = compressionBuffer ? allocSize : 0;
}
if (compressionBuffer) {
mz_compress2(compressionBuffer, &allocSize, data, size, compressionLevel);
*this << allocSize;
write((char *)compressionBuffer, allocSize);
}
// Failed - write an empty buffer...
else {
*this << 0;
}
}
// Write a binary block
template <class T> TMOStream & operator<<(T i)
{
write(reinterpret_cast<const char *>(&i), sizeof(T));
return *this;
}
// Write a character sequence
inline TMOStream & operator<<(const char * str)
{
write(str, strlen(str));
return *this;
}
// Write a string preceded by its length (char)
void writeShortStr(const char * str)
{
put(strlen(str));
*this << str;
}
// Write a string preceded by its length (int)
void writeLongStr(const char * str)
{
*this << strlen(str);
*this << str;
}
};