<commit_before>/*
    This file is part of tgl-library

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    Copyright Vitaly Valtman 2014-2015
    Copyright Topology LP 2016
*/

#include "tgl.h"

#include "crypto/rsa_pem.h"
#include "crypto/sha.h"
#include "tools.h"
#include "mtproto-client.h"
#include "structures.h"
#include "tgl_transfer_manager.h"
#include "tgl-timer.h"
#include "tgl-queries.h"
#include "tools.h"
#include "types/tgl_online_status_observer.h"
#include "types/tgl_update_callback.h"
#include "types/tgl_rsa_key.h"
#include "types/tgl_secret_chat.h"
#include "queries.h"

#include <assert.h>
#include <stdlib.h>

constexpr int MAX_DC_ID = 10;
constexpr int32_t TG_APP_ID = 10534;
constexpr const char* TG_APP_HASH = "844584f2b1fd2daecee726166dcc1ef8";

std::unique_ptr<tgl_state> tgl_state::s_instance;

tgl_state::tgl_state()
    : locks(0)
    , ev_login(NULL)
    , m_is_started(false)
    , m_online_status(tgl_online_status::not_online)
    , m_app_id(0)
    , m_error_code(0)
    , m_temp_key_expire_time(0)
    , m_pts(0)
    , m_qts(0)
    , m_date(0)
    , m_seq(0)
    , m_test_mode(0)
    , m_our_id()
    , m_enable_pfs(false)
    , m_ipv6_enabled(false)
    , m_bn_ctx(TGLC_bn_ctx_new())
    , m_online_status_observers()
{
}

tgl_state* tgl_state::instance()
{
    if (!s_instance) {
        s_instance.reset(new tgl_state);
    }
    return s_instance.get();
}

void tgl_state::reset()
{
    s_instance.reset();
}

void tgl_state::set_auth_key(int num, const char* buf)
{
    assert(num > 0 && num <= MAX_DC_ID);
    assert(m_dcs[num]);

    if (buf) {
        memcpy(m_dcs[num]->auth_key, buf, 256);
    }

    unsigned char sha1_buffer[20];
    memset(sha1_buffer, 0, sizeof(sha1_buffer));
    TGLC_sha1((unsigned char *)m_dcs[num]->auth_key, 256, sha1_buffer);
    memcpy(&m_dcs[num]->auth_key_id, sha1_buffer + 12, 8);

    m_dcs[num]->set_authorized();

    m_callback->dc_update(m_dcs[num]);
}

void tgl_state::set_our_id(int id)
{
    if (m_our_id.peer_id == id) {
        return;
    }
    m_our_id.peer_id = id;
    m_our_id.peer_type = tgl_peer_type::user;
    assert(our_id().peer_id > 0);
    m_callback->our_id(our_id().peer_id);
}

void tgl_state::set_dc_option(bool is_v6, int id, const std::string& ip, int port)
{
    if (id < 0) {
        return;
    }

    if (static_cast<size_t>(id) >= m_dcs.size()) {
        m_dcs.resize(id+1, nullptr);
    }

    if (!m_dcs[id]) {
        m_dcs[id] = tgl_state::instance()->allocate_dc(id);
        if (tgl_state::instance()->pfs_enabled()) {
          //dc->ev = tgl_state::instance()->timer_factory()->create_timer(std::bind(&regen_temp_key_gw, DC));
          //dc->ev->start(0);
        }
    }
    if (is_v6) {
        m_dcs[id]->ipv6_options.option_list.push_back(std::make_pair(ip, port));
    } else {
        m_dcs[id]->ipv4_options.option_list.push_back(std::make_pair(ip, port));
    }
}

void tgl_state::set_dc_logged_in(int num)
{
    TGL_DEBUG2("set signed " << num);
    assert(num > 0 && num <= MAX_DC_ID);
    assert(m_dcs[num]);
    m_dcs[num]->set_logged_in();
    m_callback->dc_update(m_dcs[num]);
}

void tgl_state::set_working_dc(int num)
{
    if (m_working_dc && m_working_dc->id == num) {
        return;
    }
    TGL_DEBUG2("change working DC to " << num);
    assert(num > 0 && num <= MAX_DC_ID);
    m_working_dc = m_dcs[num];
    m_callback->change_active_dc(num);
}

void tgl_state::set_qts(int32_t qts, bool force)
{
    if (locks & TGL_LOCK_DIFF) {
        return;
    }

    if (qts <= m_qts && !force) {
        return;
    }

    m_qts = qts;
    m_callback->qts_changed(qts);
}

void tgl_state::set_pts(int32_t pts, bool force)
{
    if (locks & TGL_LOCK_DIFF && !force) {
        return;
    }

    if (pts <= m_pts && !force) {
        return;
    }

    m_pts = pts;
    m_callback->pts_changed(pts);
}

void tgl_state::set_date(int64_t date, bool force)
{
    if (locks & TGL_LOCK_DIFF && !force) {
        return;
    }

    if (date <= m_date && !force) {
        return;
    }

    m_date = date;
    m_callback->date_changed(date);
}

void tgl_state::set_seq(int32_t seq)
{
    if (locks & TGL_LOCK_DIFF) {
        return;
    }

    if (seq <= m_seq) {
        return;
    }

    m_seq = seq;
}

void tgl_state::reset_server_state()
{
    m_qts = 0;
    m_pts = 0;
    m_date = 0;
    m_seq = 0;
}

void tgl_state::add_rsa_key(const std::string& key)
{
    m_rsa_key_list.push_back(std::unique_ptr<tgl_rsa_key>(new tgl_rsa_key(key)));
}

int tgl_state::init(const std::string& download_dir, int app_id, const std::string& app_hash, const std::string& app_version)
{
    m_transfer_manager = std::make_shared<tgl_transfer_manager>(download_dir);
    m_app_id = app_id;
    m_app_hash = app_hash;
    m_app_version = app_version;
    assert(m_timer_factory);
    assert(m_connection_factory);
    if (!m_temp_key_expire_time) {
        m_temp_key_expire_time = 7200; // seconds
    }

    if (tglmp_on_start() < 0) {
        return -1;
    }

    if (!m_app_id) {
        m_app_id = TG_APP_ID;
        m_app_hash = TG_APP_HASH;
    }

    m_state_lookup_timer = m_timer_factory->create_timer(std::bind(&tgl_state::state_lookup_timeout, this));
    m_state_lookup_timer->start(3600);
    return 0;
}

void tgl_state::set_enable_pfs(bool val)
{
    m_enable_pfs = val;
}

void tgl_state::set_test_mode(bool val)
{
    m_test_mode = val;
}

void tgl_state::set_enable_ipv6(bool val)
{
    m_ipv6_enabled = val;
}

void tgl_state::set_error(const std::string& error, int error_code)
{
    m_error = error;
    m_error_code = error_code;
}

int32_t tgl_state::create_secret_chat_id()
{
    int chat_id = tgl_random<int>();
    while (tgl_state::instance()->secret_chat_for_id(chat_id)) {
        chat_id = tgl_random<int>();
    }
    return chat_id;
}

std::shared_ptr<tgl_secret_chat> tgl_state::create_secret_chat(int32_t id)
{
    int chat_id;
    if (id) {
        chat_id = id;
    } else {
        chat_id = create_secret_chat_id();
    }

    auto secret_chat = std::make_shared<tgl_secret_chat>();
    secret_chat->id = tgl_input_peer_t(tgl_peer_type::enc_chat, chat_id, 0);
    m_secret_chats[chat_id] = secret_chat;

    return secret_chat;
}

std::shared_ptr<tgl_secret_chat> tgl_state::create_secret_chat(const tgl_input_peer_t& chat_id)
{
    if (m_secret_chats.find(chat_id.peer_id) != m_secret_chats.end()) {
        return nullptr;
    }

    auto secret_chat = std::make_shared<tgl_secret_chat>();
    secret_chat->id = chat_id;
    m_secret_chats[chat_id.peer_id] = secret_chat;

    return secret_chat;
}

std::shared_ptr<tgl_secret_chat> tgl_state::secret_chat_for_id(int chat_id) const
{
    auto secret_chat_it = m_secret_chats.find(chat_id);
    if (secret_chat_it == m_secret_chats.end()) {
        return nullptr;
    }
    return secret_chat_it->second;
}

void tgl_state::add_secret_chat(const std::shared_ptr<tgl_secret_chat>& secret_chat)
{
    m_secret_chats[secret_chat->id.peer_id] = secret_chat;
}

void tgl_state::add_query(const std::shared_ptr<query>& q)
{
    auto id = q->msg_id();
    assert(id);
    auto inserted_iterator_pair = m_active_queries.emplace(id, q);
    if (inserted_iterator_pair.second) {
        q->dc()->increase_active_queries();
    } else {
        inserted_iterator_pair.first->second = q;
    }
}

std::shared_ptr<query> tgl_state::get_query(int64_t id) const
{
    assert(id);
    auto it = m_active_queries.find(id);
    if (it == m_active_queries.end()) {
        return nullptr;
    }
    return it->second;
}

void tgl_state::remove_query(const std::shared_ptr<query>& q)
{
    auto id = q->msg_id();
    assert(id);
    auto it = m_active_queries.find(id);
    if (it != m_active_queries.end()) {
        m_active_queries.erase(it);
        q->dc()->decrease_active_queries();
    }
}

void tgl_state::remove_all_queries()
{
    m_active_queries.clear();
}

std::shared_ptr<tgl_dc> tgl_state::dc_at(int id)
{
    if (static_cast<size_t>(id) >= m_dcs.size()) {
        return nullptr;
    }

    return m_dcs[id];
}

std::shared_ptr<tgl_dc> tgl_state::allocate_dc(int id)
{
    if (static_cast<size_t>(id) >= m_dcs.size()) {
        m_dcs.resize(id+1, nullptr);
    }

    assert(!m_dcs[id]);

    std::shared_ptr<tgl_dc> dc = std::make_shared<tgl_dc>();
    dc->id = id;
    m_dcs[id] = dc;

    return dc;
}

void tgl_state::state_lookup_timeout()
{
    tgl_do_lookup_state();
    if (m_state_lookup_timer) {
        m_state_lookup_timer->start(3600);
    }
}

void tgl_state::logout()
{
    tgl_do_logout(nullptr);
}

void tgl_state::set_online_status(tgl_online_status status)
{
    if (status == m_online_status) {
        return;
    }

    m_online_status = status;
    for (const auto& weak_observer: m_online_status_observers) {
        if (auto observer = weak_observer.lock()) {
            observer->on_online_status_changed(status);
        }
    }
}
<commit_msg>Add log message when changing online status<commit_after>/*
    This file is part of tgl-library

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    Copyright Vitaly Valtman 2014-2015
    Copyright Topology LP 2016
*/

#include "tgl.h"

