Node definition manager refactor (#7016)
[oweals/minetest.git] / src / itemstackmetadata.cpp
1 #include "itemstackmetadata.h"
2 #include "util/serialize.h"
3 #include "util/strfnd.h"
4
5 #define DESERIALIZE_START '\x01'
6 #define DESERIALIZE_KV_DELIM '\x02'
7 #define DESERIALIZE_PAIR_DELIM '\x03'
8 #define DESERIALIZE_START_STR "\x01"
9 #define DESERIALIZE_KV_DELIM_STR "\x02"
10 #define DESERIALIZE_PAIR_DELIM_STR "\x03"
11
12 #define TOOLCAP_KEY "tool_capabilities"
13
14 void ItemStackMetadata::clear()
15 {
16         Metadata::clear();
17         updateToolCapabilities();
18 }
19
20 bool ItemStackMetadata::setString(const std::string &name, const std::string &var)
21 {
22         bool result = Metadata::setString(name, var);
23         if (name == TOOLCAP_KEY)
24                 updateToolCapabilities();
25         return result;
26 }
27
28 void ItemStackMetadata::serialize(std::ostream &os) const
29 {
30         std::ostringstream os2;
31         os2 << DESERIALIZE_START;
32         for (const auto &stringvar : m_stringvars) {
33                 if (!stringvar.first.empty() || !stringvar.second.empty())
34                         os2 << stringvar.first << DESERIALIZE_KV_DELIM
35                                 << stringvar.second << DESERIALIZE_PAIR_DELIM;
36         }
37         os << serializeJsonStringIfNeeded(os2.str());
38 }
39
40 void ItemStackMetadata::deSerialize(std::istream &is)
41 {
42         std::string in = deSerializeJsonStringIfNeeded(is);
43
44         m_stringvars.clear();
45
46         if (!in.empty()) {
47                 if (in[0] == DESERIALIZE_START) {
48                         Strfnd fnd(in);
49                         fnd.to(1);
50                         while (!fnd.at_end()) {
51                                 std::string name = fnd.next(DESERIALIZE_KV_DELIM_STR);
52                                 std::string var  = fnd.next(DESERIALIZE_PAIR_DELIM_STR);
53                                 m_stringvars[name] = var;
54                         }
55                 } else {
56                         // BACKWARDS COMPATIBILITY
57                         m_stringvars[""] = in;
58                 }
59         }
60         updateToolCapabilities();
61 }
62
63 void ItemStackMetadata::updateToolCapabilities()
64 {
65         if (contains(TOOLCAP_KEY)) {
66                 toolcaps_overridden = true;
67                 toolcaps_override = ToolCapabilities();
68                 std::istringstream is(getString(TOOLCAP_KEY));
69                 toolcaps_override.deserializeJson(is);
70         } else {
71                 toolcaps_overridden = false;
72         }
73 }
74
75 void ItemStackMetadata::setToolCapabilities(const ToolCapabilities &caps)
76 {
77         std::ostringstream os;
78         caps.serializeJson(os);
79         setString(TOOLCAP_KEY, os.str());
80 }
81
82 void ItemStackMetadata::clearToolCapabilities()
83 {
84         setString(TOOLCAP_KEY, "");
85 }