<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cachet Software &#187; sd_dba_LTY1OTI3</title>
	<atom:link href="http://www.cachet.co.jp/?author=1&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.cachet.co.jp</link>
	<description>キャシェイソフトウェア－最先端の金融市場ソフトウェアを開発するベンチャーです</description>
	<lastBuildDate>Sun, 07 Jul 2013 12:21:12 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>8. Reactorフレームワーク</title>
		<link>http://www.cachet.co.jp/?p=126</link>
		<comments>http://www.cachet.co.jp/?p=126#comments</comments>
		<pubDate>Fri, 20 Jan 2012 10:31:23 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=126</guid>
		<description><![CDATA[最終回は、予定を変えてReactorフレームワークを詳解します。 TCPServerはスレッドプールによるマルチスレッドのソケット通信ですが、クライアントの数が巨大なシステムではC10K問題を起こしてしまいます。それを解決するノンブロッキングI/Oを実現するのにPocoではReactorフレームワークを提供しています。 Reactorフレームワークを使うNetライブラリのサンプルとして、EchoServerプロジェクトがPOCOに付属しています。EchoServerプロジェクトを、Reactorフレームワークが提供するすべてのイベントハンドラをサポートするように改造してみます。 まずは、サンプルをそのままコンパイルして実行してみましょう。 $ EchoServer これで、サーバが起動されたので、telnetでサーバと通信してみます。 $ telnet 127.0.0.1 9977 以下のように、接続したあと入力した文字をエコーすると思います。 $ telnet localhost 9977 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. hello hello それでは、何も入力しないで30秒経つとタイムアウトして接続を切断するように変更します。 変更したソースを以下に記載します。 #include &#34;Poco/Net/SocketReactor.h&#34; #include &#34;Poco/Net/SocketAcceptor.h&#34; #include &#34;Poco/Net/SocketNotification.h&#34; #include &#34;Poco/Net/StreamSocket.h&#34; #include &#34;Poco/Net/ServerSocket.h&#34; #include &#8230; <a href="http://www.cachet.co.jp/?p=126">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>最終回は、予定を変えてReactorフレームワークを詳解します。<br />
TCPServerはスレッドプールによるマルチスレッドのソケット通信ですが、クライアントの数が巨大なシステムではC10K問題を起こしてしまいます。それを解決するノンブロッキングI/Oを実現するのにPocoではReactorフレームワークを提供しています。</p>
<p>Reactorフレームワークを使うNetライブラリのサンプルとして、EchoServerプロジェクトがPOCOに付属しています。EchoServerプロジェクトを、Reactorフレームワークが提供するすべてのイベントハンドラをサポートするように改造してみます。<br />
<span id="more-126"></span><br />
まずは、サンプルをそのままコンパイルして実行してみましょう。<br />
$ EchoServer<br />
これで、サーバが起動されたので、telnetでサーバと通信してみます。<br />
$ telnet 127.0.0.1 9977<br />
以下のように、接続したあと入力した文字をエコーすると思います。</p>
<p><pre><code>$ telnet localhost 9977
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
hello</code></pre></p>
<p>それでは、何も入力しないで30秒経つとタイムアウトして接続を切断するように変更します。<br />
変更したソースを以下に記載します。</p>
<p><pre><code>#include &quot;Poco/Net/SocketReactor.h&quot;
#include &quot;Poco/Net/SocketAcceptor.h&quot;
#include &quot;Poco/Net/SocketNotification.h&quot;
#include &quot;Poco/Net/StreamSocket.h&quot;
#include &quot;Poco/Net/ServerSocket.h&quot;
#include &quot;Poco/NObserver.h&quot;
#include &quot;Poco/Exception.h&quot;
#include &quot;Poco/Thread.h&quot;
#include &quot;Poco/Timespan.h&quot;
#include &quot;Poco/Util/ServerApplication.h&quot;
#include &quot;Poco/Util/Option.h&quot;
#include &quot;Poco/Util/OptionSet.h&quot;
#include &quot;Poco/Util/HelpFormatter.h&quot;
#include &lt;iostream&gt;
#include &lt;sstream&gt;


using Poco::Net::SocketReactor;
using Poco::Net::SocketAcceptor;
using Poco::Net::ReadableNotification;
using Poco::Net::ShutdownNotification;
using Poco::Net::WritableNotification;
using Poco::Net::ErrorNotification;
using Poco::Net::TimeoutNotification;
using Poco::Net::IdleNotification;
using Poco::Net::ServerSocket;
using Poco::Net::StreamSocket;
using Poco::NObserver;
using Poco::AutoPtr;
using Poco::Thread;
using Poco::Timespan;
using Poco::Util::ServerApplication;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;


class EchoServiceHandler
{
public:
	EchoServiceHandler(StreamSocket&amp; socket, SocketReactor&amp; reactor)
		:_socket(socket)
		,_reactor(reactor)
		,_pBuffer(new char[BUFFER_SIZE])
		,_onWritableAdded(false)
		,_onTimeoutAdded(false)
	{
		Application&amp; app = Application::instance();
		app.logger().information(&quot;Connection from &quot; + socket.peerAddress().toString());

		_reactor.addEventHandler(_socket, NObserver&lt;EchoServiceHandler, ReadableNotification&gt;(*this, &amp;EchoServiceHandler::onReadable));
		_reactor.addEventHandler(_socket, NObserver&lt;EchoServiceHandler, ShutdownNotification&gt;(*this, &amp;EchoServiceHandler::onShutdown));
		_reactor.addEventHandler(_socket, NObserver&lt;EchoServiceHandler, ErrorNotification&gt;(*this, &amp;EchoServiceHandler::onError));
		_reactor.addEventHandler(_socket, NObserver&lt;EchoServiceHandler, IdleNotification&gt;(*this, &amp;EchoServiceHandler::onIdle));
	}
	
	~EchoServiceHandler()
	{
		Application&amp; app = Application::instance();
		try
		{
			app.logger().information(&quot;Disconnecting &quot; + _socket.peerAddress().toString());
		}
		catch (...)
		{
		}
		_reactor.removeEventHandler(_socket, NObserver&lt;EchoServiceHandler, ReadableNotification&gt;(*this, &amp;EchoServiceHandler::onReadable));
		_reactor.removeEventHandler(_socket, NObserver&lt;EchoServiceHandler, ShutdownNotification&gt;(*this, &amp;EchoServiceHandler::onShutdown));
		_reactor.removeEventHandler(_socket, NObserver&lt;EchoServiceHandler, ErrorNotification&gt;(*this, &amp;EchoServiceHandler::onError));
		_reactor.removeEventHandler(_socket, NObserver&lt;EchoServiceHandler, IdleNotification&gt;(*this, &amp;EchoServiceHandler::onIdle));
		if (_onWritableAdded)
			_reactor.removeEventHandler(_socket, NObserver&lt;EchoServiceHandler, WritableNotification&gt;(*this, &amp;EchoServiceHandler::onWritable));
		if (_onTimeoutAdded)
			_reactor.removeEventHandler(_socket, NObserver&lt;EchoServiceHandler, TimeoutNotification&gt;(*this, &amp;EchoServiceHandler::onTimeout));
		delete [] _pBuffer;
	}
	
	void onReadable(const AutoPtr&lt;ReadableNotification&gt;&amp; pNf)
	{
		int n = _socket.receiveBytes(_pBuffer, BUFFER_SIZE);
		if (n &gt; 0) {
			std::stringstream str;
			str.write(_pBuffer, n);
			_data = str.str();
			_reactor.addEventHandler(_socket, NObserver&lt;EchoServiceHandler, WritableNotification&gt;(*this, &amp;EchoServiceHandler::onWritable));
			_onWritableAdded = true;
		}
		else {
			delete this;
		}
	}
	
	void onShutdown(const AutoPtr&lt;ShutdownNotification&gt;&amp; pNf)
	{
		delete this;
	}
	
	void onWritable(const AutoPtr&lt;WritableNotification&gt;&amp; pNf)
	{
		Application::instance().logger().information(&quot;onWritable called&quot;);
		std::string data = Poco::format(&quot;received %s&quot;, _data);
		_socket.sendBytes(data.data(), data.length());
		_reactor.removeEventHandler(_socket, NObserver&lt;EchoServiceHandler, WritableNotification&gt;(*this, &amp;EchoServiceHandler::onWritable));
		if (_onTimeoutAdded) {
			_reactor.removeEventHandler(_socket, NObserver&lt;EchoServiceHandler, TimeoutNotification&gt;(*this, &amp;EchoServiceHandler::onTimeout));
		}
		_reactor.addEventHandler(_socket, NObserver&lt;EchoServiceHandler, TimeoutNotification&gt;(*this, &amp;EchoServiceHandler::onTimeout));
		_onTimeoutAdded = true;
	}

	void onError(const AutoPtr&lt;ErrorNotification&gt;&amp; pNf)
	{
		Application::instance().logger().information(&quot;onError called&quot;);
	}

	void onTimeout(const AutoPtr&lt;TimeoutNotification&gt;&amp; pNf)
	{
		Application::instance().logger().information(&quot;onTimeout called&quot;);
		_reactor.removeEventHandler(_socket, NObserver&lt;EchoServiceHandler, TimeoutNotification&gt;(*this, &amp;EchoServiceHandler::onTimeout));
		delete this;
	}

	void onIdle(const AutoPtr&lt;IdleNotification&gt;&amp; pNf)
	{
		Application::instance().logger().information(&quot;onIdle called&quot;);
	}

private:
	enum
	{
		BUFFER_SIZE = 1024
	};
	
	StreamSocket   _socket;
	SocketReactor&amp; _reactor;
	char*          _pBuffer;
	std::string  	 _data;
	bool			 _onWritableAdded;
	bool			 _onTimeoutAdded;
};


class EchoServer: public Poco::Util::ServerApplication
	/// The main application class.
	///
	/// This class handles command-line arguments and
	/// configuration files.
	/// Start the EchoServer executable with the help
	/// option (/help on Windows, --help on Unix) for
	/// the available command line options.
	///
	/// To use the sample configuration file (EchoServer.properties),
	/// copy the file to the directory where the EchoServer executable
	/// resides. If you start the debug version of the EchoServer
	/// (EchoServerd[.exe]), you must also create a copy of the configuration
	/// file named EchoServerd.properties. In the configuration file, you
	/// can specify the port on which the server is listening (default
	/// 9977) and the format of the date/time string sent back to the client.
	///
	/// To test the EchoServer you can use any telnet client (telnet localhost 9977).
{
public:
	EchoServer(): _helpRequested(false)
	{
	}
	
	~EchoServer()
	{
	}

protected:
	void initialize(Application&amp; self)
	{
		loadConfiguration(); // load default configuration files, if present
		ServerApplication::initialize(self);
	}
		
	void uninitialize()
	{
		ServerApplication::uninitialize();
	}

	void defineOptions(OptionSet&amp; options)
	{
		ServerApplication::defineOptions(options);
		
		options.addOption(
			Option(&quot;help&quot;, &quot;h&quot;, &quot;display help information on command line arguments&quot;)
				.required(false)
				.repeatable(false));
	}

	void handleOption(const std::string&amp; name, const std::string&amp; value)
	{
		ServerApplication::handleOption(name, value);

		if (name == &quot;help&quot;)
			_helpRequested = true;
	}

	void displayHelp()
	{
		HelpFormatter helpFormatter(options());
		helpFormatter.setCommand(commandName());
		helpFormatter.setUsage(&quot;OPTIONS&quot;);
		helpFormatter.setHeader(&quot;An echo server implemented using the Reactor and Acceptor patterns.&quot;);
		helpFormatter.format(std::cout);
	}

	int main(const std::vector&lt;std::string&gt;&amp; args)
	{
		if (_helpRequested)
		{
			displayHelp();
		}
		else
		{
			// get parameters from configuration file
			unsigned short port = (unsigned short) config().getInt(&quot;EchoServer.port&quot;, 9977);
			
			// set-up a server socket
			ServerSocket svs(port);
			// set-up a SocketReactor...
			Timespan timeout(30000000);	// timeout is set to 30sec
			SocketReactor reactor(timeout);
			// ... and a SocketAcceptor
			SocketAcceptor&lt;EchoServiceHandler&gt; acceptor(svs, reactor);
			// run the reactor in its own thread so that we can wait for 
			// a termination request
			Thread thread;
			thread.start(reactor);
			// wait for CTRL-C or kill
			waitForTerminationRequest();
			// Stop the SocketReactor
			reactor.stop();
			thread.join();
		}
		return Application::EXIT_OK;
	}
	
private:
	bool _helpRequested;
};


int main(int argc, char** argv)
{
	EchoServer app;
	return app.run(argc, argv);
}</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=126</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>7. クラスローディング</title>
		<link>http://www.cachet.co.jp/?p=118</link>
		<comments>http://www.cachet.co.jp/?p=118#comments</comments>
		<pubDate>Thu, 19 Jan 2012 05:22:38 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=118</guid>
		<description><![CDATA[今回は、POCOでのクラスローディングの実装例を詳解します。 まず、参考情報のポインタを示します。 http://pocoproject.org/slides/120-SharedLibraries.pdf さて、このクラスローディングはPOCO独自の機能で、シェアドライブラリからプログラム実行時にクラスを動的生成することができます。 シェアドライブラリを追加・変更することで、プログラムの振る舞いを変更できますので、主な用途としてはプラグインが挙げられます。 クラスローディングのサンプルコードは、シェアドライブラリのコードとクラスローディングするコードの２つに分かれます。 シェアドライブラリ；TestPlugin.h #ifndef TestPlugin_INCLUDED #define TestPlugin_INCLUDED #include &#34;Poco/Foundation.h&#34; class TestPlugin { public: TestPlugin(); virtual ~TestPlugin(); virtual std::string name() const = 0; }; #endif // TestPlugin_INCLUDED シェアドライブラリ；TestPlugin.cpp #include &#34;TestPlugin.h&#34; TestPlugin::TestPlugin() { } TestPlugin::~TestPlugin() { } シェアドライブラリ；TestLibrary.cpp &#8230; <a href="http://www.cachet.co.jp/?p=118">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>今回は、POCOでのクラスローディングの実装例を詳解します。<br />
まず、参考情報のポインタを示します。<br />
<a href="http://pocoproject.org/slides/120-SharedLibraries.pdf">http://pocoproject.org/slides/120-SharedLibraries.pdf</a></p>
<p>さて、このクラスローディングはPOCO独自の機能で、シェアドライブラリからプログラム実行時にクラスを動的生成することができます。<br />
シェアドライブラリを追加・変更することで、プログラムの振る舞いを変更できますので、主な用途としてはプラグインが挙げられます。<br />
クラスローディングのサンプルコードは、シェアドライブラリのコードとクラスローディングするコードの２つに分かれます。<br />
<span id="more-118"></span></p>
<p>シェアドライブラリ；TestPlugin.h<br />
<pre><code>#ifndef TestPlugin_INCLUDED
#define TestPlugin_INCLUDED

#include &quot;Poco/Foundation.h&quot;

class TestPlugin
{
public:
	TestPlugin();
	virtual ~TestPlugin();
	virtual std::string name() const = 0;
};


#endif // TestPlugin_INCLUDED</code></pre></p>
<p>シェアドライブラリ；TestPlugin.cpp<br />
<pre><code>#include &quot;TestPlugin.h&quot;

TestPlugin::TestPlugin()
{
}

TestPlugin::~TestPlugin()
{
}</code></pre></p>
<p>シェアドライブラリ；TestLibrary.cpp<br />
<pre><code>#include &quot;TestPlugin.h&quot;
#include &quot;Poco/ClassLibrary.h&quot;
#include &lt;iostream&gt;


class PluginA: public TestPlugin
{
public:
	PluginA()
	{
	}
	
	~PluginA()
	{
	}
	
	std::string name() const
	{
		return &quot;PluginA&quot;;
	}
};

POCO_BEGIN_MANIFEST(TestPlugin)
	POCO_EXPORT_CLASS(PluginA)
POCO_END_MANIFEST


void pocoInitializeLibrary()
{
	std::cout &lt;&lt; &quot;TestLibrary initializing&quot; &lt;&lt; std::endl;
}


void pocoUninitializeLibrary()
{
	std::cout &lt;&lt; &quot;TestLibrary uninitialzing&quot; &lt;&lt; std::endl;
}</code></pre></p>
<p>実行コード：ClassLoaderSample.cpp<br />
<pre><code>#include &quot;Poco/ClassLoader.h&quot;
#include &quot;Poco/Manifest.h&quot;
#include &quot;Poco/Exception.h&quot;
#include &quot;Poco/Util/Application.h&quot;
#include &quot;Poco/Util/Option.h&quot;
#include &quot;Poco/Util/OptionSet.h&quot;
#include &quot;Poco/Util/HelpFormatter.h&quot;
#include &quot;Poco/Util/AbstractConfiguration.h&quot;
#include &lt;iostream&gt;
#include &quot;TestPlugin.h&quot;

using Poco::ClassLoader;
using Poco::Manifest;
using Poco::SharedLibrary;
using Poco::AbstractMetaObject;
using Poco::NotFoundException;
using Poco::InvalidAccessException;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Util::AbstractConfiguration;
using Poco::Util::OptionCallback;


class ClassLoaderSample: public Application
	/// This sample demonstrates some of the features of the Poco::ClassLoader class.
{
public:
	ClassLoaderSample(): _helpRequested(false)
	{
	}

protected:
	void initialize(Application&amp; self)
	{
		loadConfiguration(); // load default configuration files, if present
		Application::initialize(self);
		// add your own initialization code here
	}

	void uninitialize()
	{
		// add your own uninitialization code here
		Application::uninitialize();
	}

	void reinitialize(Application&amp; self)
	{
		Application::reinitialize(self);
		// add your own reinitialization code here
	}

	void defineOptions(OptionSet&amp; options)
	{
		Application::defineOptions(options);

		options.addOption(
			Option(&quot;help&quot;, &quot;h&quot;, &quot;display help information on command line arguments&quot;)
				.required(false)
				.repeatable(false)
				.callback(OptionCallback&lt;ClassLoaderSample&gt;(this, &amp;ClassLoaderSample::handleHelp)));
	}

	void handleHelp(const std::string&amp; name, const std::string&amp; value)
	{
		_helpRequested = true;
		displayHelp();
		stopOptionsProcessing();
	}

	void handleConfig(const std::string&amp; name, const std::string&amp; value)
	{
		loadConfiguration(value);
	}

	void displayHelp()
	{
		HelpFormatter helpFormatter(options());
		helpFormatter.setCommand(commandName());
		helpFormatter.setUsage(&quot;OPTIONS&quot;);
		helpFormatter.setHeader(&quot;A PropertySample application that demonstrates how to use Poco::ClassLoader.&quot;);
		helpFormatter.format(std::cout);
	}

	int main(const std::vector&lt;std::string&gt;&amp; args)
	{
		if (!_helpRequested)
		{
			// ライブラリをロードします。
			std::string path = &quot;libTestLibrary&quot;;
			path.append(SharedLibrary::suffix());

			ClassLoader&lt;TestPlugin&gt; cl;
			cl.loadLibrary(path);
			cl.findClass(&quot;PluginA&quot;);
			cl.findManifest(path);

			// ライブラリからインスタンスを作成します。
			TestPlugin* pPluginA = cl.classFor(&quot;PluginA&quot;).create();
			std::cout &lt;&lt; pPluginA-&gt;name() &lt;&lt; std::endl;

			// 後始末をします。
			delete pPluginA;
			cl.unloadLibrary(path);
		}

		return Application::EXIT_OK;
	}

private:
	bool _helpRequested;
};


POCO_APP_MAIN(ClassLoaderSample)</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=118</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>6. バリデーション</title>
		<link>http://www.cachet.co.jp/?p=115</link>
		<comments>http://www.cachet.co.jp/?p=115#comments</comments>
		<pubDate>Thu, 19 Jan 2012 03:47:37 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=115</guid>
		<description><![CDATA[今回は、POCOのバリデーションを詳解します。 POCOで用意されているバリデーションはコマンドラインオプションの入力値のバリデーションで、intと正規表現の２種類のバリデーションが提供されています。 オプションは、エラーメッセージに使われているだけなので、HTMLフォームのバリデーションに使うこともできます。ただ、実際のアプリケーションでは、エラーメッセージ体系を独自に決めるでしょうから、POCOの実装を参考にして自作することになると思います。 簡単なバリデーションのサンプルコードは以下のようになります。 #include &#34;Poco/Util/RegExpValidator.h&#34; #include &#34;Poco/Util/IntValidator.h&#34; #include &#34;Poco/Util/Option.h&#34; #include &#34;Poco/Util/OptionException.h&#34; #include &#34;Poco/AutoPtr.h&#34; #include &#34;Poco/Util/Application.h&#34; #include &#34;Poco/Util/OptionSet.h&#34; #include &#34;Poco/Util/HelpFormatter.h&#34; #include &#34;Poco/Util/AbstractConfiguration.h&#34; #include &#60;iostream&#62; using Poco::Util::Validator; using Poco::Util::RegExpValidator; using Poco::Util::IntValidator; using Poco::Util::Option; using Poco::Util::InvalidArgumentException; using Poco::AutoPtr; using Poco::Util::Application; using Poco::Util::OptionSet; &#8230; <a href="http://www.cachet.co.jp/?p=115">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>今回は、POCOのバリデーションを詳解します。<br />
POCOで用意されているバリデーションはコマンドラインオプションの入力値のバリデーションで、intと正規表現の２種類のバリデーションが提供されています。<br />
オプションは、エラーメッセージに使われているだけなので、HTMLフォームのバリデーションに使うこともできます。ただ、実際のアプリケーションでは、エラーメッセージ体系を独自に決めるでしょうから、POCOの実装を参考にして自作することになると思います。<br />
簡単なバリデーションのサンプルコードは以下のようになります。<br />
<span id="more-115"></span><br />
<pre><code>#include &quot;Poco/Util/RegExpValidator.h&quot;
#include &quot;Poco/Util/IntValidator.h&quot;
#include &quot;Poco/Util/Option.h&quot;
#include &quot;Poco/Util/OptionException.h&quot;
#include &quot;Poco/AutoPtr.h&quot;
#include &quot;Poco/Util/Application.h&quot;
#include &quot;Poco/Util/OptionSet.h&quot;
#include &quot;Poco/Util/HelpFormatter.h&quot;
#include &quot;Poco/Util/AbstractConfiguration.h&quot;
#include &lt;iostream&gt;

using Poco::Util::Validator;
using Poco::Util::RegExpValidator;
using Poco::Util::IntValidator;
using Poco::Util::Option;
using Poco::Util::InvalidArgumentException;
using Poco::AutoPtr;
using Poco::Util::Application;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Util::AbstractConfiguration;
using Poco::Util::OptionCallback;


class ValidatorSample: public Application
	/// This sample demonstrates some of the features of the Poco::Util::Validator class.
{
public:
	ValidatorSample(): _helpRequested(false)
	{
	}

protected:
	void initialize(Application&amp; self)
	{
		loadConfiguration(); // load default configuration files, if present
		Application::initialize(self);
		// add your own initialization code here
	}

	void uninitialize()
	{
		// add your own uninitialization code here
		Application::uninitialize();
	}

	void reinitialize(Application&amp; self)
	{
		Application::reinitialize(self);
		// add your own reinitialization code here
	}

	void defineOptions(OptionSet&amp; options)
	{
		Application::defineOptions(options);

		options.addOption(
			Option(&quot;help&quot;, &quot;h&quot;, &quot;display help information on command line arguments&quot;)
				.required(false)
				.repeatable(false)
				.callback(OptionCallback&lt;ValidatorSample&gt;(this, &amp;ValidatorSample::handleHelp)));
	}

	void handleHelp(const std::string&amp; name, const std::string&amp; value)
	{
		_helpRequested = true;
		displayHelp();
		stopOptionsProcessing();
	}

	void handleConfig(const std::string&amp; name, const std::string&amp; value)
	{
		loadConfiguration(value);
	}

	void displayHelp()
	{
		HelpFormatter helpFormatter(options());
		helpFormatter.setCommand(commandName());
		helpFormatter.setUsage(&quot;OPTIONS&quot;);
		helpFormatter.setHeader(&quot;A PropertySample application that demonstrates how to use Poco::Util::PropertyFileConfiguration.&quot;);
		helpFormatter.format(std::cout);
	}

	int main(const std::vector&lt;std::string&gt;&amp; args)
	{
		if (!_helpRequested)
		{
			// 正規表現でバリデーションします。
			Option strField(&quot;string field&quot;, &quot;s&quot;);
			AutoPtr&lt;Validator&gt; pRegVal(new RegExpValidator(&quot;[0-9]+&quot;));

			pRegVal-&gt;validate(strField, &quot;0&quot;);
			pRegVal-&gt;validate(strField, &quot;12345&quot;);

			try
			{
				pRegVal-&gt;validate(strField, &quot;234asdf&quot;);
			}
			catch (InvalidArgumentException&amp; exc)
			{
				std::cout &lt;&lt; exc.message() &lt;&lt; std::endl;
			}

			// 整数(最大値、最小値)でバリデーションします。
			Option intField(&quot;integer field&quot;, &quot;i&quot;);
			AutoPtr&lt;Validator&gt; pIntVal(new IntValidator(0, 100));

			pIntVal-&gt;validate(intField, &quot;0&quot;);
			pIntVal-&gt;validate(intField, &quot;100&quot;);
			pIntVal-&gt;validate(intField, &quot;55&quot;);

			try
			{
				pIntVal-&gt;validate(intField, &quot;-1&quot;);
			}
			catch (InvalidArgumentException&amp; exc)
			{
				std::cout &lt;&lt; exc.message() &lt;&lt; std::endl;
			}

			try
			{
				pIntVal-&gt;validate(intField, &quot;101&quot;);
			}
			catch (InvalidArgumentException&amp; exc)
			{
				std::cout &lt;&lt; exc.message() &lt;&lt; std::endl;
			}

			try
			{
				pIntVal-&gt;validate(intField, &quot;asdf&quot;);
			}
			catch (InvalidArgumentException&amp; exc)
			{
				std::cout &lt;&lt; exc.message() &lt;&lt; std::endl;
			}
		}

		return Application::EXIT_OK;
	}

private:
	bool _helpRequested;
};


POCO_APP_MAIN(ValidatorSample)</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=115</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5. プロパティファイル</title>
		<link>http://www.cachet.co.jp/?p=111</link>
		<comments>http://www.cachet.co.jp/?p=111#comments</comments>
		<pubDate>Thu, 19 Jan 2012 03:38:28 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=111</guid>
		<description><![CDATA[今回は、POCOでのプロパティファイルの使い方を詳解します。 実は、「2. ロギングフレームワークの使い方」でプロパティファイルは既出なのですが、ロギングフレームワーク内でプロパティファイルの読み込みが行われているため、詳解したコードにはプロパティファイルの処理が含まれていませんでした。 MySQLの接続情報をプロパティファイルから読み込むサンプルコードは以下のようになります。 プロパティファイル：mysql.properties host=localhost port=3306 user=test password=test db=test 実装ファイル：PropertySample.cpp #include &#34;Poco/AutoPtr.h&#34; #include &#34;Poco/FileStream.h&#34; #include &#34;Poco/Util/PropertyFileConfiguration.h&#34; #include &#34;Poco/Util/Application.h&#34; #include &#34;Poco/Util/Option.h&#34; #include &#34;Poco/Util/OptionSet.h&#34; #include &#34;Poco/Util/HelpFormatter.h&#34; #include &#34;Poco/Util/AbstractConfiguration.h&#34; #include &#60;vector&#62; #include &#60;iostream&#62; using Poco::AutoPtr; using Poco::FileInputStream; using Poco::Util::PropertyFileConfiguration; using Poco::Util::Application; using &#8230; <a href="http://www.cachet.co.jp/?p=111">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>今回は、POCOでのプロパティファイルの使い方を詳解します。<br />
実は、「2. ロギングフレームワークの使い方」でプロパティファイルは既出なのですが、ロギングフレームワーク内でプロパティファイルの読み込みが行われているため、詳解したコードにはプロパティファイルの処理が含まれていませんでした。<br />
MySQLの接続情報をプロパティファイルから読み込むサンプルコードは以下のようになります。<br />
<span id="more-111"></span><br />
プロパティファイル：mysql.properties<br />
<pre><code>host=localhost
port=3306
user=test
password=test
db=test</code></pre></p>
<p>実装ファイル：PropertySample.cpp<br />
<pre><code>#include &quot;Poco/AutoPtr.h&quot;
#include &quot;Poco/FileStream.h&quot;
#include &quot;Poco/Util/PropertyFileConfiguration.h&quot;
#include &quot;Poco/Util/Application.h&quot;
#include &quot;Poco/Util/Option.h&quot;
#include &quot;Poco/Util/OptionSet.h&quot;
#include &quot;Poco/Util/HelpFormatter.h&quot;
#include &quot;Poco/Util/AbstractConfiguration.h&quot;
#include &lt;vector&gt;
#include &lt;iostream&gt;

using Poco::AutoPtr;
using Poco::FileInputStream;
using Poco::Util::PropertyFileConfiguration;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Util::AbstractConfiguration;
using Poco::Util::OptionCallback;


class PropertySample: public Application
	/// This sample demonstrates some of the features of the Poco::Util::PropertyFileConfiguration class.
{
public:
	PropertySample(): _helpRequested(false)
	{
	}

protected:
	void initialize(Application&amp; self)
	{
		loadConfiguration(); // load default configuration files, if present
		Application::initialize(self);
		// add your own initialization code here
	}

	void uninitialize()
	{
		// add your own uninitialization code here
		Application::uninitialize();
	}

	void reinitialize(Application&amp; self)
	{
		Application::reinitialize(self);
		// add your own reinitialization code here
	}

	void defineOptions(OptionSet&amp; options)
	{
		Application::defineOptions(options);

		options.addOption(
			Option(&quot;help&quot;, &quot;h&quot;, &quot;display help information on command line arguments&quot;)
				.required(false)
				.repeatable(false)
				.callback(OptionCallback&lt;PropertySample&gt;(this, &amp;PropertySample::handleHelp)));
	}

	void handleHelp(const std::string&amp; name, const std::string&amp; value)
	{
		_helpRequested = true;
		displayHelp();
		stopOptionsProcessing();
	}

	void handleConfig(const std::string&amp; name, const std::string&amp; value)
	{
		loadConfiguration(value);
	}

	void displayHelp()
	{
		HelpFormatter helpFormatter(options());
		helpFormatter.setCommand(commandName());
		helpFormatter.setUsage(&quot;OPTIONS&quot;);
		helpFormatter.setHeader(&quot;A PropertySample application that demonstrates how to use Poco::Util::PropertyFileConfiguration.&quot;);
		helpFormatter.format(std::cout);
	}

	int main(const std::vector&lt;std::string&gt;&amp; args)
	{
		if (!_helpRequested)
		{
			// プロパティファイルを開きます。
			FileInputStream istr(&quot;./mysql.properties&quot;);
			AutoPtr&lt;PropertyFileConfiguration&gt; pConf = new PropertyFileConfiguration(istr);

			// プロパティを取得します。
			std::cout &lt;&lt; &quot;host:&quot; &lt;&lt; pConf-&gt;getString(&quot;host&quot;) &lt;&lt; std::endl;
			std::cout &lt;&lt; &quot;port:&quot; &lt;&lt; pConf-&gt;getString(&quot;port&quot;) &lt;&lt; std::endl;
			std::cout &lt;&lt; &quot;user:&quot; &lt;&lt; pConf-&gt;getString(&quot;user&quot;) &lt;&lt; std::endl;
			std::cout &lt;&lt; &quot;password:&quot; &lt;&lt; pConf-&gt;getString(&quot;password&quot;) &lt;&lt; std::endl;
			std::cout &lt;&lt; &quot;db:&quot; &lt;&lt; pConf-&gt;getString(&quot;db&quot;) &lt;&lt; std::endl;
		}

		return Application::EXIT_OK;
	}

private:
	bool _helpRequested;
};


POCO_APP_MAIN(PropertySample)</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=111</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>4. データベース利用の実装例</title>
		<link>http://www.cachet.co.jp/?p=106</link>
		<comments>http://www.cachet.co.jp/?p=106#comments</comments>
		<pubDate>Wed, 18 Jan 2012 10:46:38 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=106</guid>
		<description><![CDATA[今回は、POCOでのデータベース利用の実装例を詳解します。 まず、参考情報のポインタを示します。 http://pocoproject.org/docs/00200-DataUserManual.html 英語サイトですが、データベースフレームワークの使い方を丁寧に説明しています。 英語を苦にしない人は、上記サイトを見てもらえればOKです。 でも、これだけだとこの記事が寂しすぎるので、MySQLでのCRUDのサンプルプログラムを紹介しておきます。 #include &#34;Poco/Tuple.h&#34; #include &#34;Poco/Data/Common.h&#34; #include &#34;Poco/Data/Session.h&#34; #include &#34;Poco/Data/MySQL/Connector.h&#34; #include &#34;Poco/Util/Application.h&#34; #include &#34;Poco/Util/Option.h&#34; #include &#34;Poco/Util/OptionSet.h&#34; #include &#34;Poco/Util/HelpFormatter.h&#34; #include &#34;Poco/Util/AbstractConfiguration.h&#34; #include &#60;vector&#62; #include &#60;iostream&#62; using namespace Poco::Data; using Poco::Util::Application; using Poco::Util::Option; using Poco::Util::OptionSet; using Poco::Util::HelpFormatter; using &#8230; <a href="http://www.cachet.co.jp/?p=106">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>今回は、POCOでのデータベース利用の実装例を詳解します。<br />
まず、参考情報のポインタを示します。<br />
<a href=" http://pocoproject.org/docs/00200-DataUserManual.html "> http://pocoproject.org/docs/00200-DataUserManual.html </a></p>
<p>英語サイトですが、データベースフレームワークの使い方を丁寧に説明しています。<br />
英語を苦にしない人は、上記サイトを見てもらえればOKです。<br />
でも、これだけだとこの記事が寂しすぎるので、MySQLでのCRUDのサンプルプログラムを紹介しておきます。<br />
<span id="more-106"></span></p>
<p><pre><code>#include &quot;Poco/Tuple.h&quot;
#include &quot;Poco/Data/Common.h&quot;
#include &quot;Poco/Data/Session.h&quot;
#include &quot;Poco/Data/MySQL/Connector.h&quot;
#include &quot;Poco/Util/Application.h&quot;
#include &quot;Poco/Util/Option.h&quot;
#include &quot;Poco/Util/OptionSet.h&quot;
#include &quot;Poco/Util/HelpFormatter.h&quot;
#include &quot;Poco/Util/AbstractConfiguration.h&quot;
#include &lt;vector&gt;
#include &lt;iostream&gt;

using namespace Poco::Data;

using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Util::AbstractConfiguration;
using Poco::Util::OptionCallback;


typedef Poco::Tuple&lt;std::string, std::string, int&gt; Person;
typedef std::vector&lt;Person&gt; People;


class MysqlSample: public Application
	/// This sample demonstrates some of the features of the Poco::Data::MySQL class.
{
public:
	MysqlSample(): _helpRequested(false), _dbConnString(&quot;host=localhost;port=3306;user=test;password=test;db=test;compress=true;auto-reconnect=true&quot;)
	{
	}

protected:
	void initialize(Application&amp; self)
	{
		loadConfiguration(); // load default configuration files, if present
		Application::initialize(self);
		// add your own initialization code here
	}

	void uninitialize()
	{
		// add your own uninitialization code here
		Application::uninitialize();
	}

	void reinitialize(Application&amp; self)
	{
		Application::reinitialize(self);
		// add your own reinitialization code here
	}

	void defineOptions(OptionSet&amp; options)
	{
		Application::defineOptions(options);

		options.addOption(
			Option(&quot;help&quot;, &quot;h&quot;, &quot;display help information on command line arguments&quot;)
				.required(false)
				.repeatable(false)
				.callback(OptionCallback&lt;MysqlSample&gt;(this, &amp;MysqlSample::handleHelp)));
	}

	void handleHelp(const std::string&amp; name, const std::string&amp; value)
	{
		_helpRequested = true;
		displayHelp();
		stopOptionsProcessing();
	}

	void handleConfig(const std::string&amp; name, const std::string&amp; value)
	{
		loadConfiguration(value);
	}

	void displayHelp()
	{
		HelpFormatter helpFormatter(options());
		helpFormatter.setCommand(commandName());
		helpFormatter.setUsage(&quot;OPTIONS&quot;);
		helpFormatter.setHeader(&quot;A MysqlSample application that demonstrates how to use Poco::Data.&quot;);
		helpFormatter.format(std::cout);
	}

	int main(const std::vector&lt;std::string&gt;&amp; args)
	{
		if (!_helpRequested)
		{
			// MySQLコネクタを登録します
			MySQL::Connector::registerConnector();

			// MySQLセッションを作成します。
			Session session(SessionFactory::instance().create(MySQL::Connector::KEY, _dbConnString));

			// もし存在していたら、サンプルテーブルを削除します。
			session &lt;&lt; &quot;DROP TABLE IF EXISTS Person&quot;, now;

			// サンプルテーブルを作成します。
			session &lt;&lt; &quot;CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR(30), Age INTEGER)&quot;, now;

			// レコードを追加します。[C]
			Statement insert(session);
			Person person(&quot;Bart Simpson&quot;, &quot;Springfield&quot;, 35);
			insert &lt;&lt; &quot;INSERT INTO Person VALUES(?, ?, ?)&quot;, use(person);
			insert.execute();

			person.set&lt;0&gt;(&quot;Lisa Obama&quot;);
			person.set&lt;1&gt;(&quot;Washington&quot;);
			person.set&lt;2&gt;(10);
			insert.execute();

			// レコードを照会します。[R]
			Statement select(session);
			People people;
			select &lt;&lt; &quot;SELECT Name, Address, Age FROM Person&quot;, into(people), now;
			for (unsigned int i = 0; i &lt; people.size(); ++i)
			{
				std::cout &lt;&lt; people.at(i).get&lt;0&gt;() &lt;&lt; &quot;,&quot; &lt;&lt; people.at(i).get&lt;1&gt;() &lt;&lt; &quot;,&quot; &lt;&lt; people.at(i).get&lt;2&gt;() &lt;&lt; std::endl;
			}

			// レコードを更新します。[U]
			Statement update(session);
			person.set&lt;2&gt;(12);
			update &lt;&lt; &quot;UPDATE Person set Age = ? where Name = ?&quot;, use(person.get&lt;2&gt;()), use(person.get&lt;0&gt;()), now;

			// レコードを削除します。[D]
			Statement del(session);
			person.set&lt;0&gt;(&quot;Bart Simpson&quot;);
			del &lt;&lt; &quot;DELETE from Person where Name = ?&quot;, use(person.get&lt;0&gt;()), now;
		}

		return Application::EXIT_OK;
	}

private:
	bool _helpRequested;
	std::string _dbConnString;
};


POCO_APP_MAIN(MysqlSample)</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=106</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3. iPhone開発</title>
		<link>http://www.cachet.co.jp/?p=99</link>
		<comments>http://www.cachet.co.jp/?p=99#comments</comments>
		<pubDate>Wed, 18 Jan 2012 10:26:25 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=99</guid>
		<description><![CDATA[今回は、iPhoneアプリ開発にPOCOを使う方法を詳解します。 まずiPhone SDKがインストールされていて、以下のチュートリアルを実行してHello Worldプロジェクトができていることをスタート地点とします。 http://knol.google.com/k/iphone-sdk-helloworld# POCOをXcodeで使うには、以下の３点が必要です。 ・POCOをiPhone用にビルド＆デプロイする。 ・Xcodeプロジェクト設定をPOCO用に変更する。 ・Object-C++で、POCOを使う。 それでは、ボタンを押したときにPOCOサンプルのTimeServerから現在時刻を取得してラベルに表示するようにHello Worldプロジェクトを改造してみましょう。 1. 以下の手順で、POCOをiPhone用にビルド＆デプロイします。 $ ./configure --config=iPhone --omit=Crypto,NetSSL_OpenSSL,Data/ODBC,Data/MySQL $ make -s $ sudo make -s install 2. Xcodeプロジェクト設定画面を開いて(Project->Edit Project Settings)、Buildタブの設定を変更／追加します。 Other Linker Flags = -l PocoFoundationd -l PocoNetd Header Search Paths &#8230; <a href="http://www.cachet.co.jp/?p=99">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>今回は、iPhoneアプリ開発にPOCOを使う方法を詳解します。<br />
まずiPhone SDKがインストールされていて、以下のチュートリアルを実行してHello Worldプロジェクトができていることをスタート地点とします。<br />
<a href="http://knol.google.com/k/iphone-sdk-helloworld#">http://knol.google.com/k/iphone-sdk-helloworld#</a></p>
<p>POCOをXcodeで使うには、以下の３点が必要です。<br />
・POCOをiPhone用にビルド＆デプロイする。<br />
・Xcodeプロジェクト設定をPOCO用に変更する。<br />
・Object-C++で、POCOを使う。<br />
<span id="more-99"></span></p>
<p>それでは、ボタンを押したときにPOCOサンプルのTimeServerから現在時刻を取得してラベルに表示するようにHello Worldプロジェクトを改造してみましょう。</p>
<p>1. 以下の手順で、POCOをiPhone用にビルド＆デプロイします。<br />
<pre><code>$ ./configure --config=iPhone --omit=Crypto,NetSSL_OpenSSL,Data/ODBC,Data/MySQL
$ make -s
$ sudo make -s install</code></pre></p>
<p>2. Xcodeプロジェクト設定画面を開いて(Project->Edit Project Settings)、Buildタブの設定を変更／追加します。<br />
<pre><code>Other Linker Flags =	-l PocoFoundationd -l PocoNetd
Header Search Paths	= /usr/local/include
Library Search Paths	= /usr/local/lib
GCC_ENABLE_CPP_EXCEPTIONS = YES （追加）
GCC_ENABLE_CPP_RTTI = YES（追加）</code></pre></p>
<p>3. Object-C++からはFacadeを経由してPOCOを使うものとしてHello Worldプロジェクトを改造します。</p>
<p>まず、MainView.mファイルをMainView.mmへ名前変更して、Object-C++用にします。<br />
ラベルの文字列セットをFacadeメソッド呼び出しで行うように改造します。改造後のソースは以下のようになります。<br />
<pre><code>#import &quot;MainView.h&quot;
#import &quot;PocoFacade.h&quot;

@implementation MainView

@synthesize mainText;

- (IBAction)showText {
//    mainText.text = @&quot;Hello World&quot;;
	
	PocoFacade* facade = [[PocoFacade alloc] init];
    mainText.text = [facade getCurrentDate];
	[facade release];
}

@end</code></pre></p>
<p>次にFacadeクラスのヘッダファイルと実装ファイルを追加します。追加したヘッダファイルと実装ファイルはそれぞれ以下のようになります。</p>
<p>ヘッダファイル；<br />
<pre><code>#import &lt;Foundation/Foundation.h&gt;

class PocoFacadeImpl {
	
public:
	PocoFacadeImpl();
	void setCurrentDate(char* buffer);
	
};


@interface PocoFacade : NSObject {
	
@private
	PocoFacadeImpl *poco;
	
}

- (id)init;
- (void)dealloc;
- (NSString*)getCurrentDate;
@end</code></pre></p>
<p>実装ファイル：<br />
<pre><code>#import &quot;PocoFacade.h&quot;
#import &lt;string&gt;
#include &quot;Poco/Net/DialogSocket.h&quot;
#include &quot;Poco/Net/SocketAddress.h&quot;

using Poco::Net::DialogSocket;
using Poco::Net::SocketAddress;


PocoFacadeImpl::PocoFacadeImpl(){}

void PocoFacadeImpl::setCurrentDate(char* buffer) {
	DialogSocket ds;
	ds.connect(SocketAddress(&quot;localhost&quot;, 9911));
	std::string now;
	ds.receiveMessage(now);
	strncpy(buffer, now.c_str(), now.length());
}

@implementation PocoFacade
- (id)init {
   if (self = [super init]) {
        poco = new PocoFacadeImpl();
    }
	
    return self;
}

- (void)dealloc {
    delete poco;
    [super dealloc];
}

- (NSString*)getCurrentDate {
	char buffer[128];
	poco-&gt;setCurrentDate(buffer);
	return [NSString stringWithUTF8String:buffer];
}

@end</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=99</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2. ロギングフレームワークの使い方</title>
		<link>http://www.cachet.co.jp/?p=94</link>
		<comments>http://www.cachet.co.jp/?p=94#comments</comments>
		<pubDate>Wed, 18 Jan 2012 08:53:54 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=94</guid>
		<description><![CDATA[ロギングフレームワークの使い方を詳解します。参考情報のCodeZineの記事でロギングフレームワークそのものは詳しく説明されています。ただ、残念なことに実際にはどのように使うのがベストなのか説明がありません。 Log4Jと同じように、ソース内で記述するログ出力処理はできるだけ少なく、でもプロパティファイルの設定によってコンソールやファイルにログ出力する方法を説明します。 その方法はとても簡単で、SplitterChannelを使う設定をプロパティファイルに記述するだけです。プロパティファイルは指定しない場合は、実行ファイルと同じディレクトリの{実行ファイル名}.propertiesが読み込まれます。 プロパティファイルの記述例は以下のようになります。 logging.loggers.root.channel.class = ConsoleChannel logging.loggers.app.name = Application logging.loggers.app.channel = c0 logging.formatters.f1.class = PatternFormatter logging.formatters.f1.pattern = %Y/%m/%d %H:%M:%S[%q] %s - %t logging.channels.c0.class = SplitterChannel logging.channels.c0.channel1 = c1 logging.channels.c0.channel2 = c2 logging.channels.c1.class = ConsoleChannel logging.channels.c1.formatter = f1 logging.channels.c2.class = &#8230; <a href="http://www.cachet.co.jp/?p=94">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>ロギングフレームワークの使い方を詳解します。参考情報のCodeZineの記事でロギングフレームワークそのものは詳しく説明されています。ただ、残念なことに実際にはどのように使うのがベストなのか説明がありません。<br />
Log4Jと同じように、ソース内で記述するログ出力処理はできるだけ少なく、でもプロパティファイルの設定によってコンソールやファイルにログ出力する方法を説明します。</p>
<p>その方法はとても簡単で、SplitterChannelを使う設定をプロパティファイルに記述するだけです。プロパティファイルは指定しない場合は、実行ファイルと同じディレクトリの{実行ファイル名}.propertiesが読み込まれます。<br />
プロパティファイルの記述例は以下のようになります。<br />
<span id="more-94"></span><br />
<pre><code>logging.loggers.root.channel.class = ConsoleChannel
logging.loggers.app.name = Application
logging.loggers.app.channel = c0
logging.formatters.f1.class = PatternFormatter
logging.formatters.f1.pattern = %Y/%m/%d %H:%M:%S[%q] %s - %t
logging.channels.c0.class = SplitterChannel
logging.channels.c0.channel1 = c1
logging.channels.c0.channel2 = c2
logging.channels.c1.class = ConsoleChannel
logging.channels.c1.formatter = f1
logging.channels.c2.class = FileChannel
logging.channels.c2.path = ./Logging.log
logging.channels.c2.formatter = f1</code></pre></p>
<p>ログ出力をするサンプルプログラムです。<br />
<pre><code>#include &quot;Poco/Util/Application.h&quot;
#include &quot;Poco/Util/Option.h&quot;
#include &quot;Poco/Util/OptionSet.h&quot;
#include &quot;Poco/Util/HelpFormatter.h&quot;
#include &quot;Poco/Util/AbstractConfiguration.h&quot;
#include &quot;Poco/AutoPtr.h&quot;
#include &lt;iostream&gt;


using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Util::AbstractConfiguration;
using Poco::Util::OptionCallback;
using Poco::AutoPtr;


class Logging: public Application
	/// This sample demonstrates some of the features of the Util::Application class,
	/// such as configuration file handling and command line arguments processing.
	///
	/// Try Logging --help (on Unix platforms) or Logging /help (elsewhere) for
	/// more information.
{
public:
	Logging(): _helpRequested(false)
	{
	}

protected:
	void initialize(Application&amp; self)
	{
		loadConfiguration(); // load default configuration files, if present
		Application::initialize(self);
		// add your own initialization code here
	}

	void uninitialize()
	{
		// add your own uninitialization code here
		Application::uninitialize();
	}

	void reinitialize(Application&amp; self)
	{
		Application::reinitialize(self);
		// add your own reinitialization code here
	}

	void defineOptions(OptionSet&amp; options)
	{
		Application::defineOptions(options);

		options.addOption(
			Option(&quot;help&quot;, &quot;h&quot;, &quot;display help information on command line arguments&quot;)
				.required(false)
				.repeatable(false)
				.callback(OptionCallback&lt;Logging&gt;(this, &amp;Logging::handleHelp)));

		options.addOption(
			Option(&quot;config-file&quot;, &quot;f&quot;, &quot;load configuration data from a file&quot;)
				.required(false)
				.repeatable(true)
				.argument(&quot;file&quot;)
				.callback(OptionCallback&lt;Logging&gt;(this, &amp;Logging::handleConfig)));
	}

	void handleHelp(const std::string&amp; name, const std::string&amp; value)
	{
		_helpRequested = true;
		displayHelp();
		stopOptionsProcessing();
	}

	void handleConfig(const std::string&amp; name, const std::string&amp; value)
	{
		loadConfiguration(value);
	}

	void displayHelp()
	{
		HelpFormatter helpFormatter(options());
		helpFormatter.setCommand(commandName());
		helpFormatter.setUsage(&quot;OPTIONS&quot;);
		helpFormatter.setHeader(&quot;A logging application that demonstrates how to use logging.&quot;);
		helpFormatter.format(std::cout);
	}

	int main(const std::vector&lt;std::string&gt;&amp; args)
	{
		if (!_helpRequested)
		{
			logger().trace(&quot;trace ログ出力です&quot;);
			logger().debug(&quot;debug ログ出力です&quot;);
			logger().information(&quot;info ログ出力です&quot;);
			logger().warning(&quot;warn ログ出力です&quot;);
			logger().error(&quot;error ログ出力です&quot;);
			logger().fatal(&quot;fatal ログ出力です&quot;);
		}
		return Application::EXIT_OK;
	}

private:
	bool _helpRequested;
};


POCO_APP_MAIN(Logging)</code></pre></p>
<p>終わりに、ロギングについての参考情報のポインタを示します。<br />
<a href="http://codezine.jp/article/detail/1901">http://codezine.jp/article/detail/1901</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=94</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>1. PUSH技術の実装例</title>
		<link>http://www.cachet.co.jp/?p=80</link>
		<comments>http://www.cachet.co.jp/?p=80#comments</comments>
		<pubDate>Wed, 18 Jan 2012 06:25:01 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=80</guid>
		<description><![CDATA[PUSH技術をPOCOを使ってどのように実装できるか詳解します。 その前に、PUSH技術とは何かおさらいしておきます。 PUSH技術とは、テレビのようにサーバから複数のクライアントへコンテンツを送信する技術で、実現方法は以下の３つです。 1. クライアントが定期的にリクエストを発行する。（ポーリング）・・・例：電子メール 2. ポーリングと同じくクライアントがリクエストを発行するが、新しいコンテンツが発生するまでレスポンスを返さない。（ロングポーリング）・・・例：Comet 3. コネクションを張りっぱなしにする。（ストリーミング）・・・例：金融取引リッチクライアント ポーリングとロングポーリングについては、ググればサンプルソースがたくさん見つかりますが、ストリーミングについてはまったく見つかりませんでした。 ここでは、POCOを使ってストリーミングを実装していきます。 通信アプリケーション開発をサポートするために、POCOはNetライブラリを提供しています。 その中のPoco::Net::TCPServerクラスは、スレッドプールによるマルチスレッドのソケット通信処理を行うことができるので、ストリーミング実装にはこれを使うこととします。 TCPServerクラスを使うNetライブラリのサンプルとして、TimeServerプロジェクトがPOCOに付属しています。 TimeServerプロジェクトを、サーバの現在時刻をプッシュするように改造してみます。 まずは、サンプルをそのままコンパイルして実行してみましょう。 $ TimeServer これで、サーバが起動されたので、telnetでサーバと通信してみます。 $ telnet 127.0.0.1 9911 以下のように、telnetにサーバの現在時刻が表示されて接続が切断されたと思います。 $ telnet 127.0.0.1 9911 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 2009-07-04T02:31:52Z Connection closed &#8230; <a href="http://www.cachet.co.jp/?p=80">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>PUSH技術をPOCOを使ってどのように実装できるか詳解します。<br />
その前に、PUSH技術とは何かおさらいしておきます。<br />
PUSH技術とは、テレビのようにサーバから複数のクライアントへコンテンツを送信する技術で、実現方法は以下の３つです。<br />
1. クライアントが定期的にリクエストを発行する。（ポーリング）・・・例：電子メール<br />
2. ポーリングと同じくクライアントがリクエストを発行するが、新しいコンテンツが発生するまでレスポンスを返さない。（ロングポーリング）・・・例：Comet<br />
3. コネクションを張りっぱなしにする。（ストリーミング）・・・例：金融取引リッチクライアント</p>
<p>ポーリングとロングポーリングについては、ググればサンプルソースがたくさん見つかりますが、ストリーミングについてはまったく見つかりませんでした。<br />
ここでは、POCOを使ってストリーミングを実装していきます。<br />
<span id="more-80"></span><br />
通信アプリケーション開発をサポートするために、POCOはNetライブラリを提供しています。<br />
その中のPoco::Net::TCPServerクラスは、スレッドプールによるマルチスレッドのソケット通信処理を行うことができるので、ストリーミング実装にはこれを使うこととします。<br />
TCPServerクラスを使うNetライブラリのサンプルとして、TimeServerプロジェクトがPOCOに付属しています。<br />
TimeServerプロジェクトを、サーバの現在時刻をプッシュするように改造してみます。</p>
<p>まずは、サンプルをそのままコンパイルして実行してみましょう。<br />
$ TimeServer<br />
これで、サーバが起動されたので、telnetでサーバと通信してみます。<br />
$ telnet 127.0.0.1 9911<br />
以下のように、telnetにサーバの現在時刻が表示されて接続が切断されたと思います。<br />
<pre><code>$ telnet 127.0.0.1 9911
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
2009-07-04T02:31:52Z
Connection closed by foreign host.</code></pre></p>
<p>接続をつなぎっぱなしにしてサーバからプッシュできるように、TimeServerConnection#runで現在時刻を送信していたのを、イベントに現在時刻送信メソッドを登録した後サスペンドするように変更します。イベント発生は、便宜的に１秒間隔で発生するものとしました。<br />
このイベントの実装には、FoundationライブラリのPoco::BasicEventクラスを使うだけです。<br />
Poco::BasicEventは、C#プログラマにはおなじみのC#のイベント機能のC++実装です。</p>
<p>変更したソースを以下に記載します。プロトタイプとして動作を確認するレベルですが、POCOを使うことでスレッドプールでの通信という高度なアプリケーションが、このように簡単に作れてしまいます。<br />
<pre><code>#include &quot;Poco/Net/TCPServer.h&quot;
#include &quot;Poco/Net/TCPServerConnection.h&quot;
#include &quot;Poco/Net/TCPServerConnectionFactory.h&quot;
#include &quot;Poco/Net/TCPServerParams.h&quot;
#include &quot;Poco/Net/StreamSocket.h&quot;
#include &quot;Poco/Net/ServerSocket.h&quot;
#include &quot;Poco/Timestamp.h&quot;
#include &quot;Poco/DateTimeFormatter.h&quot;
#include &quot;Poco/DateTimeFormat.h&quot;
#include &quot;Poco/Exception.h&quot;
#include &quot;Poco/Util/ServerApplication.h&quot;
#include &quot;Poco/Util/Option.h&quot;
#include &quot;Poco/Util/OptionSet.h&quot;
#include &quot;Poco/Util/HelpFormatter.h&quot;
#include &lt;iostream&gt;
#include &quot;Poco/BasicEvent.h&quot;
#include &quot;Poco/Delegate.h&quot;


using Poco::Net::ServerSocket;
using Poco::Net::StreamSocket;
using Poco::Net::TCPServerConnection;
using Poco::Net::TCPServerConnectionFactory;
using Poco::Net::TCPServer;
using Poco::Timestamp;
using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
using Poco::Util::ServerApplication;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;

static Poco::BasicEvent&lt;int&gt; push_event;

class PushRunnable: public Poco::Runnable
{
public:
	PushRunnable(): _stopped(false)
	{
	}

	void run()
	{
		int tmp = 0;
		while (!_stopped)
		{
			++tmp;
			push_event.notify(this, tmp);
			Poco::Thread::sleep(1000);
		}
	}

	void notify()
	{
		_stopped = true;
	}

private:
	bool _stopped;
};


class TimeServerConnection: public TCPServerConnection
	/// This class handles all client connections.
	///
	/// A string with the current date and time is sent back to the client.
{
public:
	TimeServerConnection(const StreamSocket&amp; s, const std::string&amp; format)
		: TCPServerConnection(s)
		, _format(format)
		, _stopped(false)
	{
	}
	
	void run()
	{
		Application&amp; app = Application::instance();
		app.logger().information(&quot;Request from &quot; + this-&gt;socket().peerAddress().toString());
		try
		{
			push_event += Poco::delegate(this, &amp;TimeServerConnection::onPush);
			while (!_stopped)
			{
				Poco::Thread::sleep(1);
			}
		}
		catch (Poco::Exception&amp; exc)
		{
			app.logger().log(exc);
		}
	}
	
	void onPush(const void* pSender, int&amp; i)
	{
		try
		{
			Timestamp now;
			std::string dt(DateTimeFormatter::format(now, _format));
			dt.append(&quot;\r\n&quot;);
			socket().sendBytes(dt.data(), (int) dt.length());
		}
		catch (Poco::Exception&amp; exc)
		{
			push_event -= Poco::delegate(this, &amp;TimeServerConnection::onPush);
			_stopped = true;
			Application::instance().logger().log(exc);;
		}
	}

private:
	std::string _format;
	bool _stopped;
};


class TimeServerConnectionFactory: public TCPServerConnectionFactory
	/// A factory for TimeServerConnection.
{
public:
	TimeServerConnectionFactory(const std::string&amp; format):
		_format(format)
	{
	}
	
	TCPServerConnection* createConnection(const StreamSocket&amp; socket)
	{
		return new TimeServerConnection(socket, _format);
	}

private:
	std::string _format;
};


class TimeServer: public Poco::Util::ServerApplication
	/// The main application class.
	///
	/// This class handles command-line arguments and
	/// configuration files.
	/// Start the TimeServer executable with the help
	/// option (/help on Windows, --help on Unix) for
	/// the available command line options.
	///
	/// To use the sample configuration file (TimeServer.properties),
	/// copy the file to the directory where the TimeServer executable
	/// resides. If you start the debug version of the TimeServer
	/// (TimeServerd[.exe]), you must also create a copy of the configuration
	/// file named TimeServerd.properties. In the configuration file, you
	/// can specify the port on which the server is listening (default
	/// 9911) and the format of the date/time string sent back to the client.
	///
	/// To test the TimeServer you can use any telnet client (telnet localhost 9911).
{
public:
	TimeServer(): _helpRequested(false)
	{
	}
	
	~TimeServer()
	{
	}

protected:
	void initialize(Application&amp; self)
	{
		loadConfiguration(); // load default configuration files, if present
		ServerApplication::initialize(self);
	}
		
	void uninitialize()
	{
		ServerApplication::uninitialize();
	}

	void defineOptions(OptionSet&amp; options)
	{
		ServerApplication::defineOptions(options);
		
		options.addOption(
			Option(&quot;help&quot;, &quot;h&quot;, &quot;display help information on command line arguments&quot;)
				.required(false)
				.repeatable(false));
	}

	void handleOption(const std::string&amp; name, const std::string&amp; value)
	{
		ServerApplication::handleOption(name, value);

		if (name == &quot;help&quot;)
			_helpRequested = true;
	}

	void displayHelp()
	{
		HelpFormatter helpFormatter(options());
		helpFormatter.setCommand(commandName());
		helpFormatter.setUsage(&quot;OPTIONS&quot;);
		helpFormatter.setHeader(&quot;A server application that serves the current date and time.&quot;);
		helpFormatter.format(std::cout);
	}

	int main(const std::vector&lt;std::string&gt;&amp; args)
	{
		if (_helpRequested)
		{
			displayHelp();
		}
		else
		{
			// get parameters from configuration file
			unsigned short port = (unsigned short) config().getInt(&quot;TimeServer.port&quot;, 9911);
			std::string format(config().getString(&quot;TimeServer.format&quot;, DateTimeFormat::ISO8601_FORMAT));
			
			// set-up a server socket
			ServerSocket svs(port);
			// set-up a TCPServer instance
			TCPServer srv(new TimeServerConnectionFactory(format), svs);
			// start the TCPServer
			srv.start();

			// start push thread
			Poco::Thread thread;
			PushRunnable runnable;
			thread.start(runnable);

			// wait for CTRL-C or kill
			waitForTerminationRequest();
			// Stop the TCPServer
			srv.stop();
		}
		return Application::EXIT_OK;
	}
	
private:
	bool _helpRequested;
};


int main(int argc, char** argv)
{
	TimeServer app;
	return app.run(argc, argv);
}</code></pre></p>
<p>終わりに、PUSH技術についての参考情報のポインタを示します。<br />
<a href="http://www.atmarkit.co.jp/fjava/column/andoh/andoh38.html">http://www.atmarkit.co.jp/fjava/column/andoh/andoh38.html</a><br />
<a href="http://feed.designlinkdatabase.net/feed/outsite_106801.aspx">http://feed.designlinkdatabase.net/feed/outsite_106801.aspx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=80</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>0. POCOでC++が復権する!?</title>
		<link>http://www.cachet.co.jp/?p=75</link>
		<comments>http://www.cachet.co.jp/?p=75#comments</comments>
		<pubDate>Wed, 18 Jan 2012 03:56:22 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=75</guid>
		<description><![CDATA[C++はオブジェクト指向言語の黎明期から存在し、Javaが登場するまでは人気のある開発言語でした。しかし、言語仕様がとても複雑で標準クラスライブラリがコンテナくらいしかなくしょぼいので、最近のプロジェクトではほとんど使われていないと思います。今は、Java、C#、Rubyで開発するのが普通ですが、今回、C++のオープンソースライブラリであるPOCOを詳解するのは、時間の無駄のように思うかもしれません。 私の予想は60％以上の確率で外れる気がしますが、POCOを前提としたC++開発の人気が将来でてくると思っているからです。 理由は以下の３点です。 1. POCOを使うとC++開発が、Java開発と同程度に容易になる。 2. C++は、リアルタイム処理、パフォーマンスの高さで他言語に対してアドバンテージがある。 3. iPhoneの開発に使える。 日本語でのPOCOの情報がCodeZineとPOCO Fanaticくらいでまったくないので、詳解記事を連載することとしました。 連載内容は以下を予定しています。 1. PUSH技術の実装例 2. ロギングフレームワークの使い方 3. iPhone開発 4. データベース利用の実装例 5. プロパティファイル 6. バリデーション 7. クラスローディング 8. ユーティリティ（日付処理、ID採番） 上記については、ググれば見つかる情報はポインタを示すだけで、一般に周知されていなものについてのみ詳解していく予定です。 終わりに、POCOについての参考情報のポインタを示します。 http://pocoproject.org/ POCO Fanatic http://codezine.jp/article/corner/46 http://d.hatena.ne.jp/tullio/20090617/1245252894]]></description>
			<content:encoded><![CDATA[<p>C++はオブジェクト指向言語の黎明期から存在し、Javaが登場するまでは人気のある開発言語でした。しかし、言語仕様がとても複雑で標準クラスライブラリがコンテナくらいしかなくしょぼいので、最近のプロジェクトではほとんど使われていないと思います。今は、Java、C#、Rubyで開発するのが普通ですが、今回、C++のオープンソースライブラリであるPOCOを詳解するのは、時間の無駄のように思うかもしれません。<br />
私の予想は60％以上の確率で外れる気がしますが、POCOを前提としたC++開発の人気が将来でてくると思っているからです。<br />
理由は以下の３点です。<br />
1. POCOを使うとC++開発が、Java開発と同程度に容易になる。<br />
2. C++は、リアルタイム処理、パフォーマンスの高さで他言語に対してアドバンテージがある。<br />
3. iPhoneの開発に使える。<br />
<span id="more-75"></span><br />
日本語でのPOCOの情報がCodeZineと<a href="http://poco.roundsquare.net/" title="POCO Fanatic" target="_blank">POCO Fanatic</a>くらいでまったくないので、詳解記事を連載することとしました。<br />
連載内容は以下を予定しています。<br />
1. PUSH技術の実装例<br />
2. ロギングフレームワークの使い方<br />
3. iPhone開発<br />
4. データベース利用の実装例<br />
5. プロパティファイル<br />
6. バリデーション<br />
7. クラスローディング<br />
8. ユーティリティ（日付処理、ID採番）</p>
<p>上記については、ググれば見つかる情報はポインタを示すだけで、一般に周知されていなものについてのみ詳解していく予定です。</p>
<p>終わりに、POCOについての参考情報のポインタを示します。<br />
<a href="http://pocoproject.org/" target="_blank">http://pocoproject.org/</a><br />
<a href="http://poco.roundsquare.net/" title="POCO Fanatic" target="_blank">POCO Fanatic</a><br />
<a href="http://codezine.jp/article/corner/46" target="_blank">http://codezine.jp/article/corner/46</a><br />
<a href="http://d.hatena.ne.jp/tullio/20090617/1245252894" target="_blank">http://d.hatena.ne.jp/tullio/20090617/1245252894</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=75</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ブログ始めます</title>
		<link>http://www.cachet.co.jp/?p=73</link>
		<comments>http://www.cachet.co.jp/?p=73#comments</comments>
		<pubDate>Wed, 18 Jan 2012 03:46:59 +0000</pubDate>
		<dc:creator>sd_dba_LTY1OTI3</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://www.cachet.co.jp/?p=73</guid>
		<description><![CDATA[当社は最先端の金融市場ソフトウェアを開発する会社ですが、その開発の中で蓄積した技術情報をブログとして発信していくこととしました。 微力ながら日本のIT技術発展に貢献していければ幸いです。]]></description>
			<content:encoded><![CDATA[<p>当社は最先端の金融市場ソフトウェアを開発する会社ですが、その開発の中で蓄積した技術情報をブログとして発信していくこととしました。<br />
微力ながら日本のIT技術発展に貢献していければ幸いです。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cachet.co.jp/?feed=rss2&#038;p=73</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
