Var Query::find(const std::string& path) const
{
	Var result = _source;
	StringTokenizer tokenizer(path, ".");
	for(StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); token++)
	{
		if ( !result.isEmpty() )
		{
			std::vector<int> indexes;
			RegularExpression::MatchVec matches;
			int firstOffset = -1;
			int offset = 0;
			RegularExpression regex("\\[([0-9]+)\\]");
			while(regex.match(*token, offset, matches) > 0 )
			{
				if ( firstOffset == -1 )
				{
					firstOffset = static_cast<int>(matches[0].offset);
				}
				std::string num = token->substr(matches[1].offset, matches[1].length);
				indexes.push_back(NumberParser::parse(num));
				offset = static_cast<int>(matches[0].offset + matches[0].length);
			}

			std::string name(*token);
			if ( firstOffset != -1 )
			{
				name = name.substr(0, firstOffset);
			}

			if ( name.length() > 0 )
			{
				if ( result.type() == typeid(Object::Ptr) )
				{
					Object::Ptr o = result.extract<Object::Ptr>();
					result = o->get(name);
				}
			}

			if (    !result.isEmpty()
			        && !indexes.empty() )
			{
				for(std::vector<int>::iterator it = indexes.begin(); it != indexes.end(); ++it )
				{
					if ( result.type() == typeid(Array::Ptr) )
					{
						Array::Ptr array = result.extract<Array::Ptr>();
						result = array->get(*it);
						if ( result.isEmpty() )
						{
							break;
						}
					}
				}
			}
		}
	}
	return result;
}
예제 #2
0
void Utility::detectPrefixAndIncludes(const std::string& origHFile, std::vector<std::string>& lines, std::string& prefix)
{
	std::ifstream istr(origHFile.c_str());
	try
	{
		if (istr.good())
		{
			std::string x;
			istr >> x;
			while (x.find("#ifndef") == std::string::npos)
				istr >> x;
			StringTokenizer tokenizer(x, " \t", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
			poco_assert (tokenizer.count() == 2);
			StringTokenizer::Iterator itTmp = tokenizer.begin();
			++itTmp;
			std::string defValue = *itTmp;
			istr >> x;
			// now find the corresponding #define
			while (x.find(defValue) == std::string::npos)
				istr >> x;
			 //now parse until a class def is found without a ; at the end
			bool stop = false;
			std::string prefixHint;
			do
			{
				istr >> x;
				// we add EVERYTHING to lines: reason: used macros/preprocessor defines, conditional includes should all be present in the generated code
				// just think about fwd declarations inside a NS_BEGIN ... NS_END block
				if (x.find("class") != std::string::npos && x.find(";") == std::string::npos)
				{
					StringTokenizer tok(x, " \t", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
					StringTokenizer::Iterator it = tok.begin();
					while (*it != "class" && it != tok.end())
						++it;
					// the next after class must be *_API or in case of a template it must be the class name
					++it;
					std::size_t apiPos = it->find("_API");
					if (apiPos != std::string::npos)
					{
						prefixHint = it->substr(0, apiPos);
					}
					stop = true;
				}
				else
				{
					lines.push_back(x);
				}
			}
			while (!stop && !istr.eof());
			if (!stop)
			{
				lines.clear();
				prefix.clear();
				//throw Poco::SyntaxException("Failed to parse file " + origHFile + ".No class declared?");
				return;
			}

			// now search the prefix
			if (lines.empty())
			{
				prefix.clear();
				return;
			}
			// the prefix for that file
			std::vector<std::string>::const_iterator it = lines.end();
			--it;
			std::vector<std::string>::const_iterator itBegin = lines.begin();
			for (; it != itBegin; --it)
			{
				std::size_t prefixPos = it->find("_BEGIN");
				if (prefixPos != std::string::npos)
				{
					prefix = it->substr(0, prefixPos);
					if (prefix != prefixHint && !prefixHint.empty())
					{
						throw Poco::SyntaxException("Conflicting prefixes detected: " + prefixHint + "<->" + prefix);
					}
				}
			}
		}
		else throw Poco::OpenFileException(origHFile);
	}