<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_pipelined_stream.h"

#include "base/logging.h"
#include "base/stringprintf.h"
#include "net/base/net_errors.h"
#include "net/http/http_pipelined_connection_impl.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_request_info.h"
#include "net/http/http_util.h"

namespace net {

HttpPipelinedStream::HttpPipelinedStream(HttpPipelinedConnectionImpl* pipeline,
                                         int pipeline_id)
    : pipeline_(pipeline),
      pipeline_id_(pipeline_id),
      request_info_(NULL) {
}

HttpPipelinedStream::~HttpPipelinedStream() {
  pipeline_->OnStreamDeleted(pipeline_id_);
}

int HttpPipelinedStream::InitializeStream(const HttpRequestInfo* request_info,
                                          const BoundNetLog& net_log,
                                          OldCompletionCallback* callback) {
  request_info_ = request_info;
  pipeline_->InitializeParser(pipeline_id_, request_info, net_log);
  return OK;
}

int HttpPipelinedStream::SendRequest(const HttpRequestHeaders& headers,
                                     UploadDataStream* request_body,
                                     HttpResponseInfo* response,
                                     OldCompletionCallback* callback) {
  CHECK(pipeline_id_);
  CHECK(request_info_);
  // TODO(simonjam): Proxy support will be needed here.
  const std::string path = HttpUtil::PathForRequest(request_info_->url);
  std::string request_line_ = base::StringPrintf("%s %s HTTP/1.1\r\n",
                                                 request_info_->method.c_str(),
                                                 path.c_str());
  return pipeline_->SendRequest(pipeline_id_, request_line_, headers,
                                request_body, response, callback);
}

uint64 HttpPipelinedStream::GetUploadProgress() const {
  return pipeline_->GetUploadProgress(pipeline_id_);
}

int HttpPipelinedStream::ReadResponseHeaders(OldCompletionCallback* callback) {
  return pipeline_->ReadResponseHeaders(pipeline_id_, callback);
}

const HttpResponseInfo* HttpPipelinedStream::GetResponseInfo() const {
  return pipeline_->GetResponseInfo(pipeline_id_);
}

int HttpPipelinedStream::ReadResponseBody(IOBuffer* buf, int buf_len,
                                          OldCompletionCallback* callback) {
  return pipeline_->ReadResponseBody(pipeline_id_, buf, buf_len, callback);
}

void HttpPipelinedStream::Close(bool not_reusable) {
  pipeline_->Close(pipeline_id_, not_reusable);
}

HttpStream* HttpPipelinedStream::RenewStreamForAuth() {
  // FIXME: What does this mean on a pipeline? Is it for proxies?
  return new HttpPipelinedStream(pipeline_, pipeline_id_);
}

bool HttpPipelinedStream::IsResponseBodyComplete() const {
  return pipeline_->IsResponseBodyComplete(pipeline_id_);
}

bool HttpPipelinedStream::CanFindEndOfResponse() const {
  return pipeline_->CanFindEndOfResponse(pipeline_id_);
}

bool HttpPipelinedStream::IsMoreDataBuffered() const {
  return pipeline_->IsMoreDataBuffered(pipeline_id_);
}

bool HttpPipelinedStream::IsConnectionReused() const {
  return pipeline_->IsConnectionReused(pipeline_id_);
}

void HttpPipelinedStream::SetConnectionReused() {
  pipeline_->SetConnectionReused(pipeline_id_);
}

bool HttpPipelinedStream::IsConnectionReusable() const {
  return pipeline_->usable();
}

void HttpPipelinedStream::GetSSLInfo(SSLInfo* ssl_info) {
  pipeline_->GetSSLInfo(pipeline_id_, ssl_info);
}

void HttpPipelinedStream::GetSSLCertRequestInfo(
    SSLCertRequestInfo* cert_request_info) {
  pipeline_->GetSSLCertRequestInfo(pipeline_id_, cert_request_info);
}

bool HttpPipelinedStream::IsSpdyHttpStream() const {
  return false;
}

void HttpPipelinedStream::LogNumRttVsBytesMetrics() const {
  // TODO(simonjam): I don't want to copy & paste this from http_basic_stream.
}

void HttpPipelinedStream::Drain(HttpNetworkSession*) {
  // On errors, we already evict everything from the pipeline and close it.
  // TODO(simonjam): Consider trying to drain the pipeline in the same way that
  // HttpBasicStream does.
  delete this;
}

const SSLConfig& HttpPipelinedStream::used_ssl_config() const {
  return pipeline_->used_ssl_config();
}

const ProxyInfo& HttpPipelinedStream::used_proxy_info() const {
  return pipeline_->used_proxy_info();
}

const NetLog::Source& HttpPipelinedStream::source() const {
  return pipeline_->source();
}

bool HttpPipelinedStream::was_npn_negotiated() const {
  return pipeline_->was_npn_negotiated();
}

}  // namespace net
<commit_msg>Correctly create a new stream when the server requires authentication.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_pipelined_stream.h"

#include "base/logging.h"
#include "base/stringprintf.h"
#include "net/base/net_errors.h"
#include "net/http/http_pipelined_connection_impl.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_request_info.h"
#include "net/http/http_util.h"

namespace net {

HttpPipelinedStream::HttpPipelinedStream(HttpPipelinedConnectionImpl* pipeline,
                                         int pipeline_id)
    : pipeline_(pipeline),
      pipeline_id_(pipeline_id),
      request_info_(NULL) {
}

HttpPipelinedStream::~HttpPipelinedStream() {
  pipeline_->OnStreamDeleted(pipeline_id_);
}

int HttpPipelinedStream::InitializeStream(const HttpRequestInfo* request_info,
                                          const BoundNetLog& net_log,
                                          OldCompletionCallback* callback) {
  request_info_ = request_info;
  pipeline_->InitializeParser(pipeline_id_, request_info, net_log);
  return OK;
}

int HttpPipelinedStream::SendRequest(const HttpRequestHeaders& headers,
                                     UploadDataStream* request_body,
                                     HttpResponseInfo* response,
                                     OldCompletionCallback* callback) {
  CHECK(pipeline_id_);
  CHECK(request_info_);
  // TODO(simonjam): Proxy support will be needed here.
  const std::string path = HttpUtil::PathForRequest(request_info_->url);
  std::string request_line_ = base::StringPrintf("%s %s HTTP/1.1\r\n",
                                                 request_info_->method.c_str(),
                                                 path.c_str());
  return pipeline_->SendRequest(pipeline_id_, request_line_, headers,
                                request_body, response, callback);
}

uint64 HttpPipelinedStream::GetUploadProgress() const {
  return pipeline_->GetUploadProgress(pipeline_id_);
}

int HttpPipelinedStream::ReadResponseHeaders(OldCompletionCallback* callback) {
  return pipeline_->ReadResponseHeaders(pipeline_id_, callback);
}

const HttpResponseInfo* HttpPipelinedStream::GetResponseInfo() const {
  return pipeline_->GetResponseInfo(pipeline_id_);
}

int HttpPipelinedStream::ReadResponseBody(IOBuffer* buf, int buf_len,
                                          OldCompletionCallback* callback) {
  return pipeline_->ReadResponseBody(pipeline_id_, buf, buf_len, callback);
}

void HttpPipelinedStream::Close(bool not_reusable) {
  pipeline_->Close(pipeline_id_, not_reusable);
}

HttpStream* HttpPipelinedStream::RenewStreamForAuth() {
  if (pipeline_->usable()) {
    return pipeline_->CreateNewStream();
  }
  return NULL;
}

bool HttpPipelinedStream::IsResponseBodyComplete() const {
  return pipeline_->IsResponseBodyComplete(pipeline_id_);
}

bool HttpPipelinedStream::CanFindEndOfResponse() const {
  return pipeline_->CanFindEndOfResponse(pipeline_id_);
}

bool HttpPipelinedStream::IsMoreDataBuffered() const {
  return pipeline_->IsMoreDataBuffered(pipeline_id_);
}

bool HttpPipelinedStream::IsConnectionReused() const {
  return pipeline_->IsConnectionReused(pipeline_id_);
}

void HttpPipelinedStream::SetConnectionReused() {
  pipeline_->SetConnectionReused(pipeline_id_);
}

bool HttpPipelinedStream::IsConnectionReusable() const {
  return pipeline_->usable();
}

void HttpPipelinedStream::GetSSLInfo(SSLInfo* ssl_info) {
  pipeline_->GetSSLInfo(pipeline_id_, ssl_info);
}

void HttpPipelinedStream::GetSSLCertRequestInfo(
    SSLCertRequestInfo* cert_request_info) {
  pipeline_->GetSSLCertRequestInfo(pipeline_id_, cert_request_info);
}

bool HttpPipelinedStream::IsSpdyHttpStream() const {
  return false;
}

void HttpPipelinedStream::LogNumRttVsBytesMetrics() const {
  // TODO(simonjam): I don't want to copy & paste this from http_basic_stream.
}

void HttpPipelinedStream::Drain(HttpNetworkSession*) {
  // On errors, we already evict everything from the pipeline and close it.
  // TODO(simonjam): Consider trying to drain the pipeline in the same way that
  // HttpBasicStream does.
  delete this;
}

const SSLConfig& HttpPipelinedStream::used_ssl_config() const {
  return pipeline_->used_ssl_config();
}

const ProxyInfo& HttpPipelinedStream::used_proxy_info() const {
  return pipeline_->used_proxy_info();
}

const NetLog::Source& HttpPipelinedStream::source() const {
  return pipeline_->source();
}

bool HttpPipelinedStream::was_npn_negotiated() const {
  return pipeline_->was_npn_negotiated();
}

}  // namespace net
<|endoftext|>


<commit_before>/*
  Copyright (c) by respective owners including Yahoo!, Microsoft, and
  individual contributors. All rights reserved.  Released under a BSD (revised)
  license as described in the file LICENSE.
*/
#include <float.h>

#include "vw.h"
#include "reductions.h"
#include "vw_exception.h"
#include "gen_cs_example.h"

namespace GEN_CS
{
using namespace LEARNER;
using namespace CB_ALGS;
using namespace CB;

inline bool observed_cost(cb_class* cl)
{ //cost observed for this action if it has non zero probability and cost != FLT_MAX
  return (cl != nullptr && cl->cost != FLT_MAX && cl->probability > .0);
}

cb_class* get_observed_cost(CB::label& ld)
{ for (auto& cl : ld.costs)
    if (observed_cost(&cl))
      return &cl;
  return nullptr;
}

//Multiline version
void gen_cs_example_ips(v_array<example*> examples, COST_SENSITIVE::label& cs_labels)
{ cs_labels.costs.erase();
  bool shared = CB::ec_is_example_header(*examples[0]);
  for (uint32_t i = 0; i < examples.size()-1; i++)
  { CB::label ld = examples[i]->l.cb;

    COST_SENSITIVE::wclass wc = {0.,i,0.,0.};
    if (shared && i > 0)
      wc.class_index = (uint32_t)i-1;
    if (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX)
      wc.x = ld.costs[0].cost / ld.costs[0].probability;
    cs_labels.costs.push_back(wc);
  }

  if (shared)//take care of shared examples
  { cs_labels.costs[0].class_index = 0;
    cs_labels.costs[0].x = -FLT_MAX;
  }
}

//Multiline version
void gen_cs_example_dm(v_array<example*> examples, COST_SENSITIVE::label& cs_labels)
{ cs_labels.costs.erase();
  bool shared = CB::ec_is_example_header(*examples[0]);
  for (uint32_t i = 0; i < examples.size()-1; i++)
  { CB::label ld = examples[i]->l.cb;

    COST_SENSITIVE::wclass wc = {0.,i,0.,0.};
    if (shared && i > 0)
      wc.class_index = (uint32_t)i-1;
    if (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX)
      wc.x = ld.costs[0].cost;
    cs_labels.costs.push_back(wc);
  }

  if (shared)//take care of shared examples
  { cs_labels.costs[0].class_index = 0;
    cs_labels.costs[0].x = -FLT_MAX;
  }
}

//Multiline version
void gen_cs_test_example(v_array<example*> examples, COST_SENSITIVE::label& cs_labels)
{ cs_labels.costs.erase();
  bool shared = CB::ec_is_example_header(*examples[0]);
  for (uint32_t i = 0; i < examples.size()-1; i++)
  { COST_SENSITIVE::wclass wc = {FLT_MAX,i,0.,0.};
    if (shared && i > 0)
      wc.class_index = (uint32_t)i-1;
    cs_labels.costs.push_back(wc);
  }

  if (shared)//take care of shared examples
  { cs_labels.costs[0].class_index = 0;
    cs_labels.costs[0].x = -FLT_MAX;
  }
}

//single line version
void gen_cs_example_ips(cb_to_cs& c, CB::label& ld, COST_SENSITIVE::label& cs_ld)
{ //this implements the inverse propensity score method, where cost are importance weighted by the probability of the chosen action
  //generate cost-sensitive example
  cs_ld.costs.erase();
  if (ld.costs.size() == 1 && !is_test_label(ld))   //this is a typical example where we can perform all actions
  { //in this case generate cost-sensitive example with all actions
    for (uint32_t i = 1; i <= c.num_actions; i++)
    { COST_SENSITIVE::wclass wc = {0.,i,0.,0.};
      if (c.known_cost != nullptr && i == c.known_cost->action)
      { wc.x = c.known_cost->cost / c.known_cost->probability; //use importance weighted cost for observed action, 0 otherwise
        //ips can be thought as the doubly robust method with a fixed regressor that predicts 0 costs for everything
        //update the loss of this regressor
        c.nb_ex_regressors++;
        c.avg_loss_regressors += (1.0f / c.nb_ex_regressors)*((c.known_cost->cost)*(c.known_cost->cost) - c.avg_loss_regressors);
        c.last_pred_reg = 0;
        c.last_correct_cost = c.known_cost->cost;
      }

      cs_ld.costs.push_back(wc);
    }
  }
  else   //this is an example where we can only perform a subset of the actions
  { //in this case generate cost-sensitive example with only allowed actions
    for (auto& cl : ld.costs)
    { COST_SENSITIVE::wclass wc = {0., cl.action, 0., 0.};
      if (c.known_cost != nullptr && cl.action == c.known_cost->action)
      { wc.x = c.known_cost->cost / c.known_cost->probability; //use importance weighted cost for observed action, 0 otherwise

        //ips can be thought as the doubly robust method with a fixed regressor that predicts 0 costs for everything
        //update the loss of this regressor
        c.nb_ex_regressors++;
        c.avg_loss_regressors += (1.0f / c.nb_ex_regressors)*((c.known_cost->cost)*(c.known_cost->cost) - c.avg_loss_regressors);
        c.last_pred_reg = 0;
        c.last_correct_cost = c.known_cost->cost;
      }

      cs_ld.costs.push_back(wc);
    }
  }
}

void gen_cs_example_mtr(cb_to_cs_adf& c, v_array<example*>& ec_seq, COST_SENSITIVE::label& cs_labels)
{ bool shared = CB::ec_is_example_header(*(ec_seq[0]));
  c.action_sum += ec_seq.size()-2; //-1 for shared -1 for end example
  if (!shared)
    c.action_sum += 1;
  c.event_sum++;

  c.mtr_ec_seq.erase();
  cs_labels.costs.erase();
  for (size_t i = 0; i < ec_seq.size(); i++)
  { CB::label ld = ec_seq[i]->l.cb;

    COST_SENSITIVE::wclass wc = {0, 0};

    bool keep_example = false;
    if (shared && i == 0)
    { wc.x = -FLT_MAX;
      keep_example = true;
    }
    else if (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX)
    { wc.x = ld.costs[0].cost;
      c.mtr_example = (uint32_t)i;
      keep_example = true;
    }
    if (keep_example)
    { c.mtr_ec_seq.push_back(ec_seq[i]);
      cs_labels.costs.push_back(wc);
    }
  }
  c.mtr_ec_seq.push_back(ec_seq[ec_seq.size()-1]);//must include the end-of-line example
}
}
<commit_msg>safe probability minimums<commit_after>/*
  Copyright (c) by respective owners including Yahoo!, Microsoft, and
  individual contributors. All rights reserved.  Released under a BSD (revised)
  license as described in the file LICENSE.
*/
#include <float.h>

