LogString OptionConverter::substVars()

in src/main/cpp/optionconverter.cpp [216:289]


LogString OptionConverter::substVars(const LogString& val, Properties& props)
{
	LogString sbuf;
	const logchar delimStartArray[] = { 0x24, 0x7B, 0 };
	const LogString delimStart(delimStartArray);
	const logchar delimStop = 0x7D; // '}';
	const size_t DELIM_START_LEN = 2;
	const size_t DELIM_STOP_LEN = 1;

	size_t i = 0;

	while (true)
	{
		size_t j = val.find(delimStart, i);

		if (j == val.npos)
		{
			// no more variables
			if (i == 0)
			{
				// this is a simple string
				return val;
			}
			else
			{
				// add the tail string which contails no variables and return the result.
				sbuf.append(val.substr(i, val.length() - i));
				return sbuf;
			}
		}
		else
		{
			sbuf.append(val.substr(i, j - i));
			size_t k = val.find(delimStop, j);

			if (k == val.npos)
			{
				LogString msg(1, (logchar) 0x22 /* '\"' */);
				msg.append(val);
				msg.append(LOG4CXX_STR("\" has no closing brace. Opening brace at position "));
				Pool p;
				StringHelper::toString(j, p, msg);
				msg.append(1, (logchar) 0x2E /* '.' */);
				throw IllegalArgumentException(msg);
			}
			else
			{
				j += DELIM_START_LEN;
				LogString key = val.substr(j, k - j);
				// first try in System properties
				LogString replacement(getSystemProperty(key, LogString()));

				// then try props parameter
				if (replacement.empty())
				{
					replacement = props.getProperty(key);
				}

				if (!replacement.empty())
				{
					// Do variable substitution on the replacement string
					// such that we can solve "Hello ${x2}" as "Hello p1"
					// the where the properties are
					// x1=p1
					// x2=${x1}
					LogString recursiveReplacement = substVars(replacement, props);
					sbuf.append(recursiveReplacement);
				}

				i = k + DELIM_STOP_LEN;
			}
		}
	}
}