liblcf
Loading...
Searching...
No Matches
ldb_reader.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 <fstream>
11#include <cerrno>
12#include <cstring>
13
14#include "lcf/ldb/reader.h"
15#include "lcf/ldb/chunks.h"
16#include "lcf/reader_util.h"
17#include "reader_struct.h"
18
19namespace lcf {
20
21void LDB_Reader::PrepareSave(rpg::Database& db) {
22 ++db.system.save_count;
23}
24
25std::unique_ptr<lcf::rpg::Database> LDB_Reader::Load(StringView filename, StringView encoding) {
26 std::ifstream stream(ToString(filename), std::ios::binary);
27 if (!stream.is_open()) {
28 fprintf(stderr, "Failed to open LDB file `%s' for reading : %s\n", ToString(filename).c_str(), strerror(errno));
29 return nullptr;
30 }
31 return LDB_Reader::Load(stream, encoding);
32}
33
34bool LDB_Reader::Save(StringView filename, const lcf::rpg::Database& db, StringView encoding, SaveOpt opt) {
35 std::ofstream stream(ToString(filename), std::ios::binary);
36 if (!stream.is_open()) {
37 fprintf(stderr, "Failed to open LDB file `%s' for writing : %s\n", ToString(filename).c_str(), strerror(errno));
38 return false;
39 }
40 return LDB_Reader::Save(stream, db, encoding, opt);
41}
42
43bool LDB_Reader::SaveXml(StringView filename, const lcf::rpg::Database& db) {
44 std::ofstream stream(ToString(filename), std::ios::binary);
45 if (!stream.is_open()) {
46 fprintf(stderr, "Failed to open LDB XML file `%s' for writing : %s\n", ToString(filename).c_str(), strerror(errno));
47 return false;
48 }
49 return LDB_Reader::SaveXml(stream, db);
50}
51
52std::unique_ptr<lcf::rpg::Database> LDB_Reader::LoadXml(StringView filename) {
53 std::ifstream stream(ToString(filename), std::ios::binary);
54 if (!stream.is_open()) {
55 fprintf(stderr, "Failed to open LDB XML file `%s' for reading : %s\n", ToString(filename).c_str(), strerror(errno));
56 return nullptr;
57 }
58 return LDB_Reader::LoadXml(stream);
59}
60
61std::unique_ptr<lcf::rpg::Database> LDB_Reader::Load(std::istream& filestream, StringView encoding) {
62 LcfReader reader(filestream, ToString(encoding));
63 if (!reader.IsOk()) {
64 LcfReader::SetError("Couldn't parse database file.\n");
65 return nullptr;
66 }
67 std::string header;
68 reader.ReadString(header, reader.ReadInt());
69 if (header.length() != 11) {
70 LcfReader::SetError("This is not a valid RPG2000 database.\n");
71 return nullptr;
72 }
73 if (header != "LcfDataBase") {
74 fprintf(stderr, "Warning: This header is not LcfDataBase and might not be a valid RPG2000 database.\n");
75 }
76 auto db = std::make_unique<lcf::rpg::Database>();
77 db->ldb_header = header;
78 TypeReader<rpg::Database>::ReadLcf(*db, reader, 0);
79
80 const auto engine = GetEngineVersion(*db);
81 // Delayed initialization of some actor fields because they are engine
82 // dependent
83 for (auto& actor: db->actors) {
84 actor.Setup(engine == EngineVersion::e2k3);
85 }
86
87 return db;
88}
89
90bool LDB_Reader::Save(std::ostream& filestream, const lcf::rpg::Database& db, StringView encoding, SaveOpt opt) {
91 const auto engine = GetEngineVersion(db);
92 LcfWriter writer(filestream, engine, ToString(encoding));
93 if (!writer.IsOk()) {
94 LcfReader::SetError("Couldn't parse database file.\n");
95 return false;
96 }
97 std::string header;
98 if ( db.ldb_header.empty() || !bool(opt & SaveOpt::ePreserveHeader)) {
99 header = "LcfDataBase";
100 } else {
101 header= db.ldb_header;
102 }
103 writer.WriteInt(header.size());
104 writer.Write(header);
105 TypeReader<rpg::Database>::WriteLcf(db, writer);
106 return true;
107}
108
109bool LDB_Reader::SaveXml(std::ostream& filestream, const lcf::rpg::Database& db) {
110 const auto engine = GetEngineVersion(db);
111 XmlWriter writer(filestream, engine);
112 if (!writer.IsOk()) {
113 LcfReader::SetError("Couldn't parse database file.\n");
114 return false;
115 }
116 writer.BeginElement("LDB");
117 TypeReader<rpg::Database>::WriteXml(db, writer);
118 writer.EndElement("LDB");
119 return true;
120}
121
122std::unique_ptr<lcf::rpg::Database> LDB_Reader::LoadXml(std::istream& filestream) {
123 XmlReader reader(filestream);
124 if (!reader.IsOk()) {
125 LcfReader::SetError("Couldn't parse database file.\n");
126 return nullptr;;
127 }
128 auto db = std::make_unique<lcf::rpg::Database>();
129 reader.SetHandler(new RootXmlHandler<rpg::Database>(*db, "LDB"));
130 reader.Parse();
131
132 const auto engine = GetEngineVersion(*db);
133 // Delayed initialization of some actor fields because they are engine
134 // dependent
135 for (auto& actor: db->actors) {
136 actor.Setup(engine == EngineVersion::e2k3);
137 }
138
139 return db;
140}
141
142} // namespace lcf
Definition: dbarray.cpp:13
EngineVersion GetEngineVersion(const lcf::rpg::Database &db)
Definition: saveopt.cpp:6