Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / net / module_common.cpp
blobaacf80a93c255adb9ab17720b3cb54e69662ac1c
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "stdnet.h"
19 #include "nel/misc/sstring.h"
20 #include "nel/net/module_common.h"
22 using namespace std;
23 using namespace NLMISC;
25 namespace NLNET
28 TParsedCommandLine::TParsedCommandLine(const TParsedCommandLine& copy)
29 :ParamName(copy.ParamName), ParamValue(copy.ParamValue)
34 uint first = 0, last = (uint)copy.SubParams.size();
35 SubParams.resize( last );
36 for (; first != last; ++first)
38 // calls recursively copy constructor
39 SubParams[first] = new TParsedCommandLine(*copy.SubParams[first]);
44 TParsedCommandLine::~TParsedCommandLine()
46 clear();
49 void TParsedCommandLine::clear()
51 for (std::vector<TParsedCommandLine*>::iterator it=SubParams.begin(); it!=SubParams.end(); ++it)
53 delete (*it);
55 SubParams.clear();
56 ParamName.clear();
57 ParamValue.clear();
60 bool TParsedCommandLine::parseParamList(const std::string &rawParamString)
62 // Cleanup the struct
63 clear();
65 return _parseParamList(rawParamString);
68 std::string TParsedCommandLine::toString() const
70 string ret;
72 ret = ParamName;
73 if (!ParamValue.empty())
75 ret += " = "+ParamValue;
78 if (!SubParams.empty())
80 ret += " ( ";
82 for (uint i=0; i<SubParams.size(); ++i)
84 if (i >0)
85 ret += " ";
86 ret += SubParams[i]->toString();
89 ret += " ) ";
92 return ret;
97 bool TParsedCommandLine::_parseParamList(const std::string &rawParamString)
99 CSString parsedString(rawParamString);
101 for (CSString part = parsedString.strtok(" \t", true, false);
102 !part.empty();
103 part = parsedString.strtok(" \t", true, false))
105 if (part[0] == '(')
107 // this is a sub parameter list
108 if (SubParams.empty() || SubParams.back()->ParamName.empty())
110 nlwarning("While parsing param string '%s', missing param header", rawParamString.c_str());
111 return false;
113 if (!SubParams.back()->ParamValue.empty())
115 nlwarning("While parsing param string '%s', Invalid sub param header '%s' for sub part '%s', must not define value",
116 rawParamString.c_str(),
117 SubParams.back()->ParamName.c_str(),
118 part.c_str());
120 return false;
123 if (part[part.size()-1] != ')')
125 nlwarning("While parsing param string '%s', Invalid sub param value '%s' missing closing ')'",
126 rawParamString.c_str(),
127 part.c_str());
129 return false;
132 part = part.stripBlockDelimiters();
134 if (!SubParams.back()->_parseParamList(part))
136 nlwarning("Error parsing sub param list for header '%s' in '%s'",
137 SubParams.back()->ParamName.c_str(),
138 rawParamString.c_str());
139 return false;
142 else if (part[part.size()-1] == ')')
144 nlwarning("While parsing param string '%s', Invalid param value '%s' : missing openning '('",
145 rawParamString.c_str(),
146 part.c_str());
148 return false;
150 else if (part[0] == '\"')
152 // this is a quoted parameter value
153 if (SubParams.empty() || !SubParams.back()->ParamValue.empty())
155 nlwarning("While parsing param string '%s', param '%s' already have the value '%s'",
156 rawParamString.c_str(),
157 SubParams.back()->ParamName.c_str(),
158 SubParams.back()->ParamValue.c_str());
159 return false;
161 SubParams.back()->ParamValue = part.unquote();
163 else
165 // this is a simple param
166 CSString name = part.splitTo('=', true, true);
167 if (name.empty())
169 nlwarning("Can't find param name for value '%s' in the param string '%s'",
170 part.c_str(),
171 rawParamString.c_str());
172 return false;
174 CSString value = part.strtok("=");
176 SubParams.push_back( new TParsedCommandLine() );
177 SubParams.back()->ParamName = name;
178 SubParams.back()->ParamValue = value;
182 return true;
185 const TParsedCommandLine *TParsedCommandLine::getParam(const std::string &name) const
187 vector<string> parts;
188 NLMISC::explode(name, string("."), parts);
190 return _getParam(parts.begin(), parts.end());
193 void TParsedCommandLine::setParam(const std::string &name, const std::string &value)
195 vector<string> parts;
196 NLMISC::explode(name, string("."), parts);
198 if (!name.empty())
200 // at least one part in the name
201 // check if sub ojbcct exist
202 TParsedCommandLine *sub = _getParam(parts.begin(), (parts.begin()+1));
203 if (sub == NULL)
205 TParsedCommandLine * newElem = new TParsedCommandLine();
206 newElem->ParamName = parts[0];
207 SubParams.push_back(newElem);
208 sub = SubParams.back();
211 if (!name.empty())
213 // name is more deep, need to resurse
214 parts.erase(parts.begin());
215 std::string subName;
216 join(parts, ".", subName);
217 sub->setParam(subName, value);
219 else
221 // last level, set the value
222 sub->ParamValue = value;
227 const TParsedCommandLine *TParsedCommandLine::_getParam(std::vector<std::string>::iterator it, std::vector<std::string>::iterator end) const
229 return const_cast<TParsedCommandLine&>(*this)._getParam(it, end);
232 TParsedCommandLine *TParsedCommandLine::_getParam(std::vector<std::string>::iterator it, std::vector<std::string>::iterator end)
234 if (it == end)
236 // end of recursion, we found the searched param
237 return this;
240 // look for sub param
241 for (uint i=0; i<SubParams.size(); ++i)
243 if (SubParams[i]->ParamName == *it)
244 return SubParams[i]->_getParam(++it, end);
247 // parameter not found
248 return NULL;
252 } // namespace NLMISC