liblcf
lsd_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 <cmath>
11 #include <fstream>
12 #include <cerrno>
13 #include <cstring>
14 
15 #include "lsd_reader.h"
16 #include "lsd_chunks.h"
17 #include "ldb_reader.h"
18 #include "rpg_save.h"
19 #include "reader_util.h"
20 #include "reader_struct.h"
21 
22 double LSD_Reader::ToTDateTime(std::time_t const t) {
23  // 25569 is UnixDateDelta: number of days between 1970-01-01 and 1900-01-01
24  return(t / 86400.0 + 25569.0);
25 }
26 
27 std::time_t LSD_Reader::ToUnixTimestamp(double const ms) {
28  return(std::time_t(ms * 86400.0 - 25569.0 * 86400.0 + 0.5));
29 }
30 
31 double LSD_Reader::GenerateTimestamp(std::time_t const t) {
32  return ToTDateTime(t);
33 }
34 
35 void LSD_Reader::PrepareSave(RPG::Save& save, int32_t version) {
36  ++save.system.save_count;
38  save.easyrpg_data.version = version;
39 }
40 
41 std::unique_ptr<RPG::Save> LSD_Reader::Load(const std::string& filename, const std::string& encoding) {
42  std::ifstream stream(filename.c_str(), std::ios::binary);
43  if (!stream.is_open()) {
44  fprintf(stderr, "Failed to open LSD file `%s' for reading : %s\n", filename.c_str(), strerror(errno));
45  return nullptr;
46  }
47  return LSD_Reader::Load(stream, encoding);
48 }
49 
50 bool LSD_Reader::Save(const std::string& filename, const RPG::Save& save, const std::string& encoding) {
51  std::ofstream stream(filename.c_str(), std::ios::binary);
52  if (!stream.is_open()) {
53  fprintf(stderr, "Failed to open LSD file `%s' for writing : %s\n", filename.c_str(), strerror(errno));
54  return false;
55  }
56  return LSD_Reader::Save(stream, save, encoding);
57 }
58 
59 bool LSD_Reader::SaveXml(const std::string& filename, const RPG::Save& save) {
60  std::ofstream stream(filename.c_str(), std::ios::binary);
61  if (!stream.is_open()) {
62  fprintf(stderr, "Failed to open LSD XML file `%s' for writing : %s\n", filename.c_str(), strerror(errno));
63  return false;
64  }
65  return LSD_Reader::SaveXml(stream, save);
66 }
67 
68 std::unique_ptr<RPG::Save> LSD_Reader::LoadXml(const std::string& filename) {
69  std::ifstream stream(filename.c_str(), std::ios::binary);
70  if (!stream.is_open()) {
71  fprintf(stderr, "Failed to open LSD XML file `%s' for reading : %s\n", filename.c_str(), strerror(errno));
72  return nullptr;
73  }
74  return LSD_Reader::LoadXml(stream);
75 }
76 
77 std::unique_ptr<RPG::Save> LSD_Reader::Load(std::istream& filestream, const std::string &encoding) {
78  LcfReader reader(filestream, encoding);
79  if (!reader.IsOk()) {
80  LcfReader::SetError("Couldn't parse save file.\n");
81  return std::unique_ptr<RPG::Save>();
82  }
83  std::string header;
84  reader.ReadString(header, reader.ReadInt());
85  if (header.length() != 11) {
86  LcfReader::SetError("This is not a valid RPG2000 save.\n");
87  return std::unique_ptr<RPG::Save>();
88  }
89  if (header != "LcfSaveData") {
90  fprintf(stderr, "Warning: This header is not LcfSaveData and might not be a valid RPG2000 save.\n");
91  }
92  RPG::Save* save = new RPG::Save();
93  Struct<RPG::Save>::ReadLcf(*save, reader);
94  return std::unique_ptr<RPG::Save>(save);
95 }
96 
97 bool LSD_Reader::Save(std::ostream& filestream, const RPG::Save& save, const std::string &encoding) {
98  LcfWriter writer(filestream, encoding);
99  if (!writer.IsOk()) {
100  LcfReader::SetError("Couldn't parse save file.\n");
101  return false;
102  }
103  const std::string header("LcfSaveData");
104  writer.WriteInt(header.size());
105  writer.Write(header);
106 
107  Struct<RPG::Save>::WriteLcf(save, writer);
108  return true;
109 }
110 
111 bool LSD_Reader::SaveXml(std::ostream& filestream, const RPG::Save& save) {
112  XmlWriter writer(filestream);
113  if (!writer.IsOk()) {
114  LcfReader::SetError("Couldn't parse save file.\n");
115  return false;
116  }
117 
118  writer.BeginElement("LSD");
119  Struct<RPG::Save>::WriteXml(save, writer);
120  writer.EndElement("LSD");
121  return true;
122 }
123 
124 std::unique_ptr<RPG::Save> LSD_Reader::LoadXml(std::istream& filestream) {
125  XmlReader reader(filestream);
126  if (!reader.IsOk()) {
127  LcfReader::SetError("Couldn't parse save file.\n");
128  return std::unique_ptr<RPG::Save>();
129  }
130 
131  RPG::Save* save = new RPG::Save();
132  reader.SetHandler(new RootXmlHandler<RPG::Save>(*save, "LSD"));
133  reader.Parse();
134  return std::unique_ptr<RPG::Save>(save);
135 }
136 
137 RPG::Save LSD_Reader::ClearDefaults(const RPG::Save& save_in, const RPG::MapInfo& map_info, const RPG::Map& map) {
138  auto save = save_in;
139 
140  save.system.UnFixup();
141  for (auto& actor: save.actors) {
142  actor.UnFixup();
143  }
144  save.map_info.UnFixup(map);
145  save.map_info.UnFixup(map_info);
146 
147  return save;
148 }
LDB_Reader::Save
bool Save(const std::string &filename, const std::string &encoding, SaveOpt opt=SaveOpt::eNone)
Definition: ldb_reader.cpp:33
LSD_Reader::GenerateTimestamp
double GenerateTimestamp(std::time_t const t=std::time(NULL))
Definition: lsd_reader.cpp:31
RPG::SaveTitle::timestamp
double timestamp
Definition: rpg_savetitle.h:25
XmlReader
Definition: reader_xml.h:31
RPG::SaveSystem::UnFixup
void UnFixup()
Definition: rpg_fixup.cpp:148
LSD_Reader::ToUnixTimestamp
std::time_t ToUnixTimestamp(double const ms)
Definition: lsd_reader.cpp:27
XmlReader::SetHandler
void SetHandler(XmlHandler *handler)
Definition: reader_xml.cpp:80
LcfWriter::WriteInt
void WriteInt(int val)
Definition: writer_lcf.cpp:51
RPG::SaveEasyRpgData::version
int32_t version
Definition: rpg_saveeasyrpgdata.h:24
rpg_save.h
RPG::Save
Definition: rpg_save.h:36
reader_util.h
XmlWriter::EndElement
void EndElement(const std::string &name)
Definition: writer_xml.cpp:177
reader_struct.h
LcfWriter
Definition: writer_lcf.h:27
RPG::Save::system
SaveSystem system
Definition: rpg_save.h:40
LcfReader::ReadInt
int ReadInt()
Definition: reader_lcf.cpp:84
Struct::WriteXml
static void WriteXml(const S &obj, XmlWriter &stream)
Definition: reader_struct_impl.h:157
XmlWriter
Definition: writer_xml.h:22
LcfWriter::IsOk
bool IsOk() const
Definition: writer_lcf.cpp:125
RPG::Map
Definition: rpg_map.h:26
LcfReader::ReadString
void ReadString(std::string &ref, size_t size)
Definition: reader_lcf.cpp:186
LcfWriter::Write
void Write(const void *ptr, size_t size, size_t nmemb)
Definition: writer_lcf.cpp:24
LSD_Reader::ClearDefaults
RPG::Save ClearDefaults(const RPG::Save &save, const RPG::MapInfo &map_info, const RPG::Map &map)
Definition: lsd_reader.cpp:137
RootXmlHandler
Definition: reader_struct.h:725
LcfReader::SetError
static void SetError(const char *fmt,...)
Definition: reader_lcf.cpp:278
LSD_Reader::Save
bool Save(const std::string &filename, const RPG::Save &save, const std::string &encoding)
Definition: lsd_reader.cpp:50
Struct::WriteLcf
static void WriteLcf(const S &obj, LcfWriter &stream)
Definition: reader_struct_impl.h:104
LSD_Reader::ToTDateTime
double ToTDateTime(std::time_t const t)
Definition: lsd_reader.cpp:22
lsd_reader.h
RPG::SaveSystem::save_count
int32_t save_count
Definition: rpg_savesystem.h:115
LSD_Reader::SaveXml
bool SaveXml(const std::string &filename, const RPG::Save &save)
Definition: lsd_reader.cpp:59
Struct::ReadLcf
static void ReadLcf(S &obj, LcfReader &stream)
Definition: reader_struct_impl.h:57
lsd_chunks.h
RPG::MapInfo
Definition: rpg_mapinfo.h:28
XmlReader::Parse
void Parse()
Definition: reader_xml.cpp:67
LSD_Reader::Load
std::unique_ptr< RPG::Save > Load(const std::string &filename, const std::string &encoding)
Definition: lsd_reader.cpp:41
LcfReader::IsOk
bool IsOk() const
Definition: reader_lcf.cpp:192
RPG::Save::title
SaveTitle title
Definition: rpg_save.h:39
RPG::Save::easyrpg_data
SaveEasyRpgData easyrpg_data
Definition: rpg_save.h:54
XmlWriter::IsOk
bool IsOk() const
Definition: writer_xml.cpp:199
LcfReader
Definition: reader_lcf.h:35
LSD_Reader::LoadXml
std::unique_ptr< RPG::Save > LoadXml(const std::string &filename)
Definition: lsd_reader.cpp:68
LSD_Reader::PrepareSave
void PrepareSave(RPG::Save &save, int32_t version=0)
Definition: lsd_reader.cpp:35
XmlWriter::BeginElement
void BeginElement(const std::string &name)
Definition: writer_xml.cpp:161
XmlReader::IsOk
bool IsOk() const
Definition: reader_xml.cpp:55
ldb_reader.h