[openrtm-commit:01401] r141 - in branches/newCMakeForVC2010/ImageProcessing/opencv/components: . NetworkCameraUtility NetworkCameraUtility/include NetworkCameraUtility/src
openrtm @ openrtm.org
openrtm @ openrtm.org
2014年 3月 25日 (火) 16:06:53 JST
Author: kawauchi
Date: 2014-03-25 16:06:53 +0900 (Tue, 25 Mar 2014)
New Revision: 141
Added:
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/CMakeLists.txt
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/HttpClient.h
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/HttpClientConcrete.h
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/TimeoutBlockingClient.h
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/string_utility.h
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/HttpClient.cpp
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/HttpClientConcrete.cpp
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/TimeoutBlockingClient.cpp
branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/string_utility.cpp
Modified:
branches/newCMakeForVC2010/ImageProcessing/opencv/components/CMakeLists.txt
Log:
NetworkCameraUtility : Created new shared library for network camera components. refs #2704
Modified: branches/newCMakeForVC2010/ImageProcessing/opencv/components/CMakeLists.txt
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/CMakeLists.txt 2014-03-19 07:21:46 UTC (rev 140)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/CMakeLists.txt 2014-03-25 07:06:53 UTC (rev 141)
@@ -34,5 +34,10 @@
add_subdirectory(SubStractCaptureImage)
add_subdirectory(Template)
add_subdirectory(Translate)
+if(BOOST_ROOT)
+ add_subdirectory(NetworkCameraUtility)
+ add_subdirectory(PanasonicRtComponent)
+ add_subdirectory(SonyRtComponent)
+endif()
Added: branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/CMakeLists.txt
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/CMakeLists.txt (rev 0)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/CMakeLists.txt 2014-03-25 07:06:53 UTC (rev 141)
@@ -0,0 +1,69 @@
+cmake_minimum_required (VERSION 2.8)
+
+# プロジェクト名
+# VS2010の場合ソリューション名に使われる
+project(NetworkCameraUtility)
+
+# ソースファイル指定
+set(SRC ${PROJECT_SOURCE_DIR}/src)
+set(TARGET_SORCES
+ ${SRC}/string_utility.cpp
+ ${SRC}/HttpClient.cpp
+ ${SRC}/HttpClientConcrete.cpp
+ ${SRC}/TimeoutBlockingClient.cpp
+)
+
+# マクロ定義
+# Windowsバージョン, XP以上を指定
+if (WIN32)
+ add_definitions(-D_WIN32_WINNT=0x0501)
+endif(WIN32)
+#add_definitions(-DNETWORKCAMERAUTILITY_EXPORTS)
+
+# Boost検索
+# リンク対象のライブラリを指定しないと、ライブラリサーチパスが設定されない
+#find_package(Boost 1.55.0 REQUIRED)
+find_package(Boost 1.55.0 REQUIRED COMPONENTS serialization system)
+
+# インクルードパス
+include_directories(${Boost_INCLUDE_DIRS})
+include_directories(${PROJECT_SOURCE_DIR}/include)
+
+# ライブラリサーチパス
+link_directories(${Boost_LIBRARY_DIRS})
+
+# DLL用のエクスポート設定ファイルを生成するモジュールのロード
+include (GenerateExportHeader)
+
+# 共有ライブラリの生成
+add_library(NetworkCameraUtility SHARED ${TARGET_SORCES})
+
+# エクスポート設定ファイルの生成
+GENERATE_EXPORT_HEADER(NetworkCameraUtility
+ BASE_NAME NetworkCameraUtility
+ EXPORT_MACRO_NAME NETWORKCAMERAUTILITY_API
+ EXPORT_FILE_NAME ../include/utility_dll_defs.h
+ STATIC_DEFINE NetworkCameraUtility_BUILT_AS_STATIC)
+
+# ライブラリの指定
+#target_link_libraries(NetworkCameraUtility ${Boost_SYSTEM_LIBRARIES})
+target_link_libraries(NetworkCameraUtility ${Boost_LIBRARIES})
+
+if (SolutionDir)
+ if(WIN32)
+ add_custom_command(
+ TARGET ${PROJECT_NAME}
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E
+ copy ${PROJECT_BINARY_DIR}/src/Release/${PROJECT_NAME}.dll ${SolutionDir}/bin
+ )
+ else(WIN32)
+ add_custom_command(
+ TARGET ${PROJECT_NAME}
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E
+ copy ${PROJECT_BINARY_DIR}/lib${PROJECT_NAME}.so ${SolutionDir}/bin
+ )
+ endif(WIN32)
+endif (SolutionDir)
+
Added: branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/HttpClient.h
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/HttpClient.h (rev 0)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/HttpClient.h 2014-03-25 07:06:53 UTC (rev 141)
@@ -0,0 +1,162 @@
+/*!
+ * @file HttpClient.h
+ * @brief Http client for dll export
+ * @date 2014-02-06
+ */
+#ifndef HTTP_CLIENT_H
+#define HTTP_CLIENT_H
+
+#include <stdio.h>
+#include "utility_dll_defs.h"
+
+/*!
+ * @namespace openrtm_network_camera
+ * @brief OpenRTM NetworkCamera用コンポーネント
+ *
+ */
+namespace openrtm_network_camera {
+
+/*!
+ * @namespace utility
+ * @brief 共通処理
+ *
+ */
+namespace utility {
+
+class HttpClientConcrete;
+
+/*!
+ * @class HttpClient
+ * @brief HttpClient クラス
+ *
+ * Httpを用いてアクセスするためのクラス。
+ * 実際の処理は、HttpClientConcreteクラスへ委譲する。
+ * DLL作成時にエクスポートするクラス内部でSTLを使っている場合、
+ * 問題が発生したので、外部へエクスポートするクラス(本クラス)では
+ * STLを取り除いた。
+ *
+ * @see http://support.microsoft.com/default.aspx?scid=kb;ja-jp;168958
+ * @see http://stackoverflow.com/questions/8976617/when-exporting-stl-stdbasic-string-template-from-dll-i-get-a-lnk2005-error
+ */
+class NETWORKCAMERAUTILITY_API HttpClient
+{
+public:
+ HttpClient(void);
+ ~HttpClient(void);
+
+ /*!
+ * @brief GETリクエストの実行
+ *
+ * 指定ホストに対してGETリクエストを実行する。処理は同期で行われる。
+ * リクエスト時に、HttpClient#setBasicAuthenticationParameter メソッドにより認証情報
+ * が与えられている場合は、Basic認証用の処理も実施する。
+ * Httpレスポンスコードが、200、204以外は不正なレスポンスと判断し、
+ * 必要なヘッダやコンテンツを設定しない。
+ * また、エラー発生時には、ステータスコードに-1を設定する。
+ *
+ * @param p_host_name ホスト名(IPアドレスもOK)
+ * @param p_path_name 対象となる絶対パス名
+ * @param p_port ポート番号
+ */
+ void doGet(const char* p_host_name, const char* p_path_name, const char* p_port);
+
+ /*!
+ * @brief httpレスポンスのステータスコードを取得する。
+ *
+ * httpリクエストに対するステータスコードを返す。
+ *
+ * @return ステータスコード
+ * -1:エラー発生
+ */
+ int getStatusCode() const;
+
+ /*!
+ * @brief httpレスポンスのヘッダを取得する。
+ *
+ * httpリクエストに対するヘッダの配列を取得する。
+ * 各ヘッダは ヘッダ名:パラメータ の形式の文字列がそのまま格納されている。
+ *
+ * @param p_size ヘッダ数
+ * @return ヘッダの配列へのポインタ
+ * @caution 戻り値は呼び出し側で開放しない
+ */
+ const char* const* getHeaders(int* p_size);
+
+ /*!
+ * @brief httpレスポンスのコンテンツを取得する。
+ *
+ * httpリクエストに対するコンテンツを取得する。
+ * ステータスコードが204(No Contents)の場合や、200(OK)の場合でも、
+ * コンテンツが含まれていない場合がある。
+ * コンテンツはテキストの場合もバイナリデータの場合もあるので、
+ * 取得したデータは、getContentType と getContentLength に応じて適切に
+ * 処理を行うこと。
+ *
+ * @return コンテンツデータへのポインタ
+ * @caution 戻り値は呼び出し側で開放しない
+ */
+ const char* getContents() const;
+
+ /*!
+ * @brief httpレスポンスのコンテンツタイプを取得する。
+ *
+ * httpリクエストに対するコンテンツタイプを取得する。
+ *
+ * @return コンテンツタイプ文字列へのポインタ、末尾は\0
+ * @caution 戻り値は呼び出し側で開放しない
+ */
+ const char* getContentType() const;
+
+ /*!
+ * @brief httpレスポンスのコンテンツ長を取得する。
+ *
+ * httpリクエストに対するコンテンツ長を取得する。
+ *
+ * @return コンテンツ長、データがない場合は0
+ */
+ size_t getContentLength() const;
+
+ /*!
+ * @brief httpリクエスト時の認証情報を設定する。
+ *
+ * httpリクエスト時のBasic認証用の認証情報を設定する。
+ * 指定された場合は、常に認証情報を付加してリクエストを行う。
+ *
+ * @param p_user ユーザー名
+ * @param p_password パスワード
+ */
+ void setBasicAuthenticationParameter(const char* p_user, const char* p_password);
+
+ /*!
+ * @brief タイムアウト時間の設定
+ *
+ * ネットワークアクセス時のタイムアウトを指定時間とする。
+ * 本メソッドが呼ばれない場合は、デフォルト値が使われる。
+ * (デフォルト値は60秒)
+ *
+ * @caution
+ * パラメータが0以下の場合、デフォルト値が使われる。
+ *
+ * @param timeout タイムアウト時間, 秒単位
+ */
+ void setTimeout(const long timeout);
+
+protected:
+private:
+ /*!
+ * @brief ヘッダ格納用コンテナの削除
+ */
+ void deleteHeaderContainer();
+
+ HttpClientConcrete* p_client_; //!< 実際のhttp処理を行うクラスのインスタンス, ポインタで保持するのはincludeを含めたくないため
+ const char** p_header_container_; //!< ヘッダ格納用コンテナ
+
+
+ HttpClient(const HttpClient&);
+ void operator=(const HttpClient&);
+};
+
+} // utility
+} // openrtm_network_camera
+
+#endif
Added: branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/HttpClientConcrete.h
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/HttpClientConcrete.h (rev 0)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/HttpClientConcrete.h 2014-03-25 07:06:53 UTC (rev 141)
@@ -0,0 +1,212 @@
+/*!
+ * @file HttpClientConcrete.h
+ * @brief Http client using Boost.Asio
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * @date 2014-02-06
+ */
+#ifndef HTTP_CLIENT_CONCRETE_H
+#define HTTP_CLIENT_CONCRETE_H
+
+#include <string>
+#include <vector>
+
+/*!
+ * @namespace openrtm_network_camera
+ * @brief OpenRTM NetworkCamera用コンポーネント
+ *
+ */
+namespace openrtm_network_camera {
+
+/*!
+ * @namespace utility
+ * @brief 共通処理
+ *
+ */
+namespace utility {
+
+class TimeoutBlockingClient;
+
+/*!
+ * @class HttpClientConcrete
+ * @brief Boost.Asio を用いた HttpClient クラス
+ *
+ * Httpを用いてアクセスするためのクラス。
+ * 処理は、Boost.Asio を元に実装する。
+ *
+ * Boost.Asio のサンプルを元に記述
+ * @see http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp03/http/client/sync_client.cpp
+ */
+class HttpClientConcrete
+{
+public:
+ HttpClientConcrete(void);
+ ~HttpClientConcrete(void);
+
+ /*!
+ * @brief GETリクエストの実行
+ *
+ * 指定ホストに対してGETリクエストを実行する。処理は同期で行われる。
+ * リクエスト時に、HttpClientConcrete#setBasicAuthenticationParameter メソッドにより認証情報
+ * が与えられている場合は、Basic認証用の処理も実施する。
+ * Httpレスポンスコードが、200、204以外は不正なレスポンスと判断し、
+ * 必要なヘッダやコンテンツを設定しない。
+ * また、エラー発生時には、ステータスコードに-1を設定する。
+ *
+ * @param host_name ホスト名(IPアドレスもOK)
+ * @param path_name 対象となる絶対パス名
+ * @param port ポート番号
+ */
+ void doGet(const std::string& host_name, const std::string& path_name, const std::string& port);
+
+ /*!
+ * @brief httpレスポンスのステータスコードを取得する。
+ *
+ * httpリクエストに対するステータスコードを返す。
+ *
+ * @return ステータスコード
+ * -1:エラー発生
+ */
+ int getStatusCode() const { return status_code_; }
+
+ /*!
+ * @brief httpレスポンスのヘッダを取得する。
+ *
+ * httpリクエストに対するヘッダの配列を取得する。
+ * 各ヘッダは ヘッダ名:パラメータ の形式の文字列がそのまま格納されている。
+ *
+ * @return ヘッダ
+ */
+ const std::vector<std::string>& getHeaders() const { return headers_; }
+
+ /*!
+ * @brief httpレスポンスのコンテンツを取得する。
+ *
+ * httpリクエストに対するコンテンツを取得する。
+ * ステータスコードが204(No Contents)の場合や、200(OK)の場合でも、
+ * コンテンツが含まれていない場合がある。
+ * コンテンツはテキストの場合もバイナリデータの場合もあるので、
+ * 取得したデータは、getContentType と getContentLength に応じて適切に
+ * 処理を行うこと。
+ *
+ * @return コンテンツデータへのポインタ
+ * @caution 戻り値は呼び出し側で開放しない
+ */
+ const char* getContents() const { return contents_; }
+
+ /*!
+ * @brief httpレスポンスのコンテンツタイプを取得する。
+ *
+ * httpリクエストに対するコンテンツタイプを取得する。
+ *
+ * @return コンテンツタイプ
+ */
+ const std::string& getContentType() const { return content_type_; }
+
+ /*!
+ * @brief httpレスポンスのコンテンツ長を取得する。
+ *
+ * httpリクエストに対するコンテンツ長を取得する。
+ *
+ * @return コンテンツ長、データがない場合は0
+ */
+ size_t getContentLength() const { return content_length_; }
+
+ /*!
+ * @brief httpリクエスト時の認証情報を設定する。
+ *
+ * httpリクエスト時のBasic認証用の認証情報を設定する。
+ * 指定された場合は、常に認証情報を付加してリクエストを行う。
+ *
+ * @param p_user ユーザー名
+ * @param p_password パスワード
+ */
+ void setBasicAuthenticationParameter(const std::string& user, const std::string& password);
+
+ /*!
+ * @brief タイムアウト時間の設定
+ *
+ * ネットワークアクセス時のタイムアウトを指定時間とする。
+ * 本メソッドが呼ばれない場合は、デフォルト値が使われる。
+ * (デフォルト値は60秒)
+ *
+ * @caution
+ * パラメータが0以下の場合、デフォルト値が使われる。
+ *
+ * @param timeout タイムアウト時間, 秒単位
+ */
+ void setTimeout(const long timeout);
+
+protected:
+private:
+ /*!
+ * @brief httpレスポンスに関連するメンバー変数の初期化
+ */
+ void response_member_init();
+
+ /*!
+ * @brief ヘッダの処理
+ *
+ * レスポンスデータを処理して、ヘッダを取り出す。
+ *
+ * @param client タイムアウト付き同期処理TCPクライアントの参照
+ */
+ void processHeaders(TimeoutBlockingClient& client);
+
+ /*!
+ * @breif コンテンツタイプを設定する。
+ */
+ void setContentType();
+
+ /*!
+ * @breif コンテンツ長を設定する。
+ */
+ void setContentLength();
+
+ /*!
+ * @breif コンテンツの処理。
+ *
+ * レスポンスデータを処理して、コンテンツを取り出す。
+ *
+ * @param client タイムアウト付き同期処理TCPクライアントの参照
+ */
+ void processContents(TimeoutBlockingClient& client);
+
+ /*!
+ * @breif ヘッダ値の取得。
+ *
+ * ヘッダ文字列を解析し、その値を取り出す。
+ *
+ * @param target ヘッダ文字列
+ * @return ヘッダ値(コロン以降の値)
+ */
+ std::string getHeaderValue(const std::string& target);
+
+
+ const static int ERROR_CODE = -1; //!< エラー発生時のステータスコード
+ const static int DEFAULT_TIMEOUT_SEC = 60; //!< デフォルトのタイムアウト時間, 秒単位
+
+ long timeout_; //!< タイムアウト時間, 秒単位
+
+ // リクエスト用変数
+ std::string user_; //!< ユーザー名
+ std::string password_; //!< パスワード
+
+ // レスポンス用変数
+ int status_code_; //!< HTTP問い合わせの戻り値、エラー発生時は-1とする
+ std::vector<std::string> headers_; //!< ヘッダ
+ std::string content_type_; //!< コンテンツタイプ
+ size_t content_length_; //!< コンテンツ長
+ char* contents_; //!< コンテンツ
+
+
+ HttpClientConcrete(const HttpClientConcrete&);
+ void operator=(const HttpClientConcrete&);
+};
+
+} // utility
+} // openrtm_network_camera
+
+#endif
\ No newline at end of file
Added: branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/TimeoutBlockingClient.h
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/TimeoutBlockingClient.h (rev 0)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/TimeoutBlockingClient.h 2014-03-25 07:06:53 UTC (rev 141)
@@ -0,0 +1,126 @@
+/*!
+ * @file TimoutBlockingClient.h
+ * @brief Network access client using Boost.Asio
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * @date 2014-02-13
+ */
+#ifndef TIMEOUT_BLOCKING_CLIENT_H
+#define TIMEOUT_BLOCKING_CLIENT_H
+
+#include <string>
+
+#include <boost/asio.hpp>
+
+/*!
+ * @namespace openrtm_network_camera
+ * @brief OpenRTM NetworkCamera用コンポーネント
+ *
+ */
+namespace openrtm_network_camera {
+
+/*!
+ * @namespace utility
+ * @brief 共通処理
+ *
+ */
+namespace utility {
+
+/*!
+ * @class TimeoutBlockingClient
+ * @brief Boost.Asio を用いた タイムアウト付きのClient クラス
+ *
+ * タイムアウトを備えた、ネットワークへアクセスするクライアントクラス。
+ * 処理は、Boost.Asio を元に実装する。
+ *
+ * @caution
+ * 各メソッド呼び出し時にタイムアウトを指定するが、本クラスで指定したタイムアウト
+ * 時間より早くネットワークアクセスのメソッドがタイムアウトする場合がある
+ *
+ * Boost.Asio のサンプルを元に記述
+ * @see http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp03/timeouts/blocking_tcp_client.cpp
+ */
+class TimeoutBlockingClient
+{
+public:
+ TimeoutBlockingClient();
+ ~TimeoutBlockingClient();
+
+ /*!
+ * @brief 接続
+ *
+ * ホストとポートを指定してTCPによる接続を行う。
+ * 接続確認時、指定タイムアウト時間を経過した場合はタイムアウトと
+ * 判定し、例外を投げる
+ *
+ * @caution
+ * 名前解決は同期処理で行う(明示的なタイムアウト処理はしない)
+ *
+ * @param host ホスト名またはIPアドレス
+ * @param service サービス名またはポート番号
+ * @param timeout タイムアウトまでの時間、秒単位
+ */
+ void connect(const std::string& host, const std::string& service, boost::posix_time::time_duration timeout);
+
+ /*!
+ * @brief 読み込み
+ *
+ * ソケットからの全データの読み込み
+ * 読み込み結果は、getStreambufメソッドで取得した参照を利用して取得する。
+ *
+ * @param timeout タイムアウトまでの時間、秒単位
+ * @return 読み込みバイト数
+ */
+ size_t read(boost::posix_time::time_duration timeout);
+
+ /*!
+ * @brief 指定データまでの読み込み
+ *
+ * ソケットから指定データが出現するまでを読み込み
+ * 読み込み結果は、getStreambufメソッドで取得した参照を利用して取得する。
+ *
+ * @param delimiter 指定データ
+ * @param timeout タイムアウトまでの時間、秒単位
+ * @return 読み込みバイト数
+ */
+ size_t read_until(const std::string& delimiter, boost::posix_time::time_duration timeout);
+
+ /*!
+ * @brief 書き込み
+ *
+ * ソケットへのデータの書き込み
+ *
+ * @param buf 書き込みデータを保持するバッファ
+ * @param timeout タイムアウトまでの時間、秒単位
+ */
+ void write(boost::asio::streambuf& buf, boost::posix_time::time_duration timeout);
+
+ /*!
+ * @brief 読み込み結果を保持するstreambufへの参照を取得
+ *
+ * 呼び出し側では、戻り値を参照で受けて必要な処理を行う
+ */
+ boost::asio::streambuf& getStreambuf() { return input_buffer_; }
+
+private:
+ /*!
+ * @brief タイムアウトの確認
+ */
+ void check_deadline();
+
+ boost::asio::io_service io_service_; //!< io_service
+ boost::asio::ip::tcp::socket socket_; //!< TCPソケット
+ boost::asio::deadline_timer deadline_; //!< タイマー
+ boost::asio::streambuf input_buffer_; //!< 読み込み結果を保持するバッファ
+
+
+ TimeoutBlockingClient(const TimeoutBlockingClient&);
+ void operator=(const TimeoutBlockingClient&);
+};
+
+} // utility
+} // openrtm_network_camera
+
+#endif
\ No newline at end of file
Added: branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/string_utility.h
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/string_utility.h (rev 0)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/include/string_utility.h 2014-03-25 07:06:53 UTC (rev 141)
@@ -0,0 +1,53 @@
+/*!
+ * @file string_utility.h
+ * @brief some string utility functions.
+ * @date 2014-02-06
+ */
+#ifndef STRING_UTILITY_H
+#define STRING_UTILITY_H
+
+#include <string>
+
+/*!
+ * @namespace openrtm_network_camera
+ * @brief OpenRTM NetworkCamera用コンポーネント
+ *
+ */
+namespace openrtm_network_camera {
+
+/*!
+ * @namespace utility
+ * @brief 共通処理
+ *
+ */
+namespace utility {
+
+/*!
+ * @brief 文字列を小文字に変換する。
+ *
+ * @param target 処理対象文字列
+ * @return 小文字に変換した文字列
+ */
+std::string convertToLower(const std::string& target);
+
+/*!
+ * @brief 文字列の前後より空白を削除する。
+ *
+ * @param target 処理対象文字列
+ * @param trimCharacters 削除対象の空白文字
+ * @return 空白削除後の文字列
+ */
+std::string trim(const std::string& target, const char* trimCharacters = " \t\v\r\n");
+
+/*!
+ * @brief base64エンコード後の文字列を取得する。
+ *
+ * @param target 処理対象文字列
+ * @return base64エンコード後の文字列
+ */
+std::string base64encode(const std::string& target);
+
+} // utility
+} // openrtm_network_camera
+
+#endif // STRING_UTILITY_H
Added: branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/HttpClient.cpp
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/HttpClient.cpp (rev 0)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/HttpClient.cpp 2014-03-25 07:06:53 UTC (rev 141)
@@ -0,0 +1,90 @@
+/*!
+ * @file HttpClient.cpp
+ * @brief Http client for dll export
+ * @date 2014-02-06
+ */
+#include "HttpClient.h"
+
+#include <string>
+
+#include "HttpClientConcrete.h"
+
+
+namespace openrtm_network_camera {
+namespace utility {
+
+HttpClient::HttpClient(void)
+ : p_client_(new HttpClientConcrete()),
+ p_header_container_(NULL) {
+}
+
+HttpClient::~HttpClient(void) {
+ if (p_client_ != NULL) {
+ delete p_client_;
+ p_client_ = NULL;
+ }
+ deleteHeaderContainer();
+}
+
+void HttpClient::doGet(const char* p_host_name, const char* p_path_name, const char* p_port) {
+ p_client_->doGet(p_host_name, p_path_name, p_port);
+}
+
+int HttpClient::getStatusCode() const {
+ return p_client_->getStatusCode();
+}
+
+/*!
+ * @brief ヘッダの取得
+ *
+ * ヘッダ情報は、HttpClientConcreteインスタンスが保持しており、
+ * vector<string> の形式となっている。
+ * 外部に公開する場合、STLクラスを使わないので、const char * へのポインタ
+ * として戻り値を生成する。
+ *
+ * @param p_size ヘッダ数
+ * @return ヘッダの配列へのポインタ
+ */
+const char* const* HttpClient::getHeaders(int* p_size) {
+ deleteHeaderContainer();
+
+ const std::vector<std::string>& headers = p_client_->getHeaders();
+ *p_size = headers.size();
+ p_header_container_ = new const char* [*p_size];
+
+ for (int i = 0; i < *p_size; ++i) {
+ p_header_container_[i] = headers[i].c_str();
+ }
+ return p_header_container_;
+}
+
+const char* HttpClient::getContents() const {
+ return p_client_->getContents();
+}
+
+const char* HttpClient::getContentType() const {
+ // 空文字列の場合も空文字列へのポインタを返す
+ return p_client_->getContentType().c_str();
+}
+
+size_t HttpClient::getContentLength() const {
+ return p_client_->getContentLength();
+}
+
+void HttpClient::setBasicAuthenticationParameter(const char* p_user, const char * p_password) {
+ p_client_->setBasicAuthenticationParameter(p_user, p_password);
+}
+
+void HttpClient::setTimeout(const long timeout) {
+ p_client_->setTimeout(timeout);
+}
+
+void HttpClient::deleteHeaderContainer() {
+ if (p_header_container_ != NULL) {
+ delete [] p_header_container_;
+ p_header_container_ = NULL;
+ }
+}
+
+} // utility
+} // openrtm_network_camera
Added: branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/HttpClientConcrete.cpp
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/HttpClientConcrete.cpp (rev 0)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/HttpClientConcrete.cpp 2014-03-25 07:06:53 UTC (rev 141)
@@ -0,0 +1,300 @@
+/*!
+ * @file HttpClientConcrete.cpp
+ * @brief Http client using Boost.Asio
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * @date 2014-02-06
+ */
+#include "HttpClientConcrete.h"
+
+#include <iostream>
+#include <istream>
+#include <ostream>
+#include <fstream>
+#include <string>
+
+#include <boost/asio.hpp>
+
+#include "TimeoutBlockingClient.h"
+#include "string_utility.h"
+
+
+namespace openrtm_network_camera {
+namespace utility {
+
+// 定数定義
+namespace {
+ const char * CRLF = "\r\n";
+ const char * CRLF2 = "\r\n\r\n";
+
+ // ヘッダ名は小文字で処理する
+ const std::string ContentTypeHeader = "content-type";
+ const std::string ContentLengthHeader = "content-length";
+}
+
+HttpClientConcrete::HttpClientConcrete(void)
+ : timeout_(DEFAULT_TIMEOUT_SEC),
+ user_(""),
+ password_(""),
+ status_code_(ERROR_CODE),
+ headers_(),
+ content_type_(""),
+ content_length_(0),
+ contents_(NULL) {
+}
+
+HttpClientConcrete::~HttpClientConcrete(void) {
+ if (contents_ != NULL) {
+ delete [] contents_;
+ contents_ = NULL;
+ }
+}
+
+void HttpClientConcrete::doGet(const std::string& host_name, const std::string& path_name, const std::string& port) {
+ using boost::asio::ip::tcp;
+
+ // レスポンス用のメンバー変数の初期化
+ response_member_init();
+
+ try
+ {
+ // タイムアウト付き同期処理TCPクライアント
+ TimeoutBlockingClient client;
+
+ // 接続
+ client.connect(host_name, port, boost::posix_time::seconds(timeout_));
+
+ // Form the request. We specify the "Connection: close" header so that the
+ // server will close the socket after transmitting the response. This will
+ // allow us to treat all data up until the EOF as the content.
+ boost::asio::streambuf request;
+ std::ostream request_stream(&request);
+ request_stream << "GET " << path_name << " HTTP/1.0" << CRLF;
+ request_stream << "Host: " << host_name << ":" << port << CRLF;
+ request_stream << "Accept: */*" << CRLF;
+ request_stream << "User-Agent: " << "OpenRTM-NetworkCamera-HttpClient" << CRLF;
+
+ // Basic認証
+ if (0 != user_.size() && 0 != password_.size()) {
+ std::string auth = base64encode(user_ + ":" + password_);
+ request_stream << "Authorization: Basic " << auth << CRLF;
+ }
+
+ request_stream << "Connection: close" << CRLF << CRLF;
+
+ // Send the request.
+ client.write(request, boost::posix_time::seconds(timeout_));
+
+ // Read the response status line. The response streambuf will automatically
+ // grow to accommodate the entire line. The growth may be limited by passing
+ // a maximum size to the streambuf constructor.
+ client.read_until(CRLF, boost::posix_time::seconds(timeout_));
+ boost::asio::streambuf& response = client.getStreambuf();
+
+ // Check that response is OK.
+ std::istream response_stream(&response);
+ std::string http_version;
+ response_stream >> http_version;
+ response_stream >> status_code_;
+ std::string status_message;
+ std::getline(response_stream, status_message);
+ if (!response_stream || http_version.substr(0, 5) != "HTTP/")
+ {
+ std::cout << "Invalid response\n";
+ status_code_ = ERROR_CODE;
+ return;
+ }
+ if ((status_code_ != 200) && (status_code_ != 204))
+ {
+ std::cout << "Response returned with status code " << status_code_ << "\n";
+ // ステータスコード OKまたはNo Content 以外は、ヘッダも解析しない
+ return;
+ }
+
+ // ヘッダの解析
+ processHeaders(client);
+
+ setContentType();
+ setContentLength();
+
+ // コンテンツの取得
+ processContents(client);
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << "\n";
+ status_code_ = ERROR_CODE;
+ }
+}
+
+void HttpClientConcrete::setBasicAuthenticationParameter(const std::string& user, const std::string& password) {
+ user_ = user;
+ password_ = password;
+}
+
+void HttpClientConcrete::setTimeout(const long timeout) {
+ // 0以下の場合はデフォルト値とする
+ if (0 < timeout) {
+ timeout_ = timeout;
+ } else {
+ timeout_ = DEFAULT_TIMEOUT_SEC;
+ }
+}
+
+void HttpClientConcrete::response_member_init() {
+ status_code_ = ERROR_CODE;
+ headers_.clear();
+ content_type_.clear();
+ content_length_ = 0;
+ if (contents_ != NULL) {
+ delete [] contents_;
+ contents_ = NULL;
+ }
+}
+
+void HttpClientConcrete::processHeaders(TimeoutBlockingClient& client) {
+ headers_.clear();
+
+ // Read the response headers, which are terminated by a blank line.
+ client.read_until(CRLF2, boost::posix_time::seconds(timeout_));
+ boost::asio::streambuf& response = client.getStreambuf();
+ std::istream response_stream(&response);
+
+ // Process the response headers.
+ std::string header;
+ while (std::getline(response_stream, header) && header != "\r") {
+ std::string h = header;
+
+ std::string::size_type pos = h.find_last_of("\r");
+ if (std::string::npos != pos) {
+ h = h.substr(0, pos);
+ }
+ headers_.push_back(h);
+ }
+}
+
+void HttpClientConcrete::setContentType() {
+ content_type_.clear();
+
+ // Content-Type ヘッダの取得
+ for(std::vector<std::string>::iterator iter = headers_.begin(); iter != headers_.end(); ++iter) {
+ std::string t = convertToLower((*iter).substr(0, ContentTypeHeader.size()));
+ if (t == ContentTypeHeader) {
+ std::string type = (*iter).substr(ContentTypeHeader.size());
+
+ content_type_ = getHeaderValue(type);
+ break;
+ }
+ }
+}
+
+/*!
+ * @brief コンテンツ長を設定する。
+ *
+ * ヘッダの Content-Length に記載のコンテンツ長を取得する。
+ *
+ * @caution
+ * Content-Length 0またはない場合にかかわらず、コンテンツデータがあれば、
+ * HttpClientConcrete#processContents の処理時に正しいコンテンツ長が設定される。
+ *
+ * @return コンテンツ長
+ */
+void HttpClientConcrete::setContentLength() {
+ content_length_ = 0;
+
+ // Content-Length ヘッダの取得
+ for(std::vector<std::string>::iterator iter = headers_.begin(); iter != headers_.end(); ++iter) {
+ std::string t = convertToLower((*iter).substr(0, ContentLengthHeader.size()));
+ if (t == ContentLengthHeader) {
+ std::string type = (*iter).substr(ContentLengthHeader.size());
+
+ std::string tmp = getHeaderValue(type);
+ content_length_ = ::atoi(tmp.c_str());
+ break;
+ }
+ }
+}
+
+/*!
+ * @breif コンテンツの処理。
+ *
+ * レスポンスデータを処理して、コンテンツを取り出す。
+ * streambuf に先行して読み込み済みのデータがあるので、
+ * それも含めてコンテンツとして取得する。
+ *
+ * @caution
+ * コンテンツ長が0の場合でも、実際のデータがあればそちらに従い、
+ * コンテンツ長を再設定する。
+ */
+void HttpClientConcrete::processContents(TimeoutBlockingClient& client) {
+ if (contents_ != NULL) {
+ delete [] contents_;
+ contents_ = NULL;
+ }
+
+ // コンテンツサイズの確認
+ const size_t length = getContentLength();
+ //if (0 == length) {
+ // std::cout << "Maybe no Content-Length header.\n";
+ //}
+
+ boost::asio::streambuf& response = client.getStreambuf();
+
+ // バッファに読み込み済みデータを出力
+ std::vector<char> buf_pre(0);
+ size_t pre_readed = response.size();
+ if (pre_readed > 0) {
+ buf_pre.reserve(pre_readed);
+ const char * st = boost::asio::buffer_cast<const char*>(response.data());
+ std::copy(st, st + pre_readed, std::back_inserter(buf_pre));
+ response.consume(pre_readed);
+ }
+
+ // Read until EOF, writing data to output as we go.
+ size_t bytes = client.read(boost::posix_time::seconds(timeout_));
+
+ // メッセージボディ長のチェック
+ if (0 == length) {
+ content_length_ = pre_readed + bytes; // 更新
+
+ // メッセージボディに何もなかった場合
+ if (0 == content_length_) {
+ std::cout << "Content Length is 0.\n";
+ return;
+ }
+
+ } else if ((pre_readed + bytes) != length) {
+ std::cout << "Content Length maybe invalid.\n";
+ status_code_ = ERROR_CODE;
+ return;
+ }
+
+ // 2つ目のバッファに残りデータを読み込み
+ std::vector<char> buf_second(0);
+ if (0 < bytes) {
+ buf_second.reserve(bytes);
+ const char * st = boost::asio::buffer_cast<const char*>(response.data());
+ std::copy(st, st + bytes, std::back_inserter(buf_second));
+ }
+
+ // コンテンツを保存
+ contents_ = new char [pre_readed + bytes]; // 領域の確保
+
+ std::copy(buf_pre.begin(), buf_pre.end(), contents_);
+ std::copy(buf_second.begin(), buf_second.end(), contents_ + buf_pre.size());
+
+}
+
+std::string HttpClientConcrete::getHeaderValue(const std::string& target) {
+ std::string::size_type pos = target.find(":");
+
+ if (pos != std::string::npos) {
+ return trim(target.substr(pos+1));
+ }
+ return std::string(target);
+}
+
+} // utility
+} // openrtm_network_camera
Added: branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/TimeoutBlockingClient.cpp
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/TimeoutBlockingClient.cpp (rev 0)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/TimeoutBlockingClient.cpp 2014-03-25 07:06:53 UTC (rev 141)
@@ -0,0 +1,230 @@
+/*!
+ * @file TimeoutBlockingClient.cpp
+ * @brief Network access client using Boost.Asio
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * @date 2014-02-13
+ */
+#include "TimeoutBlockingClient.h"
+
+#include <iostream>
+#include <string>
+
+#include <boost/asio.hpp>
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+
+
+namespace openrtm_network_camera {
+namespace utility {
+
+/*!
+ * @brief コンストラクタ
+ *
+ * @caution
+ * タイムアウト処理用にタイマーを初期化する
+ */
+TimeoutBlockingClient::TimeoutBlockingClient()
+ : io_service_(),
+ socket_(io_service_),
+ deadline_(io_service_),
+ input_buffer_()
+{
+ // No deadline is required until the first socket operation is started. We
+ // set the deadline to positive infinity so that the actor takes no action
+ // until a specific deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin);
+
+ // Start the persistent actor that checks for deadline expiry.
+ check_deadline();
+}
+
+TimeoutBlockingClient::~TimeoutBlockingClient()
+{
+}
+
+void TimeoutBlockingClient::connect(const std::string& host, const std::string& service, boost::posix_time::time_duration timeout)
+{
+ using boost::asio::ip::tcp;
+ using boost::lambda::var;
+ using boost::lambda::_1;
+
+ // バッファのクリア
+ input_buffer_.consume(input_buffer_.size());
+
+ // Resolve the host name and service to a list of endpoints.
+ tcp::resolver::query query(host, service);
+ tcp::resolver::iterator iter = tcp::resolver(io_service_).resolve(query);
+
+ // Set a deadline for the asynchronous operation. As a host name may
+ // resolve to multiple endpoints, this function uses the composed operation
+ // async_connect. The deadline applies to the entire operation, rather than
+ // individual connection attempts.
+ deadline_.expires_from_now(timeout);
+
+ // Set up the variable that receives the result of the asynchronous
+ // operation. The error code is set to would_block to signal that the
+ // operation is incomplete. Asio guarantees that its asynchronous
+ // operations will never fail with would_block, so any other value in
+ // ec indicates completion.
+ boost::system::error_code ec = boost::asio::error::would_block;
+
+ // Start the asynchronous operation itself. The boost::lambda function
+ // object is used as a callback and will update the ec variable when the
+ // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda.
+ boost::asio::async_connect(socket_, iter, var(ec) = _1);
+
+ // Block until the asynchronous operation has completed.
+ do {
+ io_service_.run_one();
+ } while (ec == boost::asio::error::would_block);
+
+ // Determine whether a connection was successfully established. The
+ // deadline actor may have had a chance to run and close our socket, even
+ // though the connect operation notionally succeeded. Therefore we must
+ // check whether the socket is still open before deciding if we succeeded
+ // or failed.
+ if (ec || !socket_.is_open()) {
+ std::cout << "TimeoutBlockingClient::connect, Exception: " << ec << std::endl;
+ throw boost::system::system_error(
+ ec ? ec : boost::asio::error::operation_aborted);
+ }
+}
+
+size_t TimeoutBlockingClient::read(boost::posix_time::time_duration timeout)
+{
+ using boost::lambda::var;
+ using boost::lambda::_1;
+ using boost::lambda::_2;
+
+ // Set a deadline for the asynchronous operation. Since this function uses
+ // a composed operation (async_read_until), the deadline applies to the
+ // entire operation, rather than individual reads from the socket.
+ deadline_.expires_from_now(timeout);
+
+ // Set up the variable that receives the result of the asynchronous
+ // operation. The error code is set to would_block to signal that the
+ // operation is incomplete. Asio guarantees that its asynchronous
+ // operations will never fail with would_block, so any other value in
+ // ec indicates completion.
+ boost::system::error_code ec = boost::asio::error::would_block;
+
+ // Start the asynchronous operation itself. The boost::lambda function
+ // object is used as a callback and will update the ec variable when the
+ // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda.
+ size_t length;
+ boost::asio::async_read(socket_, input_buffer_, boost::asio::transfer_all(), (var(ec) = _1, var(length) = _2) );
+
+ // Block until the asynchronous operation has completed.
+ do {
+ io_service_.run_one();
+ } while (ec == boost::asio::error::would_block);
+
+ // すべてのデータを読み込んだときは、eofが返るのでエラーとはしない
+ if (ec && ec != boost::asio::error::eof) {
+ std::cout << "TimeoutBlockingClient::read, Exception: " << ec << std::endl;
+ throw boost::system::system_error(ec);
+ }
+ return length;
+}
+size_t TimeoutBlockingClient::read_until(const std::string& delimiter, boost::posix_time::time_duration timeout)
+{
+ using boost::lambda::var;
+ using boost::lambda::_1;
+ using boost::lambda::_2;
+
+ // Set a deadline for the asynchronous operation. Since this function uses
+ // a composed operation (async_read_until), the deadline applies to the
+ // entire operation, rather than individual reads from the socket.
+ deadline_.expires_from_now(timeout);
+
+ // Set up the variable that receives the result of the asynchronous
+ // operation. The error code is set to would_block to signal that the
+ // operation is incomplete. Asio guarantees that its asynchronous
+ // operations will never fail with would_block, so any other value in
+ // ec indicates completion.
+ boost::system::error_code ec = boost::asio::error::would_block;
+
+ // Start the asynchronous operation itself. The boost::lambda function
+ // object is used as a callback and will update the ec variable when the
+ // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda.
+ size_t length;
+ boost::asio::async_read_until(socket_, input_buffer_, delimiter, (var(ec) = _1, var(length) = _2) );
+
+ // Block until the asynchronous operation has completed.
+ do {
+ io_service_.run_one();
+ } while (ec == boost::asio::error::would_block);
+
+ if (ec) {
+ std::cout << "TimeoutBlockingClient::read_until, Exception: " << ec << std::endl;
+ throw boost::system::system_error(ec);
+ }
+ return length;
+}
+
+void TimeoutBlockingClient::write(boost::asio::streambuf& buf, boost::posix_time::time_duration timeout)
+{
+ using boost::lambda::var;
+ using boost::lambda::_1;
+
+ // Set a deadline for the asynchronous operation. Since this function uses
+ // a composed operation (async_write), the deadline applies to the entire
+ // operation, rather than individual writes to the socket.
+ deadline_.expires_from_now(timeout);
+
+ // Set up the variable that receives the result of the asynchronous
+ // operation. The error code is set to would_block to signal that the
+ // operation is incomplete. Asio guarantees that its asynchronous
+ // operations will never fail with would_block, so any other value in
+ // ec indicates completion.
+ boost::system::error_code ec = boost::asio::error::would_block;
+
+ // Start the asynchronous operation itself. The boost::lambda function
+ // object is used as a callback and will update the ec variable when the
+ // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda.
+ boost::asio::async_write(socket_, buf, var(ec) = _1);
+
+ // Block until the asynchronous operation has completed.
+ do {
+ io_service_.run_one();
+ } while (ec == boost::asio::error::would_block);
+
+ if (ec) {
+ std::cout << "TimeoutBlockingClient::write, Exception: " << ec << std::endl;
+ throw boost::system::system_error(ec);
+ }
+}
+
+void TimeoutBlockingClient::check_deadline()
+{
+ // Check whether the deadline has passed. We compare the deadline against
+ // the current time since a new asynchronous operation may have moved the
+ // deadline before this actor had a chance to run.
+ if (deadline_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
+ {
+ // The deadline has passed. The socket is closed so that any outstanding
+ // asynchronous operations are cancelled. This allows the blocked
+ // connect(), read_line() or write_line() functions to return.
+ boost::system::error_code ignored_ec;
+ socket_.close(ignored_ec);
+
+ std::cout << "TimeoutBlockingClient, request is timeout\n";
+
+ // There is no longer an active deadline. The expiry is set to positive
+ // infinity so that the actor takes no action until a new deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin);
+ }
+
+ // Put the actor back to sleep.
+ deadline_.async_wait(boost::lambda::bind(&TimeoutBlockingClient::check_deadline, this));
+}
+
+} // utility
+} // openrtm_network_camera
Added: branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/string_utility.cpp
===================================================================
--- branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/string_utility.cpp (rev 0)
+++ branches/newCMakeForVC2010/ImageProcessing/opencv/components/NetworkCameraUtility/src/string_utility.cpp 2014-03-25 07:06:53 UTC (rev 141)
@@ -0,0 +1,88 @@
+/*!
+ * @file string_utility.cpp
+ * @brief some string utility functions.
+ * @date 2014-02-06
+ */
+#include "string_utility.h"
+
+#include <algorithm>
+#include <string>
+#include <sstream>
+
+#include <boost/serialization/pfto.hpp>
+#include <boost/archive/iterators/base64_from_binary.hpp>
+#include <boost/archive/iterators/transform_width.hpp>
+
+namespace openrtm_network_camera {
+namespace utility {
+
+std::string convertToLower(const std::string& target) {
+ std::string t = target;
+ std::transform(t.begin(), t.end(), t.begin(), ::tolower);
+ return t;
+}
+
+std::string trim(const std::string& target, const char* trimCharacters) {
+ std::string result("");
+
+ // 左側の空白以外の文字位置
+ std::string::size_type left = target.find_first_not_of(trimCharacters);
+
+ if (std::string::npos != left) {
+ // 右側の空白以外の文字位置
+ std::string::size_type right = target.find_last_not_of(trimCharacters);
+
+ result = target.substr(left, right - left + 1);
+ }
+ return result;
+}
+
+/*!
+ * @brief base64エンコーディングに用いる定数定義
+ */
+namespace {
+ const std::string base64_padding[] = {"", "==", "="};
+}
+
+/*!
+ * @brief base64エンコード後の文字列を取得する。
+ *
+ * Base64エンコーディングについて
+ * @see http://ja.wikipedia.org/wiki/Base64
+ *
+ * BoostでのBase64エンコーディング実装方法について
+ * @see http://stackoverflow.com/questions/7053538/how-do-i-encode-a-string-to-base64-using-only-boost
+ * @see http://d.hatena.ne.jp/amachang/20090325/1237960531
+ * @see http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/dataflow.html
+ *
+ * @param target 処理対象文字列
+ * @return base64エンコード後の文字列
+ */
+std::string base64encode(const std::string& target) {
+ using boost::archive::iterators::base64_from_binary;
+ using boost::archive::iterators::transform_width;
+
+ typedef base64_from_binary<transform_width<const char *, 6, 8> > base64_encorder;
+
+ std::stringstream ss;
+ std::copy(
+ base64_encorder(BOOST_MAKE_PFTO_WRAPPER(target.c_str())),
+ base64_encorder(BOOST_MAKE_PFTO_WRAPPER(target.c_str() + target.size())),
+ std::ostream_iterator<char>(ss)
+ );
+
+ // Base64コーディングにあわせて4文字単位になるようにパディングを行う
+ // パディング文字数の決め方は下記のとおり考えればよい
+ //
+ // 対象文字列の文字数をnとすると
+ // 8n/6 = 4n/3 : 6bit単位に分割した際の文字数(要切り上げ)
+ // (4n/3)/4 = n/3 : 4文字単位にまとめたグループの数(要切り上げ)
+ // 4*1/3 = 1.33.. : グループ数の余りが1の場合の文字数(要切り上げ、即ち2文字)
+ // 4*2/3 = 2.66.. : グループ数の余りが2の場合の文字数(要切り上げ、即ち1文字)
+ ss << base64_padding[target.size() % 3];
+
+ return ss.str();
+}
+
+} // utility
+} // openrtm_network_camera
More information about the openrtm-commit
mailing list