#include "crypto/rsa_pem.h"
#include "crypto/sha.h"
#include "tools.h"
#include "mtproto-client.h"
#include "structures.h"
#include "tgl_transfer_manager.h"
#include "tgl-timer.h"
#include "tgl-queries.h"
#include "tools.h"
#include "types/tgl_online_status_observer.h"
#include "types/tgl_update_callback.h"
#include "types/tgl_rsa_key.h"
#include "types/tgl_secret_chat.h"
#include "queries.h"

#include <assert.h>
#include <stdlib.h>

constexpr int MAX_DC_ID = 10;
constexpr int32_t TG_APP_ID = 10534;
constexpr const char* TG_APP_HASH = "844584f2b1fd2daecee726166dcc1ef8";

std::unique_ptr<tgl_state> tgl_state::s_instance;

tgl_state::tgl_state()
    : locks(0)
    , ev_login(NULL)
    , m_is_started(false)
    , m_online_status(tgl_online_status::not_online)
    , m_app_id(0)
    , m_error_code(0)
    , m_temp_key_expire_time(0)
    , m_pts(0)
    , m_qts(0)
    , m_date(0)
    , m_seq(0)
    , m_test_mode(0)
    , m_our_id()
    , m_enable_pfs(false)
    , m_ipv6_enabled(false)
    , m_bn_ctx(TGLC_bn_ctx_new())
    , m_online_status_observers()
{
}

tgl_state* tgl_state::instance()
{
    if (!s_instance) {
        s_instance.reset(new tgl_state);
    }
    return s_instance.get();
}

void tgl_state::reset()
{
    s_instance.reset();
}

void tgl_state::set_auth_key(int num, const char* buf)
{
    assert(num > 0 && num <= MAX_DC_ID);
    assert(m_dcs[num]);

    if (buf) {
        memcpy(m_dcs[num]->auth_key, buf, 256);
    }

    unsigned char sha1_buffer[20];
    memset(sha1_buffer, 0, sizeof(sha1_buffer));
    TGLC_sha1((unsigned char *)m_dcs[num]->auth_key, 256, sha1_buffer);
    memcpy(&m_dcs[num]->auth_key_id, sha1_buffer + 12, 8);

    m_dcs[num]->set_authorized();

    m_callback->dc_update(m_dcs[num]);
}

void tgl_state::set_our_id(int id)
{
    if (m_our_id.peer_id == id) {
        return;
    }
    m_our_id.peer_id = id;
    m_our_id.peer_type = tgl_peer_type::user;
    assert(our_id().peer_id > 0);
    m_callback->our_id(our_id().peer_id);
}

void tgl_state::set_dc_option(bool is_v6, int id, const std::string& ip, int port)
{
    if (id < 0) {
        return;
    }

    if (static_cast<size_t>(id) >= m_dcs.size()) {
        m_dcs.resize(id+1, nullptr);
    }

    if (!m_dcs[id]) {
        m_dcs[id] = tgl_state::instance()->allocate_dc(id);
        if (tgl_state::instance()->pfs_enabled()) {
          //dc->ev = tgl_state::instance()->timer_factory()->create_timer(std::bind(&regen_temp_key_gw, DC));
          //dc->ev->start(0);
        }
    }
    if (is_v6) {
        m_dcs[id]->ipv6_options.option_list.push_back(std::make_pair(ip, port));
    } else {
        m_dcs[id]->ipv4_options.option_list.push_back(std::make_pair(ip, port));
    }
}

void tgl_state::set_dc_logged_in(int num)
{
    TGL_DEBUG2("set signed " << num);
    assert(num > 0 && num <= MAX_DC_ID);
    assert(m_dcs[num]);
    m_dcs[num]->set_logged_in();
    m_callback->dc_update(m_dcs[num]);
}

void tgl_state::set_working_dc(int num)
{
    if (m_working_dc && m_working_dc->id == num) {
        return;
    }
    TGL_DEBUG2("change working DC to " << num);
    assert(num > 0 && num <= MAX_DC_ID);
    m_working_dc = m_dcs[num];
    m_callback->change_active_dc(num);
}

void tgl_state::set_qts(int32_t qts, bool force)
{
    if (locks & TGL_LOCK_DIFF) {
        return;
    }

    if (qts <= m_qts && !force) {
        return;
    }

    m_qts = qts;
    m_callback->qts_changed(qts);
}

void tgl_state::set_pts(int32_t pts, bool force)
{
    if (locks & TGL_LOCK_DIFF && !force) {
        return;
    }

    if (pts <= m_pts && !force) {
        return;
    }

    m_pts = pts;
    m_callback->pts_changed(pts);
}

void tgl_state::set_date(int64_t date, bool force)
{
    if (locks & TGL_LOCK_DIFF && !force) {
        return;
    }

    if (date <= m_date && !force) {
        return;
    }

    m_date = date;
    m_callback->date_changed(date);
}

void tgl_state::set_seq(int32_t seq)
{
    if (locks & TGL_LOCK_DIFF) {
        return;
    }

    if (seq <= m_seq) {
        return;
    }

    m_seq = seq;
}

void tgl_state::reset_server_state()
{
    m_qts = 0;
    m_pts = 0;
    m_date = 0;
    m_seq = 0;
}

void tgl_state::add_rsa_key(const std::string& key)
{
    m_rsa_key_list.push_back(std::unique_ptr<tgl_rsa_key>(new tgl_rsa_key(key)));
}

int tgl_state::init(const std::string& download_dir, int app_id, const std::string& app_hash, const std::string& app_version)
{
    m_transfer_manager = std::make_shared<tgl_transfer_manager>(download_dir);
    m_app_id = app_id;
    m_app_hash = app_hash;
    m_app_version = app_version;
    assert(m_timer_factory);
    assert(m_connection_factory);
    if (!m_temp_key_expire_time) {
        m_temp_key_expire_time = 7200; // seconds
    }

    if (tglmp_on_start() < 0) {
        return -1;
    }

    if (!m_app_id) {
        m_app_id = TG_APP_ID;
        m_app_hash = TG_APP_HASH;
    }

    m_state_lookup_timer = m_timer_factory->create_timer(std::bind(&tgl_state::state_lookup_timeout, this));
    m_state_lookup_timer->start(3600);
    return 0;
}

void tgl_state::set_enable_pfs(bool val)
{
    m_enable_pfs = val;
}

void tgl_state::set_test_mode(bool val)
{
    m_test_mode = val;
}

void tgl_state::set_enable_ipv6(bool val)
{
    m_ipv6_enabled = val;
}

void tgl_state::set_error(const std::string& error, int error_code)
{
    m_error = error;
    m_error_code = error_code;
}

int32_t tgl_state::create_secret_chat_id()
{
    int chat_id = tgl_random<int>();
    while (tgl_state::instance()->secret_chat_for_id(chat_id)) {
        chat_id = tgl_random<int>();
    }
    return chat_id;
}

std::shared_ptr<tgl_secret_chat> tgl_state::create_secret_chat(int32_t id)
{
    int chat_id;
    if (id) {
        chat_id = id;
    } else {
        chat_id = create_secret_chat_id();
    }

    auto secret_chat = std::make_shared<tgl_secret_chat>();
    secret_chat->id = tgl_input_peer_t(tgl_peer_type::enc_chat, chat_id, 0);
    m_secret_chats[chat_id] = secret_chat;

    return secret_chat;
}

std::shared_ptr<tgl_secret_chat> tgl_state::create_secret_chat(const tgl_input_peer_t& chat_id)
{
    if (m_secret_chats.find(chat_id.peer_id) != m_secret_chats.end()) {
        return nullptr;
    }

    auto secret_chat = std::make_shared<tgl_secret_chat>();
    secret_chat->id = chat_id;
    m_secret_chats[chat_id.peer_id] = secret_chat;

    return secret_chat;
}

std::shared_ptr<tgl_secret_chat> tgl_state::secret_chat_for_id(int chat_id) const
{
    auto secret_chat_it = m_secret_chats.find(chat_id);
    if (secret_chat_it == m_secret_chats.end()) {
        return nullptr;
    }
    return secret_chat_it->second;
}

void tgl_state::add_secret_chat(const std::shared_ptr<tgl_secret_chat>& secret_chat)
{
    m_secret_chats[secret_chat->id.peer_id] = secret_chat;
}

void tgl_state::add_query(const std::shared_ptr<query>& q)
{
    auto id = q->msg_id();
    assert(id);
    auto inserted_iterator_pair = m_active_queries.emplace(id, q);
    if (inserted_iterator_pair.second) {
        q->dc()->increase_active_queries();
    } else {
        inserted_iterator_pair.first->second = q;
    }
}

std::shared_ptr<query> tgl_state::get_query(int64_t id) const
{
    assert(id);
    auto it = m_active_queries.find(id);
    if (it == m_active_queries.end()) {
        return nullptr;
    }
    return it->second;
}

void tgl_state::remove_query(const std::shared_ptr<query>& q)
{
    auto id = q->msg_id();
    assert(id);
    auto it = m_active_queries.find(id);
    if (it != m_active_queries.end()) {
        m_active_queries.erase(it);
        q->dc()->decrease_active_queries();
    }
}

void tgl_state::remove_all_queries()
{
    m_active_queries.clear();
}

std::shared_ptr<tgl_dc> tgl_state::dc_at(int id)
{
    if (static_cast<size_t>(id) >= m_dcs.size()) {
        return nullptr;
    }

    return m_dcs[id];
}

std::shared_ptr<tgl_dc> tgl_state::allocate_dc(int id)
{
    if (static_cast<size_t>(id) >= m_dcs.size()) {
        m_dcs.resize(id+1, nullptr);
    }

    assert(!m_dcs[id]);

    std::shared_ptr<tgl_dc> dc = std::make_shared<tgl_dc>();
    dc->id = id;
    m_dcs[id] = dc;

    return dc;
}

void tgl_state::state_lookup_timeout()
{
    tgl_do_lookup_state();
    if (m_state_lookup_timer) {
        m_state_lookup_timer->start(3600);
    }
}

void tgl_state::logout()
{
    tgl_do_logout(nullptr);
}

void tgl_state::set_online_status(tgl_online_status status)
{
    if (status == m_online_status) {
        return;
    }

    TGL_DEBUG("setting online status to " << static_cast<int>(status)
            << " (previous: " << static_cast<int>(m_online_status) << ")");
    m_online_status = status;
    for (const auto& weak_observer: m_online_status_observers) {
        if (auto observer = weak_observer.lock()) {
            observer->on_online_status_changed(status);
        }
    }
}
<|endoftext|>


<commit_before>//
// Created by Harvey on 2017/1/4.
//

#include "strade_share_engine.h"

#define DEFAULT_CONFIG_PATH  "./strade_share/stradeshare_config.xml"

strade_share::SSEngine* GetStradeShareEngine(void) {
  return strade_share::SSEngineImpl::GetInstance();
}