#include "vw.h"
#include "reductions.h"
#include "vw_exception.h"
#include "gen_cs_example.h"

namespace GEN_CS
{
using namespace LEARNER;
using namespace CB_ALGS;
using namespace CB;

inline bool observed_cost(cb_class* cl)
{ //cost observed for this action if it has non zero probability and cost != FLT_MAX
  return (cl != nullptr && cl->cost != FLT_MAX && cl->probability > .0);
}

cb_class* get_observed_cost(CB::label& ld)
{ for (auto& cl : ld.costs)
    if (observed_cost(&cl))
      return &cl;
  return nullptr;
}

  float safe_probability(float prob)
  {
    if (prob <= 0.)
      {
	std::cout << "Probability " << prob << " is not possible, replacing with 1e-3.  Fix your dataset. " << std::endl;
	return 1e-3;
      }
    else
      return prob;
  }

//Multiline version
void gen_cs_example_ips(v_array<example*> examples, COST_SENSITIVE::label& cs_labels)
{ cs_labels.costs.erase();
  bool shared = CB::ec_is_example_header(*examples[0]);
  for (uint32_t i = 0; i < examples.size()-1; i++)
  { CB::label ld = examples[i]->l.cb;

    COST_SENSITIVE::wclass wc = {0.,i,0.,0.};
    if (shared && i > 0)
      wc.class_index = (uint32_t)i-1;
    if (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX)
      wc.x = ld.costs[0].cost / safe_probability(ld.costs[0].probability);
    cs_labels.costs.push_back(wc);
  }

  if (shared)//take care of shared examples
  { cs_labels.costs[0].class_index = 0;
    cs_labels.costs[0].x = -FLT_MAX;
  }
}

//Multiline version
void gen_cs_example_dm(v_array<example*> examples, COST_SENSITIVE::label& cs_labels)
{ cs_labels.costs.erase();
  bool shared = CB::ec_is_example_header(*examples[0]);
  for (uint32_t i = 0; i < examples.size()-1; i++)
  { CB::label ld = examples[i]->l.cb;

    COST_SENSITIVE::wclass wc = {0.,i,0.,0.};
    if (shared && i > 0)
      wc.class_index = (uint32_t)i-1;
    if (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX)
      wc.x = ld.costs[0].cost;
    cs_labels.costs.push_back(wc);
  }

  if (shared)//take care of shared examples
  { cs_labels.costs[0].class_index = 0;
    cs_labels.costs[0].x = -FLT_MAX;
  }
}

//Multiline version
void gen_cs_test_example(v_array<example*> examples, COST_SENSITIVE::label& cs_labels)
{ cs_labels.costs.erase();
  bool shared = CB::ec_is_example_header(*examples[0]);
  for (uint32_t i = 0; i < examples.size()-1; i++)
  { COST_SENSITIVE::wclass wc = {FLT_MAX,i,0.,0.};
    if (shared && i > 0)
      wc.class_index = (uint32_t)i-1;
    cs_labels.costs.push_back(wc);
  }

  if (shared)//take care of shared examples
  { cs_labels.costs[0].class_index = 0;
    cs_labels.costs[0].x = -FLT_MAX;
  }
}

//single line version
void gen_cs_example_ips(cb_to_cs& c, CB::label& ld, COST_SENSITIVE::label& cs_ld)
{ //this implements the inverse propensity score method, where cost are importance weighted by the probability of the chosen action
  //generate cost-sensitive example
  cs_ld.costs.erase();
  if (ld.costs.size() == 1 && !is_test_label(ld))   //this is a typical example where we can perform all actions
  { //in this case generate cost-sensitive example with all actions
    for (uint32_t i = 1; i <= c.num_actions; i++)
    { COST_SENSITIVE::wclass wc = {0.,i,0.,0.};
      if (c.known_cost != nullptr && i == c.known_cost->action)
      {
	wc.x = c.known_cost->cost / safe_probability(c.known_cost->probability); //use importance weighted cost for observed action, 0 otherwise
        //ips can be thought as the doubly robust method with a fixed regressor that predicts 0 costs for everything
        //update the loss of this regressor
        c.nb_ex_regressors++;
        c.avg_loss_regressors += (1.0f / c.nb_ex_regressors)*((c.known_cost->cost)*(c.known_cost->cost) - c.avg_loss_regressors);
        c.last_pred_reg = 0;
        c.last_correct_cost = c.known_cost->cost;
      }

      cs_ld.costs.push_back(wc);
    }
  }
  else   //this is an example where we can only perform a subset of the actions
  { //in this case generate cost-sensitive example with only allowed actions
    for (auto& cl : ld.costs)
    { COST_SENSITIVE::wclass wc = {0., cl.action, 0., 0.};
      if (c.known_cost != nullptr && cl.action == c.known_cost->action)
	{ wc.x = c.known_cost->cost / safe_probability(c.known_cost->probability); //use importance weighted cost for observed action, 0 otherwise

        //ips can be thought as the doubly robust method with a fixed regressor that predicts 0 costs for everything
        //update the loss of this regressor
        c.nb_ex_regressors++;
        c.avg_loss_regressors += (1.0f / c.nb_ex_regressors)*((c.known_cost->cost)*(c.known_cost->cost) - c.avg_loss_regressors);
        c.last_pred_reg = 0;
        c.last_correct_cost = c.known_cost->cost;
      }

      cs_ld.costs.push_back(wc);
    }
  }
}

void gen_cs_example_mtr(cb_to_cs_adf& c, v_array<example*>& ec_seq, COST_SENSITIVE::label& cs_labels)
{ bool shared = CB::ec_is_example_header(*(ec_seq[0]));
  c.action_sum += ec_seq.size()-2; //-1 for shared -1 for end example
  if (!shared)
    c.action_sum += 1;
  c.event_sum++;

  c.mtr_ec_seq.erase();
  cs_labels.costs.erase();
  for (size_t i = 0; i < ec_seq.size(); i++)
  { CB::label ld = ec_seq[i]->l.cb;

    COST_SENSITIVE::wclass wc = {0, 0};

    bool keep_example = false;
    if (shared && i == 0)
    { wc.x = -FLT_MAX;
      keep_example = true;
    }
    else if (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX)
    { wc.x = ld.costs[0].cost;
      c.mtr_example = (uint32_t)i;
      keep_example = true;
    }
    if (keep_example)
    { c.mtr_ec_seq.push_back(ec_seq[i]);
      cs_labels.costs.push_back(wc);
    }
  }
  c.mtr_ec_seq.push_back(ec_seq[ec_seq.size()-1]);//must include the end-of-line example
}
}
<|endoftext|>


<commit_before>#include <pcap/pcap.h>

#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

#include <network/network_interface.h>
#include <network/network_interface_pcap.h>

static void network_interface_pcap_handle(u_char *, const struct pcap_pkthdr *, const u_char *);

NetworkInterfacePCAP::NetworkInterfacePCAP(pcap_t *pcap)
: log_("/network/pcap"),
  pcap_(pcap),
  receive_callback_(NULL),
  receive_action_(NULL)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	int rv;

	errbuf[0] = '\0';
	rv = pcap_setnonblock(pcap_, 1, errbuf);
	if (rv == -1)
		ERROR("/network/pcap") << "Could not set interface to non-blocking mode.";
}

NetworkInterfacePCAP::~NetworkInterfacePCAP()
{
	if (pcap_ != NULL) {
		pcap_close(pcap_);
		pcap_ = NULL;
	}

	ASSERT(receive_callback_ == NULL);
	ASSERT(receive_action_ == NULL);
}

Action *
NetworkInterfacePCAP::receive(EventCallback *cb)
{
	ASSERT(receive_action_ == NULL);
	ASSERT(receive_callback_ == NULL);

	receive_callback_ = cb;
	Action *a = receive_do();
	if (a == NULL) {
		ASSERT(receive_callback_ != NULL);
		receive_action_ = receive_schedule();
		ASSERT(receive_action_ != NULL);
		return (cancellation(this, &NetworkInterfacePCAP::receive_cancel));
	}
	ASSERT(receive_callback_ == NULL);
	return (a);
}

Action *
NetworkInterfacePCAP::transmit(Buffer *buffer, EventCallback *cb)
{
	ASSERT(!buffer->empty());
	buffer->clear();

	cb->param(Event::Error);
	return (EventSystem::instance()->schedule(cb));
}

void
NetworkInterfacePCAP::receive_callback(Event e)
{
	receive_action_->cancel();
	receive_action_ = NULL;

	switch (e.type_) {
	case Event::EOS:
	case Event::Done:
		break;
	case Event::Error: {
		DEBUG(log_) << "Poll returned error: " << e;
		receive_callback_->param(e);
		Action *a = EventSystem::instance()->schedule(receive_callback_);
		receive_action_ = a;
		receive_callback_ = NULL;
		return;
	}
	default:
		HALT(log_) << "Unexpected event: " << e;
	}

	receive_action_ = receive_do();
	if (receive_action_ == NULL)
		receive_action_ = receive_schedule();
	ASSERT(receive_action_ != NULL);
}

void
NetworkInterfacePCAP::receive_cancel(void)
{
	if (receive_callback_ != NULL) {
		delete receive_callback_;
		receive_callback_ = NULL;

		ASSERT(receive_action_ != NULL);
	}

	if (receive_action_ != NULL) {
		receive_action_->cancel();
		receive_action_ = NULL;
	}
}

Action *
NetworkInterfacePCAP::receive_do(void)
{
	Buffer packet;

	int cnt = pcap_dispatch(pcap_, 1, network_interface_pcap_handle, (u_char *)&packet);
	if (cnt < 0) {
		receive_callback_->param(Event(Event::Error));
		Action *a = EventSystem::instance()->schedule(receive_callback_);
		receive_callback_ = NULL;
		return (a);
	}

	if (cnt == 0) {
		return (NULL);
	}

	ASSERT(cnt == 1);

	receive_callback_->param(Event(Event::Done, packet));
	Action *a = EventSystem::instance()->schedule(receive_callback_);
	receive_callback_ = NULL;
	return (a);
}

Action *
NetworkInterfacePCAP::receive_schedule(void)
{
	ASSERT(receive_action_ == NULL);

	EventCallback *cb = callback(this, &NetworkInterfacePCAP::receive_callback);
	Action *a = EventSystem::instance()->poll(EventPoll::Readable, pcap_fileno(pcap_), cb);
	return (a);
}

