Monthly Archives: April 2010 - Page 2

Poco::URI

前回のポストで、REST 部分を抜き出しましたが、それ以外の部分の要素も個別に取得できるクラス Poco::URI がありますので紹介します。

class URIParser

URIParser.h

Poco::URI の method をそのまま継承。
・前回のポストの GetKeyValues() を getQueryMap() に改名。
PImpl イディオム(pointer to implementation idiom)を使用し、ファイルの依存関係を削減。

#include <string>
#include <vector>
#include <map>
#include <memory>
 
class URIParser
{
public:
	URIParser(const std::string& urlStr);
	~URIParser();
	int GetURL(std::string& url) const;
 
	const std::string& getScheme() const;
	const std::string& getUserInfo() const;
	const std::string& getHost() const;
	unsigned short getPort() const;
	std::string getAuthority() const;
	const std::string& getPath() const;
	std::string getQuery() const;
	const std::string& getFragment() const;
 
	void getPathSegments(std::vector<std::string>& segments);
	void getQueryMap(std::map<std::string, std::string>& keyValues) const;
 
private:
	URIParser();
	URIParser(const URIParser&);
	URIParser& operator = (const URIParser&);
 
	class URIParserImpl;
	std::auto_ptr<URIParserImpl>	m_pImpl;
};

URIParser.cpp

・URIParser::URIParserImpl クラスは Poco::URI を継承し、オリジナルの getQueryMap() だけ追加。
・getQueryMap() 内の restTokenizer で “&” 区切りで分割、さらに keyValueTokenizer で “=” 区切りで
 分割。

#include "URIParser.h"
 
#include <Poco/URI.h>
#include <Poco/StringTokenizer.h>
 
class URIParser::URIParserImpl : public Poco::URI
{
public:
	URIParserImpl(const std::string& urlStr) :
		Poco::URI(urlStr)
	{
	}
	~URIParserImpl()
	{
	}
	void getQueryMap(std::map<std::string, std::string>& keyValues) const
	{
		if(empty())	return;
 
		std::string queryString(getQuery());
		if("" == queryString)	return;
 
		Poco::StringTokenizer restTokenizer(queryString, "&");
		for(Poco::StringTokenizer::Iterator itr=restTokenizer.begin(); itr!=restTokenizer.end(); ++itr)
		{
			Poco::StringTokenizer keyValueTokenizer(*itr, "=");
			keyValues[keyValueTokenizer[0]] = (1 < keyValueTokenizer.count()) ? keyValueTokenizer[1]:"";
		}
	}
 
private:
	URIParserImpl();
	URIParserImpl(const URIParserImpl&);
	URIParserImpl& operator = (const URIParserImpl&);
};
 
URIParser::URIParser(const std::string& urlStr) :
	m_pImpl(new URIParserImpl(urlStr))
{
}
 
URIParser::~URIParser()
{
}
 
const std::string& URIParser::getScheme() const
{
	return m_pImpl->getScheme();
}
 
const std::string& URIParser::getUserInfo() const
{
	return m_pImpl->getUserInfo();
}
 
const std::string& URIParser::getHost() const
{
	return m_pImpl->getHost();
}
 
unsigned short URIParser::getPort() const
{
	return m_pImpl->getPort();
}
 
std::string URIParser::getAuthority() const
{
	return m_pImpl->getAuthority();
}
 
const std::string& URIParser::getPath() const
{
	return m_pImpl->getPath();
}
 
std::string URIParser::getQuery() const
{
	return m_pImpl->getQuery();
}
 
const std::string& URIParser::getFragment() const
{
	return m_pImpl->getFragment();
}
 
void URIParser::getPathSegments(std::vector<std::string>& segments)
{
	m_pImpl->getPathSegments(segments);
}
 
void URIParser::getQueryMap(std::map<std::string, std::string>& keyValues) const
{
	m_pImpl->getQueryMap(keyValues);
}

URIParserTest.cpp

・ParseURI() で URIParser を使い、ログ出力。

#include <Poco/Format.h>
 
#include "ScopedLogMessage.h"
#include "PrepareConsoleLogger.h"
#include "URIParser.h"
 
//----------------------------------------
//	ParseURI
//----------------------------------------
void ParseURI(const std::string& sourceUri)
{
	ScopedLogMessage msg("ParseURI ", "start", "end");
 
	msg.Message(Poco::format(" sourceUri = %s", sourceUri));
 
	URIParser parser(sourceUri);
 
	msg.Message(Poco::format("    scheme = %s", parser.getScheme()));
	msg.Message(Poco::format("  userInfo = %s", parser.getUserInfo()));
	msg.Message(Poco::format("      host = %s", parser.getHost()));
	msg.Message(Poco::format("      port = %hu", parser.getPort()));
	msg.Message(Poco::format(" authority = %s", parser.getAuthority()));
	msg.Message(Poco::format("      path = %s", parser.getPath()));
 
	std::vector<std::string> pathSegments;
	parser.getPathSegments(pathSegments);
	for(std::vector<std::string>::iterator itr=pathSegments.begin(); itr!=pathSegments.end(); ++itr)
	{
		int count = 0;
		msg.Message(Poco::format("             path[%d] = %s", count++, *itr));
	}
 
	msg.Message(Poco::format("     query = %s", parser.getQuery()));
 
	std::map<std::string, std::string> keyValues;
	parser.getQueryMap(keyValues);
	if(0 != keyValues.size())
	{
		int count = 0;
		for(std::map<std::string, std::string>::iterator itr=keyValues.begin(); itr!=keyValues.end(); ++itr)
		{
			msg.Message(Poco::format("             query[%d] = (%s, %s)", count++, itr->first, itr->second));
		}
	}
	msg.Message(Poco::format("  fragment = %s", parser.getFragment()));
}
 
//----------------------------------------
//	main
//----------------------------------------
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);
 
	ParseURI("http://www.google.co.jp/search?source=ig&hl=ja&rlz=&q=POCO+Fanatic&meta=lr%3D&aq=f&aqi=&aql=&oq=&gs_rfai=");
 
	return 0;
}

Results of execution

[0] ParseURI start
[0]  sourceUri = http://www.google.co.jp/search?source=ig&hl=ja&rlz=&q=POCO+Fanatic&meta=lr%3D&aq=f&aqi=&aql=&oq=&gs_rfai=
[0]     scheme = http
[0]   userInfo = 
[0]       host = www.google.co.jp
[0]       port = 80
[0]  authority = www.google.co.jp
[0]       path = /search
[0]              path[0] = search
[0]      query = source=ig&hl=ja&rlz=&q=POCO+Fanatic&meta=lr=&aq=f&aqi=&aql=&oq=&gs_rfai=
[0]              query[0] = (aq, f)
[0]              query[1] = (aqi, )
[0]              query[2] = (aql, )
[0]              query[3] = (gs_rfai, )
[0]              query[4] = (hl, ja)
[0]              query[5] = (meta, lr)
[0]              query[6] = (oq, )
[0]              query[7] = (q, POCO+Fanatic)
[0]              query[8] = (rlz, )
[0]              query[9] = (source, ig)
[0]   fragment = 
[0] ParseURI end

Downloads

ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年4月27日からのダウンロード数:901

Subversion

・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。

Reference

http://pocoproject.org にある URIandUUID のプレセンテーション。(PDF)

Powered by POCO Copyright © 2010 Round Square Inc. All rights reserved.