GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/db/itemoptiondb.cpp Lines: 8 57 14.0 %
Date: 2017-11-29 Branches: 2 106 1.9 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2016-2017  The ManaPlus Developers
4
 *
5
 *  This file is part of The ManaPlus Client.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "resources/db/itemoptiondb.h"
22
23
#include "configuration.h"
24
25
#include "utils/checkutils.h"
26
27
#include "resources/beingcommon.h"
28
29
#include "resources/db/itemfielddb.h"
30
31
#include "debug.h"
32
33
namespace
34
{
35
2
    ItemOptionDb::OptionInfos mOptions;
36
2
    const STD_VECTOR<ItemFieldType*> mEmptyOption;
37
    bool mLoaded = false;
38
}  // namespace
39
40
void ItemOptionDb::load()
41
{
42
    if (mLoaded)
43
        unload();
44
45
    logger->log1("Initializing item options database...");
46
    loadXmlFile(paths.getStringValue("itemOptionsFile"), SkipError_false);
47
    loadXmlFile(paths.getStringValue("itemOptionsPatchFile"), SkipError_true);
48
    loadXmlDir("itemOptionsPatchDir", loadXmlFile);
49
    mLoaded = true;
50
}
51
52
static void addFieldByName(STD_VECTOR<ItemFieldType*> &options,
53
                           XmlNodeConstPtr node,
54
                           const ItemFieldDb::FieldInfos &fields,
55
                           const char *const name)
56
{
57
    std::string value = XML::getProperty(node, name, "");
58
    if (value.empty())
59
        return;
60
61
    FOR_EACH (ItemFieldDb::FieldInfos::const_iterator, it, fields)
62
    {
63
        const std::string fieldName = (*it).first;
64
        if (fieldName == value)
65
        {
66
            options.push_back((*it).second);
67
            return;
68
        }
69
    }
70
}
71
72
static void readOptionFields(STD_VECTOR<ItemFieldType*> &options,
73
                             XmlNodeConstPtr node,
74
                             const ItemFieldDb::FieldInfos &fields)
75
{
76
    addFieldByName(options, node, fields, "field");
77
    for (int f = 0; f < 15; f ++)
78
    {
79
        const std::string field = strprintf("field%d", f);
80
        addFieldByName(options, node, fields, field.c_str());
81
    }
82
}
83
84
void ItemOptionDb::loadXmlFile(const std::string &fileName,
85
                               const SkipError skipError)
86
{
87
    XML::Document doc(fileName,
88
        UseVirtFs_true,
89
        skipError);
90
    XmlNodeConstPtrConst rootNode = doc.rootNode();
91
92
    if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "itemoptions"))
93
    {
94
        if (skipError == SkipError_true)
95
        {
96
            logger->log("ItemFieldDb: Error while loading %s!",
97
                fileName.c_str());
98
        }
99
        else
100
        {
101
            reportAlways("ItemFieldDb: Error while loading %s!",
102
                fileName.c_str());
103
        }
104
        return;
105
    }
106
107
    const ItemFieldDb::FieldInfos &requiredFields =
108
        ItemFieldDb::getRequiredFields();
109
    const ItemFieldDb::FieldInfos &addFields =
110
        ItemFieldDb::getAddFields();
111
112
    for_each_xml_child_node(node, rootNode)
113
    {
114
        if (xmlNameEqual(node, "include"))
115
        {
116
            const std::string name = XML::getProperty(node, "name", "");
117
            if (!name.empty())
118
                loadXmlFile(name, skipError);
119
            continue;
120
        }
121
        if (xmlNameEqual(node, "option"))
122
        {
123
            const int id = XML::getProperty(node,
124
                "id",
125
                0);
126
            if (id <= 0)
127
            {
128
                reportAlways("Empty id field in ItemOptionDb");
129
                continue;
130
            }
131
            STD_VECTOR<ItemFieldType*> &options = mOptions[id];
132
            readOptionFields(options, node, requiredFields);
133
            readOptionFields(options, node, addFields);
134
        }
135
    }
136
}
137
138
384
void ItemOptionDb::unload()
139
{
140
384
    logger->log1("Unloading item options database...");
141
384
    mOptions.clear();
142
384
    mLoaded = false;
143
384
}
144
145
const STD_VECTOR<ItemFieldType*> &ItemOptionDb::getFields(const int id)
146
{
147
    OptionInfos::const_iterator it = mOptions.find(id);
148
    if (it == mOptions.end())
149
        return mEmptyOption;
150
    return (*it).second;
151

6
}