namespace strade_share {

SSEngineImpl* SSEngineImpl::instance_ = NULL;
SSEngineImpl::SSEngineImpl() {
  if (!Init()) {
    LOG_ERROR("StradeShareEngineImpl Init error");
    assert(0);
  }
}

SSEngineImpl* SSEngineImpl::GetInstance() {
  if (NULL == instance_) {
    instance_ = new SSEngineImpl();
  }
  return instance_;
}

bool SSEngineImpl::Init() {
  InitThreadrw(&lock_);
  bool r = false;
  std::string path = DEFAULT_CONFIG_PATH;
  config::FileConfig* config = config::FileConfig::GetFileConfig();
  if (config == NULL) {
    return false;
  }
  r = config->LoadConfig(path);
  if (!r) {
    return false;
  }
  mysql_engine_ = new StradeShareDB(config);
  LoadAllStockBasicInfo();
  return true;
}

void SSEngineImpl::AttachObserver(strade_logic::Observer* observer) {
  if(NULL != observer) {
    base_logic::WLockGd lk(lock_);
    this->Attach(observer);
  }
}

void SSEngineImpl::DetachObserver(strade_logic::Observer* observer) {
  if(NULL != observer) {
    base_logic::WLockGd lk(lock_);
    this->Detach(observer);
  }
}

void SSEngineImpl::LoadAllStockBasicInfo() {
  base_logic::WLockGd lk(lock_);
  std::vector<strade_logic::StockTotalInfo> stock_vec;
  mysql_engine_->FetchAllStockList(stock_vec);
  std::vector<strade_logic::StockTotalInfo>::iterator iter(stock_vec.begin());
  for (; iter != stock_vec.end(); ++iter) {
    strade_logic::StockTotalInfo& stock_total_info = (*iter);
    std::vector<strade_logic::StockHistInfo> stock_hist_vec;
    mysql_engine_->FetchStockHistList(
        stock_total_info.GetStockCode(), stock_hist_vec);
    stock_total_info.AddStockHistVec(stock_hist_vec);
    AddStockTotalInfoNonblock(stock_total_info);
  }
}

void SSEngineImpl::UpdateStockRealMarketData(
    REAL_MARKET_DATA_VEC& stocks_market_data) {

  {
    base_logic::WLockGd lk(lock_);
    int total_count = 0;
    REAL_MARKET_DATA_VEC::const_iterator iter(stocks_market_data.begin());
    for (; iter != stocks_market_data.end(); ++iter) {
      const strade_logic::StockRealInfo& stock_real_info = *iter;
      const std::string& stock_code = stock_real_info.GetStockCode();
      const time_t& trade_time = stock_real_info.GetTradeTime();
      strade_logic::StockTotalInfo* stock_total_info = NULL;
      GetStockTotalNonBlock(stock_code, &stock_total_info);
      if (NULL == stock_total_info) {
        LOG_ERROR2("UpdateStockRealMarketData stock_code=%s, not exists!!!!",
                   stock_code.c_str());
        continue;
      }
      stock_total_info->AddStockRealInfoByTime(trade_time, stock_real_info);
      ++total_count;
    }
    LOG_DEBUG2("UpdateStockRealMarketData total_count=%d, current_time=%d",
               total_count, time(NULL));
  }

  // 通知所有需要实时行情数据的观察者
  this->Notify(strade_logic::REALTIME_MARKET_VALUE_UPDATE);
}

bool SSEngineImpl::UpdateStockHistInfoByDate(const std::string& stock_code,
                                             const std::string& date,
                                             strade_logic::StockHistInfo& stock_hist_info) {
  base_logic::WLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info = NULL;
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL != stock_total_info) {
    return stock_total_info->AddStockHistInfoByDate(date, stock_hist_info);
  }
  return false;
}

bool SSEngineImpl::ClearOldRealTradeMap() {
  base_logic::WLockGd lk(lock_);
  STOCKS_MAP::iterator iter(share_cache_.stocks_map_.begin());
  for (; iter != share_cache_.stocks_map_.end(); ++iter) {
    iter->second.ClearRealMap();
  }
  return true;
}

bool SSEngineImpl::UpdateStockHistDataVec(
    const std::string& stock_code,
    STOCK_HIST_DATA_VEC& stock_vec) {
  base_logic::WLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info = NULL;
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL == stock_total_info) {
    return false;
  }
  stock_total_info->AddStockHistVec(stock_vec);
  return true;
}

bool SSEngineImpl::AddStockTotalInfoNonblock(
    const strade_logic::StockTotalInfo& stock_total_info) {
  const std::string& stock_code = stock_total_info.GetStockCode();
  share_cache_.stocks_map_[stock_code] = stock_total_info;
  return true;
}

bool SSEngineImpl::AddStockTotalInfoBlock(
    const strade_logic::StockTotalInfo& stock_total_info) {
  base_logic::WLockGd lk(lock_);
  AddStockTotalInfoNonblock(stock_total_info);
}

const STOCKS_MAP& SSEngineImpl::GetAllStockTotalMap() {
  base_logic::RLockGd lk(lock_);
  return share_cache_.stocks_map_;
}

const STOCK_HIST_MAP& SSEngineImpl::GetStockHistMap(
    const std::string& stock_code) {
  base_logic::RLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info = NULL;
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL != stock_total_info) {
    return stock_total_info->GetStockHistMap();
  }
  return STOCK_HIST_MAP();
}

const STOCK_REAL_MAP& SSEngineImpl::GetStockRealInfoMap(
    const std::string& stock_code) {
  base_logic::RLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info = NULL;
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL != stock_total_info) {
    return stock_total_info->GetStockRealMap();
  }
  return STOCK_REAL_MAP();
}

STOCKS_MAP SSEngineImpl::GetAllStockTotalMapCopy() {
  base_logic::RLockGd lk(lock_);
  return share_cache_.stocks_map_;
}

STOCK_HIST_MAP SSEngineImpl::GetStockHistMapByCodeCopy(
    const std::string& stock_code) {
  const STOCK_HIST_MAP& stock_hist_map =
      GetStockHistMap(stock_code);
  return stock_hist_map;
}

STOCK_REAL_MAP SSEngineImpl::GetStockRealInfoMapCopy(
    const std::string& stock_code) {
  const STOCK_REAL_MAP& stock_real_map =
      GetStockRealInfoMap(stock_code);
  return stock_real_map;
}

bool SSEngineImpl::GetStockTotalInfoByCode(
    const std::string& stock_code,
    strade_logic::StockTotalInfo* stock_total_info) {
  base_logic::WLockGd lk(lock_);
  GetStockTotalNonBlock(stock_code, &stock_total_info);
}

bool SSEngineImpl::GetStockHistInfoByDate(
    const std::string& stock_code,
    const std::string& date,
    strade_logic::StockHistInfo* stock_hist_info) {
  base_logic::WLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info(NULL);
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL == stock_total_info) {
    return false;
  }
  return stock_total_info->GetStockHistInfoByDate(date, &stock_hist_info);
}

bool SSEngineImpl::GetStockRealMarketDataByTime(
    const std::string& stock_code,
    const time_t& time,
    strade_logic::StockRealInfo* stock_real_info) {
  base_logic::WLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info(NULL);
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL == stock_total_info) {
    return false;
  }
  return stock_total_info->GetStockRealInfoByTradeTime(time, &stock_real_info);
}

} /* namespace strade_share */
<commit_msg>修改共享库返回map时为拷贝<commit_after>//
// Created by Harvey on 2017/1/4.
//

#include "strade_share_engine.h"

#define DEFAULT_CONFIG_PATH  "./strade_share/stradeshare_config.xml"

strade_share::SSEngine* GetStradeShareEngine(void) {
  return strade_share::SSEngineImpl::GetInstance();
}

namespace strade_share {

SSEngineImpl* SSEngineImpl::instance_ = NULL;
SSEngineImpl::SSEngineImpl() {
  if (!Init()) {
    LOG_ERROR("StradeShareEngineImpl Init error");
    assert(0);
  }
}

SSEngineImpl* SSEngineImpl::GetInstance() {
  if (NULL == instance_) {
    instance_ = new SSEngineImpl();
  }
  return instance_;
}

bool SSEngineImpl::Init() {
  InitThreadrw(&lock_);
  bool r = false;
  std::string path = DEFAULT_CONFIG_PATH;
  config::FileConfig* config = config::FileConfig::GetFileConfig();
  if (config == NULL) {
    return false;
  }
  r = config->LoadConfig(path);
  if (!r) {
    return false;
  }
  mysql_engine_ = new StradeShareDB(config);
  LoadAllStockBasicInfo();
  return true;
}

void SSEngineImpl::AttachObserver(strade_logic::Observer* observer) {
  if(NULL != observer) {
    base_logic::WLockGd lk(lock_);
    this->Attach(observer);
  }
}

void SSEngineImpl::DetachObserver(strade_logic::Observer* observer) {
  if(NULL != observer) {
    base_logic::WLockGd lk(lock_);
    this->Detach(observer);
  }
}

void SSEngineImpl::LoadAllStockBasicInfo() {
  base_logic::WLockGd lk(lock_);
  std::vector<strade_logic::StockTotalInfo> stock_vec;
  mysql_engine_->FetchAllStockList(stock_vec);
  std::vector<strade_logic::StockTotalInfo>::iterator iter(stock_vec.begin());
  for (; iter != stock_vec.end(); ++iter) {
    strade_logic::StockTotalInfo& stock_total_info = (*iter);
    std::vector<strade_logic::StockHistInfo> stock_hist_vec;
    mysql_engine_->FetchStockHistList(
        stock_total_info.GetStockCode(), stock_hist_vec);
    stock_total_info.AddStockHistVec(stock_hist_vec);
    AddStockTotalInfoNonblock(stock_total_info);
  }
}

void SSEngineImpl::UpdateStockRealMarketData(
    REAL_MARKET_DATA_VEC& stocks_market_data) {

  {
    base_logic::WLockGd lk(lock_);
    int total_count = 0;
    REAL_MARKET_DATA_VEC::const_iterator iter(stocks_market_data.begin());
    for (; iter != stocks_market_data.end(); ++iter) {
      const strade_logic::StockRealInfo& stock_real_info = *iter;
      const std::string& stock_code = stock_real_info.GetStockCode();
      const time_t& trade_time = stock_real_info.GetTradeTime();
      strade_logic::StockTotalInfo* stock_total_info = NULL;
      GetStockTotalNonBlock(stock_code, &stock_total_info);
      if (NULL == stock_total_info) {
        LOG_ERROR2("UpdateStockRealMarketData stock_code=%s, not exists!!!!",
                   stock_code.c_str());
        continue;
      }
      stock_total_info->AddStockRealInfoByTime(trade_time, stock_real_info);
      ++total_count;
    }
    LOG_DEBUG2("UpdateStockRealMarketData total_count=%d, current_time=%d",
               total_count, time(NULL));
  }

  // 通知所有需要实时行情数据的观察者
  this->Notify(strade_logic::REALTIME_MARKET_VALUE_UPDATE);
}

bool SSEngineImpl::UpdateStockHistInfoByDate(const std::string& stock_code,
                                             const std::string& date,
                                             strade_logic::StockHistInfo& stock_hist_info) {
  base_logic::WLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info = NULL;
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL != stock_total_info) {
    return stock_total_info->AddStockHistInfoByDate(date, stock_hist_info);
  }
  return false;
}