NetworkInterface *
NetworkInterfacePCAP::open(const std::string& ifname)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_t *pcap;

	errbuf[0] = '\0';
	pcap = pcap_open_live(ifname.c_str(), 65535, 1, 0, errbuf);
	if (pcap == NULL) {
		ERROR("/network/pcap") << "Unabled to open " << ifname << ": " << errbuf;
		return (NULL);
	}
	if (errbuf[0] != '\0')
		WARNING("/network/pcap") << "While opening " << ifname << ": " << errbuf;

	return (new NetworkInterfacePCAP(pcap));
}

static void
network_interface_pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{
	Buffer *packet = (Buffer *)user;
	ASSERT(packet->empty());

	packet->append(bytes, h->caplen);
}
<commit_msg>Simplify by using pcap_next_ex.<commit_after>#include <pcap/pcap.h>

#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

#include <network/network_interface.h>
#include <network/network_interface_pcap.h>

NetworkInterfacePCAP::NetworkInterfacePCAP(pcap_t *pcap)
: log_("/network/pcap"),
  pcap_(pcap),
  receive_callback_(NULL),
  receive_action_(NULL)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	int rv;

	errbuf[0] = '\0';
	rv = pcap_setnonblock(pcap_, 1, errbuf);
	if (rv == -1)
		ERROR("/network/pcap") << "Could not set interface to non-blocking mode.";
}

NetworkInterfacePCAP::~NetworkInterfacePCAP()
{
	if (pcap_ != NULL) {
		pcap_close(pcap_);
		pcap_ = NULL;
	}

	ASSERT(receive_callback_ == NULL);
	ASSERT(receive_action_ == NULL);
}

Action *
NetworkInterfacePCAP::receive(EventCallback *cb)
{
	ASSERT(receive_action_ == NULL);
	ASSERT(receive_callback_ == NULL);

	receive_callback_ = cb;
	Action *a = receive_do();
	if (a == NULL) {
		ASSERT(receive_callback_ != NULL);
		receive_action_ = receive_schedule();
		ASSERT(receive_action_ != NULL);
		return (cancellation(this, &NetworkInterfacePCAP::receive_cancel));
	}
	ASSERT(receive_callback_ == NULL);
	return (a);
}

Action *
NetworkInterfacePCAP::transmit(Buffer *buffer, EventCallback *cb)
{
	ASSERT(!buffer->empty());
	buffer->clear();

	cb->param(Event::Error);
	return (EventSystem::instance()->schedule(cb));
}

void
NetworkInterfacePCAP::receive_callback(Event e)
{
	receive_action_->cancel();
	receive_action_ = NULL;

	switch (e.type_) {
	case Event::EOS:
	case Event::Done:
		break;
	case Event::Error: {
		DEBUG(log_) << "Poll returned error: " << e;
		receive_callback_->param(e);
		Action *a = EventSystem::instance()->schedule(receive_callback_);
		receive_action_ = a;
		receive_callback_ = NULL;
		return;
	}
	default:
		HALT(log_) << "Unexpected event: " << e;
	}

	receive_action_ = receive_do();
	if (receive_action_ == NULL)
		receive_action_ = receive_schedule();
	ASSERT(receive_action_ != NULL);
}

void
NetworkInterfacePCAP::receive_cancel(void)
{
	if (receive_callback_ != NULL) {
		delete receive_callback_;
		receive_callback_ = NULL;

		ASSERT(receive_action_ != NULL);
	}

	if (receive_action_ != NULL) {
		receive_action_->cancel();
		receive_action_ = NULL;
	}
}

Action *
NetworkInterfacePCAP::receive_do(void)
{
	struct pcap_pkthdr *h;
	const u_char *bytes;
	int rv = pcap_next_ex(pcap_, &h, &bytes);
	if (rv == -1) {
		receive_callback_->param(Event(Event::Error));
		Action *a = EventSystem::instance()->schedule(receive_callback_);
		receive_callback_ = NULL;
		return (a);
	}

	if (rv == 0) {
		return (NULL);
	}

	ASSERT(rv == 1);

	receive_callback_->param(Event(Event::Done, Buffer(bytes, h->caplen)));
	Action *a = EventSystem::instance()->schedule(receive_callback_);
	receive_callback_ = NULL;
	return (a);
}

Action *
NetworkInterfacePCAP::receive_schedule(void)
{
	ASSERT(receive_action_ == NULL);

	EventCallback *cb = callback(this, &NetworkInterfacePCAP::receive_callback);
	Action *a = EventSystem::instance()->poll(EventPoll::Readable, pcap_fileno(pcap_), cb);
	return (a);
}

NetworkInterface *
NetworkInterfacePCAP::open(const std::string& ifname)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_t *pcap;

	errbuf[0] = '\0';
	pcap = pcap_open_live(ifname.c_str(), 65535, 1, 1, errbuf);
	if (pcap == NULL) {
		ERROR("/network/pcap") << "Unabled to open " << ifname << ": " << errbuf;
		return (NULL);
	}
	if (errbuf[0] != '\0')
		WARNING("/network/pcap") << "While opening " << ifname << ": " << errbuf;

	return (new NetworkInterfacePCAP(pcap));
}
<|endoftext|>


<commit_before>#include "canvaswidget.h"

#include <QDebug>
CanvasWidget::CanvasWidget(QWidget *parent) :
    QWidget(parent), selected(NULL), transformation(NONE)
{
    epsilon.x = 50;
    epsilon.y = 50;
    creatingType = 1;
    defaultOffsetParallelogram = 30.0;
}

CanvasWidget::~CanvasWidget() {
    for (unsigned i = 0; i < shapes.size(); i++) {
        delete shapes[i];
    }
}

void CanvasWidget::changeType(int type)
{
    creatingType = type;
}

void CanvasWidget::clearSelectedShapes()
{
    for(const auto &shape: shapes) {
        (&*shape)->select(false);
    }
    selectedShapes.clear();
}
void CanvasWidget::insertShapeInSelectedShapes(QtShape2D* shape)
{
    shape->select(true);
    selectedShapes.insert(shape);
}

bool CanvasWidget::havingShapeInSelectedShapes(QtShape2D* shape) {
    size_t oldSize = selectedShapes.size();
    selectedShapesContainer tmpCont = selectedShapes;
    tmpCont.insert(shape);
    return oldSize == tmpCont.size();
}

void CanvasWidget::selectAll()
{
    clearSelectedShapes();
    for(const auto &shape: shapes) {
        (&*shape)->select(true);
        selectedShapes.insert(&*shape);
    }
    update();
}

void CanvasWidget::mousePressEvent(QMouseEvent *event) {

    pressedPoint.x = event->localPos().x();
    pressedPoint.y = event->localPos().y();

    selected = NULL;
    transformation = NONE;
    for(unsigned i = shapes.size(); i > 0; i--) {
        if(shapes[i - 1]->belongs(pressedPoint)) {
            //Нажали на фигуру
            toFront(i - 1); //переместилю фигуру вперед
            selected = shapes[shapes.size() - 1]; //Запоминаем последню выбранную фигуры

            //Проверяем нажатие на контроллер масштабирования (левый верхний)
            if(selected->isTopLeft(pressedPoint, epsilon)) {
                transformation = LEFT_RESIZE;
            }
            //Проверяем нажатие на контроллек масштабирования (правый нижний)
            else if(selected->isBottomRight(pressedPoint, epsilon)){
                transformation = RIGHT_RESIZE;
            }

            if (transformation == LEFT_RESIZE || transformation == RIGHT_RESIZE) //Оставляем только одну выделенную фигуру6 которую хотим масштабировать
                clearSelectedShapes();

             insertShapeInSelectedShapes(selected);

            if(selected->getType() == 2) {
                if(((QtParallelogram*)selected)->isControlPoint(pressedPoint, epsilon)) {
                    controlPointModify = true;
                }
            }

            pressedPoint -= selected->getCenter();
            break;
        }
    }
}

void CanvasWidget::mouseMoveEvent(QMouseEvent *event) {

    if((event->buttons()) & Qt::LeftButton) {
        Point2D currentPoint;
        currentPoint.x = event->localPos().x();
        currentPoint.y = event->localPos().y();

        if(transformation == CREATING) {
            shapes.back()->setBounds(pressedPoint, currentPoint);
        } else if(selected) {
            if(transformation == LEFT_RESIZE) {
                selected->resize(currentPoint, 0);
            } else if(transformation == RIGHT_RESIZE) {
                selected->resize(currentPoint, 1);
            } else if(controlPointModify) {
                ((QtParallelogram*)selected)->setControlPoint(currentPoint.x);
            } else if (transformation == MOVING) {
                for(const auto &shape: selectedShapes) //foreach Loop
                {
                    (&*shape)->move((&*shape)->getCenter()-selected->getCenter() + currentPoint - pressedPoint);
                }
            }

        } else {
            transformation = CREATING;
            switch(creatingType) {
                case 2 :
                    selected = new QtParallelogram(pressedPoint, pressedPoint, defaultOffsetParallelogram);
                    break;
                case 1:
                    selected = new QtRectangle(pressedPoint, pressedPoint);
                    break;
            }

            shapes.push_back(selected);
            selected->select(true);

            /////////////////
            setModified(true);
        }

        update();
    }
}

void CanvasWidget::mouseReleaseEvent(QMouseEvent *)
{
    if (selected == NULL) { //Нажатие на пустую область. Снимаем выдиление
        clearSelectedShapes();
    }
    if (transformation == MOVING) {}
    else if(transformation == CREATING or !isKeyPressed(Qt::Key_Control) and selected != NULL) { //Оставляем 1 выделенную фигуру: конец создания фигуры, нажатие без Ctrl
        clearSelectedShapes();
        insertShapeInSelectedShapes(selected);
    }

    update();
    controlPointModify = false;
    transformation = NONE;
    selected = NULL;
}

void CanvasWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);

    for(unsigned i =0; i < shapes.size(); i++) {
        shapes[i]->draw(painter);
    }
}

void CanvasWidget::toFront(int number) {
    int top = shapes.size() - 1;

    QtShape2D* tmp = shapes[number];
    shapes[number] = shapes[top];
    shapes[top] = tmp;

    /////////////////
    setModified(true);
}
<commit_msg>Moving trubles:)<commit_after>#include "canvaswidget.h"

#include <QDebug>
CanvasWidget::CanvasWidget(QWidget *parent) :
    QWidget(parent), selected(NULL), transformation(NONE)
{
    epsilon.x = 50;
    epsilon.y = 50;
    creatingType = 1;
    defaultOffsetParallelogram = 30.0;
}

CanvasWidget::~CanvasWidget() {
    for (unsigned i = 0; i < shapes.size(); i++) {
        delete shapes[i];
    }
}

void CanvasWidget::changeType(int type)
{
    creatingType = type;
}

void CanvasWidget::clearSelectedShapes()
{
    for(const auto &shape: shapes) {
        (&*shape)->select(false);
    }
    selectedShapes.clear();
}
void CanvasWidget::insertShapeInSelectedShapes(QtShape2D* shape)
{
    shape->select(true);
    selectedShapes.insert(shape);
}

bool CanvasWidget::havingShapeInSelectedShapes(QtShape2D* shape) {
    size_t oldSize = selectedShapes.size();
    selectedShapesContainer tmpCont = selectedShapes;
    tmpCont.insert(shape);
    return oldSize == tmpCont.size();
}

void CanvasWidget::selectAll()
{
    clearSelectedShapes();
    for(const auto &shape: shapes) {
        (&*shape)->select(true);
        selectedShapes.insert(&*shape);
    }
    update();
}

void CanvasWidget::mousePressEvent(QMouseEvent *event) {

    pressedPoint.x = event->localPos().x();
    pressedPoint.y = event->localPos().y();

    selected = NULL;
    transformation = NONE;
    for(unsigned i = shapes.size(); i > 0; i--) {
        if(shapes[i - 1]->belongs(pressedPoint)) {
            //Нажали на фигуру
            toFront(i - 1); //переместилю фигуру вперед
            selected = shapes[shapes.size() - 1]; //Запоминаем последню выбранную фигуры

            //Проверяем нажатие на контроллер масштабирования (левый верхний)
            if(selected->isTopLeft(pressedPoint, epsilon)) {
                transformation = LEFT_RESIZE;
            }
            //Проверяем нажатие на контроллек масштабирования (правый нижний)
            else if(selected->isBottomRight(pressedPoint, epsilon)){
                transformation = RIGHT_RESIZE;
            }

            if (transformation == LEFT_RESIZE || transformation == RIGHT_RESIZE) //Оставляем только одну выделенную фигуру6 которую хотим масштабировать
                clearSelectedShapes();
            if (havingShapeInSelectedShapes(selected))
                transformation = MOVING;
             insertShapeInSelectedShapes(selected);

            if(selected->getType() == 2) {
                if(((QtParallelogram*)selected)->isControlPoint(pressedPoint, epsilon)) {
                    controlPointModify = true;
                }
            }

            pressedPoint -= selected->getCenter();
            break;
        }
    }
}

