liblcf
lmu_reader.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 <fstream>
11 #include <cerrno>
12 #include <cstring>
13 
14 #include "lmu_reader.h"
15 #include "lmu_chunks.h"
16 #include "reader_lcf.h"
17 #include "reader_util.h"
18 #include "reader_struct.h"
19 
21  ++map.save_count;
22 }
23 
24 std::unique_ptr<RPG::Map> LMU_Reader::Load(const std::string& filename, const std::string& encoding) {
25  std::ifstream stream(filename.c_str(), std::ios::binary);
26  if (!stream.is_open()) {
27  fprintf(stderr, "Failed to open LMU file `%s' for reading : %s\n", filename.c_str(), strerror(errno));
28  return nullptr;
29  }
30  return LMU_Reader::Load(stream, encoding);
31 }
32 
33 bool LMU_Reader::Save(const std::string& filename, const RPG::Map& save, const std::string& encoding, SaveOpt opt) {
34  std::ofstream stream(filename.c_str(), std::ios::binary);
35  if (!stream.is_open()) {
36  fprintf(stderr, "Failed to open LMU file `%s' for writing : %s\n", filename.c_str(), strerror(errno));
37  return false;
38  }
39  return LMU_Reader::Save(stream, save, encoding, opt);
40 }
41 
42 bool LMU_Reader::SaveXml(const std::string& filename, const RPG::Map& save) {
43  std::ofstream stream(filename.c_str(), std::ios::binary);
44  if (!stream.is_open()) {
45  fprintf(stderr, "Failed to open LMU XML file `%s' for writing : %s\n", filename.c_str(), strerror(errno));
46  return false;
47  }
48  return LMU_Reader::SaveXml(stream, save);
49 }
50 
51 std::unique_ptr<RPG::Map> LMU_Reader::LoadXml(const std::string& filename) {
52  std::ifstream stream(filename.c_str(), std::ios::binary);
53  if (!stream.is_open()) {
54  fprintf(stderr, "Failed to open LMU XML file `%s' for reading : %s\n", filename.c_str(), strerror(errno));
55  return nullptr;
56  }
57  return LMU_Reader::LoadXml(stream);
58 }
59 
60 std::unique_ptr<RPG::Map> LMU_Reader::Load(std::istream& filestream, const std::string& encoding) {
61  LcfReader reader(filestream, encoding);
62  if (!reader.IsOk()) {
63  LcfReader::SetError("Couldn't parse map file.\n");
64  return std::unique_ptr<RPG::Map>();
65  }
66  std::string header;
67  reader.ReadString(header, reader.ReadInt());
68  if (header.length() != 10) {
69  LcfReader::SetError("This is not a valid RPG2000 map.\n");
70  return std::unique_ptr<RPG::Map>();
71  }
72  if (header != "LcfMapUnit") {
73  fprintf(stderr, "Warning: This header is not LcfMapUnit and might not be a valid RPG2000 map.\n");
74  }
75 
76  auto map = std::unique_ptr<RPG::Map>(new RPG::Map());
77  map->lmu_header = std::move(header);
78  Struct<RPG::Map>::ReadLcf(*map, reader);
79  return map;
80 }
81 
82 bool LMU_Reader::Save(std::ostream& filestream, const RPG::Map& map, const std::string& encoding, SaveOpt opt) {
83  LcfWriter writer(filestream, encoding);
84  if (!writer.IsOk()) {
85  LcfReader::SetError("Couldn't parse map file.\n");
86  return false;
87  }
88  std::string header;
89  if ( map.lmu_header.empty() || !bool(opt & SaveOpt::ePreserveHeader)) {
90  header = "LcfMapUnit";
91  } else {
92  header= map.lmu_header;
93  }
94  writer.WriteInt(header.size());
95  writer.Write(header);
96 
97  Struct<RPG::Map>::WriteLcf(map, writer);
98  return true;
99 }
100 
101 bool LMU_Reader::SaveXml(std::ostream& filestream, const RPG::Map& map) {
102  XmlWriter writer(filestream);
103  if (!writer.IsOk()) {
104  LcfReader::SetError("Couldn't parse map file.\n");
105  return false;
106  }
107  writer.BeginElement("LMU");
108  Struct<RPG::Map>::WriteXml(map, writer);
109  writer.EndElement("LMU");
110  return true;
111 }
112 
113 std::unique_ptr<RPG::Map> LMU_Reader::LoadXml(std::istream& filestream) {
114  XmlReader reader(filestream);
115  if (!reader.IsOk()) {
116  LcfReader::SetError("Couldn't parse map file.\n");
117  return std::unique_ptr<RPG::Map>();
118  }
119 
120  auto map = std::unique_ptr<RPG::Map>(new RPG::Map());
121  reader.SetHandler(new RootXmlHandler<RPG::Map>(*map, "LMU"));
122  reader.Parse();
123  return map;
124 }
125 
bool Save(const std::string &filename, const RPG::Map &map, const std::string &encoding, SaveOpt opt=SaveOpt::eNone)
Definition: lmu_reader.cpp:33
bool IsOk() const
Definition: writer_xml.cpp:199
void SetHandler(XmlHandler *handler)
Definition: reader_xml.cpp:80
static void ReadLcf(S &obj, LcfReader &stream)
void BeginElement(const std::string &name)
Definition: writer_xml.cpp:161
void WriteInt(int val)
Definition: writer_lcf.cpp:51
std::string lmu_header
Definition: rpg_map.h:28
void EndElement(const std::string &name)
Definition: writer_xml.cpp:177
static void WriteXml(const S &obj, XmlWriter &stream)
void Write(const void *ptr, size_t size, size_t nmemb)
Definition: writer_lcf.cpp:24
int32_t save_count
Definition: rpg_map.h:93
int ReadInt()
Definition: reader_lcf.cpp:84
bool SaveXml(const std::string &filename, const RPG::Map &map)
Definition: lmu_reader.cpp:42
void ReadString(std::string &ref, size_t size)
Definition: reader_lcf.cpp:186
void PrepareSave(RPG::Map &map)
Definition: lmu_reader.cpp:20
std::unique_ptr< RPG::Map > Load(const std::string &filename, const std::string &encoding)
Definition: lmu_reader.cpp:24
SaveOpt
Definition: lcf_saveopt.h:16
bool IsOk() const
Definition: writer_lcf.cpp:125
static void WriteLcf(const S &obj, LcfWriter &stream)
std::unique_ptr< RPG::Map > LoadXml(const std::string &filename)
Definition: lmu_reader.cpp:51
static void SetError(const char *fmt,...)
Definition: reader_lcf.cpp:278
bool IsOk() const
Definition: reader_xml.cpp:55
bool IsOk() const
Definition: reader_lcf.cpp:192
void Parse()
Definition: reader_xml.cpp:67