bool SSEngineImpl::ClearOldRealTradeMap() {
  base_logic::WLockGd lk(lock_);
  STOCKS_MAP::iterator iter(share_cache_.stocks_map_.begin());
  for (; iter != share_cache_.stocks_map_.end(); ++iter) {
    iter->second.ClearRealMap();
  }
  return true;
}

bool SSEngineImpl::UpdateStockHistDataVec(
    const std::string& stock_code,
    STOCK_HIST_DATA_VEC& stock_vec) {
  base_logic::WLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info = NULL;
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL == stock_total_info) {
    return false;
  }
  stock_total_info->AddStockHistVec(stock_vec);
  return true;
}

bool SSEngineImpl::AddStockTotalInfoNonblock(
    const strade_logic::StockTotalInfo& stock_total_info) {
  const std::string& stock_code = stock_total_info.GetStockCode();
  share_cache_.stocks_map_[stock_code] = stock_total_info;
  return true;
}

bool SSEngineImpl::AddStockTotalInfoBlock(
    const strade_logic::StockTotalInfo& stock_total_info) {
  base_logic::WLockGd lk(lock_);
  AddStockTotalInfoNonblock(stock_total_info);
  return true;
}

const STOCKS_MAP& SSEngineImpl::GetAllStockTotalMap() {
  base_logic::RLockGd lk(lock_);
  return share_cache_.stocks_map_;
}

const STOCK_HIST_MAP& SSEngineImpl::GetStockHistMap(
    const std::string& stock_code) {
  base_logic::RLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info = NULL;
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL != stock_total_info) {
    return stock_total_info->GetStockHistMap();
  }
  return STOCK_HIST_MAP();
}

const STOCK_REAL_MAP& SSEngineImpl::GetStockRealInfoMap(
    const std::string& stock_code) {
  base_logic::RLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info = NULL;
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL != stock_total_info) {
    return stock_total_info->GetStockRealMap();
  }
  return STOCK_REAL_MAP();
}

STOCKS_MAP SSEngineImpl::GetAllStockTotalMapCopy() {
  base_logic::RLockGd lk(lock_);
  return share_cache_.stocks_map_;
}

STOCK_HIST_MAP SSEngineImpl::GetStockHistMapByCodeCopy(
    const std::string& stock_code) {
  const STOCK_HIST_MAP& stock_hist_map =
      GetStockHistMap(stock_code);
  return stock_hist_map;
}

STOCK_REAL_MAP SSEngineImpl::GetStockRealInfoMapCopy(
    const std::string& stock_code) {
  const STOCK_REAL_MAP& stock_real_map =
      GetStockRealInfoMap(stock_code);
  return stock_real_map;
}

bool SSEngineImpl::GetStockTotalInfoByCode(
    const std::string& stock_code,
    strade_logic::StockTotalInfo* stock_total_info) {
  base_logic::WLockGd lk(lock_);
  GetStockTotalNonBlock(stock_code, &stock_total_info);
}

bool SSEngineImpl::GetStockHistInfoByDate(
    const std::string& stock_code,
    const std::string& date,
    strade_logic::StockHistInfo* stock_hist_info) {
  base_logic::WLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info(NULL);
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL == stock_total_info) {
    return false;
  }
  return stock_total_info->GetStockHistInfoByDate(date, &stock_hist_info);
}

bool SSEngineImpl::GetStockRealMarketDataByTime(
    const std::string& stock_code,
    const time_t& time,
    strade_logic::StockRealInfo* stock_real_info) {
  base_logic::WLockGd lk(lock_);
  strade_logic::StockTotalInfo* stock_total_info(NULL);
  GetStockTotalNonBlock(stock_code, &stock_total_info);
  if (NULL == stock_total_info) {
    return false;
  }
  return stock_total_info->GetStockRealInfoByTradeTime(time, &stock_real_info);
}

} /* namespace strade_share */
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2003-2012
  \file      app/rdo_studio_mfc/src/model/model_view.cpp
  \author      (rdo@rk9.bmstu.ru)
  \date      20.02.2003
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "app/rdo_studio_mfc/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
#include <boost/bind.hpp>
#include <QtGui/qevent.h>
#include <QtGui/qboxlayout.h>
// ----------------------------------------------------------------------- SYNOPSIS
#include "app/rdo_studio_mfc/src/model/model_view.h"
#include "app/rdo_studio_mfc/src/application.h"
#include "app/rdo_studio_mfc/src/main_windows_base.h"
#include "app/rdo_studio_mfc/edit_ctrls/rdofindedit.h"
#include "app/rdo_studio_mfc/rdo_edit/rdoeditortabctrl.h"
#include "app/rdo_studio_mfc/resource.h"
#include "app/rdo_studio_mfc/src/main_frm.h"
// --------------------------------------------------------------------------------

using namespace rdoEditor;

// --------------------------------------------------------------------------------
// -------------------- RDOStudioModelView
// --------------------------------------------------------------------------------

// ON_UPDATE_COMMAND_UI

//! @todo qt
// RDOStudioEditBaseView -> QWidget
//BEGIN_MESSAGE_MAP(RDOStudioModelView, RDOStudioEditBaseView)
//	ON_WM_CREATE()
//	ON_WM_SETFOCUS()
//	ON_WM_SIZE()
//END_MESSAGE_MAP()

RDOStudioModelView::RDOStudioModelView(PTR(QWidget) pParent)
	: parent_type(pParent)
	, m_pModel     (NULL)
	, m_pTabCtrl   (NULL)
	, m_pFindDialog(NULL)
{
	m_pTabCtrl = new RDOEditorTabCtrl(this, this);

	PTR(QVBoxLayout) pLayout = new QVBoxLayout(this);
	pLayout->setSpacing(0);
	pLayout->setContentsMargins(0, 0, 0, 0);
	pLayout->addWidget(m_pTabCtrl);

	RDOStudioMainFrame* pMainWindow = studioApp.getMainWndUI();
	ASSERT(pMainWindow);
	pMainWindow->actSearchFindInModel->setEnabled(true);
	connect(pMainWindow->actSearchFindInModel, SIGNAL(triggered(bool)), this, SLOT(onSearchFindInModel()));
}

RDOStudioModelView::~RDOStudioModelView()
{
	RDOStudioMainFrame* pMainWindow = studioApp.getMainWndUI();
	ASSERT(pMainWindow);
	disconnect(pMainWindow->actSearchFindInModel, SIGNAL(triggered(bool)), this, SLOT(onSearchFindInModel()));
}

void RDOStudioModelView::setModel(PTR(RDOStudioModel) pModel)
{
	ASSERT(m_pModel != pModel);
	m_pModel = pModel;
}

void RDOStudioModelView::closeEvent(PTR(QCloseEvent) event)
{
	if (m_pModel)
	{
		if (m_pModel->closeModel())
		{
			event->accept();
		}
		else
		{
			event->ignore();
		}
	}
}

//! @todo qt
//BOOL RDOStudioModelView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
//{
//	if ( m_pTabCtrl->getCurrentEdit()->OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE;
//	return RDOStudioEditBaseView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
//}
//
//void RDOStudioModelView::OnSetFocus(CWnd* pOldWnd)
//{
//	RDOStudioEditBaseView::OnSetFocus( pOldWnd );
//	m_pTabCtrl->SetFocus();
//}
//

REF(rdoEditor::RDOEditorTabCtrl) RDOStudioModelView::getTab()
{
	return *m_pTabCtrl;
}

void RDOStudioModelView::onSearchFindInModel()
{
	m_findSettings.what = m_pTabCtrl->getCurrentEdit()->getWordForFind();

	if (!m_pFindDialog)
	{
		m_pFindDialog = new FindDialog(
			this,
			boost::bind(&RDOStudioModelView::onFindDlgFind, this, _1),
			boost::bind(&RDOStudioModelView::onFindDlgClose, this)
		);
	}

	m_pFindDialog->setSettings(m_findSettings);
	m_pFindDialog->show();
	m_pFindDialog->raise();
	m_pFindDialog->activateWindow();
}

void RDOStudioModelView::onFindDlgFind(CREF(FindDialog::Settings) settings)
{
	m_findSettings = settings;
	onSearchFindAll();
}

void RDOStudioModelView::onFindDlgClose()
{
	m_pFindDialog = NULL;
}