void CanvasWidget::mouseMoveEvent(QMouseEvent *event) {

    if((event->buttons()) & Qt::LeftButton) {
        Point2D currentPoint;
        currentPoint.x = event->localPos().x();
        currentPoint.y = event->localPos().y();

        if(transformation == CREATING) {
            shapes.back()->setBounds(pressedPoint, currentPoint);
        } else if(selected) {
            if(transformation == LEFT_RESIZE) {
                selected->resize(currentPoint, 0);
            } else if(transformation == RIGHT_RESIZE) {
                selected->resize(currentPoint, 1);
            } else if(controlPointModify) {
                ((QtParallelogram*)selected)->setControlPoint(currentPoint.x);
            } else if (transformation == MOVING) {
                for(const auto &shape: selectedShapes) //foreach Loop
                {
                    (&*shape)->move((&*shape)->getCenter()-selected->getCenter() + currentPoint - pressedPoint);
                }
            }

        } else {
            transformation = CREATING;
            switch(creatingType) {
                case 2 :
                    selected = new QtParallelogram(pressedPoint, pressedPoint, defaultOffsetParallelogram);
                    break;
                case 1:
                    selected = new QtRectangle(pressedPoint, pressedPoint);
                    break;
            }

            shapes.push_back(selected);
            selected->select(true);

            /////////////////
            setModified(true);
        }

        update();
    }
}

void CanvasWidget::mouseReleaseEvent(QMouseEvent *)
{
    if (selected == NULL) { //Нажатие на пустую область. Снимаем выдиление
        clearSelectedShapes();
    }
    if (transformation == MOVING) {}
    else if(transformation == CREATING or !isKeyPressed(Qt::Key_Control) and selected != NULL) { //Оставляем 1 выделенную фигуру: конец создания фигуры, нажатие без Ctrl
        clearSelectedShapes();
        insertShapeInSelectedShapes(selected);
    }

    update();
    controlPointModify = false;
    transformation = NONE;
    selected = NULL;
}

void CanvasWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);

    for(unsigned i =0; i < shapes.size(); i++) {
        shapes[i]->draw(painter);
    }
}

void CanvasWidget::toFront(int number) {
    int top = shapes.size() - 1;

    QtShape2D* tmp = shapes[number];
    shapes[number] = shapes[top];
    shapes[top] = tmp;

    /////////////////
    setModified(true);
}
<|endoftext|>


<commit_before>// Copyright (c) 2012-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// SYSCOIN
#include <primitives/transaction.h>
#include <script/standard.h>
#include <test/util/setup_common.h>

#include <stdint.h>

#include <boost/test/unit_test.hpp>

// amounts 0.00000001 .. 0.00100000
#define NUM_MULTIPLES_UNIT 100000

// amounts 0.01 .. 100.00
#define NUM_MULTIPLES_CENT 10000

// amounts 1 .. 10000
#define NUM_MULTIPLES_1SYS 10000

// amounts 50 .. 21000000
#define NUM_MULTIPLES_50SYS 420000

BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup)

bool static TestEncode(uint64_t in) {
    return in == DecompressAmount(CompressAmount(in));
}

bool static TestDecode(uint64_t in) {
    return in == CompressAmount(DecompressAmount(in));
}

bool static TestPair(uint64_t dec, uint64_t enc) {
    return CompressAmount(dec) == enc &&
           DecompressAmount(enc) == dec;
}

BOOST_AUTO_TEST_CASE(compress_amounts)
{
    BOOST_CHECK(TestPair(            0,       0x0));
    BOOST_CHECK(TestPair(            1,       0x1));
    BOOST_CHECK(TestPair(         CENT,       0x7));
    BOOST_CHECK(TestPair(         COIN,       0x9));
    BOOST_CHECK(TestPair(      50*COIN,      0x32));
    BOOST_CHECK(TestPair(21000000*COIN, 0x1406f40));

    for (uint64_t i = 1; i <= NUM_MULTIPLES_UNIT; i++)
        BOOST_CHECK(TestEncode(i));

    for (uint64_t i = 1; i <= NUM_MULTIPLES_CENT; i++)
        BOOST_CHECK(TestEncode(i * CENT));

    for (uint64_t i = 1; i <= NUM_MULTIPLES_1SYS; i++)
        BOOST_CHECK(TestEncode(i * COIN));

    for (uint64_t i = 1; i <= NUM_MULTIPLES_50SYS; i++)
        BOOST_CHECK(TestEncode(i * 50 * COIN));

    for (uint64_t i = 0; i < 100000; i++)
        BOOST_CHECK(TestDecode(i));
}

BOOST_AUTO_TEST_CASE(compress_script_to_ckey_id)
{
    // case CKeyID
    CKey key;
    key.MakeNewKey(true);
    CPubKey pubkey = key.GetPubKey();

    CScript script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
    BOOST_CHECK_EQUAL(script.size(), 25U);

    std::vector<unsigned char> out;
    bool done = CompressScript(script, out);
    BOOST_CHECK_EQUAL(done, true);

    // Check compressed script
    BOOST_CHECK_EQUAL(out.size(), 21U);
    BOOST_CHECK_EQUAL(out[0], 0x00);
    BOOST_CHECK_EQUAL(memcmp(&out[1], &script[3], 20), 0); // compare the 20 relevant chars of the CKeyId in the script
}

BOOST_AUTO_TEST_CASE(compress_script_to_cscript_id)
{
    // case CScriptID
    CScript script, redeemScript;
    script << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
    BOOST_CHECK_EQUAL(script.size(), 23U);

    std::vector<unsigned char> out;
    bool done = CompressScript(script, out);
    BOOST_CHECK_EQUAL(done, true);

    // Check compressed script
    BOOST_CHECK_EQUAL(out.size(), 21U);
    BOOST_CHECK_EQUAL(out[0], 0x01);
    BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 20), 0); // compare the 20 relevant chars of the CScriptId in the script
}

BOOST_AUTO_TEST_CASE(compress_script_to_compressed_pubkey_id)
{
    CKey key;
    key.MakeNewKey(true); // case compressed PubKeyID

    CScript script = CScript() << ToByteVector(key.GetPubKey()) << OP_CHECKSIG; // COMPRESSED_PUBLIC_KEY_SIZE (33)
    BOOST_CHECK_EQUAL(script.size(), 35U);

    std::vector<unsigned char> out;
    bool done = CompressScript(script, out);
    BOOST_CHECK_EQUAL(done, true);

    // Check compressed script
    BOOST_CHECK_EQUAL(out.size(), 33U);
    BOOST_CHECK_EQUAL(memcmp(&out[0], &script[1], 1), 0);
    BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 32), 0); // compare the 32 chars of the compressed CPubKey
}

BOOST_AUTO_TEST_CASE(compress_script_to_uncompressed_pubkey_id)
{
    CKey key;
    key.MakeNewKey(false); // case uncompressed PubKeyID
    CScript script =  CScript() << ToByteVector(key.GetPubKey()) << OP_CHECKSIG; // PUBLIC_KEY_SIZE (65)
    BOOST_CHECK_EQUAL(script.size(), 67U);                   // 1 char code + 65 char pubkey + OP_CHECKSIG

    std::vector<unsigned char> out;
    bool done = CompressScript(script, out);
    BOOST_CHECK_EQUAL(done, true);

    // Check compressed script
    BOOST_CHECK_EQUAL(out.size(), 33U);
    BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 32), 0); // first 32 chars of CPubKey are copied into out[1:]
    BOOST_CHECK_EQUAL(out[0], 0x04 | (script[65] & 0x01)); // least significant bit (lsb) of last char of pubkey is mapped into out[0]
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>check 888m<commit_after>// Copyright (c) 2012-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// SYSCOIN
#include <primitives/transaction.h>
#include <script/standard.h>
#include <test/util/setup_common.h>

#include <stdint.h>

#include <boost/test/unit_test.hpp>

// amounts 0.00000001 .. 0.00100000
#define NUM_MULTIPLES_UNIT 100000

// amounts 0.01 .. 100.00
#define NUM_MULTIPLES_CENT 10000

// amounts 1 .. 10000
#define NUM_MULTIPLES_1SYS 10000

// amounts 50 .. 21000000
#define NUM_MULTIPLES_50SYS 420000

BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup)

bool static TestEncode(uint64_t in) {
    return in == DecompressAmount(CompressAmount(in));
}

bool static TestDecode(uint64_t in) {
    return in == CompressAmount(DecompressAmount(in));
}

bool static TestPair(uint64_t dec, uint64_t enc) {
    return CompressAmount(dec) == enc &&
           DecompressAmount(enc) == dec;
}

BOOST_AUTO_TEST_CASE(compress_amounts)
{
    BOOST_CHECK(TestPair(            0,       0x0));
    BOOST_CHECK(TestPair(            1,       0x1));
    BOOST_CHECK(TestPair(         CENT,       0x7));
    BOOST_CHECK(TestPair(         COIN,       0x9));
    BOOST_CHECK(TestPair(      50*COIN,      0x32));
    BOOST_CHECK(TestPair(21000000*COIN, 0x1406f40));
    // SYSCOIN
    auto compressed = CompressAmount(888000000*COIN);
    BOOST_CHECK_EQUAL(compressed), DecompressAmount(compressed));
    for (uint64_t i = 1; i <= NUM_MULTIPLES_UNIT; i++)
        BOOST_CHECK(TestEncode(i));

    for (uint64_t i = 1; i <= NUM_MULTIPLES_CENT; i++)
        BOOST_CHECK(TestEncode(i * CENT));

    for (uint64_t i = 1; i <= NUM_MULTIPLES_1SYS; i++)
        BOOST_CHECK(TestEncode(i * COIN));

    for (uint64_t i = 1; i <= NUM_MULTIPLES_50SYS; i++)
        BOOST_CHECK(TestEncode(i * 50 * COIN));

    for (uint64_t i = 0; i < 100000; i++)
        BOOST_CHECK(TestDecode(i));
}

BOOST_AUTO_TEST_CASE(compress_script_to_ckey_id)
{
    // case CKeyID
    CKey key;
    key.MakeNewKey(true);
    CPubKey pubkey = key.GetPubKey();

    CScript script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
    BOOST_CHECK_EQUAL(script.size(), 25U);

    std::vector<unsigned char> out;
    bool done = CompressScript(script, out);
    BOOST_CHECK_EQUAL(done, true);

    // Check compressed script
    BOOST_CHECK_EQUAL(out.size(), 21U);
    BOOST_CHECK_EQUAL(out[0], 0x00);
    BOOST_CHECK_EQUAL(memcmp(&out[1], &script[3], 20), 0); // compare the 20 relevant chars of the CKeyId in the script
}

BOOST_AUTO_TEST_CASE(compress_script_to_cscript_id)
{
    // case CScriptID
    CScript script, redeemScript;
    script << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
    BOOST_CHECK_EQUAL(script.size(), 23U);

    std::vector<unsigned char> out;
    bool done = CompressScript(script, out);
    BOOST_CHECK_EQUAL(done, true);

    // Check compressed script
    BOOST_CHECK_EQUAL(out.size(), 21U);
    BOOST_CHECK_EQUAL(out[0], 0x01);
    BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 20), 0); // compare the 20 relevant chars of the CScriptId in the script
}

BOOST_AUTO_TEST_CASE(compress_script_to_compressed_pubkey_id)
{
    CKey key;
    key.MakeNewKey(true); // case compressed PubKeyID

    CScript script = CScript() << ToByteVector(key.GetPubKey()) << OP_CHECKSIG; // COMPRESSED_PUBLIC_KEY_SIZE (33)
    BOOST_CHECK_EQUAL(script.size(), 35U);

    std::vector<unsigned char> out;
    bool done = CompressScript(script, out);
    BOOST_CHECK_EQUAL(done, true);

    // Check compressed script
    BOOST_CHECK_EQUAL(out.size(), 33U);
    BOOST_CHECK_EQUAL(memcmp(&out[0], &script[1], 1), 0);
    BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 32), 0); // compare the 32 chars of the compressed CPubKey
}

BOOST_AUTO_TEST_CASE(compress_script_to_uncompressed_pubkey_id)
{
    CKey key;
    key.MakeNewKey(false); // case uncompressed PubKeyID
    CScript script =  CScript() << ToByteVector(key.GetPubKey()) << OP_CHECKSIG; // PUBLIC_KEY_SIZE (65)
    BOOST_CHECK_EQUAL(script.size(), 67U);                   // 1 char code + 65 char pubkey + OP_CHECKSIG

    std::vector<unsigned char> out;
    bool done = CompressScript(script, out);
    BOOST_CHECK_EQUAL(done, true);

    // Check compressed script
    BOOST_CHECK_EQUAL(out.size(), 33U);
    BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 32), 0); // first 32 chars of CPubKey are copied into out[1:]
    BOOST_CHECK_EQUAL(out[0], 0x04 | (script[65] & 0x01)); // least significant bit (lsb) of last char of pubkey is mapped into out[0]
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>

#include "base58.h"
#include "util.h"
#include "main.h"

using namespace std;

BOOST_AUTO_TEST_SUITE(darksend_tests)

BOOST_AUTO_TEST_CASE(darksend_sign)
{

    std::string errorMessage = "";
    std::string strBase64;
    CKey key;
    CPubKey pubkey;
    std::vector<unsigned char> vchSig;

    CDarkSendSigner dss;
    dss.SetKey("XDPugk3QgxVpQ4BubgzKaXhQudtaBnjuos9w6ZTojYx68EipNnt7", errorMessage, key, pubkey);
    BOOST_CHECK(dss.SignMessage("hello", errorMessage, vchSig, key) == true);
    BOOST_CHECK(dss.VerifyMessage(pubkey, vchSig, "hello", errorMessage) == true);
    BOOST_CHECK(dss.VerifyMessage(pubkey, vchSig, "hello2", errorMessage) == false);

}
BOOST_AUTO_TEST_CASE(darksend_vote)
{
    CPubKey key;
    CMasterNodeVote mnv;
    mnv.Set(key, 1);
    mnv.Vote();
    BOOST_CHECK(mnv.GetVotes() == 2);
    mnv.Vote();
    BOOST_CHECK(mnv.GetVotes() == 3);
}

