liblcf
Loading...
Searching...
No Matches
ldb_eventcommand.cpp
Go to the documentation of this file.
1/*
2 * This file is part of liblcf. Copyright (c) 2020 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 <string>
11#include <vector>
12#include "reader_struct.h"
13#include "rpg_eventcommand.h"
14
15template <>
16struct RawStruct<RPG::EventCommand> {
17 static void ReadLcf(RPG::EventCommand& ref, LcfReader& stream, uint32_t length);
18 static void WriteLcf(const RPG::EventCommand& ref, LcfWriter& stream);
19 static int LcfSize(const RPG::EventCommand& ref, LcfWriter& stream);
20 static void WriteXml(const RPG::EventCommand& ref, XmlWriter& stream);
21 static void BeginXml(RPG::EventCommand& ref, XmlReader& stream);
22};
23
24template <>
25struct RawStruct<std::vector<RPG::EventCommand> > {
26 static void ReadLcf(std::vector<RPG::EventCommand>& ref, LcfReader& stream, uint32_t length);
27 static void WriteLcf(const std::vector<RPG::EventCommand>& ref, LcfWriter& stream);
28 static int LcfSize(const std::vector<RPG::EventCommand>& ref, LcfWriter& stream);
29 static void WriteXml(const std::vector<RPG::EventCommand>& ref, XmlWriter& stream);
30 static void BeginXml(std::vector<RPG::EventCommand>& ref, XmlReader& stream);
31};
32
36void RawStruct<RPG::EventCommand>::ReadLcf(RPG::EventCommand& event_command, LcfReader& stream, uint32_t /* length */) {
37 stream.Read(event_command.code);
38 if (event_command.code != 0) {
39 stream.Read(event_command.indent);
40 stream.ReadString(event_command.string, stream.ReadInt());
41
42 auto& param_buf = stream.IntBuffer();
43
44 param_buf.clear();
45 for (int i = stream.ReadInt(); i > 0; i--) {
46 param_buf.push_back(stream.ReadInt());
47 }
48 if (!param_buf.empty()) {
49 event_command.parameters.reserve(param_buf.size());
50 event_command.parameters.assign(param_buf.begin(), param_buf.end());
51 }
52 }
53}
54
56 stream.Write(event_command.code);
57 stream.Write(event_command.indent);
58 stream.WriteInt(stream.Decode(event_command.string).size());
59 stream.Write(event_command.string);
60 int32_t count = (int32_t)event_command.parameters.size();
61 stream.Write(count);
62 for (int i = 0; i < count; i++)
63 stream.Write(event_command.parameters[i]);
64}
65
67 int result = 0;
68 result += LcfReader::IntSize(event_command.code);
69 result += LcfReader::IntSize(event_command.indent);
70 result += LcfReader::IntSize(stream.Decode(event_command.string).size());
71 result += stream.Decode(event_command.string).size();
72 int count = event_command.parameters.size();
73 result += LcfReader::IntSize(count);
74 for (int i = 0; i < count; i++)
75 result += LcfReader::IntSize(event_command.parameters[i]);
76 return result;
77}
78
80 stream.BeginElement("EventCommand");
81 stream.WriteNode<int32_t>("code", event_command.code);
82 stream.WriteNode<int32_t>("indent", event_command.indent);
83 stream.WriteNode<std::string>("string", event_command.string);
84 stream.WriteNode<std::vector<int32_t>>("parameters", event_command.parameters);
85 stream.EndElement("EventCommand");
86}
87
89private:
91 enum {
98public:
100 void StartElement(XmlReader& stream, const char* name, const char** /* atts */) {
101 if (strcmp(name, "code") == 0)
102 field = Code;
103 else if (strcmp(name, "indent") == 0)
104 field = Indent;
105 else if (strcmp(name, "string") == 0)
106 field = String;
107 else if (strcmp(name, "parameters") == 0)
109 else {
110 stream.Error("Unrecognized field '%s'", name);
111 field = None;
112 }
113 }
114 void EndElement(XmlReader& /* stream */, const char* /* name */) {
115 field = None;
116 }
117 void CharacterData(XmlReader& /* stream */, const std::string& data) {
118 switch (field) {
119 case None:
120 break;
121 case Code:
122 XmlReader::Read<int32_t>(ref.code, data);
123 break;
124 case Indent:
125 XmlReader::Read<int32_t>(ref.indent, data);
126 break;
127 case String:
128 XmlReader::Read<std::string>(ref.string, data);
129 break;
130 case Parameters:
131 XmlReader::Read<std::vector<int32_t>>(ref.parameters, data);
132 break;
133 }
134 }
135};
136
138 stream.SetHandler(new WrapperXmlHandler("EventCommand", new EventCommandXmlHandler(ref)));
139}
140
145 std::vector<RPG::EventCommand>& event_commands, LcfReader& stream, uint32_t length) {
146 // Event Commands is a special array
147 // Has no size information. Is terminated by 4 times 0x00.
148 unsigned long startpos = stream.Tell();
149 unsigned long endpos = startpos + length;
150
151 // Since we don't know the number of event parameters without reading, we store
152 // them all in a temporary buffer and then copy it to EventCommand::parameters.
153 // This prevents extra allocations from repeated calls to push_back().
154 for (;;) {
155 uint8_t ch = (uint8_t)stream.Peek();
156 if (ch == 0) {
157 stream.Seek(4, LcfReader::FromCurrent);
158 break;
159 }
160
161 if (stream.Tell() >= endpos) {
162 stream.Seek(endpos, LcfReader::FromStart);
163 fprintf(stderr, "Event command corrupted at %" PRIu32 "\n", stream.Tell());
164 for (;;) {
165 // Try finding the real end of the event command (4 0-bytes)
166 int i = 0;
167 for (; i < 4; ++i) {
168 stream.Read(ch);
169
170 if (ch != 0) {
171 break;
172 }
173 }
174
175 if (i == 4 || stream.Eof()) {
176 break;
177 }
178 }
179
180 break;
181 }
182
183 RPG::EventCommand command;
184 RawStruct<RPG::EventCommand>::ReadLcf(command, stream, 0);
185 event_commands.push_back(command);
186 }
187}
188
189void RawStruct<std::vector<RPG::EventCommand> >::WriteLcf(const std::vector<RPG::EventCommand>& event_commands, LcfWriter& stream) {
190 int count = event_commands.size();
191 for (int i = 0; i < count; i++)
192 RawStruct<RPG::EventCommand>::WriteLcf(event_commands[i], stream);
193 for (int i = 0; i < 4; i++)
194 stream.WriteInt(0);
195}
196
197int RawStruct<std::vector<RPG::EventCommand> >::LcfSize(const std::vector<RPG::EventCommand>& event_commands, LcfWriter& stream) {
198 int result = 0;
199 int count = event_commands.size();
200 for (int i = 0; i < count; i++)
201 result += RawStruct<RPG::EventCommand>::LcfSize(event_commands[i], stream);
202 result += 4;
203 return result;
204}
205
206void RawStruct<std::vector<RPG::EventCommand> >::WriteXml(const std::vector<RPG::EventCommand>& event_commands, XmlWriter& stream) {
207 std::vector<RPG::EventCommand>::const_iterator it;
208 for (it = event_commands.begin(); it != event_commands.end(); it++)
210}
211
213public:
214 EventCommandVectorXmlHandler(std::vector<RPG::EventCommand>& ref) : ref(ref) {}
215
216 void StartElement(XmlReader& stream, const char* name, const char** /* atts */) {
217 if (strcmp(name, "EventCommand") != 0)
218 stream.Error("Expecting %s but got %s", "EventCommand", name);
219 ref.resize(ref.size() + 1);
220 RPG::EventCommand& obj = ref.back();
221 stream.SetHandler(new EventCommandXmlHandler(obj));
222 }
223private:
224 std::vector<RPG::EventCommand>& ref;
225};
226
227void RawStruct<std::vector<RPG::EventCommand> >::BeginXml(std::vector<RPG::EventCommand>& obj, XmlReader& stream) {
229}
void StartElement(XmlReader &stream, const char *name, const char **)
std::vector< RPG::EventCommand > & ref
EventCommandVectorXmlHandler(std::vector< RPG::EventCommand > &ref)
enum EventCommandXmlHandler::@0 field
void EndElement(XmlReader &, const char *)
RPG::EventCommand & ref
void StartElement(XmlReader &stream, const char *name, const char **)
void CharacterData(XmlReader &, const std::string &data)
EventCommandXmlHandler(RPG::EventCommand &ref)
std::vector< int32_t > & IntBuffer()
Definition: reader_lcf.h:267
static int IntSize(unsigned int x)
Definition: reader_lcf.cpp:299
bool Eof() const
Definition: reader_lcf.cpp:196
void Seek(size_t pos, SeekMode mode=FromStart)
Definition: reader_lcf.cpp:200
int Peek()
Definition: reader_lcf.cpp:239
int ReadInt()
Definition: reader_lcf.cpp:84
uint32_t Tell()
Definition: reader_lcf.cpp:228
void ReadString(std::string &ref, size_t size)
Definition: reader_lcf.cpp:186
@ FromCurrent
Definition: reader_lcf.h:85
void Read(void *ptr, size_t size, size_t nmemb)
Definition: reader_lcf.cpp:47
void WriteInt(int val)
Definition: writer_lcf.cpp:51
void Write(const void *ptr, size_t size, size_t nmemb)
Definition: writer_lcf.cpp:24
std::string Decode(const std::string &str_to_encode)
Definition: writer_lcf.cpp:129
std::vector< int32_t > parameters
void SetHandler(XmlHandler *handler)
Definition: reader_xml.cpp:80
void Error(const char *fmt,...)
Definition: reader_xml.cpp:59
void BeginElement(const std::string &name)
Definition: writer_xml.cpp:161
void EndElement(const std::string &name)
Definition: writer_xml.cpp:177
void WriteNode(const std::string &name, const T &val)
Definition: writer_xml.cpp:155
Definition: rpg_actor.h:26
STL namespace.
static int LcfSize(const T &ref, LcfWriter &stream)
static void WriteXml(const T &ref, XmlWriter &stream)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t length)
static void WriteLcf(const T &ref, LcfWriter &stream)
static void BeginXml(T &ref, XmlReader &stream)