void RDOStudioModelView::onSearchFindAll()
{
	studioApp.getIMainWnd()->getDockFind().clear();
	studioApp.getIMainWnd()->getDockFind().raise();
	tstring findStr       = m_findSettings.what;
	rbool bMatchCase      = m_findSettings.matchCase;
	rbool bMatchWholeWord = m_findSettings.matchWholeWord;
	studioApp.getIMainWnd()->getDockFind().getContext().setKeyword(findStr, bMatchCase);
	studioApp.getIMainWnd()->getDockFind().appendString(rdo::format(ID_FINDINMODEL_BEGINMSG, findStr.c_str()));
	int count = 0;
	for (int i = 0; i < m_pTabCtrl->count(); i++)
	{
		PTR(RDOEditorEdit) pEdit = m_pTabCtrl->getItemEdit(i);
		int pos  = 0;
		int line = 0;
		while (pos != -1)
		{
			pos = pEdit->findPos(findStr, line, bMatchCase, bMatchWholeWord);
			if (pos != -1)
			{
				line = pEdit->getLineFromPosition(pos);
				studioApp.getIMainWnd()->getDockFind().appendString(pEdit->getLine(line), m_pTabCtrl->indexToType(i), line, pos - pEdit->getPositionFromLine(line));
				line++;
				count++;
			}
		}
	}
	m_pFindDialog = NULL;
	tstring s = count
		? rdo::format(ID_FINDINMODEL_ENDMSG_COUNT,    count)
		: rdo::format(ID_FINDINMODEL_ENDMSG_NOTFOUND, findStr.c_str());
	studioApp.getIMainWnd()->getDockFind().appendString(s);
}<commit_msg> - чистка кода<commit_after>/*!
  \copyright (c) RDO-Team, 2003-2012
  \file      app/rdo_studio_mfc/src/model/model_view.cpp
  \author      (rdo@rk9.bmstu.ru)
  \date      20.02.2003
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "app/rdo_studio_mfc/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
#include <boost/bind.hpp>
#include <QtGui/qevent.h>
#include <QtGui/qboxlayout.h>
// ----------------------------------------------------------------------- SYNOPSIS
#include "app/rdo_studio_mfc/src/model/model_view.h"
#include "app/rdo_studio_mfc/src/application.h"
#include "app/rdo_studio_mfc/src/main_windows_base.h"
#include "app/rdo_studio_mfc/edit_ctrls/rdofindedit.h"
#include "app/rdo_studio_mfc/rdo_edit/rdoeditortabctrl.h"
#include "app/rdo_studio_mfc/resource.h"
#include "app/rdo_studio_mfc/src/main_frm.h"
// --------------------------------------------------------------------------------

using namespace rdoEditor;

// --------------------------------------------------------------------------------
// -------------------- RDOStudioModelView
// --------------------------------------------------------------------------------
RDOStudioModelView::RDOStudioModelView(PTR(QWidget) pParent)
	: parent_type(pParent)
	, m_pModel     (NULL)
	, m_pTabCtrl   (NULL)
	, m_pFindDialog(NULL)
{
	m_pTabCtrl = new RDOEditorTabCtrl(this, this);

	PTR(QVBoxLayout) pLayout = new QVBoxLayout(this);
	pLayout->setSpacing(0);
	pLayout->setContentsMargins(0, 0, 0, 0);
	pLayout->addWidget(m_pTabCtrl);

	RDOStudioMainFrame* pMainWindow = studioApp.getMainWndUI();
	ASSERT(pMainWindow);
	pMainWindow->actSearchFindInModel->setEnabled(true);
	connect(pMainWindow->actSearchFindInModel, SIGNAL(triggered(bool)), this, SLOT(onSearchFindInModel()));
}

RDOStudioModelView::~RDOStudioModelView()
{
	RDOStudioMainFrame* pMainWindow = studioApp.getMainWndUI();
	ASSERT(pMainWindow);
	disconnect(pMainWindow->actSearchFindInModel, SIGNAL(triggered(bool)), this, SLOT(onSearchFindInModel()));
}

void RDOStudioModelView::setModel(PTR(RDOStudioModel) pModel)
{
	ASSERT(m_pModel != pModel);
	m_pModel = pModel;
}

void RDOStudioModelView::closeEvent(PTR(QCloseEvent) event)
{
	if (m_pModel)
	{
		if (m_pModel->closeModel())
		{
			event->accept();
		}
		else
		{
			event->ignore();
		}
	}
}

//! @todo qt
//BOOL RDOStudioModelView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
//{
//	if ( m_pTabCtrl->getCurrentEdit()->OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE;
//	return RDOStudioEditBaseView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
//}
//
//void RDOStudioModelView::OnSetFocus(CWnd* pOldWnd)
//{
//	RDOStudioEditBaseView::OnSetFocus( pOldWnd );
//	m_pTabCtrl->SetFocus();
//}
//

REF(rdoEditor::RDOEditorTabCtrl) RDOStudioModelView::getTab()
{
	return *m_pTabCtrl;
}

void RDOStudioModelView::onSearchFindInModel()
{
	m_findSettings.what = m_pTabCtrl->getCurrentEdit()->getWordForFind();

	if (!m_pFindDialog)
	{
		m_pFindDialog = new FindDialog(
			this,
			boost::bind(&RDOStudioModelView::onFindDlgFind, this, _1),
			boost::bind(&RDOStudioModelView::onFindDlgClose, this)
		);
	}

	m_pFindDialog->setSettings(m_findSettings);
	m_pFindDialog->show();
	m_pFindDialog->raise();
	m_pFindDialog->activateWindow();
}

void RDOStudioModelView::onFindDlgFind(CREF(FindDialog::Settings) settings)
{
	m_findSettings = settings;
	onSearchFindAll();
}

void RDOStudioModelView::onFindDlgClose()
{
	m_pFindDialog = NULL;
}

void RDOStudioModelView::onSearchFindAll()
{
	studioApp.getIMainWnd()->getDockFind().clear();
	studioApp.getIMainWnd()->getDockFind().raise();
	tstring findStr       = m_findSettings.what;
	rbool bMatchCase      = m_findSettings.matchCase;
	rbool bMatchWholeWord = m_findSettings.matchWholeWord;
	studioApp.getIMainWnd()->getDockFind().getContext().setKeyword(findStr, bMatchCase);
	studioApp.getIMainWnd()->getDockFind().appendString(rdo::format(ID_FINDINMODEL_BEGINMSG, findStr.c_str()));
	int count = 0;
	for (int i = 0; i < m_pTabCtrl->count(); i++)
	{
		PTR(RDOEditorEdit) pEdit = m_pTabCtrl->getItemEdit(i);
		int pos  = 0;
		int line = 0;
		while (pos != -1)
		{
			pos = pEdit->findPos(findStr, line, bMatchCase, bMatchWholeWord);
			if (pos != -1)
			{
				line = pEdit->getLineFromPosition(pos);
				studioApp.getIMainWnd()->getDockFind().appendString(pEdit->getLine(line), m_pTabCtrl->indexToType(i), line, pos - pEdit->getPositionFromLine(line));
				line++;
				count++;
			}
		}
	}
	m_pFindDialog = NULL;
	tstring s = count
		? rdo::format(ID_FINDINMODEL_ENDMSG_COUNT,    count)
		: rdo::format(ID_FINDINMODEL_ENDMSG_NOTFOUND, findStr.c_str());
	studioApp.getIMainWnd()->getDockFind().appendString(s);
}<|endoftext|>


<commit_before>/*******************************************************************************
 * ALMA - Atacama Large Millimiter Array
 * (c) European Southern Observatory, 2011
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 * "@(#) $Id: bulkDataNTReaderListener.cpp,v 1.34 2011/12/22 15:59:57 bjeram Exp $"
 *
 * who       when      what
 * --------  --------  ----------------------------------------------
 * bjeram  2011-04-19  created
 */

#include "bulkDataNTReaderListener.h"
#include "ACS_BD_Errors.h"
#include <ACS_DDS_Errors.h>
#include <ACSErrTypeCommon.h>
#include <iostream>
#include <iterator>

using namespace ACS_BD_Errors;
using namespace ACS_DDS_Errors;
using namespace AcsBulkdata;
using namespace std;

#define BDNT_READER_LISTENER_USER_ERR(call)		 								\
    try { call; 																	\
    }catch(const ACSErr::ACSbaseExImpl &ex){										\
        UserCallbackErrorCompletion ucb(ex, __FILE__, __LINE__, __FUNCTION__);		\
        ucb.setCall("#call");														\
        callback_mp->onError(ucb);													\
    }catch(const std::exception &stdex){											\
        ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);  \
        ex.setWhat(stdex.what());													\
        UserCallbackErrorCompletion ucb(ex, __FILE__, __LINE__, __FUNCTION__);		\
        ucb.setCall("#call");														\
        callback_mp->onError(ucb);													\
    }catch(...){																	\
        ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);   	\
        UserCallbackErrorCompletion ucb(ex, __FILE__, __LINE__, __FUNCTION__);		\
        ucb.setCall("#call");														\
        callback_mp->onError(ucb);													\
    }

BulkDataNTReaderListener::BulkDataNTReaderListener(const char* name, BulkDataNTCallback* cb)
: BulkDataNTDDSLoggable("BulkDataNT:"+string(name)),
  currentState_m(StartState),
  topicName_m(name),
  dataLength_m(0),
  frameCounter_m(0),
  totalFrames_m(0),
  callback_mp (cb)
{
  ACS_TRACE(__FUNCTION__);
  nextFrame_m=0;
  frameDataReader_mp=0;
  conseqErrorCount_m=0;
  maxConseqErrorCount_m = 4; //TBD now hardcoded, to be get from somewhere else
  cbReceiveTimeoutSec_m = callback_mp->getCBReceiveProcessTimeout();
}//BulkDataNTReaderListener

BulkDataNTReaderListener::~BulkDataNTReaderListener ()
{
  ACS_TRACE(__FUNCTION__);
}//~BulkDataNTReaderListener

