Poco::StringTokenizer は、元になる文字列を、その中に含まれる文字(列)で複数のトークンに分解し、インデックスまたはイテレータでのアクセスを可能にします。
例えば、Google で “POCO Fanatic” を検索すると、URL 欄に:
http://www.google.co.jp/search?source=ig&hl=ja&rlz=&q=POCO+Fanatic&meta=lr%3D&aq=f&aqi=&aql=&oq=&gs_rfai= |
と出ますが、この REST (Representational State Transfer) 形式の文字列を Poco::StringTokenizer を使って解析するクラスを紹介します。
(このクラスを POCO::Net ライブラリによる組み込み Web サーバの実装と合わせて使えば、そこそこ使える Web サーバが作れると思います)
class RestParser
RestParser.h
・”?” より前を取得する GetURL() と、REST の Key-Value ペアの map を取得する GetKeyValues()
とを備える。
・PImpl イディオム(pointer to implementation idiom)を使用し、ファイルの依存関係を削減。
#include <string> #include <map> #include <memory> class RestParser { public: RestParser(const std::string& urlStr); ~RestParser(); int GetURL(std::string& url) const; int GetKeyValues(std::map<std::string, std::string>& keyValues) const; private: RestParser(); RestParser(const RestParser&); RestParser& operator = (const RestParser&); class RestParserImpl; std::auto_ptr<RestParserImpl> m_pImpl; }; |
RestParser.cpp
・RestParser::RestParserImpl クラスは Poco::StringTokenizer を継承し、urlStr を “?” の前後で分ける。
・GetKeyValues() 内の restTokenizer で “&” 区切りで分割、さらに keyValueTokenizer で “=” 区切りで
分割。
#include "RestParser.h" #include <Poco/StringTokenizer.h> class RestParser::RestParserImpl : public Poco::StringTokenizer { public: RestParserImpl(const std::string& urlStr) : Poco::StringTokenizer(urlStr, "?") { } ~RestParserImpl() { } int GetURL(std::string& url) const { if(!IsValidUrlWithRest()) return -1; url = (*this)[0]; return 0; } int GetKeyValues(std::map<std::string, std::string>& keyValues) const { if(!IsValidUrlWithRest()) return -1; Poco::StringTokenizer restTokenizer((*this)[1], "&"); for(Poco::StringTokenizer::Iterator itr=restTokenizer.begin(); itr!=restTokenizer.end(); ++itr) { Poco::StringTokenizer keyValueTokenizer(*itr, "="); keyValues[keyValueTokenizer[0]] = (1 < keyValueTokenizer.count()) ? keyValueTokenizer[1]:""; } return 0; } private: RestParserImpl(); RestParserImpl(const RestParserImpl&); RestParserImpl& operator = (const RestParserImpl&); bool IsValidUrlWithRest(void) const { return (2 == count()); } }; RestParser::RestParser(const std::string& urlStr) : m_pImpl(new RestParserImpl(urlStr)) { } RestParser::~RestParser() { } int RestParser::GetURL(std::string& url) const { return m_pImpl->GetURL(url); } int RestParser::GetKeyValues(std::map<std::string, std::string>& keyValues) const { return m_pImpl->GetKeyValues(keyValues); } |
RestParserTest.cpp
・ParseRest() で RestParser を使い、ログ出力。
#include <Poco/Format.h> #include "ScopedLogMessage.h" #include "PrepareConsoleLogger.h" #include "RestParser.h" void ParseRest(const std::string& sourceUrl) { ScopedLogMessage msg("ParseRest ", "start", "end"); msg.Message(Poco::format(" sourceUrl = %s", sourceUrl)); RestParser parser(sourceUrl); std::string url; if(0 == parser.GetURL(url)) { msg.Message(Poco::format(" url = %s", url)); } std::map<std::string, std::string> keyValues; if(0 == parser.GetKeyValues(keyValues)) { int count = 0; for(std::map<std::string, std::string>::iterator itr=keyValues.begin(); itr!=keyValues.end(); ++itr) { msg.Message(Poco::format(" (key, value)[%d] = (%s, %s)", count++, itr->first, itr->second)); } } } int main(int /*argc*/, char** /*argv*/) { PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION); ParseRest("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] ParseRest start [0] sourceUrl = 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] url = http://www.google.co.jp/search [0] (key, value)[0] = (aq, f) [0] (key, value)[1] = (aqi, ) [0] (key, value)[2] = (aql, ) [0] (key, value)[3] = (gs_rfai, ) [0] (key, value)[4] = (hl, ja) [0] (key, value)[5] = (meta, lr%3D) [0] (key, value)[6] = (oq, ) [0] (key, value)[7] = (q, POCO+Fanatic) [0] (key, value)[8] = (rlz, ) [0] (key, value)[9] = (source, ig) [0] ParseRest end |
Downloads
・ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年4月25日からのダウンロード数:1246
Subversion
・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。
Reference
・http://pocoproject.org にある StringsAndFormatting のプレセンテーション。(PDF)
![]() |
Copyright © 2010 Round Square Inc. All rights reserved. |
---|
0 Comments.