liblcf
lsd_reader.cpp
Go to the documentation of this file.
1/*
2 * This file is part of liblcf. Copyright (c) 2021 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 "lcf/lsd/reader.h"
16#include "lcf/lsd/chunks.h"
17#include "lcf/rpg/save.h"
18#include "lcf/reader_util.h"
19#include "reader_struct.h"
20
21namespace lcf {
22
23double LSD_Reader::ToTDateTime(std::time_t t) {
24 // 25569 is UnixDateDelta: number of days between 1970-01-01 and 1900-01-01
25 return(t / 86400.0 + 25569.0);
26}
27
28std::time_t LSD_Reader::ToUnixTimestamp(double ms) {
29 return(std::time_t(ms * 86400.0 - 25569.0 * 86400.0 + 0.5));
30}
31
32double LSD_Reader::GenerateTimestamp(std::time_t t) {
33 return ToTDateTime(t);
34}
35
36void LSD_Reader::PrepareSave(rpg::Save& save, int32_t version) {
37 ++save.system.save_count;
38 save.title.timestamp = LSD_Reader::GenerateTimestamp();
39 save.easyrpg_data.version = version;
40}
41
42std::unique_ptr<rpg::Save> LSD_Reader::Load(StringView filename, StringView encoding) {
43 std::ifstream stream(ToString(filename), std::ios::binary);
44 if (!stream.is_open()) {
45 fprintf(stderr, "Failed to open LSD file `%s' for reading : %s\n", ToString(filename).c_str(), strerror(errno));
46 return nullptr;
47 }
48 return LSD_Reader::Load(stream, encoding);
49}
50
51bool LSD_Reader::Save(StringView filename, const rpg::Save& save, EngineVersion engine, StringView encoding) {
52 std::ofstream stream(ToString(filename), std::ios::binary);
53 if (!stream.is_open()) {
54 fprintf(stderr, "Failed to open LSD file `%s' for writing : %s\n", ToString(filename).c_str(), strerror(errno));
55 return false;
56 }
57 return LSD_Reader::Save(stream, save, engine, encoding);
58}
59
60bool LSD_Reader::SaveXml(StringView filename, const rpg::Save& save, EngineVersion engine) {
61 std::ofstream stream(ToString(filename), std::ios::binary);
62 if (!stream.is_open()) {
63 fprintf(stderr, "Failed to open LSD XML file `%s' for writing : %s\n", ToString(filename).c_str(), strerror(errno));
64 return false;
65 }
66 return LSD_Reader::SaveXml(stream, save, engine);
67}
68
69std::unique_ptr<rpg::Save> LSD_Reader::LoadXml(StringView filename) {
70 std::ifstream stream(ToString(filename), std::ios::binary);
71 if (!stream.is_open()) {
72 fprintf(stderr, "Failed to open LSD XML file `%s' for reading : %s\n", ToString(filename).c_str(), strerror(errno));
73 return nullptr;
74 }
75 return LSD_Reader::LoadXml(stream);
76}
77
78std::unique_ptr<rpg::Save> LSD_Reader::Load(std::istream& filestream, StringView encoding) {
79 LcfReader reader(filestream, ToString(encoding));
80 if (!reader.IsOk()) {
81 LcfReader::SetError("Couldn't parse save file.\n");
82 return std::unique_ptr<rpg::Save>();
83 }
84 std::string header;
85 reader.ReadString(header, reader.ReadInt());
86 if (header.length() != 11) {
87 LcfReader::SetError("This is not a valid RPG2000 save.\n");
88 return std::unique_ptr<rpg::Save>();
89 }
90 if (header != "LcfSaveData") {
91 fprintf(stderr, "Warning: This header is not LcfSaveData and might not be a valid RPG2000 save.\n");
92 }
93 rpg::Save* save = new rpg::Save();
94 Struct<rpg::Save>::ReadLcf(*save, reader);
95 return std::unique_ptr<rpg::Save>(save);
96}
97
98bool LSD_Reader::Save(std::ostream& filestream, const rpg::Save& save, EngineVersion engine, StringView encoding) {
99 LcfWriter writer(filestream, engine, ToString(encoding));
100 if (!writer.IsOk()) {
101 LcfReader::SetError("Couldn't parse save file.\n");
102 return false;
103 }
104 const std::string header("LcfSaveData");
105 writer.WriteInt(header.size());
106 writer.Write(header);
107
108 Struct<rpg::Save>::WriteLcf(save, writer);
109 return true;
110}
111
112bool LSD_Reader::SaveXml(std::ostream& filestream, const rpg::Save& save, EngineVersion engine) {
113 XmlWriter writer(filestream, engine);
114 if (!writer.IsOk()) {
115 LcfReader::SetError("Couldn't parse save file.\n");
116 return false;
117 }
118
119 writer.BeginElement("LSD");
120 Struct<rpg::Save>::WriteXml(save, writer);
121 writer.EndElement("LSD");
122 return true;
123}
124
125std::unique_ptr<rpg::Save> LSD_Reader::LoadXml(std::istream& filestream) {
126 XmlReader reader(filestream);
127 if (!reader.IsOk()) {
128 LcfReader::SetError("Couldn't parse save file.\n");
129 return std::unique_ptr<rpg::Save>();
130 }
131
132 rpg::Save* save = new rpg::Save();
133 reader.SetHandler(new RootXmlHandler<rpg::Save>(*save, "LSD"));
134 reader.Parse();
135 return std::unique_ptr<rpg::Save>(save);
136}
137
138} //namespace lcf
static void WriteXml(const S &obj, XmlWriter &stream)
static void WriteLcf(const S &obj, LcfWriter &stream)
static void ReadLcf(S &obj, LcfReader &stream)
Definition: dbarray.cpp:13