<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#ifndef _Stroika_Foundation_DataExchange_OptionsFile_inl_
#define _Stroika_Foundation_DataExchange_OptionsFile_inl_  1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "../Characters/Format.h"
#include    "../Streams/BasicBinaryOutputStream.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   DataExchange {

            /*
             ********************************************************************************
             ************************** DataExchange::OptionsFile ***************************
             ********************************************************************************
             */
            template    <typename T>
            Optional<T>   OptionsFile::Read ()
            {
                Optional<VariantValue>  tmp = Read<VariantValue> ();
                if (tmp.IsMissing ()) {
                    return Optional<T> ();
                }
                try {
                    return fMapper_.ToObject<T> (*tmp);
                }
                catch (const BadFormatException& bf) {
                    fLogger_ (Execution::Logger::Priority::eCriticalError, Characters::Format (L"Error analyzing configuration file (bad format) '%s' - using defaults.", GetReadFilePath_ ().c_str ()));
                    return Optional<T> ();
                }
                catch (...) {
                    // if this fails, its probably because somehow the data in the config file was bad.
                    // So at least log that, and continue without reading anything (as if empty file)
                    fLogger_ (Execution::Logger::Priority::eCriticalError, Characters::Format (L"Error analyzing configuration file '%s' - using defaults.", GetReadFilePath_ ().c_str ()));
                    return Optional<T> ();
                }
            }
            template    <typename T>
            T   OptionsFile::Read (const T& defaultObj, ReadFlags readFlags)
            {
                Optional<T> eltRead = Read<T> ();
                Optional<T> elt2Write;              // only if needed
                String      msgAugment;
                if (eltRead.IsMissing ()) {
                    if (readFlags == ReadFlags::eWriteIfChanged) {
                        elt2Write = defaultObj;
                        msgAugment = L" so defaults are more easily editable";
                    }
                }
                else {
                    if (readFlags == ReadFlags::eWriteIfChanged) {
                        if (elt2Write.IsMissing ()) {
                            // if filename differs - upgrading
                            if (GetReadFilePath_ () != GetWriteFilePath_ ()) {
                                elt2Write = eltRead;
                                msgAugment = L" in a new directory because upgrading the software has been upgraded";
                            }
                        }
                        if (elt2Write.IsMissing ()) {
                            try {
                                // See if re-persisting the item would change it.
                                // This is useful if your data model adds or removes fields. It updates the file contents written to the
                                // upgraded/latest form.
                                Memory::BLOB    oldData =   ReadRaw (); // @todo could have saved from previous Read<T>
                                Memory::BLOB    newData;
                                {
                                    Streams::BasicBinaryOutputStream outStream;
                                    fWriter_.Write (fMapper_.FromObject (*eltRead), outStream);
                                    // not sure needed? outStream.Flush();
                                    newData = outStream.As<Memory::BLOB> ();
                                }
                                if (oldData != newData) {
                                    elt2Write = eltRead;
                                    msgAugment = L" because something changed (e.g. a default, or field added/removed).";
                                }
                            }
                            catch (...) {
                                fLogger_ (Execution::Logger::Priority::eError, Characters::Format (L"Failed to compare configuration file: %s", GetReadFilePath_ ().c_str ()));
                            }
                        }
                    }
                }
                if (elt2Write.IsPresent ()) {
                    fLogger_ (Execution::Logger::Priority::eInfo, Characters::Format (L"Writing configuration file '%s'%s.", GetWriteFilePath_ ().c_str (), msgAugment.c_str ()));
                    try {
                        Write (*elt2Write);
                    }
                    catch (...) {
                        fLogger_ (Execution::Logger::Priority::eError, Characters::Format (L"Failed to write default values to file: %s", GetWriteFilePath_ ().c_str ()));
                    }
                    return *elt2Write;
                }
                else if (eltRead.IsPresent ()) {
                    return *eltRead;
                }
                else {
                    return defaultObj;
                }
            }
            template    <typename T>
            void    OptionsFile::Write (const T& optionsObject)
            {
                Write<VariantValue> (fMapper_.FromObject<T> (optionsObject));
            }

        }

    }
}
#endif  /*_Stroika_Foundation_DataExchange_OptionsFile_inl_*/
<commit_msg>updated OptionsFile message<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#ifndef _Stroika_Foundation_DataExchange_OptionsFile_inl_
#define _Stroika_Foundation_DataExchange_OptionsFile_inl_  1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "../Characters/Format.h"
#include    "../Streams/BasicBinaryOutputStream.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   DataExchange {

            /*
             ********************************************************************************
             ************************** DataExchange::OptionsFile ***************************
             ********************************************************************************
             */
            template    <typename T>
            Optional<T>   OptionsFile::Read ()
            {
                Optional<VariantValue>  tmp = Read<VariantValue> ();
                if (tmp.IsMissing ()) {
                    return Optional<T> ();
                }
                try {
                    return fMapper_.ToObject<T> (*tmp);
                }
                catch (const BadFormatException& bf) {
                    fLogger_ (Execution::Logger::Priority::eCriticalError, Characters::Format (L"Error analyzing configuration file (bad format) '%s' - using defaults.", GetReadFilePath_ ().c_str ()));
                    return Optional<T> ();
                }
                catch (...) {
                    // if this fails, its probably because somehow the data in the config file was bad.
                    // So at least log that, and continue without reading anything (as if empty file)
                    fLogger_ (Execution::Logger::Priority::eCriticalError, Characters::Format (L"Error analyzing configuration file '%s' - using defaults.", GetReadFilePath_ ().c_str ()));
                    return Optional<T> ();
                }
            }
            template    <typename T>
            T   OptionsFile::Read (const T& defaultObj, ReadFlags readFlags)
            {
                Optional<T> eltRead = Read<T> ();
                Optional<T> elt2Write;              // only if needed
                String      msgAugment;
                if (eltRead.IsMissing ()) {
                    if (readFlags == ReadFlags::eWriteIfChanged) {
                        elt2Write = defaultObj;
                        msgAugment = L" so defaults are more easily editable";
                    }
                }
                else {
                    if (readFlags == ReadFlags::eWriteIfChanged) {
                        if (elt2Write.IsMissing ()) {
                            // if filename differs - upgrading
                            if (GetReadFilePath_ () != GetWriteFilePath_ ()) {
                                elt2Write = eltRead;
                                msgAugment = L" in a new directory because the software has been upgraded";
                            }
                        }
                        if (elt2Write.IsMissing ()) {
                            try {
                                // See if re-persisting the item would change it.
                                // This is useful if your data model adds or removes fields. It updates the file contents written to the
                                // upgraded/latest form.
                                Memory::BLOB    oldData =   ReadRaw (); // @todo could have saved from previous Read<T>
                                Memory::BLOB    newData;
                                {
                                    Streams::BasicBinaryOutputStream outStream;
                                    fWriter_.Write (fMapper_.FromObject (*eltRead), outStream);
                                    // not sure needed? outStream.Flush();
                                    newData = outStream.As<Memory::BLOB> ();
                                }
                                if (oldData != newData) {
                                    elt2Write = eltRead;
                                    msgAugment = L" because something changed (e.g. a default, or field added/removed).";
                                }
                            }
                            catch (...) {
                                fLogger_ (Execution::Logger::Priority::eError, Characters::Format (L"Failed to compare configuration file: %s", GetReadFilePath_ ().c_str ()));
                            }
                        }
                    }
                }
                if (elt2Write.IsPresent ()) {
                    fLogger_ (Execution::Logger::Priority::eInfo, Characters::Format (L"Writing configuration file '%s'%s.", GetWriteFilePath_ ().c_str (), msgAugment.c_str ()));
                    try {
                        Write (*elt2Write);
                    }
                    catch (...) {
                        fLogger_ (Execution::Logger::Priority::eError, Characters::Format (L"Failed to write default values to file: %s", GetWriteFilePath_ ().c_str ()));
                    }
                    return *elt2Write;
                }
                else if (eltRead.IsPresent ()) {
                    return *eltRead;
                }
                else {
                    return defaultObj;
                }
            }
            template    <typename T>
            void    OptionsFile::Write (const T& optionsObject)
            {
                Write<VariantValue> (fMapper_.FromObject<T> (optionsObject));
            }

        }

    }
}
#endif  /*_Stroika_Foundation_DataExchange_OptionsFile_inl_*/
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	TELNET サーバー・クラス @n
		0xF0	[Sub-negotiaon End] ２次交渉終了  ２次交渉パラメータの終了 @n
		0xF1	[No Operation] オペレーションなし オペレーションなし。受信した側はこれを無視する @n
		0xF2	[Data Mark] データマーク          データ削除・リセット @n
		0xF3	[Break] ブレーク	              ブレーク @n
		0xF4	[Interrupt Process] プロセス中断  操作の一時中断・割り込み・停止 @n
		0xF5	[Abort Output] 出力中止	          出力を抑止する @n
		0xF6	[Are You There] 相手確認          相手が動作しているかどうか確認する @n
		0xF7	[Erase Character] 文字消去        最後の文字を消去する @n
		0xF8	[Erase Line] 行消去               最後の行をすべて消去する @n
		0xF9	[Go Ahead] 送信勧誘               送信するように受信側にうながす @n
		0xFA	[Sub-negotiation Begin] ２次交渉開始  ２次交渉の開始 @n
		0xFB	WILL	オプション希望 @n
		0xFC	WON'T	オプション拒絶 @n
		0xFD	DO	オプション実行要求 @n
		0xFE	DON'T	オプション使用中止 @n
		0xFF	[Interpret as Command] コマンドとして解釈	telnetエスケープシーケンス @n
		オプション・コード @n
		0x00	[Transmit Binary] バイナリ転送	IAC以外の文字列はバイナリデータと解釈される @n
		0x01	[Echo] エコー	データのエコー @n
		0x03	[Suppress Go Ahead] Go Ahead抑止    Go Aheadコマンドを使わないようにする @n
		0x05	[Telnet Status Option] telnet状態オプション	相手側のtelnetオプションの状態を見られるようにする @n
		0x06	[Telnet Timing Mark] telnetタイミングマーク	受信したデータが処理済ならばタイミングマークというデータを送る @n
		0x18	[Terminal Type] ターミナルタイプ    ターミナルタイプを交換可能にし、適切なターミナルタイプを設定する @n
		0x22	[Telnet Line Mode] telnetラインモード    行単位で転送できるようにする
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017, 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "ethernet_server.hpp"
#include "common/fixed_fifo.hpp"

#define TELNETS_DEBUG

namespace net {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  telnet_server class テンプレート
		@param[in]	SEND_SIZE	送信、一時バッファサイズ
		@param[in]	RECV_SIZE	受信、一時バッファサイズ
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <uint32_t SEND_SIZE, uint32_t RECV_SIZE>
	class telnet_server {

