1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core
3e5c31af7Sopenharmony_ci * ----------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief String template class.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
25e5c31af7Sopenharmony_ci#include "tcuDefs.hpp"
26e5c31af7Sopenharmony_ci
27e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_ci#include <sstream>
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_ciusing std::string;
32e5c31af7Sopenharmony_ciusing std::map;
33e5c31af7Sopenharmony_ciusing std::ostringstream;
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_cinamespace tcu
36e5c31af7Sopenharmony_ci{
37e5c31af7Sopenharmony_ci
38e5c31af7Sopenharmony_ciStringTemplate::StringTemplate (void)
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_ci}
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_ciStringTemplate::StringTemplate (const std::string& str)
43e5c31af7Sopenharmony_ci{
44e5c31af7Sopenharmony_ci	setString(str);
45e5c31af7Sopenharmony_ci}
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_ciStringTemplate::StringTemplate (StringTemplate&& other)
48e5c31af7Sopenharmony_ci	: m_template(std::move(other.m_template))
49e5c31af7Sopenharmony_ci{}
50e5c31af7Sopenharmony_ci
51e5c31af7Sopenharmony_ciStringTemplate::~StringTemplate (void)
52e5c31af7Sopenharmony_ci{
53e5c31af7Sopenharmony_ci}
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_civoid StringTemplate::setString (const std::string& str)
56e5c31af7Sopenharmony_ci{
57e5c31af7Sopenharmony_ci	m_template = str;
58e5c31af7Sopenharmony_ci}
59e5c31af7Sopenharmony_ci
60e5c31af7Sopenharmony_ciconst string kSingleLineFlag = "single-line";
61e5c31af7Sopenharmony_ciconst string kOptFlag = "opt";
62e5c31af7Sopenharmony_ciconst string kDefaultFlag = "default=";
63e5c31af7Sopenharmony_ci
64e5c31af7Sopenharmony_cistring StringTemplate::specialize (const map<string, string>& params) const
65e5c31af7Sopenharmony_ci{
66e5c31af7Sopenharmony_ci	ostringstream res;
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_ci	size_t curNdx = 0;
69e5c31af7Sopenharmony_ci	for (;;)
70e5c31af7Sopenharmony_ci	{
71e5c31af7Sopenharmony_ci		size_t paramNdx = m_template.find("${", curNdx);
72e5c31af7Sopenharmony_ci		if (paramNdx != string::npos)
73e5c31af7Sopenharmony_ci		{
74e5c31af7Sopenharmony_ci			// Append in-between stuff.
75e5c31af7Sopenharmony_ci			res << m_template.substr(curNdx, paramNdx - curNdx);
76e5c31af7Sopenharmony_ci
77e5c31af7Sopenharmony_ci			// Find end-of-param.
78e5c31af7Sopenharmony_ci			size_t paramEndNdx = m_template.find("}", paramNdx);
79e5c31af7Sopenharmony_ci			if (paramEndNdx == string::npos)
80e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "No '}' found in template parameter");
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ci			// Parse parameter contents.
83e5c31af7Sopenharmony_ci			string	paramStr		= m_template.substr(paramNdx+2, paramEndNdx-2-paramNdx);
84e5c31af7Sopenharmony_ci			bool	paramSingleLine	= false;
85e5c31af7Sopenharmony_ci			bool	paramOptional	= false;
86e5c31af7Sopenharmony_ci			bool	paramDefault	= false;
87e5c31af7Sopenharmony_ci			string	paramName;
88e5c31af7Sopenharmony_ci			string	defaultValue;
89e5c31af7Sopenharmony_ci			size_t colonNdx = paramStr.find(":");
90e5c31af7Sopenharmony_ci			if (colonNdx != string::npos)
91e5c31af7Sopenharmony_ci			{
92e5c31af7Sopenharmony_ci				paramName = paramStr.substr(0, colonNdx);
93e5c31af7Sopenharmony_ci				string flagsStr = paramStr.substr(colonNdx+1);
94e5c31af7Sopenharmony_ci				if (flagsStr == kSingleLineFlag)
95e5c31af7Sopenharmony_ci				{
96e5c31af7Sopenharmony_ci					paramSingleLine = true;
97e5c31af7Sopenharmony_ci				}
98e5c31af7Sopenharmony_ci				else if (flagsStr == kOptFlag)
99e5c31af7Sopenharmony_ci				{
100e5c31af7Sopenharmony_ci					paramOptional = true;
101e5c31af7Sopenharmony_ci				}
102e5c31af7Sopenharmony_ci				else if (de::beginsWith(flagsStr, kDefaultFlag))
103e5c31af7Sopenharmony_ci				{
104e5c31af7Sopenharmony_ci					paramDefault = true;
105e5c31af7Sopenharmony_ci					defaultValue = flagsStr.substr(kDefaultFlag.size());
106e5c31af7Sopenharmony_ci				}
107e5c31af7Sopenharmony_ci				else
108e5c31af7Sopenharmony_ci				{
109e5c31af7Sopenharmony_ci					TCU_THROW(InternalError, (string("Unrecognized flag") + paramStr).c_str());
110e5c31af7Sopenharmony_ci				}
111e5c31af7Sopenharmony_ci			}
112e5c31af7Sopenharmony_ci			else
113e5c31af7Sopenharmony_ci				paramName = paramStr;
114e5c31af7Sopenharmony_ci
115e5c31af7Sopenharmony_ci			// Fill in parameter value.
116e5c31af7Sopenharmony_ci			if (params.find(paramName) != params.end())
117e5c31af7Sopenharmony_ci			{
118e5c31af7Sopenharmony_ci				const string& val = (*params.find(paramName)).second;
119e5c31af7Sopenharmony_ci				if (paramSingleLine)
120e5c31af7Sopenharmony_ci				{
121e5c31af7Sopenharmony_ci					string tmp = val;
122e5c31af7Sopenharmony_ci					for (size_t ndx = tmp.find("\n"); ndx != string::npos; ndx = tmp.find("\n"))
123e5c31af7Sopenharmony_ci						tmp = tmp.replace(ndx, 1, " ");
124e5c31af7Sopenharmony_ci					res << tmp;
125e5c31af7Sopenharmony_ci				}
126e5c31af7Sopenharmony_ci				else
127e5c31af7Sopenharmony_ci					res << val;
128e5c31af7Sopenharmony_ci			}
129e5c31af7Sopenharmony_ci			else if (paramDefault)
130e5c31af7Sopenharmony_ci				res << defaultValue;
131e5c31af7Sopenharmony_ci			else if (!paramOptional)
132e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, (string("Value for parameter '") + paramName + "' not found in map").c_str());
133e5c31af7Sopenharmony_ci
134e5c31af7Sopenharmony_ci			// Skip over template.
135e5c31af7Sopenharmony_ci			curNdx = paramEndNdx + 1;
136e5c31af7Sopenharmony_ci		}
137e5c31af7Sopenharmony_ci		else
138e5c31af7Sopenharmony_ci		{
139e5c31af7Sopenharmony_ci			if (curNdx < m_template.length())
140e5c31af7Sopenharmony_ci				res << &m_template[curNdx];
141e5c31af7Sopenharmony_ci
142e5c31af7Sopenharmony_ci			break;
143e5c31af7Sopenharmony_ci		}
144e5c31af7Sopenharmony_ci	}
145e5c31af7Sopenharmony_ci
146e5c31af7Sopenharmony_ci	return res.str();
147e5c31af7Sopenharmony_ci}
148e5c31af7Sopenharmony_ci
149e5c31af7Sopenharmony_ci} // tcu
150