void BulkDataNTReaderListener::on_data_available(DDS::DataReader* reader)
{
  DDS::ReturnCode_t retCode;
  DDS::SampleInfo si ;
  ACSBulkData::BulkDataNTFrame message;
  unsigned char tmpArray[ACSBulkData::FRAME_MAX_LEN];

  initalizeLogging(); //force initialization of logging sys TBD changed

  if (frameDataReader_mp==NULL)
    {
      frameDataReader_mp = ACSBulkData::BulkDataNTFrameDataReader::narrow(reader);
      if  (  frameDataReader_mp==NULL) {
          ACS_DDS_Errors::DDSNarrowFailedCompletion nerr(__FILE__, __LINE__, __FUNCTION__);
          nerr.setVariable("frameDataReader_mp");
          nerr.setNarrowType("ACSBulkData::BulkDataNTFrameDataReader");
          callback_mp->onError(nerr);
          return;
      }//if
    }//if

  message.data.maximum(ACSBulkData::FRAME_MAX_LEN); //TBD constant from
  while (	(retCode = frameDataReader_mp->take_next_sample(message, si)) != DDS::RETCODE_NO_DATA )
    {
      if (retCode == DDS::RETCODE_OK)
        {
          if (si.valid_data == true)
            {
              switch(message.dataType)
              {
              case ACSBulkData::BD_PARAM:
                {
                  cout << topicName_m << " startSend: parameter size: " << message.data.length() << endl;
                  if (currentState_m==StartState || currentState_m==StopState)
                    {
                      dataLength_m = 0;
                      frameCounter_m = 0;
                      currentState_m = DataRcvState;
                      message.data.to_array(tmpArray, message.data.length());
                      BDNT_READER_LISTENER_USER_ERR( callback_mp->cbStart(tmpArray, message.data.length()) )
                      conseqErrorCount_m=0;
                    }
                  else //error
                    {
                      WrongFrameOrderCompletion wfo(__FILE__, __LINE__, __FUNCTION__);
                      wfo.setDataType("BD_PARAM"); wfo.setState(currentState_m);
                      wfo.setFlow(topicName_m.c_str()); wfo.setFrameCount(frameCounter_m);
                      wfo.setTotalFrameCount(totalFrames_m); wfo.setFrameLength(message.data.length());
                      callback_mp->onError(wfo);
                      increasConseqErrorCount();
                    }//if-else
                  break;
                }//	case ACSBulkData::BD_PARAM:
              case ACSBulkData::BD_DATA:
                {
                  if (currentState_m==DataRcvState)
                    {
                      if (dataLength_m==0) // we get the first data frame
                        {
                          std::cout << " *************************   New sendData @ " << topicName_m << " *******************************" << std::endl;
                          start_time = ACE_OS::gettimeofday();
                          totalFrames_m = message.restDataLength+1;
                          frameCounter_m = 0;
                        }//if

                      dataLength_m += message.data.length();
                      frameCounter_m ++;

                      if ( message.restDataLength>0)
                        {
                          if (nextFrame_m!=0 && nextFrame_m!=message.restDataLength) // do we miss a frame ?
                            {
                              FrameLostCompletion lde(__FILE__, __LINE__, __FUNCTION__);
                              lde.setNextDataFrame(nextFrame_m);
                              lde.setFrameCount(frameCounter_m);
                              lde.setRestFrames(message.restDataLength);
                              lde.setFrameLength(message.data.length());
                              lde.setFlow(topicName_m.c_str());
                              callback_mp->onError(lde);
                              increasConseqErrorCount();
                              return; // ??
                            }
                          nextFrame_m = message.restDataLength-1;
                        }
                      else //message.restDataLength==0 what means we got the last frame
                        {
                          ACE_Time_Value elapsed_time = ACE_OS::gettimeofday() - start_time;
                          cout <<	topicName_m << " Received all data from sendData: " << dataLength_m << " Bytes in ";
                          cout <<(elapsed_time.sec()+( elapsed_time.usec() / 1000000.0 ));
                          cout << "secs. => Rate: ";
                          cout << ((dataLength_m/(1024.0*1024.0))/(elapsed_time.sec()+( elapsed_time.usec() / 1000000.0 ))) << "MBytes/sec" << endl;

                          DDS::SampleLostStatus s;
                          reader->get_sample_lost_status(s);
                          cerr << topicName_m << " LOST samples: \t\t total_count: " << s.total_count << " total_count_change: " << s.total_count_change << endl;
                          dataLength_m = 0;
                        }

                      cbReceiveStartTime_m = ACE_OS::gettimeofday();
                      message.data.to_array(tmpArray, message.data.length());
                      BDNT_READER_LISTENER_USER_ERR( callback_mp->cbReceive(tmpArray, message.data.length()) )
                      conseqErrorCount_m=0;
                      cbReceiveElapsedTime_m = ACE_OS::gettimeofday() - cbReceiveStartTime_m;
                      cbReceiveElapsedTimeSec_m = cbReceiveElapsedTime_m.sec() + (cbReceiveElapsedTime_m.usec() / 1000000.0);
                      if (cbReceiveElapsedTimeSec_m>cbReceiveTimeoutSec_m)
                      {
                    	  CBReceiveProcessTimeoutCompletion cbReceiveTO(__FILE__, __LINE__, __FUNCTION__);
                    	  cbReceiveTO.setProcessTimeoutSec(cbReceiveTimeoutSec_m);
                    	  cbReceiveTO.setActaullProcessTime(cbReceiveElapsedTimeSec_m);
                    	  callback_mp->onError(cbReceiveTO);
                    	  //TBD should we increase error counter here or not ?
                      }//if cbReceiveTimeoutSec_m
                    }
                  else //error
                    {
                      WrongFrameOrderCompletion wfo(__FILE__, __LINE__, __FUNCTION__);
                      wfo.setDataType("BD_DATA"); wfo.setState(currentState_m);
                      wfo.setFlow(topicName_m.c_str()); wfo.setFrameCount(frameCounter_m);
                      wfo.setTotalFrameCount(totalFrames_m); wfo.setFrameLength(message.data.length());
                      callback_mp->onError(wfo);
                      increasConseqErrorCount();
                    }
                  break;
                }//case ACSBulkData::BD_DATA
              case ACSBulkData::BD_STOP:
                {
                  if (currentState_m==DataRcvState)
                    {
                      currentState_m = StopState;
                      cout <<	topicName_m << " Received sendStop" << endl;
                      cout << "===============================================================" << endl;
                      if (frameCounter_m==0)
                        {
                          ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
                              (LM_WARNING, "On %s got stop (BD_STOP) before any data (sendData)!",
                                  topicName_m.c_str()));
                        }else
                          {
                            if (frameCounter_m != totalFrames_m)
                              {
                                ACS_BD_Errors::FrameLostCompletion lde(__FILE__, __LINE__, __FUNCTION__);
                                lde.setNextDataFrame(nextFrame_m);
                                lde.setFrameCount(frameCounter_m);
                                lde.setRestFrames(message.restDataLength); // should be ??
                                lde.setFrameLength(message.data.length()); // should be 0
                                lde.setFlow(topicName_m.c_str());
                                callback_mp->onError(lde);
                                increasConseqErrorCount();
                              }//if
                          }//if-else
                    }else
                      {
                        if (currentState_m==StopState)
                          {
                            ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
                                (LM_WARNING, "On %s stop (BD_STOP) arrived in stop state - will be ignored!",
                                    topicName_m.c_str()));
                          }
                        else //StartState
                          {
                            ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
                                (LM_WARNING, "On %s stop (BD_STOP) arrived in start state: no parameter data (startSend) has arrived!",
                                    topicName_m.c_str()));
                          }//if-else
                      }
                  // in all above warning/error case we call  user's cbStop()
                  BDNT_READER_LISTENER_USER_ERR( callback_mp->cbStop() )
                  conseqErrorCount_m=0;
                  break;
                }//case ACSBulkData::BD_STOP
              default:
                conseqErrorCount_m++;
                UnknownDataTypeCompletion udt(__FILE__, __LINE__, __FUNCTION__);
                udt.setDataType(message.dataType);
                udt.setFrameCount(frameCounter_m);
                udt.setTotalFrameCount(totalFrames_m);
                callback_mp->onError(udt);
              }//switch
            }//if(si.valid_data)
        }
      else
        {
          conseqErrorCount_m++;
          DDSReturnErrorCompletion retErr(__FILE__, __LINE__, __FUNCTION__);
          retErr.setRetCode(retCode);  //would be good if we can give also string value
          callback_mp->onError(retErr);
        }//if(retCode)
    }//while
}//on_data_available

void BulkDataNTReaderListener::on_requested_deadline_missed(DDS::DataReader*, const DDS::RequestedDeadlineMissedStatus& )
{
  ACS_DDS_Errors::DDSDeadlineMissedCompletion dmerr(__FILE__, __LINE__, __FUNCTION__);
  initalizeLogging(); //force initialization of logging sys TBD changed
  callback_mp->onError(dmerr);
}//on_requested_deadline_missed

void BulkDataNTReaderListener::on_requested_incompatible_qos(DDS::DataReader*, const DDS::RequestedIncompatibleQosStatus&)
{
  ACS_DDS_Errors::DDSIncompatibleQoSCompletion iqerr(__FILE__, __LINE__, __FUNCTION__);
  initalizeLogging(); //force initialization of logging sys TBD changed
  callback_mp->onError(iqerr);
}//on_requested_incompatible_qos

void BulkDataNTReaderListener::on_liveliness_changed(DDS::DataReader*, const DDS::LivelinessChangedStatus& lcs)
{
  if (lcs.alive_count_change>0)
    {
      for(int i=0; i<lcs.alive_count_change; i++)
        {
          ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
              (LM_INFO, "A new sender has connected to flow: %s of the stream: %s. Total alive connection(s): %d",
                  callback_mp->getFlowName(), callback_mp->getStreamName(),
                  lcs.alive_count));
          BDNT_READER_LISTENER_USER_ERR( callback_mp->onSenderConnect() )
        }//for
    }else
      {
        for(int i=lcs.alive_count_change; i<0; i++)
          {
            ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
                (LM_INFO, "A sender has disconnected to flow: %s of the stream: %s. Total alive connection(s): %d",
                    callback_mp->getFlowName(), callback_mp->getStreamName(),
                    lcs.alive_count));
            BDNT_READER_LISTENER_USER_ERR( callback_mp->onSenderDisconnect() )
          }//for
      }//if-else
}//on_liveliness_changed

void BulkDataNTReaderListener::on_subscription_matched(DDS::DataReader*, const DDS::SubscriptionMatchedStatus&)
{
  ACS_TRACE(__FUNCTION__);
}//on_subscription_matched

void BulkDataNTReaderListener::on_sample_rejected( DDS::DataReader*, const DDS::SampleRejectedStatus& srs)
{
  ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
      (LM_WARNING, "Sample Rejected: reason %d, change: %d, total: %d!",
          srs.last_reason, srs.total_count_change, srs.total_count));
}//on_sample_rejected

void BulkDataNTReaderListener::on_sample_lost(DDS::DataReader*, const DDS::SampleLostStatus& s)
{
  ACS_BD_Errors::SampleLostCompletion sle(__FILE__, __LINE__, __FUNCTION__);
  sle.setLostSamples(s.total_count_change);
  sle.setNextDataFrame(nextFrame_m);
  sle.setFrameCount(frameCounter_m);
  sle.setFlow(topicName_m.c_str());
  initalizeLogging(); //force initialization of logging sys TBD changed
  callback_mp->onError(sle);
}//on_sample_lost

void BulkDataNTReaderListener::increasConseqErrorCount()
{
  conseqErrorCount_m++;
  if (conseqErrorCount_m>=maxConseqErrorCount_m)
    {

      ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
          (LM_ALERT, "Too many consequent errors: %d/%d on %s",
              conseqErrorCount_m, maxConseqErrorCount_m, topicName_m.c_str()));
      //TBD: disconnect
    }
}//increasConseqErroCount

<commit_msg>set FlowName to CBReceiveProcessTimeoutCompletion<commit_after>/*******************************************************************************
 * ALMA - Atacama Large Millimiter Array
 * (c) European Southern Observatory, 2011
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 * "@(#) $Id: bulkDataNTReaderListener.cpp,v 1.35 2011/12/22 16:05:45 bjeram Exp $"
 *
 * who       when      what
 * --------  --------  ----------------------------------------------
 * bjeram  2011-04-19  created
 */

#include "bulkDataNTReaderListener.h"
#include "ACS_BD_Errors.h"
#include <ACS_DDS_Errors.h>
#include <ACSErrTypeCommon.h>
#include <iostream>
#include <iterator>

using namespace ACS_BD_Errors;
using namespace ACS_DDS_Errors;
using namespace AcsBulkdata;
using namespace std;

#define BDNT_READER_LISTENER_USER_ERR(call)		 								\
    try { call; 																	\
    }catch(const ACSErr::ACSbaseExImpl &ex){										\
        UserCallbackErrorCompletion ucb(ex, __FILE__, __LINE__, __FUNCTION__);		\
        ucb.setCall("#call");														\
        callback_mp->onError(ucb);													\
    }catch(const std::exception &stdex){											\
        ACSErrTypeCommon::StdExceptionExImpl ex(__FILE__, __LINE__, __FUNCTION__);  \
        ex.setWhat(stdex.what());													\
        UserCallbackErrorCompletion ucb(ex, __FILE__, __LINE__, __FUNCTION__);		\
        ucb.setCall("#call");														\
        callback_mp->onError(ucb);													\
    }catch(...){																	\
        ACSErrTypeCommon::UnknownExImpl ex(__FILE__, __LINE__, __FUNCTION__);   	\
        UserCallbackErrorCompletion ucb(ex, __FILE__, __LINE__, __FUNCTION__);		\
        ucb.setCall("#call");														\
        callback_mp->onError(ucb);													\
    }

