blob: 6c3bad4ae1526086135a688b5235074c54072dc2 [file] [log] [blame]
Ethan Yonker74db1572015-10-28 12:44:49 -05001/*
2 Copyright 2015 _that/TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include "../data.hpp"
20#include "pages.hpp"
21#include "resources.hpp"
22
23#include "twmsg.h"
thatd62d8862015-12-20 20:40:15 +010024#include <cctype>
Ethan Yonker74db1572015-10-28 12:44:49 -050025
26std::string Message::GetFormatString(const std::string& name) const
27{
28 std::string resname;
29 size_t pos = name.find('=');
30 if (pos == std::string::npos)
31 resname = name;
32 else
33 resname = name.substr(0, pos);
34
35 std::string formatstr = resourceLookup(resname);
Ethan Yonker9ce95912015-12-20 22:50:23 -060036 bool notfound = formatstr.empty() || formatstr.substr(0, 2) == "{@"; // HACK: TODO: integrate this with resource-not-found logic
Ethan Yonker74db1572015-10-28 12:44:49 -050037 if (notfound && pos != std::string::npos)
38 // resource not found - use the default format string specified after "="
39 formatstr = name.substr(pos + 1);
40 return formatstr;
41}
42
43// Look up in local replacement vars first, if not found then use outer lookup object
44class LocalLookup : public StringLookup
45{
46 const std::vector<std::string>& vars;
47 const StringLookup& next;
48 public:
49 LocalLookup(const std::vector<std::string>& vars, const StringLookup& next) : vars(vars), next(next) {}
50 virtual std::string operator()(const std::string& name) const
51 {
52 if (!name.empty() && isdigit(name[0])) { // {1}..{9}
53 int i = atoi(name.c_str());
54 if (i > 0 && i <= (int)vars.size())
55 return vars[i - 1];
56 }
57 return next(name);
58 }
59};
60
61// conversion to final string
62Message::operator std::string() const
63{
64 // do resource lookup
65 std::string str = GetFormatString(name);
66
67 LocalLookup lookup(variables, varLookup);
68
69 // now insert stuff into curly braces
70
71 size_t pos = 0;
72 while ((pos = str.find('{', pos)) < std::string::npos) {
73 size_t end = str.find('}', pos);
74 if (end == std::string::npos)
75 break;
76
77 std::string varname = str.substr(pos + 1, end - pos - 1);
78 std::string vartext = lookup(varname);
79
80 str.replace(pos, end - pos + 1, vartext);
81 }
82 // TODO: complain about too many or too few numbered replacement variables
83 return str;
84}
85
86/*
87Resource manager lookup
88*/
89class ResourceLookup : public StringLookup
90{
91public:
92 virtual std::string operator()(const std::string& name) const
93 {
94 const ResourceManager* res = PageManager::GetResources();
95 if (res)
96 return res->FindString(name);
97 return name;
98 }
99};
100ResourceLookup resourceLookup;
101
102
103/*
104DataManager lookup
105*/
106class DataLookup : public StringLookup
107{
108public:
109 virtual std::string operator()(const std::string& name) const
110 {
111 std::string value;
112 if (DataManager::GetValue(name, value) == 0)
113 return value;
114 else
115 return "";
116 }
117};
118DataLookup dataLookup;
119
120
121// Utility functions to create messages. Short names to make usage convenient.
122Message Msg(const char* name)
123{
124 return Message(msg::kNormal, name, resourceLookup, dataLookup);
125}
126
127Message Msg(msg::Kind kind, const char* name)
128{
129 return Message(kind, name, resourceLookup, dataLookup);
130}