	private:
		// デバッグ以外で出力を無効にする
#ifdef TELNETS_DEBUG
		typedef utils::format debug_format;
#else
		typedef utils::null_format debug_format;
#endif

		ethernet&		eth_;
		ethernet_server	telnet_;

		enum class task : uint8_t {
			none,
			begin,
			wait,
			main_loop,
			disconnect_delay,
			disconnect,
		};
		task		task_;

		char		server_name_[32];
		char		user_[32];
		char		pass_[32];
		uint32_t	count_;
		uint32_t	disconnect_loop_;

		typedef utils::fixed_fifo<char, SEND_SIZE> SEND_FIFO;
		typedef utils::fixed_fifo<char, RECV_SIZE> RECV_FIFO;

		SEND_FIFO	send_;
		RECV_FIFO	recv_;

		bool		crlf_;

		enum class esc_task : uint8_t {
			none,
			entry,
			option,
			second,
			second_end,
		};
		esc_task	esc_task_;

		void write_()
		{
			char tmp[1024];
			uint16_t l = 0;
			while(send_.length() > 0) {
				auto ch = send_.get();
				tmp[l] = ch;
				++l;
				if(l >= sizeof(tmp)) {
					telnet_.write(tmp, l);
					l = 0;
				}
			}
			if(l > 0) {
				telnet_.write(tmp, l);
			}
		}