BulkDataNTReaderListener::BulkDataNTReaderListener(const char* name, BulkDataNTCallback* cb)
: BulkDataNTDDSLoggable("BulkDataNT:"+string(name)),
  currentState_m(StartState),
  topicName_m(name),
  dataLength_m(0),
  frameCounter_m(0),
  totalFrames_m(0),
  callback_mp (cb)
{
  ACS_TRACE(__FUNCTION__);
  nextFrame_m=0;
  frameDataReader_mp=0;
  conseqErrorCount_m=0;
  maxConseqErrorCount_m = 4; //TBD now hardcoded, to be get from somewhere else
  cbReceiveTimeoutSec_m = callback_mp->getCBReceiveProcessTimeout();
}//BulkDataNTReaderListener

BulkDataNTReaderListener::~BulkDataNTReaderListener ()
{
  ACS_TRACE(__FUNCTION__);
}//~BulkDataNTReaderListener

void BulkDataNTReaderListener::on_data_available(DDS::DataReader* reader)
{
  DDS::ReturnCode_t retCode;
  DDS::SampleInfo si ;
  ACSBulkData::BulkDataNTFrame message;
  unsigned char tmpArray[ACSBulkData::FRAME_MAX_LEN];

  initalizeLogging(); //force initialization of logging sys TBD changed

  if (frameDataReader_mp==NULL)
    {
      frameDataReader_mp = ACSBulkData::BulkDataNTFrameDataReader::narrow(reader);
      if  (  frameDataReader_mp==NULL) {
          ACS_DDS_Errors::DDSNarrowFailedCompletion nerr(__FILE__, __LINE__, __FUNCTION__);
          nerr.setVariable("frameDataReader_mp");
          nerr.setNarrowType("ACSBulkData::BulkDataNTFrameDataReader");
          callback_mp->onError(nerr);
          return;
      }//if
    }//if

  message.data.maximum(ACSBulkData::FRAME_MAX_LEN); //TBD constant from
  while (	(retCode = frameDataReader_mp->take_next_sample(message, si)) != DDS::RETCODE_NO_DATA )
    {
      if (retCode == DDS::RETCODE_OK)
        {
          if (si.valid_data == true)
            {
              switch(message.dataType)
              {
              case ACSBulkData::BD_PARAM:
                {
                  cout << topicName_m << " startSend: parameter size: " << message.data.length() << endl;
                  if (currentState_m==StartState || currentState_m==StopState)
                    {
                      dataLength_m = 0;
                      frameCounter_m = 0;
                      currentState_m = DataRcvState;
                      message.data.to_array(tmpArray, message.data.length());
                      BDNT_READER_LISTENER_USER_ERR( callback_mp->cbStart(tmpArray, message.data.length()) )
                      conseqErrorCount_m=0;
                    }
                  else //error
                    {
                      WrongFrameOrderCompletion wfo(__FILE__, __LINE__, __FUNCTION__);
                      wfo.setDataType("BD_PARAM"); wfo.setState(currentState_m);
                      wfo.setFlow(topicName_m.c_str()); wfo.setFrameCount(frameCounter_m);
                      wfo.setTotalFrameCount(totalFrames_m); wfo.setFrameLength(message.data.length());
                      callback_mp->onError(wfo);
                      increasConseqErrorCount();
                    }//if-else
                  break;
                }//	case ACSBulkData::BD_PARAM:
              case ACSBulkData::BD_DATA:
                {
                  if (currentState_m==DataRcvState)
                    {
                      if (dataLength_m==0) // we get the first data frame
                        {
                          std::cout << " *************************   New sendData @ " << topicName_m << " *******************************" << std::endl;
                          start_time = ACE_OS::gettimeofday();
                          totalFrames_m = message.restDataLength+1;
                          frameCounter_m = 0;
                        }//if

                      dataLength_m += message.data.length();
                      frameCounter_m ++;

                      if ( message.restDataLength>0)
                        {
                          if (nextFrame_m!=0 && nextFrame_m!=message.restDataLength) // do we miss a frame ?
                            {
                              FrameLostCompletion lde(__FILE__, __LINE__, __FUNCTION__);
                              lde.setNextDataFrame(nextFrame_m);
                              lde.setFrameCount(frameCounter_m);
                              lde.setRestFrames(message.restDataLength);
                              lde.setFrameLength(message.data.length());
                              lde.setFlow(topicName_m.c_str());
                              callback_mp->onError(lde);
                              increasConseqErrorCount();
                              return; // ??
                            }
                          nextFrame_m = message.restDataLength-1;
                        }
                      else //message.restDataLength==0 what means we got the last frame
                        {
                          ACE_Time_Value elapsed_time = ACE_OS::gettimeofday() - start_time;
                          cout <<	topicName_m << " Received all data from sendData: " << dataLength_m << " Bytes in ";
                          cout <<(elapsed_time.sec()+( elapsed_time.usec() / 1000000.0 ));
                          cout << "secs. => Rate: ";
                          cout << ((dataLength_m/(1024.0*1024.0))/(elapsed_time.sec()+( elapsed_time.usec() / 1000000.0 ))) << "MBytes/sec" << endl;

                          DDS::SampleLostStatus s;
                          reader->get_sample_lost_status(s);
                          cerr << topicName_m << " LOST samples: \t\t total_count: " << s.total_count << " total_count_change: " << s.total_count_change << endl;
                          dataLength_m = 0;
                        }

                      cbReceiveStartTime_m = ACE_OS::gettimeofday();
                      message.data.to_array(tmpArray, message.data.length());
                      BDNT_READER_LISTENER_USER_ERR( callback_mp->cbReceive(tmpArray, message.data.length()) )
                      conseqErrorCount_m=0;
                      cbReceiveElapsedTime_m = ACE_OS::gettimeofday() - cbReceiveStartTime_m;
                      cbReceiveElapsedTimeSec_m = cbReceiveElapsedTime_m.sec() + (cbReceiveElapsedTime_m.usec() / 1000000.0);
                      if (cbReceiveElapsedTimeSec_m>cbReceiveTimeoutSec_m)
                      {
                    	  CBReceiveProcessTimeoutCompletion cbReceiveTO(__FILE__, __LINE__, __FUNCTION__);
                    	  cbReceiveTO.setFlowName(topicName_m.c_str());
                    	  cbReceiveTO.setProcessTimeoutSec(cbReceiveTimeoutSec_m);
                    	  cbReceiveTO.setActaullProcessTime(cbReceiveElapsedTimeSec_m);
                    	  callback_mp->onError(cbReceiveTO);
                    	  //TBD should we increase error counter here or not ?
                      }//if cbReceiveTimeoutSec_m
                    }
                  else //error
                    {
                      WrongFrameOrderCompletion wfo(__FILE__, __LINE__, __FUNCTION__);
                      wfo.setDataType("BD_DATA"); wfo.setState(currentState_m);
                      wfo.setFlow(topicName_m.c_str()); wfo.setFrameCount(frameCounter_m);
                      wfo.setTotalFrameCount(totalFrames_m); wfo.setFrameLength(message.data.length());
                      callback_mp->onError(wfo);
                      increasConseqErrorCount();
                    }
                  break;
                }//case ACSBulkData::BD_DATA
              case ACSBulkData::BD_STOP:
                {
                  if (currentState_m==DataRcvState)
                    {
                      currentState_m = StopState;
                      cout <<	topicName_m << " Received sendStop" << endl;
                      cout << "===============================================================" << endl;
                      if (frameCounter_m==0)
                        {
                          ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
                              (LM_WARNING, "On %s got stop (BD_STOP) before any data (sendData)!",
                                  topicName_m.c_str()));
                        }else
                          {
                            if (frameCounter_m != totalFrames_m)
                              {
                                ACS_BD_Errors::FrameLostCompletion lde(__FILE__, __LINE__, __FUNCTION__);
                                lde.setNextDataFrame(nextFrame_m);
                                lde.setFrameCount(frameCounter_m);
                                lde.setRestFrames(message.restDataLength); // should be ??
                                lde.setFrameLength(message.data.length()); // should be 0
                                lde.setFlow(topicName_m.c_str());
                                callback_mp->onError(lde);
                                increasConseqErrorCount();
                              }//if
                          }//if-else
                    }else
                      {
                        if (currentState_m==StopState)
                          {
                            ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
                                (LM_WARNING, "On %s stop (BD_STOP) arrived in stop state - will be ignored!",
                                    topicName_m.c_str()));
                          }
                        else //StartState
                          {
                            ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
                                (LM_WARNING, "On %s stop (BD_STOP) arrived in start state: no parameter data (startSend) has arrived!",
                                    topicName_m.c_str()));
                          }//if-else
                      }
                  // in all above warning/error case we call  user's cbStop()
                  BDNT_READER_LISTENER_USER_ERR( callback_mp->cbStop() )
                  conseqErrorCount_m=0;
                  break;
                }//case ACSBulkData::BD_STOP
              default:
                conseqErrorCount_m++;
                UnknownDataTypeCompletion udt(__FILE__, __LINE__, __FUNCTION__);
                udt.setDataType(message.dataType);
                udt.setFrameCount(frameCounter_m);
                udt.setTotalFrameCount(totalFrames_m);
                callback_mp->onError(udt);
              }//switch
            }//if(si.valid_data)
        }
      else
        {
          conseqErrorCount_m++;
          DDSReturnErrorCompletion retErr(__FILE__, __LINE__, __FUNCTION__);
          retErr.setRetCode(retCode);  //would be good if we can give also string value
          callback_mp->onError(retErr);
        }//if(retCode)
    }//while
}//on_data_available

void BulkDataNTReaderListener::on_requested_deadline_missed(DDS::DataReader*, const DDS::RequestedDeadlineMissedStatus& )
{
  ACS_DDS_Errors::DDSDeadlineMissedCompletion dmerr(__FILE__, __LINE__, __FUNCTION__);
  initalizeLogging(); //force initialization of logging sys TBD changed
  callback_mp->onError(dmerr);
}//on_requested_deadline_missed

void BulkDataNTReaderListener::on_requested_incompatible_qos(DDS::DataReader*, const DDS::RequestedIncompatibleQosStatus&)
{
  ACS_DDS_Errors::DDSIncompatibleQoSCompletion iqerr(__FILE__, __LINE__, __FUNCTION__);
  initalizeLogging(); //force initialization of logging sys TBD changed
  callback_mp->onError(iqerr);
}//on_requested_incompatible_qos