BOOST_AUTO_TEST_CASE(darksend_masternode_voting)
{
    uint256 n1 = 10000;
    uint256 n2 = 10001;
    CTxIn fromMn1 = CTxIn(n2, 0);
    CTxIn testVin1 = CTxIn(n1, 0);
    CTxIn testVin2 = CTxIn(n2, 0);
    CService addr;
    std::vector<unsigned char> vchSig;

    //setup a couple fake masternodes
    CMasterNode mn1(addr, testVin1, CPubKey(), vchSig, 0, CPubKey());
    darkSendMasterNodes.push_back(mn1);

    CMasterNode mn2(addr, testVin2, CPubKey(), vchSig, 0, CPubKey());
    darkSendMasterNodes.push_back(mn2);

    // return -1 if nothing present
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1000) == -1);

    darkSendPool.SubmitMasternodeVote(testVin1, fromMn1,1000);
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1000) == 0); // vin1

    darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1000);
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1000) == 1); // vin2 - prevout breaks ties
    darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1000);
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1000) == 1); // vin2

    darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1000);
    darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1000);

    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1001) == -1);

    darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1001);
    darkSendPool.SubmitMasternodeVote(testVin1, fromMn1, 1001);
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1001) == 1); // vin2 - prevout breaks ties

    darkSendPool.SubmitMasternodeVote(testVin1, fromMn1, 1001);
    darkSendPool.SubmitMasternodeVote(testVin1, fromMn1, 1001);

    darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1001);
    darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1001);
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1000) == 1); // vin2

    darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1001);
    darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1001);

    vecBlockVotes.push_back(make_pair(1001, make_pair(testVin1, 10)));
    vecBlockVotes.push_back(make_pair(1001, make_pair(testVin2, 4)));

    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1001) == 0); //vin1
}

BOOST_AUTO_TEST_CASE(darksend_masternode_search_by_vin)
{
    uint256 n1 = 10000;
    uint256 n2 = 10001;
    uint256 n3 = 99999;
    CTxIn testVin1 = CTxIn(n1, 0);
    CTxIn testVin2 = CTxIn(n2, 0);
    CTxIn testVinNotFound = CTxIn(n3, 0);
    CService addr;
    std::vector<unsigned char> vchSig;

    //setup a couple fake masternodes
    CMasterNode mn1(addr, testVin1, CPubKey(), vchSig, 0, CPubKey());
    darkSendMasterNodes.push_back(mn1);

    CMasterNode mn2(addr, testVin2, CPubKey(), vchSig, 0, CPubKey());
    darkSendMasterNodes.push_back(mn2);

    BOOST_CHECK(darkSendPool.GetMasternodeByVin(testVinNotFound) == -1);
    BOOST_CHECK(darkSendPool.GetMasternodeByVin(testVin1) == 0);
    BOOST_CHECK(darkSendPool.GetMasternodeByVin(testVin2) == 1);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>fixed unit tests<commit_after>#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>

#include "base58.h"
#include "util.h"
#include "main.h"

using namespace std;

BOOST_AUTO_TEST_SUITE(darksend_tests)

BOOST_AUTO_TEST_CASE(darksend_sign)
{

    std::string errorMessage = "";
    std::string strBase64;
    CKey key;
    CPubKey pubkey;
    std::vector<unsigned char> vchSig;

    CDarkSendSigner dss;
    dss.SetKey("XDPugk3QgxVpQ4BubgzKaXhQudtaBnjuos9w6ZTojYx68EipNnt7", errorMessage, key, pubkey);
    BOOST_CHECK(dss.SignMessage("hello", errorMessage, vchSig, key) == true);
    BOOST_CHECK(dss.VerifyMessage(pubkey, vchSig, "hello", errorMessage) == true);
    BOOST_CHECK(dss.VerifyMessage(pubkey, vchSig, "hello2", errorMessage) == false);

}
BOOST_AUTO_TEST_CASE(darksend_vote)
{
    CPubKey key;
    CMasterNodeVote mnv;
    mnv.Set(key, 1);
    mnv.Vote();
    BOOST_CHECK(mnv.GetVotes() == 2);
    mnv.Vote();
    BOOST_CHECK(mnv.GetVotes() == 3);
}

BOOST_AUTO_TEST_CASE(darksend_masternode_voting)
{
    uint256 n1 = 10000;
    uint256 n2 = 10001;
    CTxIn fromMn1 = CTxIn(n2, 0);
    CTxIn testVin1 = CTxIn(n1, 0);
    CTxIn testVin2 = CTxIn(n2, 0);
    CService addr;
    int i = 0;
    std::vector<unsigned char> vchSig;

    //setup a couple fake masternodes
    CMasterNode mn1(addr, testVin1, CPubKey(), vchSig, 0, CPubKey());
    darkSendMasterNodes.push_back(mn1);

    CMasterNode mn2(addr, testVin2, CPubKey(), vchSig, 0, CPubKey());
    darkSendMasterNodes.push_back(mn2);

    // return -1 if nothing present
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1000) == -1);

    //block 1000
    for(i = 0; i <= 2; i++)
        darkSendPool.SubmitMasternodeVote(testVin1, fromMn1,1000);

    // not enough votes
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1000) == -1); //

    for(i = 0; i <= 4; i++)
        darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1000);

    // not enough votes
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1000) == -1); //

    for(i = 0; i <= 4; i++)
        darkSendPool.SubmitMasternodeVote(testVin2, fromMn1, 1000);

    // should have 8 votes now
    BOOST_CHECK(darkSendPool.GetCurrentMasterNodeConsessus(1000) == 1); // vin2
}