		bool service_options_(char ch)
		{
			bool ret = true;
			switch(esc_task_) {
			case esc_task::entry:
				if(ch == 0xFB || ch == 0xFC || ch == 0xFD || ch == 0xFE) {
					esc_task_ = esc_task::option;
					ret = false;
				} else if(ch == 0xFA) {  // 二次交渉開始
					esc_task_ = esc_task::second;
					ret = false;
				}
				break;
			case esc_task::option:
				esc_task_ = esc_task::none;
				ret = false;
				break;
			case esc_task::second:
				if(ch == 0xFF) {
					esc_task_ = esc_task::second_end;
				}
				ret = false;
				break;
			case esc_task::second_end:
				if(ch == 0xF0) {
					esc_task_ = esc_task::none;
				}
				ret = false;
				break;

			case esc_task::none:
			default:
				if(ch == 0xFF) {  // TELNET ESC シーケンス開始
					esc_task_ = esc_task::entry;
					ret = false;
				}
				break;
			}
			return ret;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	e	イーサーネット・コンテキスト
			@param[in]	crlf	LF コードを CR/LF に変換しない場合「false」
		*/
		//-----------------------------------------------------------------//
		telnet_server(ethernet& e, bool crlf = true) : eth_(e), telnet_(e), task_(task::none),
			server_name_{ 0 }, user_{ 0 }, pass_{ 0 },
			count_(0), disconnect_loop_(0), crlf_(crlf),
			esc_task_(esc_task::none)
		{ }

		//-----------------------------------------------------------------//
		/*!
			@brief  スタート
			@param[in]	server_name	サーバー名
			@param[in]	user		ユーザー名
			@param[in]	pass		パスワード
		*/
		//-----------------------------------------------------------------//
		void start(const char* server_name, const char* user = nullptr, const char* pass = nullptr)
		{
			std::strncpy(server_name_, server_name, sizeof(server_name_) - 1);
			if(user != nullptr) std::strncpy(user_, user, sizeof(user_) - 1);
			if(pass != nullptr) std::strncpy(pass_, pass, sizeof(pass_) - 1);

			count_ = 0;
			disconnect_loop_ = 0;
			esc_task_ = esc_task::none;

			task_ = task::begin;

			debug_format("TELNET Server: SEND_BUFF: %d, RECV_BUFF: %d\n") % SEND_SIZE % RECV_SIZE;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  接続の確認
			@return 接続中なら「true」
		*/
		//-----------------------------------------------------------------//
		bool probe() const { return task_ == task::main_loop; }

		//-----------------------------------------------------------------//
		/*!
			@brief  サービス
			@param[in]	cycle	サービス・サイクル（通常１００Ｈｚ）
			@param[in]	port	TELNET ポート番号（通常２３番）
		*/
		//-----------------------------------------------------------------//
		void service(uint32_t cycle, uint16_t port = 23)
		{
			switch(task_) {
			case task::none:
				break;

			case task::begin:
				telnet_.begin(port);
				debug_format("Start TELNET Server: '%s' port(%d), fd(%d)\n")
					% eth_.get_local_ip().c_str()
					% static_cast<int>(telnet_.get_port()) % telnet_.get_cepid();
				task_ = task::wait;
				break;

			case task::wait:
				if(telnet_.connected()) {
					debug_format("TELNET Server: New connected, from: %s\n") % telnet_.get_from_ip().c_str();
					++count_;
					task_ = task::main_loop;
				}
				break;

			case task::main_loop:
				if(telnet_.connected()) {
					if(telnet_.available() > 0) {  // リードデータがあるか？
						char tmp[256];
						int len = telnet_.read(tmp, sizeof(tmp));
						if(len > 0) {
							int l = 0;
// utils::format("Len: %d\n") % len;
							while((recv_.size() - recv_.length()) > 2) {
								char ch = tmp[l];
								++l;
								if(service_options_(ch)) {
///									putch(ch);  // local echo
///	utils::format("%d: %02X\n") % l % static_cast<uint16_t>(ch);
									recv_.put(ch);
								}
								if(l >= len) break;
							}
						}
					}
					write_();
				} else {
					task_ = task::disconnect_delay;
					disconnect_loop_ = 10;
				}
				break;

			case task::disconnect_delay:
				if(disconnect_loop_ > 0) {
					--disconnect_loop_;
				} else {
					task_ = task::disconnect;
				}
				break;

			case task::disconnect:
			default:
				telnet_.stop();
				debug_format("TELNET Server: disconnected\n");
				task_ = task::begin;
				break;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  出力
			@param[in]	ch	出力文字
		*/
		//-----------------------------------------------------------------//
		void putch(char ch)
		{
			if(crlf_ && ch == '\n') {
				putch('\r');
			}
			if(task_ == task::main_loop) {
				if((send_.size() - send_.length()) <= 2) {
					write_();
				}
				send_.put(ch);
//				if(ch == '\r') {
//					flush_();
//				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  出力
			@param[in]	str	出力文字列
		*/
		//-----------------------------------------------------------------//
		void puts(const char* str)
		{
			if(str == nullptr) return;

			char ch;
			while((ch = *str++) != 0) {
				putch(ch);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  入力文字数取得
			@return 入力文字数
		*/
		//-----------------------------------------------------------------//
		uint32_t length() const
		{
			return recv_.length();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  入力文字取得
			@return 入力文字（入力文字が無い場合「０」が返る）
		*/
		//-----------------------------------------------------------------//
		char getch()
		{
			if(recv_.length() > 0) {
				return recv_.get();
			} else {
utils::format("!!!!\n");
				return 0;
			}
		}
	};
}

<commit_msg>update: cleanup<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	TELNET サーバー・クラス @n
		0xF0	[Sub-negotiaon End] ２次交渉終了  ２次交渉パラメータの終了 @n
		0xF1	[No Operation] オペレーションなし オペレーションなし。受信した側はこれを無視する @n
		0xF2	[Data Mark] データマーク          データ削除・リセット @n
		0xF3	[Break] ブレーク	              ブレーク @n
		0xF4	[Interrupt Process] プロセス中断  操作の一時中断・割り込み・停止 @n
		0xF5	[Abort Output] 出力中止	          出力を抑止する @n
		0xF6	[Are You There] 相手確認          相手が動作しているかどうか確認する @n
		0xF7	[Erase Character] 文字消去        最後の文字を消去する @n
		0xF8	[Erase Line] 行消去               最後の行をすべて消去する @n
		0xF9	[Go Ahead] 送信勧誘               送信するように受信側にうながす @n
		0xFA	[Sub-negotiation Begin] ２次交渉開始  ２次交渉の開始 @n
		0xFB	WILL	オプション希望 @n
		0xFC	WON'T	オプション拒絶 @n
		0xFD	DO	オプション実行要求 @n
		0xFE	DON'T	オプション使用中止 @n
		0xFF	[Interpret as Command] コマンドとして解釈	telnetエスケープシーケンス @n
		オプション・コード @n
		0x00	[Transmit Binary] バイナリ転送	IAC以外の文字列はバイナリデータと解釈される @n
		0x01	[Echo] エコー	データのエコー @n
		0x03	[Suppress Go Ahead] Go Ahead抑止    Go Aheadコマンドを使わないようにする @n
		0x05	[Telnet Status Option] telnet状態オプション	相手側のtelnetオプションの状態を見られるようにする @n
		0x06	[Telnet Timing Mark] telnetタイミングマーク	受信したデータが処理済ならばタイミングマークというデータを送る @n
		0x18	[Terminal Type] ターミナルタイプ    ターミナルタイプを交換可能にし、適切なターミナルタイプを設定する @n
		0x22	[Telnet Line Mode] telnetラインモード    行単位で転送できるようにする
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017, 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "ethernet_server.hpp"
#include "common/fixed_fifo.hpp"

#define TELNETS_DEBUG

namespace net {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  telnet_server class テンプレート
		@param[in]	SEND_SIZE	送信、一時バッファサイズ
		@param[in]	RECV_SIZE	受信、一時バッファサイズ
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <uint32_t SEND_SIZE, uint32_t RECV_SIZE>
	class telnet_server {

	private:
		// デバッグ以外で出力を無効にする
#ifdef TELNETS_DEBUG
		typedef utils::format debug_format;
#else
		typedef utils::null_format debug_format;
#endif

		ethernet&		eth_;
		ethernet_server	telnet_;

		enum class task : uint8_t {
			none,
			begin,
			wait,
			main_loop,
			disconnect_delay,
			disconnect,
		};
		task		task_;

		char		server_name_[32];
		char		user_[32];
		char		pass_[32];
		uint32_t	count_;
		uint32_t	disconnect_loop_;

		typedef utils::fixed_fifo<char, SEND_SIZE> SEND_FIFO;
		typedef utils::fixed_fifo<char, RECV_SIZE> RECV_FIFO;

		SEND_FIFO	send_;
		RECV_FIFO	recv_;

		bool		crlf_;

		enum class esc_task : uint8_t {
			none,
			entry,
			option,
			second,
			second_end,
		};
		esc_task	esc_task_;

		void write_()
		{
			char tmp[1024];
			uint16_t l = 0;
			while(send_.length() > 0) {
				auto ch = send_.get();
				tmp[l] = ch;
				++l;
				if(l >= sizeof(tmp)) {
					telnet_.write(tmp, l);
					l = 0;
				}
			}
			if(l > 0) {
				telnet_.write(tmp, l);
			}
		}

		bool service_options_(char ch)
		{
			bool ret = true;
			switch(esc_task_) {
			case esc_task::entry:
				if(ch == 0xFB || ch == 0xFC || ch == 0xFD || ch == 0xFE) {
					esc_task_ = esc_task::option;
					ret = false;
				} else if(ch == 0xFA) {  // 二次交渉開始
					esc_task_ = esc_task::second;
					ret = false;
				}
				break;
			case esc_task::option:
				esc_task_ = esc_task::none;
				ret = false;
				break;
			case esc_task::second:
				if(ch == 0xFF) {
					esc_task_ = esc_task::second_end;
				}
				ret = false;
				break;
			case esc_task::second_end:
				if(ch == 0xF0) {
					esc_task_ = esc_task::none;
				}
				ret = false;
				break;

			case esc_task::none:
			default:
				if(ch == 0xFF) {  // TELNET ESC シーケンス開始
					esc_task_ = esc_task::entry;
					ret = false;
				}
				break;
			}
			return ret;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	e	イーサーネット・コンテキスト
			@param[in]	crlf	LF コードを CR/LF に変換しない場合「false」
		*/
		//-----------------------------------------------------------------//
		telnet_server(ethernet& e, bool crlf = true) : eth_(e), telnet_(e), task_(task::none),
			server_name_{ 0 }, user_{ 0 }, pass_{ 0 },
			count_(0), disconnect_loop_(0), crlf_(crlf),
			esc_task_(esc_task::none)
		{ }

		//-----------------------------------------------------------------//
		/*!
			@brief  スタート
			@param[in]	server_name	サーバー名
			@param[in]	user		ユーザー名
			@param[in]	pass		パスワード
		*/
		//-----------------------------------------------------------------//
		void start(const char* server_name, const char* user = nullptr, const char* pass = nullptr)
		{
			std::strncpy(server_name_, server_name, sizeof(server_name_) - 1);
			if(user != nullptr) std::strncpy(user_, user, sizeof(user_) - 1);
			if(pass != nullptr) std::strncpy(pass_, pass, sizeof(pass_) - 1);

			count_ = 0;
			disconnect_loop_ = 0;
			esc_task_ = esc_task::none;

			task_ = task::begin;

			debug_format("TELNET Server: SEND_BUFF: %d, RECV_BUFF: %d\n") % SEND_SIZE % RECV_SIZE;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  接続の確認
			@return 接続中なら「true」
		*/
		//-----------------------------------------------------------------//
		bool probe() const { return task_ == task::main_loop; }

		//-----------------------------------------------------------------//
		/*!
			@brief  サービス
			@param[in]	cycle	サービス・サイクル（通常１００Ｈｚ）
			@param[in]	port	TELNET ポート番号（通常２３番）
		*/
		//-----------------------------------------------------------------//
		void service(uint32_t cycle, uint16_t port = 23)
		{
			switch(task_) {
			case task::none:
				break;

			case task::begin:
				telnet_.begin(port);
				debug_format("Start TELNET Server: '%s' port(%d), fd(%d)\n")
					% eth_.get_local_ip().c_str()
					% static_cast<int>(telnet_.get_port()) % telnet_.get_cepid();
				task_ = task::wait;
				break;

			case task::wait:
				if(telnet_.connected()) {
					debug_format("TELNET Server: New connected, from: %s\n")
						% telnet_.get_from_ip().c_str();
					++count_;
					task_ = task::main_loop;
				}
				break;

			case task::main_loop:
				if(telnet_.connected()) {
					if(telnet_.available() > 0) {  // リードデータがあるか？
						char tmp[256];
						int len = telnet_.read(tmp, sizeof(tmp));
						if(len > 0) {
							int l = 0;
// utils::format("Len: %d\n") % len;
							while((recv_.size() - recv_.length()) > 2) {
								char ch = tmp[l];
								++l;
								if(service_options_(ch)) {
///									putch(ch);  // local echo
///	utils::format("%d: %02X\n") % l % static_cast<uint16_t>(ch);
									recv_.put(ch);
								}
								if(l >= len) break;
							}
						}
					}
					write_();
				} else {
					task_ = task::disconnect_delay;
					disconnect_loop_ = 10;
				}
				break;

			case task::disconnect_delay:
				if(disconnect_loop_ > 0) {
					--disconnect_loop_;
				} else {
					task_ = task::disconnect;
				}
				break;

			case task::disconnect:
			default:
				telnet_.stop();
				debug_format("TELNET Server: disconnected\n");
				task_ = task::begin;
				break;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  出力
			@param[in]	ch	出力文字
		*/
		//-----------------------------------------------------------------//
		void putch(char ch)
		{
			if(crlf_ && ch == '\n') {
				putch('\r');
			}
			if(task_ == task::main_loop) {
				if((send_.size() - send_.length()) <= 2) {
					write_();
				}
				send_.put(ch);
//				if(ch == '\r') {
//					flush_();
//				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  出力
			@param[in]	str	出力文字列
		*/
		//-----------------------------------------------------------------//
		void puts(const char* str)
		{
			if(str == nullptr) return;

			char ch;
			while((ch = *str++) != 0) {
				putch(ch);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  入力文字数取得
			@return 入力文字数
		*/
		//-----------------------------------------------------------------//
		uint32_t length() const
		{
			return recv_.length();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  入力文字取得
			@return 入力文字（入力文字が無い場合「０」が返る）
		*/
		//-----------------------------------------------------------------//
		char getch()
		{
			if(recv_.length() > 0) {
				return recv_.get();
			} else {
utils::format("!!!!\n");
				return 0;
			}
		}
	};
}

<|endoftext|>


<commit_before>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplicationFactory.h"
#include "otbWrapperCompositeApplication.h"

namespace otb
{
namespace Wrapper
{
class BundleToPerfectSensor : public CompositeApplication
{
public:
  /** Standard class typedefs. */
  typedef BundleToPerfectSensor         Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(BundleToPerfectSensor, otb::Wrapper::CompositeApplication);

private:

  void DoInit() ITK_OVERRIDE
  {
    SetName("BundleToPerfectSensor");
    SetDescription("Perform P+XS pansharpening");

    // Documentation
    SetDocName("Bundle to perfect sensor");
    SetDocLongDescription("This application performs P+XS pansharpening. The default mode use Pan and XS sensor models to estimate the transformation to superimpose XS over Pan before the fusion (\"default mode\"). The application provides also a PHR mode for Pleiades images which does not use sensor models as Pan and XS products are already coregistered but only estimate an affine transformation to superimpose XS over the Pan.Note that this option is automatically activated in case Pleiades images are detected as input.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Geometry);
    AddDocTag(Tags::Pansharpening);

    AddApplication("Superimpose", "superimpose", "Reproject XS onto Pan");
    AddApplication("Pansharpening", "pansharp", "Fusion of XS and Pan");

    ShareParameter("inp","superimpose.inr","Input PAN Image","Input panchromatic image.");
    ShareParameter("inxs","superimpose.inm","Input XS Image","Input XS image.");
    ShareParameter("out","pansharp.out");
    ShareParameter("elev","superimpose.elev");
    ShareParameter("mode","superimpose.mode");
    ShareParameter("lms","superimpose.lms",
      "Spacing of the deformation field",
      "Spacing of the deformation field. Default is 10 times the PAN image spacing.");
    ShareParameter("ram","superimpose.ram");

    Connect("pansharp.inp","superimpose.inr");
    Connect("pansharp.ram","superimpose.ram");

    GetInternalApplication("superimpose")->SetParameterString("interpolator","bco");
    GetInternalApplication("pansharp")->SetParameterString("method","rcs");

    // Doc example parameter settings
    SetDocExampleParameterValue("inp", "QB_Toulouse_Ortho_PAN.tif");
    SetDocExampleParameterValue("inxs", "QB_Toulouse_Ortho_XS.tif");
    SetDocExampleParameterValue("out", "BundleToPerfectSensor.png uchar");

  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
    UpdateInternalParameters("superimpose");
  }

  void DoExecute() ITK_OVERRIDE
  {
    ExecuteInternal("superimpose");

    GetInternalApplication("pansharp")->SetParameterInputImage("inxs",
      GetInternalApplication("superimpose")->GetParameterOutputImage("out"));

    ExecuteInternal("pansharp");
  }

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::BundleToPerfectSensor)
<commit_msg>ENH: clean application in DoInit()<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplicationFactory.h"
#include "otbWrapperCompositeApplication.h"

namespace otb
{
namespace Wrapper
{
class BundleToPerfectSensor : public CompositeApplication
{
public:
  /** Standard class typedefs. */
  typedef BundleToPerfectSensor         Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(BundleToPerfectSensor, otb::Wrapper::CompositeApplication);

private:

  void DoInit() ITK_OVERRIDE
  {
    SetName("BundleToPerfectSensor");
    SetDescription("Perform P+XS pansharpening");

    // Documentation
    SetDocName("Bundle to perfect sensor");
    SetDocLongDescription("This application performs P+XS pansharpening. The default mode use Pan and XS sensor models to estimate the transformation to superimpose XS over Pan before the fusion (\"default mode\"). The application provides also a PHR mode for Pleiades images which does not use sensor models as Pan and XS products are already coregistered but only estimate an affine transformation to superimpose XS over the Pan.Note that this option is automatically activated in case Pleiades images are detected as input.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Geometry);
    AddDocTag(Tags::Pansharpening);

    ClearApplications();
    AddApplication("Superimpose", "superimpose", "Reproject XS onto Pan");
    AddApplication("Pansharpening", "pansharp", "Fusion of XS and Pan");

    ShareParameter("inp","superimpose.inr","Input PAN Image","Input panchromatic image.");
    ShareParameter("inxs","superimpose.inm","Input XS Image","Input XS image.");
    ShareParameter("out","pansharp.out");
    ShareParameter("elev","superimpose.elev");
    ShareParameter("mode","superimpose.mode");
    ShareParameter("lms","superimpose.lms",
      "Spacing of the deformation field",
      "Spacing of the deformation field. Default is 10 times the PAN image spacing.");
    ShareParameter("ram","superimpose.ram");

    Connect("pansharp.inp","superimpose.inr");
    Connect("pansharp.ram","superimpose.ram");

    GetInternalApplication("superimpose")->SetParameterString("interpolator","bco");
    GetInternalApplication("pansharp")->SetParameterString("method","rcs");

    // Doc example parameter settings
    SetDocExampleParameterValue("inp", "QB_Toulouse_Ortho_PAN.tif");
    SetDocExampleParameterValue("inxs", "QB_Toulouse_Ortho_XS.tif");
    SetDocExampleParameterValue("out", "BundleToPerfectSensor.png uchar");

  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
    UpdateInternalParameters("superimpose");
  }

  void DoExecute() ITK_OVERRIDE
  {
    ExecuteInternal("superimpose");

    GetInternalApplication("pansharp")->SetParameterInputImage("inxs",
      GetInternalApplication("superimpose")->GetParameterOutputImage("out"));

    ExecuteInternal("pansharp");
  }

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::BundleToPerfectSensor)
<|endoftext|>


<commit_before>/*!
    \file string_utils.inl
    \brief String utilities inline implementation
    \author Ivan Shynkarenka
    \date 15.05.2016
    \copyright MIT License
*/

namespace CppCommon {

inline bool StringUtils::IsBlank(char ch)
{
    return std::isspace(ch);
}

inline char StringUtils::ToLowerInternal(char ch)
{
    return (char)std::tolower(ch);
}

inline char StringUtils::ToUpperInternal(char ch)
{
    return (char)std::toupper(ch);
}

inline char StringUtils::ToLower(char ch)
{
    return ToLowerInternal(ch);
}

inline char StringUtils::ToUpper(char ch)
{
    return ToUpperInternal(ch);
}

inline std::string StringUtils::ToLower(std::string_view str)
{
    std::string result(str);
    Lower(result);
    return result;
}

inline std::string StringUtils::ToUpper(std::string_view str)
{
    std::string result(str);
    Upper(result);
    return result;
}

inline std::string& StringUtils::Lower(std::string& str)
{
    std::transform(str.begin(), str.end(), str.begin(), ToLowerInternal);
    return str;
}

inline std::string& StringUtils::Upper(std::string& str)
{
    std::transform(str.begin(), str.end(), str.begin(), ToUpperInternal);
    return str;
}

inline std::string& StringUtils::Trim(std::string& str)
{
    return LTrim(RTrim(str));
}

inline bool StringUtils::Contains(std::string_view str, const char ch)
{
    return (str.find(ch) != std::string::npos);
}

inline bool StringUtils::Contains(std::string_view str, const char* substr)
{
    return (str.find(substr) != std::string::npos);
}

inline bool StringUtils::Contains(std::string_view str, std::string_view substr)
{
    return (str.find(substr) != std::string::npos);
}

inline bool StringUtils::StartsWith(std::string_view str, std::string_view prefix)
{
    return (str.size() >= prefix.size()) && (str.compare(0, prefix.size(), prefix) == 0);
}

inline bool StringUtils::EndsWith(std::string_view str, std::string_view suffix)
{
    return (str.size() >= suffix.size()) && (str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0);
}

template <typename T>
inline std::string StringUtils::ToString(const T& value)
{
    std::ostringstream ss;
    ss << value;
    return ss.str();
}

template <typename T>
inline T StringUtils::FromString(std::string_view str)
{
    T result;
    std::istringstream(str) >> result;
    return result;
}

template <>
inline const char* StringUtils::FromString(std::string_view str)
{
    return std::string(str).c_str();
}

template <>
inline std::string StringUtils::FromString(std::string_view str)
{
    return std::string(str);
}

template <>
inline std::string_view StringUtils::FromString(std::string_view str)
{
    return str;
}

template <>
inline bool StringUtils::FromString(std::string_view str)
{
    std::string value = ToLower(str);
    if ((value == "true") || (value == "yes") || (value == "on") || (value == "1"))
        return true;
    if ((value == "false") || (value == "no") || (value == "off") || (value == "0"))
        return false;

    assert("Invalid boolean value represented in string!");
    return false;
}

} // namespace CppCommon
<commit_msg>update<commit_after>/*!
    \file string_utils.inl
    \brief String utilities inline implementation
    \author Ivan Shynkarenka
    \date 15.05.2016
    \copyright MIT License
*/

namespace CppCommon {

inline bool StringUtils::IsBlank(char ch)
{
    return std::isspace(ch);
}

inline char StringUtils::ToLowerInternal(char ch)
{
    return (char)std::tolower(ch);
}

inline char StringUtils::ToUpperInternal(char ch)
{
    return (char)std::toupper(ch);
}

inline char StringUtils::ToLower(char ch)
{
    return ToLowerInternal(ch);
}

inline char StringUtils::ToUpper(char ch)
{
    return ToUpperInternal(ch);
}

inline std::string StringUtils::ToLower(std::string_view str)
{
    std::string result(str);
    Lower(result);
    return result;
}

inline std::string StringUtils::ToUpper(std::string_view str)
{
    std::string result(str);
    Upper(result);
    return result;
}

inline std::string& StringUtils::Lower(std::string& str)
{
    std::transform(str.begin(), str.end(), str.begin(), ToLowerInternal);
    return str;
}

inline std::string& StringUtils::Upper(std::string& str)
{
    std::transform(str.begin(), str.end(), str.begin(), ToUpperInternal);
    return str;
}

inline std::string& StringUtils::Trim(std::string& str)
{
    return LTrim(RTrim(str));
}

inline bool StringUtils::Contains(std::string_view str, const char ch)
{
    return (str.find(ch) != std::string::npos);
}

inline bool StringUtils::Contains(std::string_view str, const char* substr)
{
    return (str.find(substr) != std::string::npos);
}

inline bool StringUtils::Contains(std::string_view str, std::string_view substr)
{
    return (str.find(substr) != std::string::npos);
}

inline bool StringUtils::StartsWith(std::string_view str, std::string_view prefix)
{
    return (str.size() >= prefix.size()) && (str.compare(0, prefix.size(), prefix) == 0);
}

inline bool StringUtils::EndsWith(std::string_view str, std::string_view suffix)
{
    return (str.size() >= suffix.size()) && (str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0);
}

template <typename T>
inline std::string StringUtils::ToString(const T& value)
{
    std::ostringstream ss;
    ss << value;
    return ss.str();
}

template <typename T>
inline T StringUtils::FromString(std::string_view str)
{
    T result;
    std::istringstream(std::string(str)) >> result;
    return result;
}

template <>
inline const char* StringUtils::FromString(std::string_view str)
{
    return std::string(str).c_str();
}

template <>
inline std::string StringUtils::FromString(std::string_view str)
{
    return std::string(str);
}

template <>
inline std::string_view StringUtils::FromString(std::string_view str)
{
    return str;
}

template <>
inline bool StringUtils::FromString(std::string_view str)
{
    std::string value = ToLower(str);
    if ((value == "true") || (value == "yes") || (value == "on") || (value == "1"))
        return true;
    if ((value == "false") || (value == "no") || (value == "off") || (value == "0"))
        return false;

    assert("Invalid boolean value represented in string!");
    return false;
}

} // namespace CppCommon
<|endoftext|>


<commit_before>/**@file   QueryCorrectionSubmanager.cpp
 * @brief  source file of Query Correction
 * @author Jinglei Zhao&Jinli Liu
 * @date   2009-08-21
 * @details
 * - Log
 *     - 2009.09.26 add new candidate generation
 *     - 2009.10.08 add new error model for english
 *     - 2009.11.27 add isEnglishWord() and isKoreanWord() to check if one word is mixure
 *      -2010.03.05 add log manager periodical worker.
 */
#include "Util.h"
#include "QueryCorrectionSubmanager.h"
#include <common/SFLogger.h>
#include <util/ustring/ustr_tool.h>
#include <boost/algorithm/string.hpp>

namespace
{

static const float SMOOTH = 0.000001;
static const float FACTOR = 0.05;
static const int UNIGRAM_FREQ_THRESHOLD = 3;
static const int BIGRAM_FREQ_THRESHOLD = 3;
static const int UNIGRAM_FACTOR = 10;
static const int BIGRAM_FACTOR = 1;
static const unsigned int CHINESE_CORRECTION_LENGTH = 8;

}
using namespace izenelib::util::ustring_tool;
namespace sf1r
{

_QueryCorrectionSubmanagerParam QueryCorrectionSubmanagerParam::param_;

QueryCorrectionSubmanager::QueryCorrectionSubmanager
(const string& path, const std::string& workingPath, bool enableEK, bool enableChn, int ed)
:path_(path), workingPath_(workingPath)
, enableEK_(enableEK), enableChn_(enableChn)
, activate_(false)
, cmgr_(path_+"/cn", workingPath_), ekmgr_(path, workingPath, ed)
, has_new_inject_(false)
{
    initialize();
}

QueryCorrectionSubmanager& QueryCorrectionSubmanager::getInstance()
{
    _QueryCorrectionSubmanagerParam& param =
        QueryCorrectionSubmanagerParam::get();
    static QueryCorrectionSubmanager qcManager(param.path_, param.workingPath_,
            param.enableEK_, param.enableChn_);
    return qcManager;
}

// bool QueryCorrectionSubmanager::stopHere(
//     const izenelib::util::UString& queryUString)
// {
//     bool is = true;
//     std::vector<UString> queryTokens;
//
//     string queryStr;
//     queryUString.convertString(queryStr, UString::UTF_8);
//     if (cmgr_.inPinyinDict(queryStr))
//         return false;
//
//     getTokensFromUString(UString::UTF_8,' ', queryUString, queryTokens);
// //	Tokenize(queryUString, queryTokens);
//
//     uint32_t chineseCount = 0;
//     uint32_t ekCount = 0;
//     for (size_t i = 0; i < queryUString.length(); i++)
//     {
//         if (queryUString.isChineseChar(i))
//         {
//             ++chineseCount;
//         }
//         else
//         {
//             ++ekCount;
//         }
//     }
//     // if( !enableChn_ && chineseCount>0 ) return true;
//     // if( !enableEK_ && ekCount>0 ) return true;
//     if (chineseCount > CHINESE_CORRECTION_LENGTH)
//         return true;
//
//     vector<UString>::iterator it_token = queryTokens.begin();
//     for (; it_token != queryTokens.end(); it_token++)
//     {
//         string str;
//         it_token->convertString(str, izenelib::util::UString::UTF_8);
//
//         //if it is one word in Chinese dictionary, Chinese
//         //QueryCorrection is firstly processed.
//         (*it_token).toLowerString();
//         if (queryTokens.size() == 1 && cmgr_.inPinyinDict(str))
//         {
//             return false;
//         }
//         bool b1 = ekmgr_.inDict(*it_token);
//         bool b2 = cmgr_.inChineseDict(str);
//         if ( b2 )
//         {
//             return false;
//         }
//         else
//         {
//             if ( !b1 )
//                 is = false;
//         }
//
//     }
//     return is;
// }

//Initialize some member variables
bool QueryCorrectionSubmanager::initialize()
{
    std::cout<< "Start Speller construction!" << std::endl;
    activate_ = true;
    if (!boost::filesystem::exists(path_) || !boost::filesystem::is_directory(
                path_))
    {
        std::string
        msg =
            "Initialize query correction failed, please ensure that you set the correct path in configuration file.";
        sflog->error(SFL_MINE, msg.c_str());
        activate_ = false;
        return false;
    }

    if (enableEK_)
    {
        ekmgr_.initialize();
    }

    if (enableChn_)
    {
        if(!cmgr_.Load())
        {
            std::cerr<<"Load failed for Chinese query correction"<<std::endl;
            activate_ = false;
            return false;
        }
    }

    {
        boost::mutex::scoped_lock scopedLock(logMutex_);
        if (enableEK_)
        {
            ekmgr_.warmUp();
        }

    }

    //load inject
    std::string inject_file = workingPath_+"/inject_data.txt";
    std::vector<izenelib::util::UString> str_list;
    std::ifstream ifs(inject_file.c_str());
    std::string line;
    while( getline(ifs, line) )
    {
        boost::algorithm::trim(line);
        if(line.length()==0)
        {
            //do with str_list;
            if(str_list.size()>=1)
            {
                std::string str_query;
                str_list[0].convertString(str_query, izenelib::util::UString::UTF_8);
                izenelib::util::UString result;
                if(str_list.size()>=2)
                {
                    result = str_list[1];
                }
                inject_data_.insert(std::make_pair(str_query, result));
            }
            str_list.resize(0);
            continue;
        }
        str_list.push_back( izenelib::util::UString(line, izenelib::util::UString::UTF_8));
    }
    ifs.close();

    std::cout << "End Speller construction!" << std::endl;

    return true;
}

QueryCorrectionSubmanager::~QueryCorrectionSubmanager()
{
    DLOG(INFO) << "... Query Correction module is destroyed" << std::endl;
}

bool QueryCorrectionSubmanager::getRefinedToken_(const std::string& collectionName, const izenelib::util::UString& token, izenelib::util::UString& result)
{
    if (enableChn_)
    {
        std::vector<izenelib::util::UString> vec_result;
        if ( cmgr_.GetResult(token, vec_result) )
        {
            if(vec_result.size()>0)
            {
                result = vec_result[0];
                return true;
            }
            return false;
        }
    }
    if (enableEK_)
    {
        if ( ekmgr_.getRefinedQuery(collectionName, token, result) )
        {
            if(result.length()>0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    return false;
}

//The public interface, when user input wrong query, given the correct refined query.
bool QueryCorrectionSubmanager::getRefinedQuery(const UString& queryUString,
        UString& refinedQueryUString)
{
    return getRefinedQuery("", queryUString, refinedQueryUString);
}

bool QueryCorrectionSubmanager::getRefinedQuery(
    const std::string& collectionName, const UString& queryUString,
    UString& refinedQueryUString)
{
//     std::vector<izenelib::util::UString> vec_result;
//     if ( cmgr_.GetResult(queryUString, vec_result) )
//     {
//         if(vec_result.size()>0)
//         {
//             refinedQueryUString = vec_result[0];
//             return true;
//         }
//
//     }
//     return false;

    std::string str_query;
    queryUString.convertString(str_query, izenelib::util::UString::UTF_8);
    boost::algorithm::to_lower(str_query);
    boost::unordered_map<std::string, izenelib::util::UString>::iterator it = inject_data_.find(str_query);
    if(it!=inject_data_.end())
    {
        refinedQueryUString = it->second;
        return true;
    }
    if (queryUString.empty() || !activate_)
    {
        return false;
    }
    if (!enableEK_ && !enableChn_)
    {
        return false;
    }

    CREATE_SCOPED_PROFILER(getRealRefinedQuery, "QueryCorrectionSubmanager",
                           "QueryCorrectionSubmanager :: getRealRefinedQuery");

    // std::string sourceString( env.queryString_ );

    typedef tokenizer<char_separator<char> > tokenizers;
    char_separator<char> sep(QueryManager::seperatorString.c_str());//In order to omit ' punction.As we need to support words with suffix 's

    std::string queryStr;
    queryUString.convertString(queryStr, izenelib::util::UString::UTF_8);
    tokenizers stringTokenizer(queryStr, sep);

    // Tokenizing and apply query correction.
//     izenelib::util::UString originalToken;
    bool bRefined = false;
    bool first = true;
    for (tokenizers::iterator iter = stringTokenizer.begin(); iter
            != stringTokenizer.end(); iter++)
    {
        if (!first)
        {
            refinedQueryUString += ' ';
        }
        izenelib::util::UString token(*iter, izenelib::util::UString::UTF_8);
        izenelib::util::UString refined_token;
        if(getRefinedToken_(collectionName, token, refined_token) )
        {
            refinedQueryUString += refined_token;
            bRefined = true;
        }
        else
        {
            refinedQueryUString += token;
        }

        first = false;
    }

    if(bRefined)
    {
        return true;
    }
    else
    {
        refinedQueryUString.clear();
        return false;
    }

//     if (stopHere(queryUString) )
//     {
//         return false;
//     }
}

bool QueryCorrectionSubmanager::getPinyin(
    const izenelib::util::UString& hanzis, std::vector<
    izenelib::util::UString>& pinyin)
{
//     return cmgr_.getPinyin(hanzis, pinyin);
    return false;
}
//
// bool QueryCorrectionSubmanager::pinyinSegment(const string& str,
//         std::vector<string>& result)
// {
//
//     std::vector<std::vector<string> > vpy;
//     if ( !cmgr_.pinyinSegment(str, vpy) )
//     {
//         result.push_back(str);
//         return true;
//     }
//
//     size_t minSize = 1000;
//     for (size_t i=0; i<vpy.size(); i++)
//     {
//         if (vpy[i].size() < minSize)
//         {
//             minSize = vpy[i].size() ;
//             result = vpy[i];
//         }
//         for (size_t j=0; j<vpy[i].size(); j++)
//             cout<<vpy[i][j]<<" -> ";
//         cout<<endl;
//     }
//     return true;
// }
//
//
bool QueryCorrectionSubmanager::isPinyin(const izenelib::util::UString& str)
{
//     std::string tempString;
//     str.convertString(tempString, izenelib::util::UString::UTF_8);
//     return cmgr_.isPinyin(tempString);
    return false;
}
//
void QueryCorrectionSubmanager::updateCogramAndDict(const std::list<std::pair<izenelib::util::UString, uint32_t> >& recentQueryList)
{
    updateCogramAndDict("", recentQueryList);
}

void QueryCorrectionSubmanager::updateCogramAndDict(const std::string& collectionName, const std::list<std::pair<izenelib::util::UString, uint32_t> >& recentQueryList)
{
    boost::mutex::scoped_lock scopedLock(logMutex_);

    DLOG(INFO)<<"updateCogramAndDict..."<<endl;
    const std::list < std :: pair < izenelib::util::UString, uint32_t> >& queryList = recentQueryList;
    std::list < std :: pair < izenelib::util::UString, uint32_t> >::const_iterator lit;
    //no collection independent
    cmgr_.Update(queryList);

}

void QueryCorrectionSubmanager::Inject(const izenelib::util::UString& query, const izenelib::util::UString& result)
{
    std::string str_query;
    query.convertString(str_query, izenelib::util::UString::UTF_8);
    boost::algorithm::trim(str_query);
    if(str_query.empty()) return;
    boost::algorithm::to_lower(str_query);
    std::cout<<"Inject query correction : "<<str_query<<std::endl;
    inject_data_.erase( str_query );
    inject_data_.insert(std::make_pair( str_query, result) );
    has_new_inject_ = true;
}

void QueryCorrectionSubmanager::FinishInject()
{
    if(!has_new_inject_) return;
    std::string inject_file = workingPath_+"/inject_data.txt";
    if(boost::filesystem::exists( inject_file) )
    {
        boost::filesystem::remove_all( inject_file);
    }
    std::ofstream ofs(inject_file.c_str());
    boost::unordered_map<std::string, izenelib::util::UString>::iterator it = inject_data_.begin();
    while(it!= inject_data_.end())
    {
        std::string result;
        it->second.convertString(result, izenelib::util::UString::UTF_8);
        ofs<<it->first<<std::endl;
        ofs<<result<<std::endl;
        ofs<<std::endl;
        ++it;
    }
    ofs.close();
    has_new_inject_ = false;
    std::cout<<"Finish inject query correction."<<std::endl;
}

}/*namespace sf1r*/

<commit_msg>support pinyin autofill.<commit_after>/**@file   QueryCorrectionSubmanager.cpp
 * @brief  source file of Query Correction
 * @author Jinglei Zhao&Jinli Liu
 * @date   2009-08-21
 * @details
 * - Log
 *     - 2009.09.26 add new candidate generation
 *     - 2009.10.08 add new error model for english
 *     - 2009.11.27 add isEnglishWord() and isKoreanWord() to check if one word is mixure
 *      -2010.03.05 add log manager periodical worker.
 */
#include "Util.h"
#include "QueryCorrectionSubmanager.h"
#include <common/SFLogger.h>
#include <util/ustring/ustr_tool.h>
#include <boost/algorithm/string.hpp>

namespace
{

static const float SMOOTH = 0.000001;
static const float FACTOR = 0.05;
static const int UNIGRAM_FREQ_THRESHOLD = 3;
static const int BIGRAM_FREQ_THRESHOLD = 3;
static const int UNIGRAM_FACTOR = 10;
static const int BIGRAM_FACTOR = 1;
static const unsigned int CHINESE_CORRECTION_LENGTH = 8;

}
using namespace izenelib::util::ustring_tool;
namespace sf1r
{

_QueryCorrectionSubmanagerParam QueryCorrectionSubmanagerParam::param_;

QueryCorrectionSubmanager::QueryCorrectionSubmanager
(const string& path, const std::string& workingPath, bool enableEK, bool enableChn, int ed)
:path_(path), workingPath_(workingPath)
, enableEK_(enableEK), enableChn_(enableChn)
, activate_(false)
, cmgr_(path_+"/cn", workingPath_), ekmgr_(path, workingPath, ed)
, has_new_inject_(false)
{
    initialize();
}

QueryCorrectionSubmanager& QueryCorrectionSubmanager::getInstance()
{
    _QueryCorrectionSubmanagerParam& param =
        QueryCorrectionSubmanagerParam::get();
    static QueryCorrectionSubmanager qcManager(param.path_, param.workingPath_,
            param.enableEK_, param.enableChn_);
    return qcManager;
}

// bool QueryCorrectionSubmanager::stopHere(
//     const izenelib::util::UString& queryUString)
// {
//     bool is = true;
//     std::vector<UString> queryTokens;
//
//     string queryStr;
//     queryUString.convertString(queryStr, UString::UTF_8);
//     if (cmgr_.inPinyinDict(queryStr))
//         return false;
//
//     getTokensFromUString(UString::UTF_8,' ', queryUString, queryTokens);
// //	Tokenize(queryUString, queryTokens);
//
//     uint32_t chineseCount = 0;
//     uint32_t ekCount = 0;
//     for (size_t i = 0; i < queryUString.length(); i++)
//     {
//         if (queryUString.isChineseChar(i))
//         {
//             ++chineseCount;
//         }
//         else
//         {
//             ++ekCount;
//         }
//     }
//     // if( !enableChn_ && chineseCount>0 ) return true;
//     // if( !enableEK_ && ekCount>0 ) return true;
//     if (chineseCount > CHINESE_CORRECTION_LENGTH)
//         return true;
//
//     vector<UString>::iterator it_token = queryTokens.begin();
//     for (; it_token != queryTokens.end(); it_token++)
//     {
//         string str;
//         it_token->convertString(str, izenelib::util::UString::UTF_8);
//
//         //if it is one word in Chinese dictionary, Chinese
//         //QueryCorrection is firstly processed.
//         (*it_token).toLowerString();
//         if (queryTokens.size() == 1 && cmgr_.inPinyinDict(str))
//         {
//             return false;
//         }
//         bool b1 = ekmgr_.inDict(*it_token);
//         bool b2 = cmgr_.inChineseDict(str);
//         if ( b2 )
//         {
//             return false;
//         }
//         else
//         {
//             if ( !b1 )
//                 is = false;
//         }
//
//     }
//     return is;
// }

//Initialize some member variables
bool QueryCorrectionSubmanager::initialize()
{
    std::cout<< "Start Speller construction!" << std::endl;
    activate_ = true;
    if (!boost::filesystem::exists(path_) || !boost::filesystem::is_directory(
                path_))
    {
        std::string
        msg =
            "Initialize query correction failed, please ensure that you set the correct path in configuration file.";
        sflog->error(SFL_MINE, msg.c_str());
        activate_ = false;
        return false;
    }

    if (enableEK_)
    {
        ekmgr_.initialize();
    }

    if (enableChn_)
    {
        if(!cmgr_.Load())
        {
            std::cerr<<"Load failed for Chinese query correction"<<std::endl;
            activate_ = false;
            return false;
        }
    }

    {
        boost::mutex::scoped_lock scopedLock(logMutex_);
        if (enableEK_)
        {
            ekmgr_.warmUp();
        }

    }

    //load inject
    std::string inject_file = workingPath_+"/inject_data.txt";
    std::vector<izenelib::util::UString> str_list;
    std::ifstream ifs(inject_file.c_str());
    std::string line;
    while( getline(ifs, line) )
    {
        boost::algorithm::trim(line);
        if(line.length()==0)
        {
            //do with str_list;
            if(str_list.size()>=1)
            {
                std::string str_query;
                str_list[0].convertString(str_query, izenelib::util::UString::UTF_8);
                izenelib::util::UString result;
                if(str_list.size()>=2)
                {
                    result = str_list[1];
                }
                inject_data_.insert(std::make_pair(str_query, result));
            }
            str_list.resize(0);
            continue;
        }
        str_list.push_back( izenelib::util::UString(line, izenelib::util::UString::UTF_8));
    }
    ifs.close();

    std::cout << "End Speller construction!" << std::endl;

    return true;
}

QueryCorrectionSubmanager::~QueryCorrectionSubmanager()
{
    DLOG(INFO) << "... Query Correction module is destroyed" << std::endl;
}

bool QueryCorrectionSubmanager::getRefinedToken_(const std::string& collectionName, const izenelib::util::UString& token, izenelib::util::UString& result)
{
    if (enableChn_)
    {
        std::vector<izenelib::util::UString> vec_result;
        if ( cmgr_.GetResult(token, vec_result) )
        {
            if(vec_result.size()>0)
            {
                result = vec_result[0];
                return true;
            }
            return false;
        }
    }
    if (enableEK_)
    {
        if ( ekmgr_.getRefinedQuery(collectionName, token, result) )
        {
            if(result.length()>0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    return false;
}

//The public interface, when user input wrong query, given the correct refined query.
bool QueryCorrectionSubmanager::getRefinedQuery(const UString& queryUString,
        UString& refinedQueryUString)
{
    return getRefinedQuery("", queryUString, refinedQueryUString);
}

bool QueryCorrectionSubmanager::getRefinedQuery(
    const std::string& collectionName, const UString& queryUString,
    UString& refinedQueryUString)
{
//     std::vector<izenelib::util::UString> vec_result;
//     if ( cmgr_.GetResult(queryUString, vec_result) )
//     {
//         if(vec_result.size()>0)
//         {
//             refinedQueryUString = vec_result[0];
//             return true;
//         }
//
//     }
//     return false;

    std::string str_query;
    queryUString.convertString(str_query, izenelib::util::UString::UTF_8);
    boost::algorithm::to_lower(str_query);
    boost::unordered_map<std::string, izenelib::util::UString>::iterator it = inject_data_.find(str_query);
    if(it!=inject_data_.end())
    {
        refinedQueryUString = it->second;
        return true;
    }
    if (queryUString.empty() || !activate_)
    {
        return false;
    }
    if (!enableEK_ && !enableChn_)
    {
        return false;
    }

    CREATE_SCOPED_PROFILER(getRealRefinedQuery, "QueryCorrectionSubmanager",
                           "QueryCorrectionSubmanager :: getRealRefinedQuery");

    // std::string sourceString( env.queryString_ );

    typedef tokenizer<char_separator<char> > tokenizers;
    char_separator<char> sep(QueryManager::seperatorString.c_str());//In order to omit ' punction.As we need to support words with suffix 's

    std::string queryStr;
    queryUString.convertString(queryStr, izenelib::util::UString::UTF_8);
    tokenizers stringTokenizer(queryStr, sep);

    // Tokenizing and apply query correction.
//     izenelib::util::UString originalToken;
    bool bRefined = false;
    bool first = true;
    for (tokenizers::iterator iter = stringTokenizer.begin(); iter
            != stringTokenizer.end(); iter++)
    {
        if (!first)
        {
            refinedQueryUString += ' ';
        }
        izenelib::util::UString token(*iter, izenelib::util::UString::UTF_8);
        izenelib::util::UString refined_token;
        if(getRefinedToken_(collectionName, token, refined_token) )
        {
            refinedQueryUString += refined_token;
            bRefined = true;
        }
        else
        {
            refinedQueryUString += token;
        }

        first = false;
    }

    if(bRefined)
    {
        return true;
    }
    else
    {
        refinedQueryUString.clear();
        return false;
    }

//     if (stopHere(queryUString) )
//     {
//         return false;
//     }
}

bool QueryCorrectionSubmanager::getPinyin(
    const izenelib::util::UString& hanzis, std::vector<
    izenelib::util::UString>& pinyin)
{
    std::vector<std::string> result_list;
    cmgr_.GetPinyin(hanzis, result_list);
    for(uint32_t i=0;i<result_list.size();i++)
    {
        boost::algorithm::replace_all(result_list[i], ",", "");
        pinyin.push_back( izenelib::util::UString(result_list[i], izenelib::util::UString::UTF_8) );
    }
    if(pinyin.size()>0) return true;
    return false;
}
//
// bool QueryCorrectionSubmanager::pinyinSegment(const string& str,
//         std::vector<string>& result)
// {
//
//     std::vector<std::vector<string> > vpy;
//     if ( !cmgr_.pinyinSegment(str, vpy) )
//     {
//         result.push_back(str);
//         return true;
//     }
//
//     size_t minSize = 1000;
//     for (size_t i=0; i<vpy.size(); i++)
//     {
//         if (vpy[i].size() < minSize)
//         {
//             minSize = vpy[i].size() ;
//             result = vpy[i];
//         }
//         for (size_t j=0; j<vpy[i].size(); j++)
//             cout<<vpy[i][j]<<" -> ";
//         cout<<endl;
//     }
//     return true;
// }
//
//
bool QueryCorrectionSubmanager::isPinyin(const izenelib::util::UString& str)
{
//     std::string tempString;
//     str.convertString(tempString, izenelib::util::UString::UTF_8);
//     return cmgr_.isPinyin(tempString);
    return false;
}
//
void QueryCorrectionSubmanager::updateCogramAndDict(const std::list<std::pair<izenelib::util::UString, uint32_t> >& recentQueryList)
{
    updateCogramAndDict("", recentQueryList);
}

void QueryCorrectionSubmanager::updateCogramAndDict(const std::string& collectionName, const std::list<std::pair<izenelib::util::UString, uint32_t> >& recentQueryList)
{
    boost::mutex::scoped_lock scopedLock(logMutex_);

    DLOG(INFO)<<"updateCogramAndDict..."<<endl;
    const std::list < std :: pair < izenelib::util::UString, uint32_t> >& queryList = recentQueryList;
    std::list < std :: pair < izenelib::util::UString, uint32_t> >::const_iterator lit;
    //no collection independent
    cmgr_.Update(queryList);

}

void QueryCorrectionSubmanager::Inject(const izenelib::util::UString& query, const izenelib::util::UString& result)
{
    std::string str_query;
    query.convertString(str_query, izenelib::util::UString::UTF_8);
    boost::algorithm::trim(str_query);
    if(str_query.empty()) return;
    boost::algorithm::to_lower(str_query);
    std::cout<<"Inject query correction : "<<str_query<<std::endl;
    inject_data_.erase( str_query );
    inject_data_.insert(std::make_pair( str_query, result) );
    has_new_inject_ = true;
}

void QueryCorrectionSubmanager::FinishInject()
{
    if(!has_new_inject_) return;
    std::string inject_file = workingPath_+"/inject_data.txt";
    if(boost::filesystem::exists( inject_file) )
    {
        boost::filesystem::remove_all( inject_file);
    }
    std::ofstream ofs(inject_file.c_str());
    boost::unordered_map<std::string, izenelib::util::UString>::iterator it = inject_data_.begin();
    while(it!= inject_data_.end())
    {
        std::string result;
        it->second.convertString(result, izenelib::util::UString::UTF_8);
        ofs<<it->first<<std::endl;
        ofs<<result<<std::endl;
        ofs<<std::endl;
        ++it;
    }
    ofs.close();
    has_new_inject_ = false;
    std::cout<<"Finish inject query correction."<<std::endl;
}

}/*namespace sf1r*/

<|endoftext|>


<commit_before><commit_msg>add failing tests for DivModDown<commit_after><|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/ocmb/odyssey/procedures/hwp/memory/lib/phy/ody_draminit_procedure.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2022                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// EKB-Mirror-To: hostboot
///
/// @file ody_draminit_procedure.C
/// @brief Odyssey draminit procedure
/// @note Using a separate file as simulation might need a different draminit procedure for now
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include <generic/memory/lib/utils/find.H>

#include <lib/phy/ody_draminit_utils.H>
#include <lib/phy/ody_phy_utils.H>
#include <mss_odyssey_attribute_getters.H>

namespace mss
{
namespace ody
{

///
/// @brief Runs draminit
/// @param[in] i_target the target on which to operate
/// @return fapi2::FAPI2_RC_SUCCESS iff successful
/// @note Assumes PHY init has already been run
///
fapi2::ReturnCode draminit(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target)
{
    fapi2::ATTR_DRAMINIT_TRAINING_TIMEOUT_Type l_poll_count;
    FAPI_TRY(mss::attr::get_draminit_training_timeout(i_target , l_poll_count));

    // 1. Loads the IMEM Memory (instructions)
    // TODO:ZEN:MST-1561 Create code to load IMEM, DMEM, and message block onto Synopsys PHY

    // 2. Loads the DMEM Memory (data)
    // TODO:ZEN:MST-1561 Create code to load IMEM, DMEM, and message block onto Synopsys PHY

    // 3. Configures and loads the message block
    // TODO:ZEN:MST-1561 Create code to load IMEM, DMEM, and message block onto Synopsys PHY

    // 4. Initialize mailbox protocol and start training
    FAPI_TRY(mss::ody::phy::init_mailbox_protocol(i_target));
    FAPI_TRY(mss::ody::phy::start_training(i_target));

    // 5. Processes and handles training messages (aka poll for completion)
    FAPI_TRY (mss::ody::phy::poll_for_completion(i_target, l_poll_count));

    // 6. Cleans up after training
    FAPI_TRY(mss::ody::phy::cleanup_training(i_target));

    // 7. Read the data structure and set attributes
    // TODO:ZEN:MST-1567 Create code to process data from the Synopsys message block

    // 8. Error handling
    // TODO:ZEN:MST-1568 Add Odyssey draminit error processing

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Runs draminit
/// @param[in] i_target the target on which to operate
/// @return fapi2::FAPI2_RC_SUCCESS iff successful
/// @note Assumes PHY init has already been run
///
fapi2::ReturnCode draminit(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
    for(const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
    {
        // Note: This will need to be updated to allow training to fail on one port but continue on the second
        FAPI_TRY(draminit(l_port));
    }

    // Blame FIRs and unmask FIRs (done on the OCMB chip level)
    // TODO:ZEN:MST-1530 Specialize unmask::after_draminit_training for Odyssey

fapi_try_exit:
    return fapi2::current_err;
}

} // namespace ody
} // namespace mss
<commit_msg>Adds ODY draminit wrap<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/ocmb/odyssey/procedures/hwp/memory/lib/phy/ody_draminit_procedure.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2022                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// EKB-Mirror-To: hostboot
///
/// @file ody_draminit_procedure.C
/// @brief Odyssey draminit procedure
/// @note Using a separate file as simulation might need a different draminit procedure for now
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include <generic/memory/lib/utils/find.H>

#include <lib/phy/ody_draminit_utils.H>
#include <lib/phy/ody_phy_utils.H>
#include <mss_odyssey_attribute_getters.H>
#include <lib/phy/ody_draminit_procedure.H>

namespace mss
{
namespace ody
{

///
/// @brief Runs draminit
/// @param[in] i_target the target on which to operate
/// @return fapi2::FAPI2_RC_SUCCESS iff successful
/// @note Assumes PHY init has already been run
///
fapi2::ReturnCode draminit(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target)
{
    fapi2::ATTR_DRAMINIT_TRAINING_TIMEOUT_Type l_poll_count;
    FAPI_TRY(mss::attr::get_draminit_training_timeout(i_target , l_poll_count));

    // 1. Loads the IMEM Memory (instructions)
    // TODO:ZEN:MST-1561 Create code to load IMEM, DMEM, and message block onto Synopsys PHY

    // 2. Loads the DMEM Memory (data)
    // TODO:ZEN:MST-1561 Create code to load IMEM, DMEM, and message block onto Synopsys PHY

    // 3. Configures and loads the message block
    // TODO:ZEN:MST-1561 Create code to load IMEM, DMEM, and message block onto Synopsys PHY

    // 4. Initialize mailbox protocol and start training
    FAPI_TRY(mss::ody::phy::init_mailbox_protocol(i_target));
    FAPI_TRY(mss::ody::phy::start_training(i_target));

    // 5. Processes and handles training messages (aka poll for completion)
    FAPI_TRY (mss::ody::phy::poll_for_completion(i_target, l_poll_count));

    // 6. Cleans up after training
    FAPI_TRY(mss::ody::phy::cleanup_training(i_target));

    // 7. Read the data structure and set attributes
    // TODO:ZEN:MST-1567 Create code to process data from the Synopsys message block

    // 8. Error handling
    // TODO:ZEN:MST-1568 Add Odyssey draminit error processing

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Runs draminit
/// @param[in] i_target the target on which to operate
/// @return fapi2::FAPI2_RC_SUCCESS iff successful
/// @note Assumes PHY init has already been run
///
fapi2::ReturnCode draminit(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
    for(const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
    {
        // Note: This will need to be updated to allow training to fail on one port but continue on the second
        FAPI_TRY(draminit(l_port));
    }

    // Blame FIRs and unmask FIRs (done on the OCMB chip level)
    // TODO:ZEN:MST-1530 Specialize unmask::after_draminit_training for Odyssey

fapi_try_exit:
    return fapi2::current_err;
}

} // namespace ody
} // namespace mss
<|endoftext|>


<commit_before>#include "../include/morton.h"
#include <iostream>
#include <iomanip>

using namespace std;

#define MAX 256

// Timer struct for easy timing
struct Timer {
	clock_t Start;
	clock_t Elapsed;
	Timer(){
		Elapsed = 0;
		Start = clock();
	}
	void reset(){
		Start = clock();
	}
	void resetTotal(){
		Elapsed = 0;
	}
	void start(){
		Start = clock();
	}
	void stop(){
		clock_t End = clock();
		Elapsed = Elapsed + (End - Start);
	}
	double getTotalTimeMs() const{
		return ((double)Elapsed) / ((double)CLOCKS_PER_SEC / 1000.0f);
	}
};

// Don't optimize this, since the loops themselves are useless - we're testing
#pragma optimize( "", off )
int main(int argc, char *argv[]) {
	size_t total = MAX*MAX*MAX;
	cout << "Running morton encoding / decoding tests ..." << endl;
	cout << "+++ Encoding " << MAX << "^3 morton codes (" << total << " in total)" << endl;

	Timer morton_LUT;
	morton_LUT.reset();
	morton_LUT.start();
	for(size_t i = 0; i < MAX; i++){
		for(size_t j = 0; j < MAX; j++){
			for(size_t k = 0; k < MAX; k++){
				mortonEncode_LUT(i,j,k);
			}
		}
	}
	morton_LUT.stop();
	cout << "LUT-based method: " << morton_LUT.getTotalTimeMs() << " ms" << endl;

	Timer morton_magicbits;
	morton_magicbits.reset();
	morton_magicbits.start();
	for (size_t i = 0; i < MAX; i++){
		for (size_t j = 0; j < MAX; j++){
			for (size_t k = 0; k < MAX; k++){
				mortonEncode_magicbits(i, j, k);
			}
		}
	}
	morton_magicbits.stop();
	cout << "Magic bits-based method: " << morton_magicbits.getTotalTimeMs() << " ms" << endl;

	Timer morton_for;
	morton_for.reset();
	morton_for.start();
	for (size_t i = 0; i < MAX; i++){
		for (size_t j = 0; j < MAX; j++){
			for (size_t k = 0; k < MAX; k++){
				mortonEncode_for(i, j, k);
			}
		}
	}
	morton_for.stop();
	cout << "For-loop method: " << morton_for.getTotalTimeMs() << " ms" << endl;

	cout << "+++ Decoding " << MAX << "^3 morton codes (" << total << " in total)" << endl;

	Timer morton_decode_magicbits;
	morton_decode_magicbits.reset();
	morton_decode_magicbits.start();
	for (size_t i = 0; i < MAX; i++){
		for (size_t j = 0; j < MAX; j++){
			for (size_t k = 0; k < MAX; k++){
				uint64_t s = mortonEncode_LUT(i, j, k);
				if (i != mortonDecode_magicbits_X(s) || j != mortonDecode_magicbits_Y(s) || k != mortonDecode_magicbits_Z(s)){
					cout << "Encode and decode don't match" << endl;
				}
			}
		}
	}
	morton_decode_magicbits.stop();
	cout << "Magicbits method: " << morton_decode_magicbits.getTotalTimeMs() - morton_LUT.getTotalTimeMs() << " ms" << endl;

	Timer morton_decode_for;
	morton_decode_for.reset();
	morton_decode_for.start();
	for (size_t i = 0; i < MAX; i++){
		for (size_t j = 0; j < MAX; j++){
			for (size_t k = 0; k < MAX; k++){
				uint64_t s = mortonEncode_LUT(i, j, k);
				unsigned int x = 0;
				unsigned int y = 0;
				unsigned int z = 0;
				mortonDecode_for(s, x, y, z);
				if (i != x || j != y || k != z){
					cout << "Encode and decode don't match" << endl;
				}
			}
		}
	}
	morton_decode_for.stop();
	cout << "For-loop method: " << morton_decode_for.getTotalTimeMs() - morton_LUT.getTotalTimeMs() << " ms" << endl;
}
	<commit_msg>Changed comments<commit_after>#include "../include/morton.h"
#include <iostream>
#include <iomanip>

using namespace std;

#define MAX 256

// Timer struct for easy timing
struct Timer {
	clock_t Start;
	clock_t Elapsed;
	Timer(){
		Elapsed = 0;
		Start = clock();
	}
	void reset(){
		Start = clock();
	}
	void resetTotal(){
		Elapsed = 0;
	}
	void start(){
		Start = clock();
	}
	void stop(){
		clock_t End = clock();
		Elapsed = Elapsed + (End - Start);
	}
	double getTotalTimeMs() const{
		return ((double)Elapsed) / ((double)CLOCKS_PER_SEC / 1000.0f);
	}
};

// Don't optimize this, since the loops themselves are useless - we're testing
#pragma optimize( "", off )
int main(int argc, char *argv[]) {
	size_t total = MAX*MAX*MAX;
	cout << "Running morton encoding / decoding tests ..." << endl;
	cout << "+++ Encoding " << MAX << "^3 morton codes (" << total << " in total)" << endl;

	Timer morton_LUT;
	morton_LUT.reset();
	morton_LUT.start();
	for(size_t i = 0; i < MAX; i++){
		for(size_t j = 0; j < MAX; j++){
			for(size_t k = 0; k < MAX; k++){
				mortonEncode_LUT(i,j,k);
			}
		}
	}
	morton_LUT.stop();
	cout << "LUT-based method: " << morton_LUT.getTotalTimeMs() << " ms" << endl;

	Timer morton_magicbits;
	morton_magicbits.reset();
	morton_magicbits.start();
	for (size_t i = 0; i < MAX; i++){
		for (size_t j = 0; j < MAX; j++){
			for (size_t k = 0; k < MAX; k++){
				mortonEncode_magicbits(i, j, k);
			}
		}
	}
	morton_magicbits.stop();
	cout << "Magic bits-based method: " << morton_magicbits.getTotalTimeMs() << " ms" << endl;

	Timer morton_for;
	morton_for.reset();
	morton_for.start();
	for (size_t i = 0; i < MAX; i++){
		for (size_t j = 0; j < MAX; j++){
			for (size_t k = 0; k < MAX; k++){
				mortonEncode_for(i, j, k);
			}
		}
	}
	morton_for.stop();
	cout << "For-loop method: " << morton_for.getTotalTimeMs() << " ms" << endl;

	cout << "+++ Decoding " << MAX << "^3 morton codes (" << total << " in total)" << endl;

	Timer morton_decode_magicbits;
	morton_decode_magicbits.reset();
	morton_decode_magicbits.start();
	for (size_t i = 0; i < MAX; i++){
		for (size_t j = 0; j < MAX; j++){
			for (size_t k = 0; k < MAX; k++){
				uint64_t s = mortonEncode_LUT(i, j, k);
				if (i != mortonDecode_magicbits_X(s) || j != mortonDecode_magicbits_Y(s) || k != mortonDecode_magicbits_Z(s)){
					cout << "Encode and decode don't match" << endl;
				}
			}
		}
	}
	morton_decode_magicbits.stop();
	cout << "Magicbits method: " << morton_decode_magicbits.getTotalTimeMs() - morton_LUT.getTotalTimeMs() << " ms" << endl; // we subtract morton code generation time with LUT-based method

	Timer morton_decode_for;
	morton_decode_for.reset();
	morton_decode_for.start();
	for (size_t i = 0; i < MAX; i++){
		for (size_t j = 0; j < MAX; j++){
			for (size_t k = 0; k < MAX; k++){
				uint64_t s = mortonEncode_LUT(i, j, k);
				unsigned int x = 0;
				unsigned int y = 0;
				unsigned int z = 0;
				mortonDecode_for(s, x, y, z);
				if (i != x || j != y || k != z){
					cout << "Encode and decode don't match" << endl;
				}
			}
		}
	}
	morton_decode_for.stop();
	cout << "For-loop method: " << morton_decode_for.getTotalTimeMs() - morton_LUT.getTotalTimeMs() << " ms" << endl; // we subtract morton code generation time with LUT method
}
<|endoftext|>


<commit_before>/*
***************************************
*   Asylum3D @ 2014-12-09
***************************************
*/

#ifndef __TEXPOOL_HPP__
#define __TEXPOOL_HPP__

/* Asylum Namespace */
namespace asy {

/***************/
/* TexPool Key */
/***************/
struct texpool_key
{
    int32u      hash;
    const char* name;
};

/****************/
/* TexPool Unit */
/****************/
struct texpool_unit
{
    size_t      idx;
    texpool_key key;

    /* ====== */
    void free ()
    {
        mem_free(this->key.name);
    }
};

/***************/
/* TexPool Cmp */
/***************/
class texpool_cmp
{
public:
    /* ======================== */
    size_t hash (texpool_key* key)
    {
        key->hash = hash_crc32i_total(key->name, str_lenA(key->name));
        return ((size_t)key->hash);
    }

    /* ========================================== */
    bool match (texpool_key* key, texpool_unit* obj)
    {
        if (key->hash != obj->key.hash)
            return (false);
        if (str_cmpIA(key->name, obj->key.name) != 0)
            return (false);
        return (true);
    }
};

/******************/
/* TexPool Rehash */
/******************/
class texpool_rehash
{
public:
    /* ================================== */
    bool doit (void* ctx, texpool_unit* obj)
    {
        table_c<texpool_unit, texpool_key, texpool_cmp>*    tbl2;

        tbl2 = (table_c<texpool_unit, texpool_key, texpool_cmp>*)ctx;
        tbl2->insert(&obj->key, obj, false);
        return (true);
    }
};

/****************/
/* Texture Pool */
/****************/
template<class TTEX>
class texpool : public asylum
{
private:
    size_t                                          m_cnt;
    array<TTEX>                                     m_lst;
    table_c<texpool_unit, texpool_key, texpool_cmp> m_tbl;

public:
    /* ====== */
    bool init ()
    {
        m_cnt = hash_count(0);
        if (!m_tbl.init(m_cnt))
            return (false);
        m_lst.init();
        return (true);
    }

    /* ====== */
    void free ()
    {
        m_tbl.free();
        m_lst.free();
    }

public:
    /* ============== */
    size_t size () const
    {
        return (m_lst.size());
    }

    /* ======================= */
    TTEX* get2 (size_t idx) const
    {
        return (m_lst.get(idx));
    }

    /* =========================== */
    TTEX* get_safe (size_t idx) const
    {
        return (m_lst.get_safe(idx));
    }

    /* ============================ */
    TTEX* get (const char* name) const
    {
        texpool_key     key;
        texpool_unit*   unt;

        key.name = name;
        unt = m_tbl.get(&key);
        if (unt != NULL)
            return (m_lst.get(unt->idx));
        return (NULL);
    }

    /* ======================================== */
    TTEX* get (const char* name, const char* type)
    {
        texpool_key     key;
        texpool_unit*   unt;

        key.name = name;
        unt = m_tbl.get(&key);
        if (unt != NULL)
            return (m_lst.get(unt->idx));

        TTEX    tex, *ret;

        if (!tex.init(name, type))
            return (NULL);
        ret = m_lst.append(&tex);
        if (ret == NULL) {
            tex.free();
            return (NULL);
        }

        size_t          cnt;
        texpool_unit    tmp;

        key.name = str_dupA(name);
        if (key.name == NULL) {
            m_lst.pop();
            return (NULL);
        }
        mem_cpy(&tmp.key, &key, sizeof(key));
        tmp.idx = m_lst.size() - 1;
        if (m_tbl.insert(&key, &tmp, false) == NULL)
        {
            table_c<texpool_unit, texpool_key, texpool_cmp> tbl2;

            cnt = hash_count(m_cnt + 1);
            if (cnt == m_cnt || !tbl2.init(cnt)) {
                mem_free(key.name);
                m_lst.pop();
                return (NULL);
            }
            m_tbl.traverse<texpool_rehash>(&tbl2);
            m_tbl.setup(&tbl2);
            m_cnt = cnt;
            m_tbl.insert(&key, &tmp, false);
        }
        return (ret);
    }
};

}   /* namespace */

#endif  /* __TEXPOOL_HPP__ */
<commit_msg>Asylum3D: 加载纹理时要传入主对象参数<commit_after>/*
***************************************
*   Asylum3D @ 2014-12-09
***************************************
*/

#ifndef __TEXPOOL_HPP__
#define __TEXPOOL_HPP__

/* Asylum Namespace */
namespace asy {

/***************/
/* TexPool Key */
/***************/
struct texpool_key
{
    int32u      hash;
    const char* name;
};

/****************/
/* TexPool Unit */
/****************/
struct texpool_unit
{
    size_t      idx;
    texpool_key key;

    /* ====== */
    void free ()
    {
        mem_free(this->key.name);
    }
};

/***************/
/* TexPool Cmp */
/***************/
class texpool_cmp
{
public:
    /* ======================== */
    size_t hash (texpool_key* key)
    {
        key->hash = hash_crc32i_total(key->name, str_lenA(key->name));
        return ((size_t)key->hash);
    }

    /* ========================================== */
    bool match (texpool_key* key, texpool_unit* obj)
    {
        if (key->hash != obj->key.hash)
            return (false);
        if (str_cmpIA(key->name, obj->key.name) != 0)
            return (false);
        return (true);
    }
};

/******************/
/* TexPool Rehash */
/******************/
class texpool_rehash
{
public:
    /* ================================== */
    bool doit (void* ctx, texpool_unit* obj)
    {
        table_c<texpool_unit, texpool_key, texpool_cmp>*    tbl2;

        tbl2 = (table_c<texpool_unit, texpool_key, texpool_cmp>*)ctx;
        tbl2->insert(&obj->key, obj, false);
        return (true);
    }
};

/****************/
/* Texture Pool */
/****************/
template<class TTEX, class TA3D>
class texpool : public asylum
{
private:
    size_t                                          m_cnt;
    array<TTEX>                                     m_lst;
    table_c<texpool_unit, texpool_key, texpool_cmp> m_tbl;

public:
    /* ====== */
    bool init ()
    {
        m_cnt = hash_count(0);
        if (!m_tbl.init(m_cnt))
            return (false);
        m_lst.init();
        return (true);
    }

    /* ====== */
    void free ()
    {
        m_tbl.free();
        m_lst.free();
    }

public:
    /* ============== */
    size_t size () const
    {
        return (m_lst.size());
    }

    /* ======================= */
    TTEX* get2 (size_t idx) const
    {
        return (m_lst.get(idx));
    }

    /* =========================== */
    TTEX* get_safe (size_t idx) const
    {
        return (m_lst.get_safe(idx));
    }

    /* ============================ */
    TTEX* get (const char* name) const
    {
        texpool_key     key;
        texpool_unit*   unt;

        key.name = name;
        unt = m_tbl.get(&key);
        if (unt != NULL)
            return (m_lst.get(unt->idx));
        return (NULL);
    }

    /* ==================================================== */
    TTEX* get (const char* name, const char* type, TA3D *main)
    {
        texpool_key     key;
        texpool_unit*   unt;

        key.name = name;
        unt = m_tbl.get(&key);
        if (unt != NULL)
            return (m_lst.get(unt->idx));

        TTEX    tex, *ret;

        if (!tex.init(name, type, main))
            return (NULL);
        ret = m_lst.append(&tex);
        if (ret == NULL) {
            tex.free();
            return (NULL);
        }

        size_t          cnt;
        texpool_unit    tmp;

        key.name = str_dupA(name);
        if (key.name == NULL) {
            m_lst.pop();
            return (NULL);
        }
        mem_cpy(&tmp.key, &key, sizeof(key));
        tmp.idx = m_lst.size() - 1;
        if (m_tbl.insert(&key, &tmp, false) == NULL)
        {
            table_c<texpool_unit, texpool_key, texpool_cmp> tbl2;

            cnt = hash_count(m_cnt + 1);
            if (cnt == m_cnt || !tbl2.init(cnt)) {
                mem_free(key.name);
                m_lst.pop();
                return (NULL);
            }
            m_tbl.traverse<texpool_rehash>(&tbl2);
            m_tbl.setup(&tbl2);
            m_cnt = cnt;
            m_tbl.insert(&key, &tmp, false);
        }
        return (ret);
    }
};

}   /* namespace */

#endif  /* __TEXPOOL_HPP__ */
<|endoftext|>