liblcf
Toggle main menu visibility
Loading...
Searching...
No Matches
dbstring_struct.cpp
Go to the documentation of this file.
1
/*
2
* This file is part of liblcf. Copyright (c) liblcf authors.
3
* https://github.com/EasyRPG/liblcf - https://easyrpg.org
4
*
5
* liblcf is Free/Libre Open Source Software, released under the MIT License.
6
* For the full copyright and license information, please view the COPYING
7
* file that was distributed with this source code.
8
*/
9
10
#include "lcf/dbstring.h"
11
#include "
log.h
"
12
#include "
reader_struct.h
"
13
#include <iostream>
14
15
namespace
lcf
{
16
17
/*
18
DBString has the structure of a Pascal String (Length + Data).
19
It could be a primitive type but vector<DBString> needs special handling.
20
21
Vector<DBString> is Maniac Patch and is sparse:
22
When size is > 0xFFFFFFFF there is a gap of "0x800000000 - size"
23
In other cases it is as above: Size Data ... Size Data
24
*/
25
26
template
<>
27
struct
RawStruct
<DBString> {
28
static
void
ReadLcf
(DBString& ref, LcfReader& stream, uint32_t length);
29
static
void
WriteLcf
(
const
DBString& ref, LcfWriter& stream);
30
static
int
LcfSize
(
const
DBString& ref, LcfWriter& stream);
31
static
void
WriteXml
(
const
DBString& ref, XmlWriter& stream);
32
static
void
BeginXml
(DBString& ref, XmlReader& stream);
33
};
34
35
template
<>
36
struct
RawStruct
<std::vector<DBString> > {
37
static
void
ReadLcf
(std::vector<DBString>& ref, LcfReader& stream, uint32_t length);
38
static
void
WriteLcf
(
const
std::vector<DBString>& ref, LcfWriter& stream);
39
static
int
LcfSize
(
const
std::vector<DBString>& ref, LcfWriter& stream);
40
static
void
WriteXml
(
const
std::vector<DBString>& ref, XmlWriter& stream);
41
static
void
BeginXml
(std::vector<DBString>& ref, XmlReader& stream);
42
};
43
44
void
RawStruct<DBString>::ReadLcf
(DBString& ref, LcfReader& stream, uint32_t length) {
45
stream.ReadString(ref, length);
46
#ifdef LCF_DEBUG_TRACE
47
fprintf(stderr,
" %s\n"
, ref.c_str());
48
#endif
49
}
50
51
void
RawStruct<DBString>::WriteLcf
(
const
DBString& ref, LcfWriter& stream) {
52
stream.Write(ref);
53
}
54
55
int
RawStruct<DBString>::LcfSize
(
const
DBString& ref, LcfWriter& stream) {
56
return
stream.Decode(ref).size();
57
}
58
59
void
RawStruct<DBString>::WriteXml
(
const
DBString& ref, XmlWriter& stream) {
60
stream.Write(ref);
61
}
62
63
class
DbStringXmlHandler
:
public
XmlHandler {
64
private
:
65
DBString&
ref
;
66
public
:
67
DbStringXmlHandler
(DBString&
ref
) :
68
ref
(
ref
) {}
69
void
StartElement
(XmlReader&
/* stream */
,
const
char
*
/* name */
,
const
char
**
/* atts */
) {
70
// no-op
71
}
72
void
EndElement
(XmlReader&
/* stream */
,
const
char
*
/* name */
) {
73
// no-op
74
}
75
void
CharacterData
(XmlReader&
/* stream */
,
const
std::string& data) {
76
ref
= DBString(data);
77
}
78
};
79
80
void
RawStruct<DBString>::BeginXml
(DBString& ref, XmlReader& stream) {
81
stream.SetHandler(
new
DbStringXmlHandler
(ref));
82
}
83
84
void
RawStruct<std::vector<DBString>
>
::ReadLcf
(std::vector<DBString>& ref, LcfReader& stream, uint32_t length) {
85
int
index = 0;
86
DBString string_var;
87
88
uint32_t startpos = stream.Tell();
89
uint32_t endpos = startpos + length;
90
while
(stream.Tell() < endpos) {
91
// If size is bigger than 4 bytes, size indicates the gap size
92
// Otherwise it indicates the size of the next string
93
auto
size = stream.ReadUInt64();
94
if
(size > std::numeric_limits<uint32_t>::max()) {
95
index +=
static_cast<
uint32_t
>
(0x800000000 - size);
96
97
ref.resize(index);
98
}
else
{
99
stream.ReadString(string_var, size);
100
#ifdef LCF_DEBUG_TRACE
101
fprintf(stderr,
"t[%d]: %s\n"
, index + 1, string_var.c_str());
102
#endif
103
ref.push_back(string_var);
104
105
++index;
106
}
107
}
108
109
if
(stream.Tell() != endpos) {
110
Log::Warning
(
"vector<string> Misaligned at 0x%"
PRIx32
""
, stream.Tell());
111
stream.Seek(endpos);
112
}
113
}
114
115
void
RawStruct<std::vector<DBString>
>
::WriteLcf
(
const
std::vector<DBString>& ref, LcfWriter& stream) {
116
int
gap_size = 0;
117
118
for
(
size_t
i = 0; i < ref.size(); ++i) {
119
const
auto
& e = ref[i];
120
if
(e.empty()) {
121
++gap_size;
122
continue
;
123
}
124
125
if
(gap_size > 0) {
126
stream.WriteUInt64(0x800000000 -
static_cast<
uint64_t
>
(gap_size));
127
gap_size = 0;
128
}
129
130
auto
len =
RawStruct<DBString>::LcfSize
(e, stream);
131
stream.WriteInt(len);
132
RawStruct<DBString>::WriteLcf
(e, stream);
133
}
134
}
135
136
int
RawStruct<std::vector<DBString>
>
::LcfSize
(
const
std::vector<DBString>& ref, LcfWriter& stream) {
137
int
result = 0;
138
int
gap_size = 0;
139
140
for
(
size_t
i = 0; i < ref.size(); ++i) {
141
const
auto
& e = ref[i];
142
if
(e.empty()) {
143
++gap_size;
144
continue
;
145
}
146
147
if
(gap_size > 0) {
148
result += LcfReader::UInt64Size(0x800000000 -
static_cast<
uint64_t
>
(gap_size));
149
gap_size = 0;
150
}
151
152
int
size =
RawStruct<DBString>::LcfSize
(e, stream);
153
result += LcfReader::IntSize(size);
154
result += size;
155
}
156
157
return
result;
158
}
159
160
void
RawStruct<std::vector<DBString>
>
::WriteXml
(
const
std::vector<DBString>& ref, XmlWriter& stream) {
161
for
(
size_t
i = 0; i < ref.size(); ++i) {
162
const
auto
& e = ref[i];
163
if
(e.empty()) {
164
continue
;
165
}
166
167
stream.BeginElement(
"item"
, i + 1);
168
RawStruct<DBString>::WriteXml
(e, stream);
169
stream.EndElement(
"item"
);
170
}
171
}
172
173
class
DbStringVectorXmlHandler
:
public
XmlHandler {
174
public
:
175
DbStringVectorXmlHandler
(std::vector<DBString>&
ref
) :
ref
(
ref
) {}
176
177
void
StartElement
(XmlReader& stream,
const
char
*
name
,
const
char
** atts) {
178
if
(strcmp(
name
,
"item"
) != 0) {
179
Log::Error
(
"XML: Expecting %s but got %s"
,
"item"
,
name
);
180
return
;
181
}
182
183
int
last_id = -1;
184
int
id
= -1;
185
for
(
int
i = 0; atts[i] != NULL && atts[i + 1] != NULL; i += 2) {
186
if
(strcmp(atts[i],
"id"
) == 0) {
187
id
= atoi(atts[i + 1]);
188
break
;
189
}
190
}
191
192
if
(
id
<= last_id ||
id
< -1) {
193
Log::Error
(
"XML: Bad Id %d / %d"
,
id
, last_id);
194
return
;
195
}
196
197
ref
.resize(
id
);
198
DBString& obj =
ref
.back();
199
200
stream.SetHandler(
new
DbStringXmlHandler
(obj));
201
}
202
private
:
203
std::vector<DBString>&
ref
;
204
};
205
206
void
RawStruct<std::vector<DBString>
>
::BeginXml
(std::vector<DBString>& obj, XmlReader& stream) {
207
stream.SetHandler(
new
DbStringVectorXmlHandler
(obj));
208
}
209
210
}
//namspace lcf
lcf::DbStringVectorXmlHandler
Definition
dbstring_struct.cpp:173
lcf::DbStringVectorXmlHandler::ref
std::vector< DBString > & ref
Definition
dbstring_struct.cpp:203
lcf::DbStringVectorXmlHandler::DbStringVectorXmlHandler
DbStringVectorXmlHandler(std::vector< DBString > &ref)
Definition
dbstring_struct.cpp:175
lcf::DbStringVectorXmlHandler::StartElement
void StartElement(XmlReader &stream, const char *name, const char **atts)
Definition
dbstring_struct.cpp:177
lcf::DbStringXmlHandler
Definition
dbstring_struct.cpp:63
lcf::DbStringXmlHandler::ref
DBString & ref
Definition
dbstring_struct.cpp:65
lcf::DbStringXmlHandler::StartElement
void StartElement(XmlReader &, const char *, const char **)
Definition
dbstring_struct.cpp:69
lcf::DbStringXmlHandler::CharacterData
void CharacterData(XmlReader &, const std::string &data)
Definition
dbstring_struct.cpp:75
lcf::DbStringXmlHandler::DbStringXmlHandler
DbStringXmlHandler(DBString &ref)
Definition
dbstring_struct.cpp:67
lcf::DbStringXmlHandler::EndElement
void EndElement(XmlReader &, const char *)
Definition
dbstring_struct.cpp:72
log.h
lcf::Log::Warning
void Warning(const char *fmt,...) LIKE_PRINTF
Definition
log_handler.cpp:80
lcf::Log::Error
void Error(const char *fmt,...) LIKE_PRINTF
Definition
log_handler.cpp:90
lcf
Definition
dbarray.cpp:13
lcf::name
const char *const Struct< rpg::Actor >::name
Definition
fwd_struct_impl.h:16
reader_struct.h
lcf::RawStruct< std::vector< DBString > >::ReadLcf
static void ReadLcf(std::vector< DBString > &ref, LcfReader &stream, uint32_t length)
Definition
dbstring_struct.cpp:84
lcf::RawStruct< std::vector< DBString > >::WriteLcf
static void WriteLcf(const std::vector< DBString > &ref, LcfWriter &stream)
Definition
dbstring_struct.cpp:115
lcf::RawStruct< std::vector< DBString > >::WriteXml
static void WriteXml(const std::vector< DBString > &ref, XmlWriter &stream)
Definition
dbstring_struct.cpp:160
lcf::RawStruct< std::vector< DBString > >::BeginXml
static void BeginXml(std::vector< DBString > &ref, XmlReader &stream)
Definition
dbstring_struct.cpp:206
lcf::RawStruct< std::vector< DBString > >::LcfSize
static int LcfSize(const std::vector< DBString > &ref, LcfWriter &stream)
Definition
dbstring_struct.cpp:136
lcf::RawStruct
Definition
reader_struct.h:117
lcf::RawStruct::WriteXml
static void WriteXml(const T &ref, XmlWriter &stream)
lcf::RawStruct::BeginXml
static void BeginXml(T &ref, XmlReader &stream)
lcf::RawStruct::ReadLcf
static void ReadLcf(T &ref, LcfReader &stream, uint32_t length)
lcf::RawStruct::WriteLcf
static void WriteLcf(const T &ref, LcfWriter &stream)
lcf::RawStruct::LcfSize
static int LcfSize(const T &ref, LcfWriter &stream)
src
dbstring_struct.cpp
Generated on
for liblcf by
1.17.0