blob: 00c693150d93e8cbee5d7f8110890d5f6dbe500c [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"
24
25std::string Message::GetFormatString(const std::string& name) const
26{
27 std::string resname;
28 size_t pos = name.find('=');
29 if (pos == std::string::npos)
30 resname = name;
31 else
32 resname = name.substr(0, pos);
33
34 std::string formatstr = resourceLookup(resname);
35 bool notfound = formatstr.empty() || formatstr[0] == '['; // HACK: TODO: integrate this with resource-not-found logic
36 if (notfound && pos != std::string::npos)
37 // resource not found - use the default format string specified after "="
38 formatstr = name.substr(pos + 1);
39 return formatstr;
40}
41
42// Look up in local replacement vars first, if not found then use outer lookup object
43class LocalLookup : public StringLookup
44{
45 const std::vector<std::string>& vars;
46 const StringLookup& next;
47 public:
48 LocalLookup(const std::vector<std::string>& vars, const StringLookup& next) : vars(vars), next(next) {}
49 virtual std::string operator()(const std::string& name) const
50 {
51 if (!name.empty() && isdigit(name[0])) { // {1}..{9}
52 int i = atoi(name.c_str());
53 if (i > 0 && i <= (int)vars.size())
54 return vars[i - 1];
55 }
56 return next(name);
57 }
58};
59
60// conversion to final string
61Message::operator std::string() const
62{
63 // do resource lookup
64 std::string str = GetFormatString(name);
65
66 LocalLookup lookup(variables, varLookup);
67
68 // now insert stuff into curly braces
69
70 size_t pos = 0;
71 while ((pos = str.find('{', pos)) < std::string::npos) {
72 size_t end = str.find('}', pos);
73 if (end == std::string::npos)
74 break;
75
76 std::string varname = str.substr(pos + 1, end - pos - 1);
77 std::string vartext = lookup(varname);
78
79 str.replace(pos, end - pos + 1, vartext);
80 }
81 // TODO: complain about too many or too few numbered replacement variables
82 return str;
83}
84
85/*
86Resource manager lookup
87*/
88class ResourceLookup : public StringLookup
89{
90public:
91 virtual std::string operator()(const std::string& name) const
92 {
93 const ResourceManager* res = PageManager::GetResources();
94 if (res)
95 return res->FindString(name);
96 return name;
97 }
98};
99ResourceLookup resourceLookup;
100
101
102/*
103DataManager lookup
104*/
105class DataLookup : public StringLookup
106{
107public:
108 virtual std::string operator()(const std::string& name) const
109 {
110 std::string value;
111 if (DataManager::GetValue(name, value) == 0)
112 return value;
113 else
114 return "";
115 }
116};
117DataLookup dataLookup;
118
119
120// Utility functions to create messages. Short names to make usage convenient.
121Message Msg(const char* name)
122{
123 return Message(msg::kNormal, name, resourceLookup, dataLookup);
124}
125
126Message Msg(msg::Kind kind, const char* name)
127{
128 return Message(kind, name, resourceLookup, dataLookup);
129}