void BulkDataNTReaderListener::on_liveliness_changed(DDS::DataReader*, const DDS::LivelinessChangedStatus& lcs)
{
  if (lcs.alive_count_change>0)
    {
      for(int i=0; i<lcs.alive_count_change; i++)
        {
          ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
              (LM_INFO, "A new sender has connected to flow: %s of the stream: %s. Total alive connection(s): %d",
                  callback_mp->getFlowName(), callback_mp->getStreamName(),
                  lcs.alive_count));
          BDNT_READER_LISTENER_USER_ERR( callback_mp->onSenderConnect() )
        }//for
    }else
      {
        for(int i=lcs.alive_count_change; i<0; i++)
          {
            ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
                (LM_INFO, "A sender has disconnected to flow: %s of the stream: %s. Total alive connection(s): %d",
                    callback_mp->getFlowName(), callback_mp->getStreamName(),
                    lcs.alive_count));
            BDNT_READER_LISTENER_USER_ERR( callback_mp->onSenderDisconnect() )
          }//for
      }//if-else
}//on_liveliness_changed

void BulkDataNTReaderListener::on_subscription_matched(DDS::DataReader*, const DDS::SubscriptionMatchedStatus&)
{
  ACS_TRACE(__FUNCTION__);
}//on_subscription_matched

void BulkDataNTReaderListener::on_sample_rejected( DDS::DataReader*, const DDS::SampleRejectedStatus& srs)
{
  ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
      (LM_WARNING, "Sample Rejected: reason %d, change: %d, total: %d!",
          srs.last_reason, srs.total_count_change, srs.total_count));
}//on_sample_rejected

void BulkDataNTReaderListener::on_sample_lost(DDS::DataReader*, const DDS::SampleLostStatus& s)
{
  ACS_BD_Errors::SampleLostCompletion sle(__FILE__, __LINE__, __FUNCTION__);
  sle.setLostSamples(s.total_count_change);
  sle.setNextDataFrame(nextFrame_m);
  sle.setFrameCount(frameCounter_m);
  sle.setFlow(topicName_m.c_str());
  initalizeLogging(); //force initialization of logging sys TBD changed
  callback_mp->onError(sle);
}//on_sample_lost

void BulkDataNTReaderListener::increasConseqErrorCount()
{
  conseqErrorCount_m++;
  if (conseqErrorCount_m>=maxConseqErrorCount_m)
    {

      ACS_LOG(LM_RUNTIME_CONTEXT, __FUNCTION__,
          (LM_ALERT, "Too many consequent errors: %d/%d on %s",
              conseqErrorCount_m, maxConseqErrorCount_m, topicName_m.c_str()));
      //TBD: disconnect
    }
}//increasConseqErroCount

<|endoftext|>


<commit_before><commit_msg>Update DepthBuffer.cpp<commit_after><|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2017.  All rights reserved
 */
#include "../StroikaPreComp.h"

#include "../IO/FileAccessException.h"

#include "Exceptions.h"

#include "ErrNoException.h"

using namespace Stroika;
using namespace Stroika::Foundation;

using namespace Characters;
using namespace Execution;

using Debug::TraceContextBumper;

/*
 ********************************************************************************
 ***************************** errno_ErrorException *****************************
 ********************************************************************************
 */
errno_ErrorException::errno_ErrorException (Execution::errno_t e)
    : StringException (SDKString2Wide (LookupMessage (e)))
    , fError (e)
{
}

SDKString errno_ErrorException::LookupMessage (Execution::errno_t e)
{
    SDKString justErrnoNumberMessage;
    {
        SDKChar justNumBuf[2048];
        justNumBuf[0] = '\0';
#if qPlatform_Windows
        (void)::_stprintf_s (justNumBuf, SDKSTR ("errno: %d"), e);
#else
        (void)::snprintf (justNumBuf, NEltsOf (justNumBuf), SDKSTR ("errno: %d"), e);
#endif
        justErrnoNumberMessage = justNumBuf;
    }
    SDKChar buf[2048];
    buf[0] = '\0';
#if qPlatform_Windows
    if (::_tcserror_s (buf, e) == 0) {
        return buf + SDKString (SDKSTR (" (") + justErrnoNumberMessage + SDKSTR (")"));
    }
#elif qPlatform_POSIX
/*
     * A bit quirky - gcc and POSIX handle this API fairly differently.
     * https://linux.die.net/man/3/strerror_r - in one case returns int and 0 means worked, and other case 0 means didnt work
     */
#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE
    // The XSI-compliant strerror_r() function returns 0 on success
    if (::strerror_r (e, buf, NEltsOf (buf)) == 0) {
        return buf + SDKString (SDKSTR (" (") + justErrnoNumberMessage + SDKSTR (")"));
    }
#else
    // The strerror() and the GNU-specific strerror_r() functions return the appropriate error description string
    (void)::strerror_r (e, buf, NEltsOf (buf));
    return buf + SDKString (SDKSTR (" (") + justErrnoNumberMessage + SDKSTR (")"));
#endif
#else
    AssertNotImplemented ();
#endif
    return justErrnoNumberMessage;
}

[[noreturn]] void errno_ErrorException::Throw (Execution::errno_t error)
{
    //REVIEW EXCPETIONS ANMD MPAPING - THIS IS NOT GOOD - NOT EVEN CLOSE!!! -- LGP 2011-09-29
    switch (error) {
        case ENOMEM: {
            Execution::Throw (bad_alloc (), "errno_ErrorException::Throw (ENOMEM) - throwing bad_alloc");
        }
        case ENOENT: {
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
        case EACCES: {
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
// If I decide to pursue mapping, this maybe a good place to start
//  http://aplawrence.com/Unixart/errors.html
//      -- LGP 2009-01-02
#if 0
        case    EPERM: {
                // not sure any point in this unification. Maybe if I added my OWN private 'access denied' exception
                // the mapping/unification would make sense.
                //      -- LGP 2009-01-02
                DbgTrace ("errno_ErrorException::Throw (EPERM) - throwing ERROR_ACCESS_DENIED");
                throw Win32Exception (ERROR_ACCESS_DENIED);
            }
#endif
    }
    DbgTrace (L"errno_ErrorException::Throw (%d) - throwing errno_ErrorException '%s'", error, SDKString2Wide (LookupMessage (error)).c_str ());
    throw errno_ErrorException (error);
}
<commit_msg>fixed another bug with Execution/ErrNoException - using GNU verison of strerror_r<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2017.  All rights reserved
 */
#include "../StroikaPreComp.h"

#include "../IO/FileAccessException.h"

#include "Exceptions.h"

#include "ErrNoException.h"

using namespace Stroika;
using namespace Stroika::Foundation;

using namespace Characters;
using namespace Execution;

using Debug::TraceContextBumper;

/*
 ********************************************************************************
 ***************************** errno_ErrorException *****************************
 ********************************************************************************
 */
errno_ErrorException::errno_ErrorException (Execution::errno_t e)
    : StringException (SDKString2Wide (LookupMessage (e)))
    , fError (e)
{
}

SDKString errno_ErrorException::LookupMessage (Execution::errno_t e)
{
    SDKString justErrnoNumberMessage;
    {
        SDKChar justNumBuf[2048];
        justNumBuf[0] = '\0';
#if qPlatform_Windows
        (void)::_stprintf_s (justNumBuf, SDKSTR ("errno: %d"), e);
#else
        (void)::snprintf (justNumBuf, NEltsOf (justNumBuf), SDKSTR ("errno: %d"), e);
#endif
        justErrnoNumberMessage = justNumBuf;
    }
    SDKChar buf[2048];
    buf[0] = '\0';
#if qPlatform_Windows
    if (::_tcserror_s (buf, e) == 0) {
        return buf + SDKString (SDKSTR (" (") + justErrnoNumberMessage + SDKSTR (")"));
    }
#elif qPlatform_POSIX
/*
     * A bit quirky - gcc and POSIX handle this API fairly differently.
     * https://linux.die.net/man/3/strerror_r - in one case returns int and 0 means worked, and other case 0 means didnt work
     */
#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE
    // The XSI-compliant strerror_r() function returns 0 on success
    if (::strerror_r (e, buf, NEltsOf (buf)) == 0) {
        return buf + SDKString (SDKSTR (" (") + justErrnoNumberMessage + SDKSTR (")"));
    }
#else
    // the GNU-specific strerror_r() functions return the appropriate error description string
    return ::strerror_r (e, buf, NEltsOf (buf)) + SDKString (SDKSTR (" (") + justErrnoNumberMessage + SDKSTR (")"));
#endif
#else
    AssertNotImplemented ();
#endif
    return justErrnoNumberMessage;
}

[[noreturn]] void errno_ErrorException::Throw (Execution::errno_t error)
{
    //REVIEW EXCPETIONS ANMD MPAPING - THIS IS NOT GOOD - NOT EVEN CLOSE!!! -- LGP 2011-09-29
    switch (error) {
        case ENOMEM: {
            Execution::Throw (bad_alloc (), "errno_ErrorException::Throw (ENOMEM) - throwing bad_alloc");
        }
        case ENOENT: {
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
        case EACCES: {
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
// If I decide to pursue mapping, this maybe a good place to start
//  http://aplawrence.com/Unixart/errors.html
//      -- LGP 2009-01-02
#if 0
        case    EPERM: {
                // not sure any point in this unification. Maybe if I added my OWN private 'access denied' exception
                // the mapping/unification would make sense.
                //      -- LGP 2009-01-02
                DbgTrace ("errno_ErrorException::Throw (EPERM) - throwing ERROR_ACCESS_DENIED");
                throw Win32Exception (ERROR_ACCESS_DENIED);
            }
#endif
    }
    DbgTrace (L"errno_ErrorException::Throw (%d) - throwing errno_ErrorException '%s'", error, SDKString2Wide (LookupMessage (error)).c_str ());
    throw errno_ErrorException (error);
}
<|endoftext|>


<commit_before>#include "stan/math/functions/fma.hpp"
#include <gtest/gtest.h>

TEST(MathFunctions, fma) {
  using stan::math::fma;

  EXPECT_FLOAT_EQ(5.0, fma(1.0,2.0,3.0));
  EXPECT_FLOAT_EQ(10.0, fma(2.0,3.0,4.0));
}

<commit_msg>added NaN test for fma<commit_after>#include <stan/math/functions/fma.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <gtest/gtest.h>

TEST(MathFunctions, fma) {
  using stan::math::fma;

  EXPECT_FLOAT_EQ(5.0, fma(1.0,2.0,3.0));
  EXPECT_FLOAT_EQ(10.0, fma(2.0,3.0,4.0));
}

TEST(MathFunctions, fma_nan) {
  double nan = std::numeric_limits<double>::quiet_NaN();

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fma(1.0, 2.0, nan));

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fma(1.0, nan, 3.0));

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fma(1.0, nan, nan));

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fma(nan, 2.0, 3.0));

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fma(nan, 2.0, nan));

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fma(nan, nan, 3.0));

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fma(nan, nan, nan));
}
<|endoftext|>