BOOST_AUTO_TEST_CASE(darksend_masternode_search_by_vin)
{
    uint256 n1 = 10000;
    uint256 n2 = 10001;
    uint256 n3 = 99999;
    CTxIn testVin1 = CTxIn(n1, 0);
    CTxIn testVin2 = CTxIn(n2, 0);
    CTxIn testVinNotFound = CTxIn(n3, 0);
    CService addr;
    std::vector<unsigned char> vchSig;

    //setup a couple fake masternodes
    CMasterNode mn1(addr, testVin1, CPubKey(), vchSig, 0, CPubKey());
    darkSendMasterNodes.push_back(mn1);

    CMasterNode mn2(addr, testVin2, CPubKey(), vchSig, 0, CPubKey());
    darkSendMasterNodes.push_back(mn2);

    BOOST_CHECK(darkSendPool.GetMasternodeByVin(testVinNotFound) == -1);
    BOOST_CHECK(darkSendPool.GetMasternodeByVin(testVin1) == 0);
    BOOST_CHECK(darkSendPool.GetMasternodeByVin(testVin2) == 1);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>// -*- mode:C++ { } tab-width:4 { } c-basic-offset:4 { } indent-tabs-mode:nil -*-

/*
 * Copyright (C) 2015 iCub Facility
 * Authors: Ali Paikan
 * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
 *
 */

#include <cstdlib>
#include <stdio.h>

#include <rtf/TestResult.h>
#include <rtf/ConsoleListener.h>
#include <rtf/TestResultCollector.h>
#include <rtf/TextOutputter.h>
#include <JUnitOutputter.h>

#include <cmdline.h>
#include <SuitRunner.h>
#include <ErrorLogger.h>
#include <Version.h>

#if defined(ENABLE_WEB_LISTENER)
    #include <rtf/WebProgressListener.h>
#endif

#if defined(WIN32)
    #include <windows.h>
#else
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <signal.h>
#endif

using namespace RTF;
using namespace std;

void reportErrors(void) {
    ErrorLogger& logger  = ErrorLogger::Instance();
    for(unsigned int i=0; i<logger.errorCount(); i++)
        cout<<"[testrunner] "<<logger.getLastError()<<endl;
    for(unsigned int i=0; i<logger.warningCount(); i++)
        cout<<"[testrunner] "<<logger.getLastWarning()<<endl;
}

void addOptions(cmdline::parser &cmd) {
    cmd.add<string>("test", 't',
                    "Runs a single test from the given plugin file.",
                    false);

    cmd.add<string>("tests", '\0',
                    "Runs multiple tests from the given folder which contains plugins.",
                    false);

    cmd.add<string>("suit", 's',
                    "Runs a single test suit from the given XMl file.",
                    false);

    cmd.add<string>("suits", '\0',
                    "Runs multiple test suits from the given folder which contains XML files.",
                    false);

    cmd.add<string>("output", 'o',
                    "The output file to save the result. Default is result.txt",
                    false, "");
    cmd.add<string>("output-type", '\0',
                    "The output file type (text, junit)",
                    false, "text");

    cmd.add<string>("param", 'p',
                    "Sets the test case parameters. (Can be used only with --test option.)",
                    false);
    cmd.add<string>("environment", 'e',
                    "Sets the test case environment. (Can be used only with --test option.)",
                    false);
    cmd.add<unsigned int>("repetition", '\0',
                    "Sets the test run repetition. (Can be used only with --test option.)",
                    false, 0);
    cmd.add("web-reporter", 'w',
            "Enables web reporter");
    cmd.add<int>("web-port", '\0',
                    "Sets the web reporter server port. (The default port number is 8080.)",
                    false, 8080);
    cmd.add("recursive", 'r',
            "Searches into subfolders for plugins or XML files. (Can be used with --tests or --suits options.)");
    cmd.add("detail", 'd',
            "Enables verbose mode of test assertions.");
    cmd.add("verbose", 'v',
            "Enables verbose mode.");
    cmd.add("version", '\0',
            "Shows version information.");
}

static TestRunner* currentRunner = NULL;
void signalHandler(int signum) {
    cout<<endl<<"[testrunner] interrupted..."<<endl<<endl;
    if(currentRunner)
        currentRunner->interrupt();
}

#if defined(WIN32)
BOOL CtrlHandler( DWORD fdwCtrlType ) {
  switch( fdwCtrlType ) {
    // Handle the CTRL-C signal.
    case CTRL_C_EVENT:
        signalHandler(0);
        return(TRUE);
    case CTRL_BREAK_EVENT:
        signalHandler(0);
      return TRUE;
    default:
      return FALSE;
  }
}
#endif

int main(int argc, char *argv[]) {

// setup signal handler to cathc ctrl+c
#if defined(WIN32)
     SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
#else
    struct sigaction new_action, old_action;
    new_action.sa_handler = signalHandler;
    sigemptyset (&new_action.sa_mask);
    new_action.sa_flags = 0;
    sigaction (SIGINT, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGINT, &new_action, NULL);
    sigaction (SIGHUP, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGHUP, &new_action, NULL);
    sigaction (SIGTERM, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGTERM, &new_action, NULL);
#endif

    cmdline::parser cmd;
    addOptions(cmd);
    cmd.parse_check(argc, argv);

    // print version info
    if(cmd.exist("version")) {
        cout<<"testrunner version "<<TESTRUNNER_VERSION<<endl;
        return 0;
    }

    // exit if no test or suit is given
    if(!cmd.get<string>("test").size() &&
            !cmd.get<string>("tests").size() &&
            !cmd.get<string>("suit").size() &&
            !cmd.get<string>("suits").size()) {
        cout<<cmd.usage();
        return 0;
    }

    // create a test runner
    SuitRunner runner(cmd.exist("verbose"));
    currentRunner = &runner;

    // load a single plugin
    if(cmd.get<string>("test").size())
        if(!runner.loadPlugin(cmd.get<string>("test"),
                              cmd.get<unsigned int>("repetition"),
                              cmd.get<string>("param"),
                              cmd.get<string>("environment"))) {
            reportErrors();
            return EXIT_FAILURE;
        }

    // load multiple plugins
    if(cmd.get<string>("tests").size())
        if(!runner.loadMultiplePlugins(cmd.get<string>("tests"),
                                       cmd.exist("recursive"))) {
            reportErrors();
            return EXIT_FAILURE;
        }

    // load a single suit
    if(cmd.get<string>("suit").size())
        if(!runner.loadSuit(cmd.get<string>("suit"))) {
            reportErrors();
            return EXIT_FAILURE;
        }

    // load multiple suits
    if(cmd.get<string>("suits").size())
        if(!runner.loadMultipleSuits(cmd.get<string>("suits"),
                                       cmd.exist("recursive"))) {
            reportErrors();
            return EXIT_FAILURE;
        }

    // report any warning or errors
    reportErrors();

    // create a test result collector to collect the result
    TestResultCollector collector;

    // create a test result and add the listeners
    TestResult result;
    result.addListener(&collector);

    // create a test listener to collect the result
    ConsoleListener listener(cmd.exist("detail"));
    result.addListener(&listener);
    if(!cmd.exist("verbose"))
        listener.hideUncriticalMessages();

    // create web listener
#if defined(ENABLE_WEB_LISTENER)
    WebProgressListener webListener(cmd.get<int>("web-port"),
                                    cmd.exist("detail"));
#endif
    if(cmd.exist("web-reporter")) {
#if defined(ENABLE_WEB_LISTENER)
        result.addListener(&webListener);
#else
        cout<<"Web reporter is not enabled! (please build RTF with ENABLE_WEB_LISTENER.)"<<endl;
#endif
    }

    // create a test runner and run the test case
    runner.run(result);

    // store the results
    string outptType = cmd.get<string>("output-type");
    if (outptType == "text") {
        TextOutputter outputter(collector, cmd.exist("detail"));
        string output = (cmd.get<string>("output").size() == 0) ? "result.txt" : cmd.get<string>("output");
        RTF::TestMessage msg;
        if(!outputter.write(output, &msg))
            cout<<endl<<msg.getMessage()<<". "<<msg.getDetail()<<endl;
    } else if (outptType == "junit") {
        JUnitOutputter outputter(collector, cmd.exist("detail"));
        string output = (cmd.get<string>("output").size() == 0) ? "result.xml" : cmd.get<string>("output");
        RTF::TestMessage msg;
        if(!outputter.write(output, &msg)) {
            cout<<endl<<msg.getMessage()<<". "<<msg.getDetail()<<endl;
        }
    }else
        cout<<endl<<"Results are not saved! Unknown output type "<<outptType<<"."<<endl;

    // print out some simple statistics
    cout<<endl<<"---------- results -----------"<<endl;
    if(collector.suitCount()) {
    cout<<"Total number of test suites  : "<<collector.suitCount()<<endl;
    cout<<"Number of passed test suites : "<<collector.passedSuitCount()<<endl;
    cout<<"Number of failed test suites : "<<collector.failedSuitCount()<<endl;
    }
    cout<<"Total number of test cases   : "<<collector.testCount()<<endl;
    cout<<"Number of passed test cases  : "<<collector.passedCount()<<endl;
    cout<<"Number of failed test cases  : "<<collector.failedCount()<<endl;

    currentRunner = NULL;

    int exitCode;
    if( (collector.failedCount() == 0)  &&
        (collector.failedSuitCount() == 0))
        exitCode = EXIT_SUCCESS;
    else
        exitCode = EXIT_FAILURE;

    return exitCode;
}
<commit_msg>forces to kill the tests after receiving CTRL+C for more than 3 times<commit_after>// -*- mode:C++ { } tab-width:4 { } c-basic-offset:4 { } indent-tabs-mode:nil -*-

/*
 * Copyright (C) 2015 iCub Facility
 * Authors: Ali Paikan
 * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
 *
 */

#include <cstdlib>
#include <stdio.h>

#include <rtf/TestResult.h>
#include <rtf/ConsoleListener.h>
#include <rtf/TestResultCollector.h>
#include <rtf/TextOutputter.h>
#include <JUnitOutputter.h>

#include <cmdline.h>
#include <SuitRunner.h>
#include <ErrorLogger.h>
#include <Version.h>

#if defined(ENABLE_WEB_LISTENER)
    #include <rtf/WebProgressListener.h>
#endif

#if defined(WIN32)
    #include <windows.h>
#else
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <signal.h>
#endif

using namespace RTF;
using namespace std;

void reportErrors(void) {
    ErrorLogger& logger  = ErrorLogger::Instance();
    for(unsigned int i=0; i<logger.errorCount(); i++)
        cout<<"[testrunner] "<<logger.getLastError()<<endl;
    for(unsigned int i=0; i<logger.warningCount(); i++)
        cout<<"[testrunner] "<<logger.getLastWarning()<<endl;
}

void addOptions(cmdline::parser &cmd) {
    cmd.add<string>("test", 't',
                    "Runs a single test from the given plugin file.",
                    false);

    cmd.add<string>("tests", '\0',
                    "Runs multiple tests from the given folder which contains plugins.",
                    false);

    cmd.add<string>("suit", 's',
                    "Runs a single test suit from the given XMl file.",
                    false);

    cmd.add<string>("suits", '\0',
                    "Runs multiple test suits from the given folder which contains XML files.",
                    false);

    cmd.add<string>("output", 'o',
                    "The output file to save the result. Default is result.txt",
                    false, "");
    cmd.add<string>("output-type", '\0',
                    "The output file type (text, junit)",
                    false, "text");

    cmd.add<string>("param", 'p',
                    "Sets the test case parameters. (Can be used only with --test option.)",
                    false);
    cmd.add<string>("environment", 'e',
                    "Sets the test case environment. (Can be used only with --test option.)",
                    false);
    cmd.add<unsigned int>("repetition", '\0',
                    "Sets the test run repetition. (Can be used only with --test option.)",
                    false, 0);
    cmd.add("web-reporter", 'w',
            "Enables web reporter");
    cmd.add<int>("web-port", '\0',
                    "Sets the web reporter server port. (The default port number is 8080.)",
                    false, 8080);
    cmd.add("recursive", 'r',
            "Searches into subfolders for plugins or XML files. (Can be used with --tests or --suits options.)");
    cmd.add("detail", 'd',
            "Enables verbose mode of test assertions.");
    cmd.add("verbose", 'v',
            "Enables verbose mode.");
    cmd.add("version", '\0',
            "Shows version information.");
}

static TestRunner* currentRunner = NULL;
void signalHandler(int signum) {
    static int interuptCount = 1;
    cout<<endl<<"[testrunner] ("<<interuptCount<<") interrupted..."<<endl<<endl;
    if(interuptCount++ > 3) {
        cout<<endl<<"[testrunner] killing the tests (interrupted for more than 3 times)!"<<endl<<endl;
        exit(EXIT_FAILURE);
    }

    if(currentRunner)
        currentRunner->interrupt();
}

#if defined(WIN32)
BOOL CtrlHandler( DWORD fdwCtrlType ) {
  switch( fdwCtrlType ) {
    // Handle the CTRL-C signal.
    case CTRL_C_EVENT:
        signalHandler(0);
        return(TRUE);
    case CTRL_BREAK_EVENT:
        signalHandler(0);
      return TRUE;
    default:
      return FALSE;
  }
}
#endif

int main(int argc, char *argv[]) {

// setup signal handler to cathc ctrl+c
#if defined(WIN32)
     SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
#else
    struct sigaction new_action, old_action;
    new_action.sa_handler = signalHandler;
    sigemptyset (&new_action.sa_mask);
    new_action.sa_flags = 0;
    sigaction (SIGINT, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGINT, &new_action, NULL);
    sigaction (SIGHUP, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGHUP, &new_action, NULL);
    sigaction (SIGTERM, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
        sigaction (SIGTERM, &new_action, NULL);
#endif

    cmdline::parser cmd;
    addOptions(cmd);
    cmd.parse_check(argc, argv);

    // print version info
    if(cmd.exist("version")) {
        cout<<"testrunner version "<<TESTRUNNER_VERSION<<endl;
        return 0;
    }

    // exit if no test or suit is given
    if(!cmd.get<string>("test").size() &&
            !cmd.get<string>("tests").size() &&
            !cmd.get<string>("suit").size() &&
            !cmd.get<string>("suits").size()) {
        cout<<cmd.usage();
        return 0;
    }

    // create a test runner
    SuitRunner runner(cmd.exist("verbose"));
    currentRunner = &runner;

    // load a single plugin
    if(cmd.get<string>("test").size())
        if(!runner.loadPlugin(cmd.get<string>("test"),
                              cmd.get<unsigned int>("repetition"),
                              cmd.get<string>("param"),
                              cmd.get<string>("environment"))) {
            reportErrors();
            return EXIT_FAILURE;
        }

    // load multiple plugins
    if(cmd.get<string>("tests").size())
        if(!runner.loadMultiplePlugins(cmd.get<string>("tests"),
                                       cmd.exist("recursive"))) {
            reportErrors();
            return EXIT_FAILURE;
        }

    // load a single suit
    if(cmd.get<string>("suit").size())
        if(!runner.loadSuit(cmd.get<string>("suit"))) {
            reportErrors();
            return EXIT_FAILURE;
        }

    // load multiple suits
    if(cmd.get<string>("suits").size())
        if(!runner.loadMultipleSuits(cmd.get<string>("suits"),
                                       cmd.exist("recursive"))) {
            reportErrors();
            return EXIT_FAILURE;
        }

    // report any warning or errors
    reportErrors();

    // create a test result collector to collect the result
    TestResultCollector collector;

    // create a test result and add the listeners
    TestResult result;
    result.addListener(&collector);

    // create a test listener to collect the result
    ConsoleListener listener(cmd.exist("detail"));
    result.addListener(&listener);
    if(!cmd.exist("verbose"))
        listener.hideUncriticalMessages();

    // create web listener
#if defined(ENABLE_WEB_LISTENER)
    WebProgressListener webListener(cmd.get<int>("web-port"),
                                    cmd.exist("detail"));
#endif
    if(cmd.exist("web-reporter")) {
#if defined(ENABLE_WEB_LISTENER)
        result.addListener(&webListener);
#else
        cout<<"Web reporter is not enabled! (please build RTF with ENABLE_WEB_LISTENER.)"<<endl;
#endif
    }

    // create a test runner and run the test case
    runner.run(result);

    // store the results
    string outptType = cmd.get<string>("output-type");
    if (outptType == "text") {
        TextOutputter outputter(collector, cmd.exist("detail"));
        string output = (cmd.get<string>("output").size() == 0) ? "result.txt" : cmd.get<string>("output");
        RTF::TestMessage msg;
        if(!outputter.write(output, &msg))
            cout<<endl<<msg.getMessage()<<". "<<msg.getDetail()<<endl;
    } else if (outptType == "junit") {
        JUnitOutputter outputter(collector, cmd.exist("detail"));
        string output = (cmd.get<string>("output").size() == 0) ? "result.xml" : cmd.get<string>("output");
        RTF::TestMessage msg;
        if(!outputter.write(output, &msg)) {
            cout<<endl<<msg.getMessage()<<". "<<msg.getDetail()<<endl;
        }
    }else
        cout<<endl<<"Results are not saved! Unknown output type "<<outptType<<"."<<endl;

    // print out some simple statistics
    cout<<endl<<"---------- results -----------"<<endl;
    if(collector.suitCount()) {
    cout<<"Total number of test suites  : "<<collector.suitCount()<<endl;
    cout<<"Number of passed test suites : "<<collector.passedSuitCount()<<endl;
    cout<<"Number of failed test suites : "<<collector.failedSuitCount()<<endl;
    }
    cout<<"Total number of test cases   : "<<collector.testCount()<<endl;
    cout<<"Number of passed test cases  : "<<collector.passedCount()<<endl;
    cout<<"Number of failed test cases  : "<<collector.failedCount()<<endl;

    currentRunner = NULL;

    int exitCode;
    if( (collector.failedCount() == 0)  &&
        (collector.failedSuitCount() == 0))
        exitCode = EXIT_SUCCESS;
    else
        exitCode = EXIT_FAILURE;

    return exitCode;
}
<|endoftext|>


<commit_before>/*
* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/

/**
 @file
 @internalComponent
 @released
*/

#include "persistencelayerimpl.h"
#include "clplcontactproperties.h"
#include "cntfilesearch.h"
#include "persistencelayer.h"
#include "cntdbconsts_internal.h"
#include "cntimagerescaleutility.h"

#include <pathinfo.h>
#include <driveinfo.h>
#include <bautils.h>
#include <utf.h>

const TInt KDriveNameWidth = 2; // e.g. "C:"

_LIT(KSqLiteFilePrefix, "SQLite__");

// Transaction constants (only used by CPplContactsFile)
_LIT(KStartTransaction,"BEGIN TRANSACTION;");
_LIT(KCommitTransaction,"COMMIT;");
_LIT(KRollbackTransaction,"ROLLBACK;");

/**
@SYMPatchable
@publishedPartner
@released

Patchable optional constant that overrides the cache size of the Contacts model databases set in the
SqlServer.cfg file in the SQL data cage.
If this value is left at 0, the cache size from the SqlServer.cfg file is used.
The cache size affects the size of the cache in Kb that opens and creates Contacts model files.
See SQLite documentation for more details.

The constant can be changed at ROM build time using patchdata OBY keyword.
*/
IMPORT_C extern const TInt KContactsModelSqliteDbCacheSize;

const TInt KCacheDataSize = 8; // The size in chars of patchable constant 'KContactsModelSqliteDbCacheSize' passed in

//configure string used to create and open sqlite database
_LIT8(KSqliteCacheSize, "cache_size=%d");

/**
CPplContactsFile NewL.
*/
CPplContactsFile* CPplContactsFile::NewL(CLplContactProperties& aProps, MContactDbObserverV2* aObserver)
	{
	CPplContactsFile* self = new (ELeave) CPplContactsFile(aProps, aObserver);
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

/**
CPplContactsFile ConstructL.
*/
void CPplContactsFile::ConstructL()
	{
    // Do this first since the contacts table created by the
    // iItemManager will need to know if the directory exists.
   TCntImageRescaleUtility::CreateImageDirectoryL();

	iItemManager = CPplContactItemManager::NewL(iDatabase, *this, iContactProperties, iIccContactStore);
	iContactProperties.SetContactItemManagerL(*iItemManager);

	iConfigureStr = NULL;
	if(KContactsModelSqliteDbCacheSize > 0)
		{
		//Create configure string to be used when creating/opening database
		iConfigureStr = HBufC8::NewL(KSqliteCacheSize().Length() + KCacheDataSize);
		TPtr8 ptrConfigureStr = iConfigureStr->Des();
		ptrConfigureStr.Format(KSqliteCacheSize(), KContactsModelSqliteDbCacheSize);
		}
	}

/**
CPplContactsFile constructor.
*/
CPplContactsFile::CPplContactsFile(CLplContactProperties& aProps, MContactDbObserverV2* aObserver)
	:
	iActive(EFalse),
 	iDbObserver(aObserver),
 	iContactProperties(aProps),
 	iIccContactStore(aProps)
	{
	}

/**
CPplContactsFile destructor.
*/
CPplContactsFile::~CPplContactsFile()
	{
  	Close();
	delete iItemManager;
	delete iConfigureStr;
	iSqlDatabaseObservers.Reset();
	}

/**
Set the database observer for event propagation.
*/
void CPplContactsFile::RegisterDbObserver(MContactDbObserverV2& aDbObserver)
	{
	iDbObserver = &aDbObserver;
	}

/**
Utility method used to construct physical path for a given file name

@param aPhysicalFileName in/out paramter; file name to which physical path will be append
@param aSecuredFileName secured file name
*/
void CPplContactsFile::GetPhysicalFileNameL(TDes& aPhysicalFileName, const TDesC& aSecuredFileName)
	{
	GetPhysicalPathL(aPhysicalFileName, aSecuredFileName);
	aPhysicalFileName.Append(KSqLiteFilePrefix);
	aPhysicalFileName.Append(aSecuredFileName.Right(aSecuredFileName.Length() - KDriveNameWidth));
	}

/**
Utility method used to construct physical path for a given file name

@param aPhysicalFileName in/out paramter; file name to which physical path will be append
@param aSecuredFileName secured file name
*/
void CPplContactsFile::GetPhysicalPathL(TDes& aPhysicalFileName, const TDesC& aSecuredFileName)
	{
	const TUint16 KDriveDelimiter = ':';

	// Check for the drive delimiter.
	__ASSERT_ALWAYS(aSecuredFileName.Length() > 2 &&
		aSecuredFileName[1] == KDriveDelimiter, User::Leave(KErrBadName));

	// Check for malformed file name (path included explicitly).
	__ASSERT_ALWAYS(aSecuredFileName.Locate('\\') == KErrNotFound, User::Leave(KErrBadName));

	// Get the private path from the file session.
	const TInt KMaxPrivatePathLength = 32;
	TBuf<KMaxPrivatePathLength> privatePath;

  	LocalFsL();
  	iLocalFs.PrivatePath(privatePath);

	aPhysicalFileName = aSecuredFileName.Left(KDriveNameWidth);

	// Set current drive.
	iDatabaseDrive = aPhysicalFileName;

	aPhysicalFileName.Append(privatePath);

  	// Make sure private path exists.
  	TInt err = iLocalFs.MkDirAll(aPhysicalFileName);
	if (err != KErrNone && err != KErrAlreadyExists)
		{
		User::Leave(err);
		}
	}

/**
Open the given database file.
*/
void CPplContactsFile::OpenL(const TDesC& aFileName, TBool aNotify)
	{
	// Contact databases are in the Contact model private directory.
	TFileName fileName;
	GetPhysicalFileNameL(fileName, aFileName);

	iDatabase.Close();
	iDatabase.OpenL(fileName, iConfigureStr);

    iFileIsOpen = ETrue;

    //check compatibility
    iItemManager->MakeDatabaseCompatibleL();

	GenerateNotificationEventL(aNotify);
	}
/**
Utility method used to generate EContactDbObserverEventTablesOpened event
*/
void CPplContactsFile::GenerateNotificationEventL(TBool aNotify)
	{
	#if defined(__PROFILE_DEBUG__)
		RDebug::Print(_L("[CNTMODEL] MTD: CPplContactsFile::GenerateNotificationEventL"));
	#endif

	// Generate an event - this event is generated if this was an explicit call from the
 	// server to opentables or recover database - ie A call on the contactsDatabase API
 	if (iDbObserver && aNotify)
 		{
 		TContactDbObserverEventV2 event;
		event.iType = EContactDbObserverEventTablesOpened;
		event.iContactId = 0;
 		event.iConnectionId = 0;
 		event.iTypeV2 = EContactDbObserverEventV2Null;
 		event.iAdditionalContactIds = NULL;
 		TRAP_IGNORE(iDbObserver->HandleDatabaseEventV2L(event));
 		}
	}

/**
  Open the database tables (a state change, no action on file necessary).
*/
void CPplContactsFile::OpenTablesL(TBool aNotify)
  	{
  	// Do nothing but notify

  	#if defined(__PROFILE_DEBUG__)
  	    _LIT(KMessage, "[CNTMODEL] MTD: CPplContactsFile::OpenTablesL");
  		RDebug::Print(KMessage);
  	#endif

	iFileIsOpen = ETrue;
 	GenerateNotificationEventL(aNotify);
   	}

/**
  Close the database tables leaving the iDatabase itself open.
  Despite the trailing 'L', this method cannot leave.
*/
void CPplContactsFile::CloseTablesL(TBool aNotify)
	{
	// Do nothing but notify

 	if (iDbObserver && aNotify) // Observer is optional.
  		{
  		// Notify observers that table is closed.
  		TContactDbObserverEventV2 event;
  		event.iType = EContactDbObserverEventTablesClosed;
  		event.iContactId = 0;
  		event.iConnectionId = 0;
        event.iTypeV2 = EContactDbObserverEventV2Null;
        event.iAdditionalContactIds = NULL;
  		TRAP_IGNORE(iDbObserver->HandleDatabaseEventV2L(event));
  		}
  	}

/**
File cleanup class used if creating database and its tables leaves.
*/
class TFileCleanup
	{
public:
	TFileCleanup(RSqlDatabase& aDb, RFs& aFs, const TDesC& aFileName) : iDb(aDb),iFs(aFs),iFileName(aFileName) {}
	static void Cleanup(TAny* aSelf) { STATIC_CAST(TFileCleanup*,aSelf)->DoCleanup(); }

private:
	void DoCleanup()
		{
		iDb.Close();
		(void)iFs.Delete(iFileName);
		}

public:
	RSqlDatabase& iDb;
	RFs& iFs;
	const TDesC& iFileName;
	};

/**
Create a new database.
*/
EXPORT_C void CPplContactsFile::CreateL(const TDesC& aFileName, TPlCreateMode aMode)
	{
	TFileName fileName;
	GetPhysicalFileNameL(fileName, aFileName);

	TUint attVal;
	LocalFsL();
	TInt err = iLocalFs.Att(fileName, attVal);
	TBool fileExists = (err == KErrNone);

	if (fileExists)
		{
		switch (aMode)
			{
			case EPlLeaveIfExist:
				User::Leave(KErrAlreadyExists);
				break;

			case EPlOverwrite:
				err = iLocalFs.Delete(fileName);
				break;
			}
		}

	// If the database is not created propertly delete the database file using
	// the cleanup item.
	TFileCleanup cleanupData(iDatabase, iLocalFs, fileName);
	CleanupStack::PushL(TCleanupItem(TFileCleanup::Cleanup,&cleanupData));

	if ((err != KErrNone) && (err != KErrNotFound))
		{
		User::LeaveIfError(err);
		}

	User::LeaveIfError(iDatabase.Create(fileName, iConfigureStr));
  	iItemManager->CreateTablesL();

  	// If the folder exists recreate it since the database is new
  	TRAP_IGNORE(TCntImageRescaleUtility::DeleteImageDirectoryL());
  	TCntImageRescaleUtility::CreateImageDirectoryL();

  	iContactProperties.SystemTemplateManager().RecreateSystemTemplateL();

	CleanupStack::Pop(); // The TCleanupItem.

	iDatabase.Close();
	}

/**
Delete the given database.
*/
void CPplContactsFile::DeleteL(const TDesC& aFileName)
	{
	TFileName fileName;
	GetPhysicalFileNameL(fileName, aFileName);

	User::LeaveIfError(iLocalFs.Delete(fileName));

	TCntImageRescaleUtility::DeleteImageDirectoryL();

	iFileIsOpen = EFalse;
	}

/**
Get a list of the contacts database on the given drive.
*/
CDesCArray* CPplContactsFile::ListL(TDriveUnit* aDriveUnit)
	{
 	LocalFsL();
  	return CCntFileScanner::ListFilesL(iLocalFs, aDriveUnit);
	}

/**
Close the database.
*/
void CPplContactsFile::Close(TBool aNotify)
	{
	// Close the resource which depends on iDatabase before it will be closed.
    for (TInt i = 0; i < iSqlDatabaseObservers.Count(); i++ )
        {
        iSqlDatabaseObservers[i]->OnCloseL();
        }

  	iDatabase.Close();
  	iFileIsOpen = EFalse;

  	REComSession::FinalClose(); // This line is necessary to make sure the plug-in is unloaded properly
  	iLocalFs.Close(); //we now use a local File Session

	iIccContactStore.Close();

	TRAP_IGNORE(CloseTablesL(aNotify) ); // CloseTablesL() cannot leave anyway but still
										 // trap in case implementation changes later
	}

/**
Starts a new transaction if one is not currently active otherwise leave.
*/
void CPplContactsFile::StartTransactionL()
	{
	if (iActive)
		{
		User::Leave(KErrInUse);
		}
	User::LeaveIfError(iDatabase.Exec(KStartTransaction));
	iIccContactStore.StartTransactionL();
	iActive = ETrue;
	}

/**
Commit all changes made since the transaction was started.
*/
void CPplContactsFile::CommitCurrentTransactionL(TUint aSessionId)
	{

	if (!iActive)
		{
		User::Leave(KErrNotReady);
		}
	iIccContactStore.CommitCurrentTransactionL(aSessionId);
	User::LeaveIfError(iDatabase.Exec(KCommitTransaction));
	iActive = EFalse;
	}

/**
Rollback all changes made since the active the transaction was started.
*/
void CPplContactsFile::RollbackCurrentTransactionL(TUint aSessionId)
	{
	// Check that the database is open before rolling back.
	if (iFileIsOpen && iActive)
		{
		iActive = EFalse;
		iIccContactStore.RollbackCurrentTransaction(aSessionId);
		User::LeaveIfError(iDatabase.Exec(KRollbackTransaction));
		}
	}

/**
Gets the size of the database file in bytes.

@return The size of the contact database.
*/
TInt CPplContactsFile::FileSize() const
 	{
  	return iDatabase.Size();
  	}

/**
Gets the current database drive.  The database drive is the drive on which
the default contact database is located.

@param aDriveUnit On return, contains the database drive.
*/
void CPplContactsFile::DatabaseDrive(TDriveUnit& aDriveUnit)
	{
	aDriveUnit = iDatabaseDrive;
	}

/**
A static method to determine if a given Contacts database exists.

@param	aFileName The Contacts database to search for.

@return ETrue if the Contacts database is found, EFalse otherwise.
*/
TBool CPplContactsFile::DatabaseExistsL(const TDesC& aFileName)
	{
	TFileName fileName;
	GetPhysicalFileNameL(fileName, aFileName);
	LocalFsL();
	return BaflUtils::FileExists(iLocalFs, fileName);
	}

/**
 * Add an observer for monitoring RSqlDatabase.
 *
 * @param  aSqlDatabaseObserver The observer for monitoring RSqlDatabase.
 *
 * @return None
 */
void CPplContactsFile::AddSqlDBObserverL(
    MLplSqlDatabaseObserver& aSqlDatabaseObserver )
    {
    iSqlDatabaseObservers.AppendL( &aSqlDatabaseObserver );
    }

/**
 * Remove an RSqlDatabase observer.
 *
 * @param  aSqlDatabaseObserver The observer is to be removed.
 *
 * @return None
 */
void CPplContactsFile::RemoveSqlDBObserverL(
    MLplSqlDatabaseObserver& aSqlDatabaseObserver )
    {
    TInt id = iSqlDatabaseObservers.Find( &aSqlDatabaseObserver );
    if ( id != KErrNotFound )
        {
        iSqlDatabaseObservers.Remove( id );
        }
    }

<commit_msg>Bug id: ou1cimx1#740266<commit_after>/*
* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/

/**
 @file
 @internalComponent
 @released
*/

#include "persistencelayerimpl.h"
#include "clplcontactproperties.h"
#include "cntfilesearch.h"
#include "persistencelayer.h"
#include "cntdbconsts_internal.h"
#include "cntimagerescaleutility.h"

#include <pathinfo.h>
#include <driveinfo.h>
#include <bautils.h>
#include <utf.h>

const TInt KDriveNameWidth = 2; // e.g. "C:"

_LIT(KSqLiteFilePrefix, "SQLite__");

// Transaction constants (only used by CPplContactsFile)
_LIT(KStartTransaction,"BEGIN TRANSACTION;");
_LIT(KCommitTransaction,"COMMIT;");
_LIT(KRollbackTransaction,"ROLLBACK;");

/**
@SYMPatchable
@publishedPartner
@released

Patchable optional constant that overrides the cache size of the Contacts model databases set in the
SqlServer.cfg file in the SQL data cage.
If this value is left at 0, the cache size from the SqlServer.cfg file is used.
The cache size affects the size of the cache in Kb that opens and creates Contacts model files.
See SQLite documentation for more details.

The constant can be changed at ROM build time using patchdata OBY keyword.
*/
IMPORT_C extern const TInt KContactsModelSqliteDbCacheSize;

const TInt KCacheDataSize = 8; // The size in chars of patchable constant 'KContactsModelSqliteDbCacheSize' passed in

//configure string used to create and open sqlite database
_LIT8(KSqliteCacheSize, "cache_size=%d");

/**
CPplContactsFile NewL.
*/
CPplContactsFile* CPplContactsFile::NewL(CLplContactProperties& aProps, MContactDbObserverV2* aObserver)
	{
	CPplContactsFile* self = new (ELeave) CPplContactsFile(aProps, aObserver);
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

/**
CPplContactsFile ConstructL.
*/
void CPplContactsFile::ConstructL()
    {
    // Do this first since the contacts table created by the
    // iItemManager will need to know if the directory exists.
    TRAP_IGNORE(TCntImageRescaleUtility::CreateImageDirectoryL());

    iItemManager = CPplContactItemManager::NewL(iDatabase, *this, iContactProperties, iIccContactStore);
    iContactProperties.SetContactItemManagerL(*iItemManager);

    iConfigureStr = NULL;
    if(KContactsModelSqliteDbCacheSize > 0)
        {
        //Create configure string to be used when creating/opening database
        iConfigureStr = HBufC8::NewL(KSqliteCacheSize().Length() + KCacheDataSize);
        TPtr8 ptrConfigureStr = iConfigureStr->Des();
        ptrConfigureStr.Format(KSqliteCacheSize(), KContactsModelSqliteDbCacheSize);
        }
    }

/**
CPplContactsFile constructor.
*/
CPplContactsFile::CPplContactsFile(CLplContactProperties& aProps, MContactDbObserverV2* aObserver)
	:
	iActive(EFalse),
 	iDbObserver(aObserver),
 	iContactProperties(aProps),
 	iIccContactStore(aProps)
	{
	}

/**
CPplContactsFile destructor.
*/
CPplContactsFile::~CPplContactsFile()
	{
  	Close();
	delete iItemManager;
	delete iConfigureStr;
	iSqlDatabaseObservers.Reset();
	}

/**
Set the database observer for event propagation.
*/
void CPplContactsFile::RegisterDbObserver(MContactDbObserverV2& aDbObserver)
	{
	iDbObserver = &aDbObserver;
	}

/**
Utility method used to construct physical path for a given file name

@param aPhysicalFileName in/out paramter; file name to which physical path will be append
@param aSecuredFileName secured file name
*/
void CPplContactsFile::GetPhysicalFileNameL(TDes& aPhysicalFileName, const TDesC& aSecuredFileName)
	{
	GetPhysicalPathL(aPhysicalFileName, aSecuredFileName);
	aPhysicalFileName.Append(KSqLiteFilePrefix);
	aPhysicalFileName.Append(aSecuredFileName.Right(aSecuredFileName.Length() - KDriveNameWidth));
	}

/**
Utility method used to construct physical path for a given file name

@param aPhysicalFileName in/out paramter; file name to which physical path will be append
@param aSecuredFileName secured file name
*/
void CPplContactsFile::GetPhysicalPathL(TDes& aPhysicalFileName, const TDesC& aSecuredFileName)
	{
	const TUint16 KDriveDelimiter = ':';

	// Check for the drive delimiter.
	__ASSERT_ALWAYS(aSecuredFileName.Length() > 2 &&
		aSecuredFileName[1] == KDriveDelimiter, User::Leave(KErrBadName));

	// Check for malformed file name (path included explicitly).
	__ASSERT_ALWAYS(aSecuredFileName.Locate('\\') == KErrNotFound, User::Leave(KErrBadName));

	// Get the private path from the file session.
	const TInt KMaxPrivatePathLength = 32;
	TBuf<KMaxPrivatePathLength> privatePath;

  	LocalFsL();
  	iLocalFs.PrivatePath(privatePath);

	aPhysicalFileName = aSecuredFileName.Left(KDriveNameWidth);

	// Set current drive.
	iDatabaseDrive = aPhysicalFileName;

	aPhysicalFileName.Append(privatePath);

  	// Make sure private path exists.
  	TInt err = iLocalFs.MkDirAll(aPhysicalFileName);
	if (err != KErrNone && err != KErrAlreadyExists)
		{
		User::Leave(err);
		}
	}

/**
Open the given database file.
*/
void CPplContactsFile::OpenL(const TDesC& aFileName, TBool aNotify)
	{
	// Contact databases are in the Contact model private directory.
	TFileName fileName;
	GetPhysicalFileNameL(fileName, aFileName);

	iDatabase.Close();
	iDatabase.OpenL(fileName, iConfigureStr);

    iFileIsOpen = ETrue;

    //check compatibility
    iItemManager->MakeDatabaseCompatibleL();

	GenerateNotificationEventL(aNotify);
	}
/**
Utility method used to generate EContactDbObserverEventTablesOpened event
*/
void CPplContactsFile::GenerateNotificationEventL(TBool aNotify)
	{
	#if defined(__PROFILE_DEBUG__)
		RDebug::Print(_L("[CNTMODEL] MTD: CPplContactsFile::GenerateNotificationEventL"));
	#endif

	// Generate an event - this event is generated if this was an explicit call from the
 	// server to opentables or recover database - ie A call on the contactsDatabase API
 	if (iDbObserver && aNotify)
 		{
 		TContactDbObserverEventV2 event;
		event.iType = EContactDbObserverEventTablesOpened;
		event.iContactId = 0;
 		event.iConnectionId = 0;
 		event.iTypeV2 = EContactDbObserverEventV2Null;
 		event.iAdditionalContactIds = NULL;
 		TRAP_IGNORE(iDbObserver->HandleDatabaseEventV2L(event));
 		}
	}

/**
  Open the database tables (a state change, no action on file necessary).
*/
void CPplContactsFile::OpenTablesL(TBool aNotify)
  	{
  	// Do nothing but notify

  	#if defined(__PROFILE_DEBUG__)
  	    _LIT(KMessage, "[CNTMODEL] MTD: CPplContactsFile::OpenTablesL");
  		RDebug::Print(KMessage);
  	#endif

	iFileIsOpen = ETrue;
 	GenerateNotificationEventL(aNotify);
   	}

/**
  Close the database tables leaving the iDatabase itself open.
  Despite the trailing 'L', this method cannot leave.
*/
void CPplContactsFile::CloseTablesL(TBool aNotify)
	{
	// Do nothing but notify

 	if (iDbObserver && aNotify) // Observer is optional.
  		{
  		// Notify observers that table is closed.
  		TContactDbObserverEventV2 event;
  		event.iType = EContactDbObserverEventTablesClosed;
  		event.iContactId = 0;
  		event.iConnectionId = 0;
        event.iTypeV2 = EContactDbObserverEventV2Null;
        event.iAdditionalContactIds = NULL;
  		TRAP_IGNORE(iDbObserver->HandleDatabaseEventV2L(event));
  		}
  	}

/**
File cleanup class used if creating database and its tables leaves.
*/
class TFileCleanup
	{
public:
	TFileCleanup(RSqlDatabase& aDb, RFs& aFs, const TDesC& aFileName) : iDb(aDb),iFs(aFs),iFileName(aFileName) {}
	static void Cleanup(TAny* aSelf) { STATIC_CAST(TFileCleanup*,aSelf)->DoCleanup(); }

private:
	void DoCleanup()
		{
		iDb.Close();
		(void)iFs.Delete(iFileName);
		}

public:
	RSqlDatabase& iDb;
	RFs& iFs;
	const TDesC& iFileName;
	};

/**
Create a new database.
*/
EXPORT_C void CPplContactsFile::CreateL(const TDesC& aFileName, TPlCreateMode aMode)
    {
    TFileName fileName;
    GetPhysicalFileNameL(fileName, aFileName);

    TUint attVal;
    LocalFsL();
    TInt err = iLocalFs.Att(fileName, attVal);
    TBool fileExists = (err == KErrNone);

    if (fileExists)
        {
        switch (aMode)
            {
            case EPlLeaveIfExist:
                User::Leave(KErrAlreadyExists);
                break;

            case EPlOverwrite:
                err = iLocalFs.Delete(fileName);
                break;
            }
        }

    // If the database is not created propertly delete the database file using
    // the cleanup item.
    TFileCleanup cleanupData(iDatabase, iLocalFs, fileName);
    CleanupStack::PushL(TCleanupItem(TFileCleanup::Cleanup,&cleanupData));

    if ((err != KErrNone) && (err != KErrNotFound))
        {
        User::LeaveIfError(err);
        }

    User::LeaveIfError(iDatabase.Create(fileName, iConfigureStr));
    iItemManager->CreateTablesL();

    // If the folder exists recreate it since the database is new
    TRAP_IGNORE(TCntImageRescaleUtility::DeleteImageDirectoryL());
    TRAP_IGNORE(TCntImageRescaleUtility::CreateImageDirectoryL());

    iContactProperties.SystemTemplateManager().RecreateSystemTemplateL();

    CleanupStack::Pop(); // The TCleanupItem.

    iDatabase.Close();
    }

/**
Delete the given database.
*/
void CPplContactsFile::DeleteL(const TDesC& aFileName)
	{
	TFileName fileName;
	GetPhysicalFileNameL(fileName, aFileName);

	User::LeaveIfError(iLocalFs.Delete(fileName));

	TCntImageRescaleUtility::DeleteImageDirectoryL();

	iFileIsOpen = EFalse;
	}

/**
Get a list of the contacts database on the given drive.
*/
CDesCArray* CPplContactsFile::ListL(TDriveUnit* aDriveUnit)
	{
 	LocalFsL();
  	return CCntFileScanner::ListFilesL(iLocalFs, aDriveUnit);
	}

/**
Close the database.
*/
void CPplContactsFile::Close(TBool aNotify)
	{
	// Close the resource which depends on iDatabase before it will be closed.
    for (TInt i = 0; i < iSqlDatabaseObservers.Count(); i++ )
        {
        iSqlDatabaseObservers[i]->OnCloseL();
        }

  	iDatabase.Close();
  	iFileIsOpen = EFalse;

  	REComSession::FinalClose(); // This line is necessary to make sure the plug-in is unloaded properly
  	iLocalFs.Close(); //we now use a local File Session

	iIccContactStore.Close();

	TRAP_IGNORE(CloseTablesL(aNotify) ); // CloseTablesL() cannot leave anyway but still
										 // trap in case implementation changes later
	}

/**
Starts a new transaction if one is not currently active otherwise leave.
*/
void CPplContactsFile::StartTransactionL()
	{
	if (iActive)
		{
		User::Leave(KErrInUse);
		}
	User::LeaveIfError(iDatabase.Exec(KStartTransaction));
	iIccContactStore.StartTransactionL();
	iActive = ETrue;
	}

/**
Commit all changes made since the transaction was started.
*/
void CPplContactsFile::CommitCurrentTransactionL(TUint aSessionId)
	{

	if (!iActive)
		{
		User::Leave(KErrNotReady);
		}
	iIccContactStore.CommitCurrentTransactionL(aSessionId);
	User::LeaveIfError(iDatabase.Exec(KCommitTransaction));
	iActive = EFalse;
	}

/**
Rollback all changes made since the active the transaction was started.
*/
void CPplContactsFile::RollbackCurrentTransactionL(TUint aSessionId)
	{
	// Check that the database is open before rolling back.
	if (iFileIsOpen && iActive)
		{
		iActive = EFalse;
		iIccContactStore.RollbackCurrentTransaction(aSessionId);
		User::LeaveIfError(iDatabase.Exec(KRollbackTransaction));
		}
	}

/**
Gets the size of the database file in bytes.

@return The size of the contact database.
*/
TInt CPplContactsFile::FileSize() const
 	{
  	return iDatabase.Size();
  	}

/**
Gets the current database drive.  The database drive is the drive on which
the default contact database is located.

@param aDriveUnit On return, contains the database drive.
*/
void CPplContactsFile::DatabaseDrive(TDriveUnit& aDriveUnit)
	{
	aDriveUnit = iDatabaseDrive;
	}

/**
A static method to determine if a given Contacts database exists.

@param	aFileName The Contacts database to search for.

@return ETrue if the Contacts database is found, EFalse otherwise.
*/
TBool CPplContactsFile::DatabaseExistsL(const TDesC& aFileName)
	{
	TFileName fileName;
	GetPhysicalFileNameL(fileName, aFileName);
	LocalFsL();
	return BaflUtils::FileExists(iLocalFs, fileName);
	}

/**
 * Add an observer for monitoring RSqlDatabase.
 *
 * @param  aSqlDatabaseObserver The observer for monitoring RSqlDatabase.
 *
 * @return None
 */
void CPplContactsFile::AddSqlDBObserverL(
    MLplSqlDatabaseObserver& aSqlDatabaseObserver )
    {
    iSqlDatabaseObservers.AppendL( &aSqlDatabaseObserver );
    }

/**
 * Remove an RSqlDatabase observer.
 *
 * @param  aSqlDatabaseObserver The observer is to be removed.
 *
 * @return None
 */
void CPplContactsFile::RemoveSqlDBObserverL(
    MLplSqlDatabaseObserver& aSqlDatabaseObserver )
    {
    TInt id = iSqlDatabaseObservers.Find( &aSqlDatabaseObserver );
    if ( id != KErrNotFound )
        {
        iSqlDatabaseObservers.Remove( id );
        }
    }

<|endoftext|>


<commit_before><commit_msg>Add NOTREACHED() in switch default part which should never be reached.<commit_after><|endoftext|>