<commit_before>/*!
 * Copyright 2015 by Contributors
 * \file rank_metric.cc
 * \brief prediction rank based metrics.
 * \author Kailong Chen, Tianqi Chen
 */
#include <xgboost/metric.h>
#include <dmlc/registry.h>
#include <cmath>
#include "../common/sync.h"
#include "../common/math.h"

namespace xgboost {
namespace metric {
// tag the this file, used by force static link later.
DMLC_REGISTRY_FILE_TAG(rank_metric);

/*! \brief AMS: also records best threshold */
struct EvalAMS : public Metric {
 public:
  explicit EvalAMS(const char* param) {
    CHECK(param != nullptr)
        << "AMS must be in format ams@k";
    ratio_ = atof(param);
    std::ostringstream os;
    os << "ams@" << ratio_;
    name_ = os.str();
  }
  bst_float Eval(const std::vector<bst_float> &preds,
                 const MetaInfo &info,
                 bool distributed) const override {
    CHECK(!distributed) << "metric AMS do not support distributed evaluation";
    using namespace std;  // NOLINT(*)

    const bst_omp_uint ndata = static_cast<bst_omp_uint>(info.labels.size());
    CHECK_EQ(info.weights.size(), ndata) << "we need weight to evaluate ams";
    std::vector<std::pair<bst_float, unsigned> > rec(ndata);

    #pragma omp parallel for schedule(static)
    for (bst_omp_uint i = 0; i < ndata; ++i) {
      rec[i] = std::make_pair(preds[i], i);
    }
    std::sort(rec.begin(), rec.end(), common::CmpFirst);
    unsigned ntop = static_cast<unsigned>(ratio_ * ndata);
    if (ntop == 0) ntop = ndata;
    const double br = 10.0;
    unsigned thresindex = 0;
    double s_tp = 0.0, b_fp = 0.0, tams = 0.0;
    for (unsigned i = 0; i < static_cast<unsigned>(ndata-1) && i < ntop; ++i) {
      const unsigned ridx = rec[i].second;
      const bst_float wt = info.weights[ridx];
      if (info.labels[ridx] > 0.5f) {
        s_tp += wt;
      } else {
        b_fp += wt;
      }
      if (rec[i].first != rec[i + 1].first) {
        double ams = sqrt(2 * ((s_tp + b_fp + br) * log(1.0 + s_tp / (b_fp + br)) - s_tp));
        if (tams < ams) {
          thresindex = i;
          tams = ams;
        }
      }
    }
    if (ntop == ndata) {
      LOG(INFO) << "best-ams-ratio=" << static_cast<bst_float>(thresindex) / ndata;
      return static_cast<bst_float>(tams);
    } else {
      return static_cast<bst_float>(
          sqrt(2 * ((s_tp + b_fp + br) * log(1.0 + s_tp/(b_fp + br)) - s_tp)));
    }
  }

  const char* Name() const override {
    return name_.c_str();
  }

 private:
  std::string name_;
  float ratio_;
};

/*! \brief Area Under Curve, for both classification and rank */
struct EvalAuc : public Metric {
  bst_float Eval(const std::vector<bst_float> &preds,
                 const MetaInfo &info,
                 bool distributed) const override {
    CHECK_NE(info.labels.size(), 0) << "label set cannot be empty";
    CHECK_EQ(preds.size(), info.labels.size())
        << "label size predict size not match";
    std::vector<unsigned> tgptr(2, 0);
    tgptr[1] = static_cast<unsigned>(info.labels.size());

    const std::vector<unsigned> &gptr = info.group_ptr.size() == 0 ? tgptr : info.group_ptr;
    CHECK_EQ(gptr.back(), info.labels.size())
        << "EvalAuc: group structure must match number of prediction";
    const bst_omp_uint ngroup = static_cast<bst_omp_uint>(gptr.size() - 1);
    // sum statistics
    bst_float sum_auc = 0.0f;
    int auc_error = 0;
    #pragma omp parallel reduction(+:sum_auc)
    {
      // each thread takes a local rec
      std::vector< std::pair<bst_float, unsigned> > rec;
      #pragma omp for schedule(static)
      for (bst_omp_uint k = 0; k < ngroup; ++k) {
        rec.clear();
        for (unsigned j = gptr[k]; j < gptr[k + 1]; ++j) {
          rec.push_back(std::make_pair(preds[j], j));
        }
        std::sort(rec.begin(), rec.end(), common::CmpFirst);
        // calculate AUC
        double sum_pospair = 0.0;
        double sum_npos = 0.0, sum_nneg = 0.0, buf_pos = 0.0, buf_neg = 0.0;
        for (size_t j = 0; j < rec.size(); ++j) {
          const bst_float wt = info.GetWeight(rec[j].second);
          const bst_float ctr = info.labels[rec[j].second];
          // keep bucketing predictions in same bucket
          if (j != 0 && rec[j].first != rec[j - 1].first) {
            sum_pospair += buf_neg * (sum_npos + buf_pos *0.5);
            sum_npos += buf_pos;
            sum_nneg += buf_neg;
            buf_neg = buf_pos = 0.0f;
          }
          buf_pos += ctr * wt;
          buf_neg += (1.0f - ctr) * wt;
        }
        sum_pospair += buf_neg * (sum_npos + buf_pos *0.5);
        sum_npos += buf_pos;
        sum_nneg += buf_neg;
        // check weird conditions
        if (sum_npos <= 0.0 || sum_nneg <= 0.0) {
          auc_error = 1;
          continue;
        }
        // this is the AUC
        sum_auc += sum_pospair / (sum_npos*sum_nneg);
      }
    }
    CHECK(!auc_error)
      << "AUC: the dataset only contains pos or neg samples";
    if (distributed) {
      bst_float dat[2];
      dat[0] = static_cast<bst_float>(sum_auc);
      dat[1] = static_cast<bst_float>(ngroup);
      // approximately estimate auc using mean
      rabit::Allreduce<rabit::op::Sum>(dat, 2);
      return dat[0] / dat[1];
    } else {
      return static_cast<bst_float>(sum_auc) / ngroup;
    }
  }
  const char* Name() const override {
    return "auc";
  }
};

/*! \brief Evaluate rank list */
struct EvalRankList : public Metric {
 public:
  bst_float Eval(const std::vector<bst_float> &preds,
                 const MetaInfo &info,
                 bool distributed) const override {
    CHECK_EQ(preds.size(), info.labels.size())
        << "label size predict size not match";
    // quick consistency when group is not available
    std::vector<unsigned> tgptr(2, 0);
    tgptr[1] = static_cast<unsigned>(preds.size());
    const std::vector<unsigned> &gptr = info.group_ptr.size() == 0 ? tgptr : info.group_ptr;
    CHECK_NE(gptr.size(), 0) << "must specify group when constructing rank file";
    CHECK_EQ(gptr.back(), preds.size())
        << "EvalRanklist: group structure must match number of prediction";
    const bst_omp_uint ngroup = static_cast<bst_omp_uint>(gptr.size() - 1);
    // sum statistics
    double sum_metric = 0.0f;
    #pragma omp parallel reduction(+:sum_metric)
    {
      // each thread takes a local rec
      std::vector< std::pair<bst_float, unsigned> > rec;
      #pragma omp for schedule(static)
      for (bst_omp_uint k = 0; k < ngroup; ++k) {
        rec.clear();
        for (unsigned j = gptr[k]; j < gptr[k + 1]; ++j) {
          rec.push_back(std::make_pair(preds[j], static_cast<int>(info.labels[j])));
        }
        sum_metric += this->EvalMetric(rec);
      }
    }
    if (distributed) {
      bst_float dat[2];
      dat[0] = static_cast<bst_float>(sum_metric);
      dat[1] = static_cast<bst_float>(ngroup);
      // approximately estimate the metric using mean
      rabit::Allreduce<rabit::op::Sum>(dat, 2);
      return dat[0] / dat[1];
    } else {
      return static_cast<bst_float>(sum_metric) / ngroup;
    }
  }
  const char* Name() const override {
    return name_.c_str();
  }

 protected:
  explicit EvalRankList(const char* name, const char* param) {
    using namespace std;  // NOLINT(*)
    minus_ = false;
    if (param != nullptr) {
      std::ostringstream os;
      os << name << '@' << param;
      name_ = os.str();
      if (sscanf(param, "%u[-]?", &topn_) != 1) {
        topn_ = std::numeric_limits<unsigned>::max();
      }
      if (param[strlen(param) - 1] == '-') {
        minus_ = true;
      }
    } else {
      name_ = name;
      topn_ = std::numeric_limits<unsigned>::max();
    }
  }
  /*! \return evaluation metric, given the pair_sort record, (pred,label) */
  virtual bst_float EvalMetric(std::vector<std::pair<bst_float, unsigned> > &pair_sort) const = 0; // NOLINT(*)

 protected:
  unsigned topn_;
  std::string name_;
  bool minus_;
};

/*! \brief Precision at N, for both classification and rank */
struct EvalPrecision : public EvalRankList{
 public:
  explicit EvalPrecision(const char *name) : EvalRankList("pre", name) {}

 protected:
  virtual bst_float EvalMetric(std::vector< std::pair<bst_float, unsigned> > &rec) const {
    // calculate Precision
    std::sort(rec.begin(), rec.end(), common::CmpFirst);
    unsigned nhit = 0;
    for (size_t j = 0; j < rec.size() && j < this->topn_; ++j) {
      nhit += (rec[j].second != 0);
    }
    return static_cast<bst_float>(nhit) / topn_;
  }
};

/*! \brief NDCG: Normalized Discounted Cumulative Gain at N */
struct EvalNDCG : public EvalRankList{
 public:
  explicit EvalNDCG(const char *name) : EvalRankList("ndcg", name) {}

 protected:
  inline bst_float CalcDCG(const std::vector<std::pair<bst_float, unsigned> > &rec) const {
    double sumdcg = 0.0;
    for (size_t i = 0; i < rec.size() && i < this->topn_; ++i) {
      const unsigned rel = rec[i].second;
      if (rel != 0) {
        sumdcg += ((1 << rel) - 1) / std::log2(i + 2.0);
      }
    }
    return sumdcg;
  }
  virtual bst_float EvalMetric(std::vector<std::pair<bst_float, unsigned> > &rec) const { // NOLINT(*)
    std::stable_sort(rec.begin(), rec.end(), common::CmpFirst);
    bst_float dcg = this->CalcDCG(rec);
    std::stable_sort(rec.begin(), rec.end(), common::CmpSecond);
    bst_float idcg = this->CalcDCG(rec);
    if (idcg == 0.0f) {
      if (minus_) {
        return 0.0f;
      } else {
        return 1.0f;
      }
    }
    return dcg/idcg;
  }
};

/*! \brief Mean Average Precision at N, for both classification and rank */
struct EvalMAP : public EvalRankList {
 public:
  explicit EvalMAP(const char *name) : EvalRankList("map", name) {}

 protected:
  virtual bst_float EvalMetric(std::vector< std::pair<bst_float, unsigned> > &rec) const {
    std::sort(rec.begin(), rec.end(), common::CmpFirst);
    unsigned nhits = 0;
    double sumap = 0.0;
    for (size_t i = 0; i < rec.size(); ++i) {
      if (rec[i].second != 0) {
        nhits += 1;
        if (i < this->topn_) {
          sumap += static_cast<bst_float>(nhits) / (i + 1);
        }
      }
    }
    if (nhits != 0) {
      sumap /= nhits;
      return static_cast<bst_float>(sumap);
    } else {
      if (minus_) {
        return 0.0f;
      } else {
        return 1.0f;
      }
    }
  }
};

XGBOOST_REGISTER_METRIC(AMS, "ams")
.describe("AMS metric for higgs.")
.set_body([](const char* param) { return new EvalAMS(param); });

XGBOOST_REGISTER_METRIC(Auc, "auc")
.describe("Area under curve for both classification and rank.")
.set_body([](const char* param) { return new EvalAuc(); });

XGBOOST_REGISTER_METRIC(Precision, "pre")
.describe("precision@k for rank.")
.set_body([](const char* param) { return new EvalPrecision(param); });

XGBOOST_REGISTER_METRIC(NDCG, "ndcg")
.describe("ndcg@k for rank.")
.set_body([](const char* param) { return new EvalNDCG(param); });

XGBOOST_REGISTER_METRIC(MAP, "map")
.describe("map@k for rank.")
.set_body([](const char* param) { return new EvalMAP(param); });
}  // namespace metric
}  // namespace xgboost
<commit_msg>rank_metric.cc: Use GetWeight in EvalAMS<commit_after>/*!
 * Copyright 2015 by Contributors
 * \file rank_metric.cc
 * \brief prediction rank based metrics.
 * \author Kailong Chen, Tianqi Chen
 */
#include <xgboost/metric.h>
#include <dmlc/registry.h>
#include <cmath>
#include "../common/sync.h"
#include "../common/math.h"

namespace xgboost {
namespace metric {
// tag the this file, used by force static link later.
DMLC_REGISTRY_FILE_TAG(rank_metric);

/*! \brief AMS: also records best threshold */
struct EvalAMS : public Metric {
 public:
  explicit EvalAMS(const char* param) {
    CHECK(param != nullptr)
        << "AMS must be in format ams@k";
    ratio_ = atof(param);
    std::ostringstream os;
    os << "ams@" << ratio_;
    name_ = os.str();
  }
  bst_float Eval(const std::vector<bst_float> &preds,
                 const MetaInfo &info,
                 bool distributed) const override {
    CHECK(!distributed) << "metric AMS do not support distributed evaluation";
    using namespace std;  // NOLINT(*)

    const bst_omp_uint ndata = static_cast<bst_omp_uint>(info.labels.size());
    std::vector<std::pair<bst_float, unsigned> > rec(ndata);

    #pragma omp parallel for schedule(static)
    for (bst_omp_uint i = 0; i < ndata; ++i) {
      rec[i] = std::make_pair(preds[i], i);
    }
    std::sort(rec.begin(), rec.end(), common::CmpFirst);
    unsigned ntop = static_cast<unsigned>(ratio_ * ndata);
    if (ntop == 0) ntop = ndata;
    const double br = 10.0;
    unsigned thresindex = 0;
    double s_tp = 0.0, b_fp = 0.0, tams = 0.0;
    for (unsigned i = 0; i < static_cast<unsigned>(ndata-1) && i < ntop; ++i) {
      const unsigned ridx = rec[i].second;
      const bst_float wt = info.GetWeight(ridx);
      if (info.labels[ridx] > 0.5f) {
        s_tp += wt;
      } else {
        b_fp += wt;
      }
      if (rec[i].first != rec[i + 1].first) {
        double ams = sqrt(2 * ((s_tp + b_fp + br) * log(1.0 + s_tp / (b_fp + br)) - s_tp));
        if (tams < ams) {
          thresindex = i;
          tams = ams;
        }
      }
    }
    if (ntop == ndata) {
      LOG(INFO) << "best-ams-ratio=" << static_cast<bst_float>(thresindex) / ndata;
      return static_cast<bst_float>(tams);
    } else {
      return static_cast<bst_float>(
          sqrt(2 * ((s_tp + b_fp + br) * log(1.0 + s_tp/(b_fp + br)) - s_tp)));
    }
  }

  const char* Name() const override {
    return name_.c_str();
  }

 private:
  std::string name_;
  float ratio_;
};

/*! \brief Area Under Curve, for both classification and rank */
struct EvalAuc : public Metric {
  bst_float Eval(const std::vector<bst_float> &preds,
                 const MetaInfo &info,
                 bool distributed) const override {
    CHECK_NE(info.labels.size(), 0) << "label set cannot be empty";
    CHECK_EQ(preds.size(), info.labels.size())
        << "label size predict size not match";
    std::vector<unsigned> tgptr(2, 0);
    tgptr[1] = static_cast<unsigned>(info.labels.size());

    const std::vector<unsigned> &gptr = info.group_ptr.size() == 0 ? tgptr : info.group_ptr;
    CHECK_EQ(gptr.back(), info.labels.size())
        << "EvalAuc: group structure must match number of prediction";
    const bst_omp_uint ngroup = static_cast<bst_omp_uint>(gptr.size() - 1);
    // sum statistics
    bst_float sum_auc = 0.0f;
    int auc_error = 0;
    #pragma omp parallel reduction(+:sum_auc)
    {
      // each thread takes a local rec
      std::vector< std::pair<bst_float, unsigned> > rec;
      #pragma omp for schedule(static)
      for (bst_omp_uint k = 0; k < ngroup; ++k) {
        rec.clear();
        for (unsigned j = gptr[k]; j < gptr[k + 1]; ++j) {
          rec.push_back(std::make_pair(preds[j], j));
        }
        std::sort(rec.begin(), rec.end(), common::CmpFirst);
        // calculate AUC
        double sum_pospair = 0.0;
        double sum_npos = 0.0, sum_nneg = 0.0, buf_pos = 0.0, buf_neg = 0.0;
        for (size_t j = 0; j < rec.size(); ++j) {
          const bst_float wt = info.GetWeight(rec[j].second);
          const bst_float ctr = info.labels[rec[j].second];
          // keep bucketing predictions in same bucket
          if (j != 0 && rec[j].first != rec[j - 1].first) {
            sum_pospair += buf_neg * (sum_npos + buf_pos *0.5);
            sum_npos += buf_pos;
            sum_nneg += buf_neg;
            buf_neg = buf_pos = 0.0f;
          }
          buf_pos += ctr * wt;
          buf_neg += (1.0f - ctr) * wt;
        }
        sum_pospair += buf_neg * (sum_npos + buf_pos *0.5);
        sum_npos += buf_pos;
        sum_nneg += buf_neg;
        // check weird conditions
        if (sum_npos <= 0.0 || sum_nneg <= 0.0) {
          auc_error = 1;
          continue;
        }
        // this is the AUC
        sum_auc += sum_pospair / (sum_npos*sum_nneg);
      }
    }
    CHECK(!auc_error)
      << "AUC: the dataset only contains pos or neg samples";
    if (distributed) {
      bst_float dat[2];
      dat[0] = static_cast<bst_float>(sum_auc);
      dat[1] = static_cast<bst_float>(ngroup);
      // approximately estimate auc using mean
      rabit::Allreduce<rabit::op::Sum>(dat, 2);
      return dat[0] / dat[1];
    } else {
      return static_cast<bst_float>(sum_auc) / ngroup;
    }
  }
  const char* Name() const override {
    return "auc";
  }
};

/*! \brief Evaluate rank list */
struct EvalRankList : public Metric {
 public:
  bst_float Eval(const std::vector<bst_float> &preds,
                 const MetaInfo &info,
                 bool distributed) const override {
    CHECK_EQ(preds.size(), info.labels.size())
        << "label size predict size not match";
    // quick consistency when group is not available
    std::vector<unsigned> tgptr(2, 0);
    tgptr[1] = static_cast<unsigned>(preds.size());
    const std::vector<unsigned> &gptr = info.group_ptr.size() == 0 ? tgptr : info.group_ptr;
    CHECK_NE(gptr.size(), 0) << "must specify group when constructing rank file";
    CHECK_EQ(gptr.back(), preds.size())
        << "EvalRanklist: group structure must match number of prediction";
    const bst_omp_uint ngroup = static_cast<bst_omp_uint>(gptr.size() - 1);
    // sum statistics
    double sum_metric = 0.0f;
    #pragma omp parallel reduction(+:sum_metric)
    {
      // each thread takes a local rec
      std::vector< std::pair<bst_float, unsigned> > rec;
      #pragma omp for schedule(static)
      for (bst_omp_uint k = 0; k < ngroup; ++k) {
        rec.clear();
        for (unsigned j = gptr[k]; j < gptr[k + 1]; ++j) {
          rec.push_back(std::make_pair(preds[j], static_cast<int>(info.labels[j])));
        }
        sum_metric += this->EvalMetric(rec);
      }
    }
    if (distributed) {
      bst_float dat[2];
      dat[0] = static_cast<bst_float>(sum_metric);
      dat[1] = static_cast<bst_float>(ngroup);
      // approximately estimate the metric using mean
      rabit::Allreduce<rabit::op::Sum>(dat, 2);
      return dat[0] / dat[1];
    } else {
      return static_cast<bst_float>(sum_metric) / ngroup;
    }
  }
  const char* Name() const override {
    return name_.c_str();
  }

 protected:
  explicit EvalRankList(const char* name, const char* param) {
    using namespace std;  // NOLINT(*)
    minus_ = false;
    if (param != nullptr) {
      std::ostringstream os;
      os << name << '@' << param;
      name_ = os.str();
      if (sscanf(param, "%u[-]?", &topn_) != 1) {
        topn_ = std::numeric_limits<unsigned>::max();
      }
      if (param[strlen(param) - 1] == '-') {
        minus_ = true;
      }
    } else {
      name_ = name;
      topn_ = std::numeric_limits<unsigned>::max();
    }
  }
  /*! \return evaluation metric, given the pair_sort record, (pred,label) */
  virtual bst_float EvalMetric(std::vector<std::pair<bst_float, unsigned> > &pair_sort) const = 0; // NOLINT(*)

 protected:
  unsigned topn_;
  std::string name_;
  bool minus_;
};

/*! \brief Precision at N, for both classification and rank */
struct EvalPrecision : public EvalRankList{
 public:
  explicit EvalPrecision(const char *name) : EvalRankList("pre", name) {}

 protected:
  virtual bst_float EvalMetric(std::vector< std::pair<bst_float, unsigned> > &rec) const {
    // calculate Precision
    std::sort(rec.begin(), rec.end(), common::CmpFirst);
    unsigned nhit = 0;
    for (size_t j = 0; j < rec.size() && j < this->topn_; ++j) {
      nhit += (rec[j].second != 0);
    }
    return static_cast<bst_float>(nhit) / topn_;
  }
};

/*! \brief NDCG: Normalized Discounted Cumulative Gain at N */
struct EvalNDCG : public EvalRankList{
 public:
  explicit EvalNDCG(const char *name) : EvalRankList("ndcg", name) {}

 protected:
  inline bst_float CalcDCG(const std::vector<std::pair<bst_float, unsigned> > &rec) const {
    double sumdcg = 0.0;
    for (size_t i = 0; i < rec.size() && i < this->topn_; ++i) {
      const unsigned rel = rec[i].second;
      if (rel != 0) {
        sumdcg += ((1 << rel) - 1) / std::log2(i + 2.0);
      }
    }
    return sumdcg;
  }
  virtual bst_float EvalMetric(std::vector<std::pair<bst_float, unsigned> > &rec) const { // NOLINT(*)
    std::stable_sort(rec.begin(), rec.end(), common::CmpFirst);
    bst_float dcg = this->CalcDCG(rec);
    std::stable_sort(rec.begin(), rec.end(), common::CmpSecond);
    bst_float idcg = this->CalcDCG(rec);
    if (idcg == 0.0f) {
      if (minus_) {
        return 0.0f;
      } else {
        return 1.0f;
      }
    }
    return dcg/idcg;
  }
};

/*! \brief Mean Average Precision at N, for both classification and rank */
struct EvalMAP : public EvalRankList {
 public:
  explicit EvalMAP(const char *name) : EvalRankList("map", name) {}

 protected:
  virtual bst_float EvalMetric(std::vector< std::pair<bst_float, unsigned> > &rec) const {
    std::sort(rec.begin(), rec.end(), common::CmpFirst);
    unsigned nhits = 0;
    double sumap = 0.0;
    for (size_t i = 0; i < rec.size(); ++i) {
      if (rec[i].second != 0) {
        nhits += 1;
        if (i < this->topn_) {
          sumap += static_cast<bst_float>(nhits) / (i + 1);
        }
      }
    }
    if (nhits != 0) {
      sumap /= nhits;
      return static_cast<bst_float>(sumap);
    } else {
      if (minus_) {
        return 0.0f;
      } else {
        return 1.0f;
      }
    }
  }
};

XGBOOST_REGISTER_METRIC(AMS, "ams")
.describe("AMS metric for higgs.")
.set_body([](const char* param) { return new EvalAMS(param); });

XGBOOST_REGISTER_METRIC(Auc, "auc")
.describe("Area under curve for both classification and rank.")
.set_body([](const char* param) { return new EvalAuc(); });

XGBOOST_REGISTER_METRIC(Precision, "pre")
.describe("precision@k for rank.")
.set_body([](const char* param) { return new EvalPrecision(param); });

XGBOOST_REGISTER_METRIC(NDCG, "ndcg")
.describe("ndcg@k for rank.")
.set_body([](const char* param) { return new EvalNDCG(param); });

XGBOOST_REGISTER_METRIC(MAP, "map")
.describe("map@k for rank.")
.set_body([](const char* param) { return new EvalMAP(param); });
}  // namespace metric
}  // namespace xgboost
<|endoftext|>


<commit_before>#include "sshtunnelout.h"
#include "sshclient.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QEventLoop>
#include <cerrno>

Q_LOGGING_CATEGORY(logsshtunnelout, "ssh.tunnelout", QtWarningMsg)

SshTunnelOut::SshTunnelOut(SshClient *client, QTcpSocket *tcpSocket, const QString &port_identifier, quint16 port, QObject *parent):
    QObject(parent),
    m_opened(false),
    m_port(port),
    m_name(port_identifier),
    m_tcpsocket(tcpSocket),
    m_client(client),
    m_sshChannel(nullptr),
    m_dataSsh(16384, 0),
    m_dataSocket(16384, 0),
    m_callDepth(0)
{
    qCDebug(logsshtunnelout) << "SshTunnelOut::SshTunnelOut() " << m_name;
    m_sshChannel = qssh2_channel_direct_tcpip(m_client->session(), "127.0.0.1", m_port);
    if(m_sshChannel == nullptr)
    {
        int ret = qssh2_session_last_error(m_client->session(), nullptr, nullptr, 0);
        if(ret != LIBSSH2_ERROR_CHANNEL_FAILURE)
        {
            qDebug() << "ERROR: Can't connect direct tcpip " << ret << " for port " << m_port;
        }
        else
        {
            qCDebug(logsshtunnelout) << "Can't connect direct tcpip " << ret << " for port " << m_port;
        }
        return;
    }

    QObject::connect(m_client,    &SshClient::sshDataReceived, this, &SshTunnelOut::sshDataReceived, Qt::QueuedConnection);
    QObject::connect(m_tcpsocket, &QTcpSocket::readyRead,      this, &SshTunnelOut::tcpDataReceived);
    QObject::connect(m_tcpsocket, &QTcpSocket::disconnected,   this, &SshTunnelOut::tcpDisconnected);
    QObject::connect(m_tcpsocket, SIGNAL(error(QAbstractSocket::SocketError)),   this, SLOT(displayError(QAbstractSocket::SocketError)));

    m_opened = true;

    qCDebug(logsshtunnelout) << "SshTunnelOut::SshTunnelOut() OK " << m_name;
    tcpDataReceived();
}

SshTunnelOut::~SshTunnelOut()
{
    qCDebug(logsshtunnelout) << "~SshTunnelOut() " << m_name;
    _stopSocket();
    _stopChannel();
}

QString SshTunnelOut::name() const
{
    return m_name;
}

void SshTunnelOut::sshDataReceived()
{
    ssize_t len = 0,wr = 0;
    qint64 i;

    do
    {
        if(libssh2_channel_eof(m_sshChannel) == 1)
        {
            emit disconnected();
            return;
        }
        /* Read data from SSH */
        /*
         * In this case, we must not used qssh2_channel_read
         * beacause we don't need to ProcessEvent to be locked
         * We can return, we will be recall at the next sshDataReceived
         */
        len = static_cast<ssize_t>(libssh2_channel_read(m_sshChannel, m_dataSsh.data(), static_cast<unsigned int>(m_dataSsh.size())));
        if(len == LIBSSH2_ERROR_EAGAIN)
        {
            return;
        }
        if (len < 0)
        {
            qDebug() << "ERROR : " << m_name << " remote failed to read (" << len << ")";
            return;
        }
        if(len == 0)
            return;

        /* Write data into output local socket */
        wr = 0;
        if(m_tcpsocket != nullptr)
        {
            while (wr < len)
            {
                i = m_tcpsocket->write( m_dataSsh.mid(wr, len));
                if (i <= 0)
                {
                    qDebug() << "ERROR : " << m_name << " local failed to write (" << i << ")";
                    return;
                }
                wr += i;
            }
        }
        else
        {
            if(m_opened) qDebug() << "ERROR : Data loose";
        }

        if (libssh2_channel_eof(m_sshChannel) && m_opened)
        {
            qCDebug(logsshtunnelout) << "Disconnected from ssh";
            emit disconnected();
        }
    }
    while(len == m_dataSsh.size());
}

void SshTunnelOut::tcpDataReceived()
{
    qint64 len = 0;
    ssize_t wr = 0;
    ssize_t i = 0;

    if (m_tcpsocket == nullptr || m_sshChannel == nullptr)
    {
        qDebug() << "ERROR : SshTunnelOut(" << m_name << ") : received TCP data but not seems to be a valid Tcp socket or channel not ready";
        return;
    }

    do
    {
        /* Read data from local socket */
        len = m_tcpsocket->read(m_dataSocket.data(), m_dataSocket.size());
        if (-EAGAIN == len)
        {
            break;
        }
        if (len < 0)
        {
            qDebug() << "ERROR : " << m_name << " local failed to read (" << len << ")";
            return;
        }

        do
        {
            i = qssh2_channel_write(m_sshChannel, m_dataSocket.data(), static_cast<size_t>(len));
            if (i < 0)
            {
                qDebug() << "ERROR : " << m_name << " remote failed to write (" << i << ")";
                return;
            }
            wr += i;
        } while(i > 0 && wr < len);
    }
    while(len > 0);
}

void SshTunnelOut::tcpDisconnected()
{
    qCDebug(logsshtunnelout) << "Disconnected from socket";
    emit disconnected();
}

bool SshTunnelOut::ready() const
{
    return m_opened;
}

void SshTunnelOut::displayError(QAbstractSocket::SocketError error)
{
    if(error != QAbstractSocket::RemoteHostClosedError)
    qDebug() << "ERROR : SshTunnelOut(" << m_name << ") : redirection socket error=" << error;
}
void SshTunnelOut::_stopChannel()
{
    if (m_sshChannel == nullptr)
        return;

    QObject::disconnect(m_client,    &SshClient::sshDataReceived, this, &SshTunnelOut::sshDataReceived);

    int ret = qssh2_channel_close(m_sshChannel);

    if(ret)
    {
        qCDebug(logsshtunnelout) << "Failed to channel_close: LIBSSH2_ERROR_SOCKET_SEND";
        return;
    }

    ret = qssh2_channel_wait_closed(m_sshChannel);
    if(ret)
    {
        qDebug(logsshtunnelout) << "Failed to channel_wait_closed";
        return;
    }

    ret = qssh2_channel_free(m_sshChannel);
    if(ret)
    {
        qCDebug(logsshtunnelout) << "Failed to channel_free";
        return;
    }
    m_sshChannel = nullptr;
}

void SshTunnelOut::_stopSocket()
{
    if(m_tcpsocket)
    {
        QObject::disconnect(m_tcpsocket, &QTcpSocket::readyRead, this,  &SshTunnelOut::tcpDataReceived);
        QObject::disconnect(m_tcpsocket, SIGNAL(disconnected()),                        this, SLOT(tcpDisconnected()));
        QObject::disconnect(m_tcpsocket, SIGNAL(error(QAbstractSocket::SocketError)),   this, SLOT(displayError(QAbstractSocket::SocketError)));
        if(m_tcpsocket->state() == QAbstractSocket::ConnectedState)
        {
            m_tcpsocket->disconnectFromHost();
        }
        m_tcpsocket->deleteLater();
        m_tcpsocket = nullptr;
    }
}
<commit_msg>sshtunnelout: Avoid channel write of empty buffer<commit_after>#include "sshtunnelout.h"
#include "sshclient.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QEventLoop>
#include <cerrno>

Q_LOGGING_CATEGORY(logsshtunnelout, "ssh.tunnelout", QtWarningMsg)

SshTunnelOut::SshTunnelOut(SshClient *client, QTcpSocket *tcpSocket, const QString &port_identifier, quint16 port, QObject *parent):
    QObject(parent),
    m_opened(false),
    m_port(port),
    m_name(port_identifier),
    m_tcpsocket(tcpSocket),
    m_client(client),
    m_sshChannel(nullptr),
    m_dataSsh(16384, 0),
    m_dataSocket(16384, 0),
    m_callDepth(0)
{
    qCDebug(logsshtunnelout) << "SshTunnelOut::SshTunnelOut() " << m_name;
    m_sshChannel = qssh2_channel_direct_tcpip(m_client->session(), "127.0.0.1", m_port);
    if(m_sshChannel == nullptr)
    {
        int ret = qssh2_session_last_error(m_client->session(), nullptr, nullptr, 0);
        if(ret != LIBSSH2_ERROR_CHANNEL_FAILURE)
        {
            qDebug() << "ERROR: Can't connect direct tcpip " << ret << " for port " << m_port;
        }
        else
        {
            qCDebug(logsshtunnelout) << "Can't connect direct tcpip " << ret << " for port " << m_port;
        }
        return;
    }

    QObject::connect(m_client,    &SshClient::sshDataReceived, this, &SshTunnelOut::sshDataReceived, Qt::QueuedConnection);
    QObject::connect(m_tcpsocket, &QTcpSocket::readyRead,      this, &SshTunnelOut::tcpDataReceived);
    QObject::connect(m_tcpsocket, &QTcpSocket::disconnected,   this, &SshTunnelOut::tcpDisconnected);
    QObject::connect(m_tcpsocket, SIGNAL(error(QAbstractSocket::SocketError)),   this, SLOT(displayError(QAbstractSocket::SocketError)));

    m_opened = true;

    qCDebug(logsshtunnelout) << "SshTunnelOut::SshTunnelOut() OK " << m_name;
    tcpDataReceived();
}

SshTunnelOut::~SshTunnelOut()
{
    qCDebug(logsshtunnelout) << "~SshTunnelOut() " << m_name;
    _stopSocket();
    _stopChannel();
}

QString SshTunnelOut::name() const
{
    return m_name;
}

void SshTunnelOut::sshDataReceived()
{
    ssize_t len = 0,wr = 0;
    qint64 i;

    do
    {
        if(libssh2_channel_eof(m_sshChannel) == 1)
        {
            emit disconnected();
            return;
        }
        /* Read data from SSH */
        /*
         * In this case, we must not used qssh2_channel_read
         * beacause we don't need to ProcessEvent to be locked
         * We can return, we will be recall at the next sshDataReceived
         */
        len = static_cast<ssize_t>(libssh2_channel_read(m_sshChannel, m_dataSsh.data(), static_cast<unsigned int>(m_dataSsh.size())));
        if(len == LIBSSH2_ERROR_EAGAIN)
        {
            return;
        }
        if (len < 0)
        {
            qDebug() << "ERROR : " << m_name << " remote failed to read (" << len << ")";
            return;
        }
        if(len == 0)
            return;

        /* Write data into output local socket */
        wr = 0;
        if(m_tcpsocket != nullptr)
        {
            while (wr < len)
            {
                i = m_tcpsocket->write( m_dataSsh.mid(wr, len));
                if (i <= 0)
                {
                    qDebug() << "ERROR : " << m_name << " local failed to write (" << i << ")";
                    return;
                }
                wr += i;
            }
        }
        else
        {
            if(m_opened) qDebug() << "ERROR : Data loose";
        }

        if (libssh2_channel_eof(m_sshChannel) && m_opened)
        {
            qCDebug(logsshtunnelout) << "Disconnected from ssh";
            emit disconnected();
        }
    }
    while(len == m_dataSsh.size());
}

void SshTunnelOut::tcpDataReceived()
{
    qint64 len = 0;
    ssize_t wr = 0;
    ssize_t i = 0;

    if (m_tcpsocket == nullptr || m_sshChannel == nullptr)
    {
        qDebug() << "ERROR : SshTunnelOut(" << m_name << ") : received TCP data but not seems to be a valid Tcp socket or channel not ready";
        return;
    }

    do
    {
        /* Read data from local socket */
        len = m_tcpsocket->read(m_dataSocket.data(), m_dataSocket.size());
        if (-EAGAIN == len)
        {
            break;
        }
        if (len < 0)
        {
            qDebug() << "ERROR : " << m_name << " local failed to read (" << len << ")";
            return;
        }

        if(len > 0)
        {
            do
            {
                i = qssh2_channel_write(m_sshChannel, m_dataSocket.data(), static_cast<size_t>(len));
                if (i < 0)
                {
                    qDebug() << "ERROR : " << m_name << " remote failed to write (" << i << ")";
                    return;
                }
                wr += i;
            } while(i > 0 && wr < len);
        }
    }
    while(len > 0);
}

void SshTunnelOut::tcpDisconnected()
{
    qCDebug(logsshtunnelout) << "Disconnected from socket";
    emit disconnected();
}

bool SshTunnelOut::ready() const
{
    return m_opened;
}

void SshTunnelOut::displayError(QAbstractSocket::SocketError error)
{
    if(error != QAbstractSocket::RemoteHostClosedError)
    qDebug() << "ERROR : SshTunnelOut(" << m_name << ") : redirection socket error=" << error;
}
void SshTunnelOut::_stopChannel()
{
    if (m_sshChannel == nullptr)
        return;

    QObject::disconnect(m_client,    &SshClient::sshDataReceived, this, &SshTunnelOut::sshDataReceived);

    int ret = qssh2_channel_close(m_sshChannel);

    if(ret)
    {
        qCDebug(logsshtunnelout) << "Failed to channel_close: LIBSSH2_ERROR_SOCKET_SEND";
        return;
    }

    ret = qssh2_channel_wait_closed(m_sshChannel);
    if(ret)
    {
        qDebug(logsshtunnelout) << "Failed to channel_wait_closed";
        return;
    }

    ret = qssh2_channel_free(m_sshChannel);
    if(ret)
    {
        qCDebug(logsshtunnelout) << "Failed to channel_free";
        return;
    }
    m_sshChannel = nullptr;
}

void SshTunnelOut::_stopSocket()
{
    if(m_tcpsocket)
    {
        QObject::disconnect(m_tcpsocket, &QTcpSocket::readyRead, this,  &SshTunnelOut::tcpDataReceived);
        QObject::disconnect(m_tcpsocket, SIGNAL(disconnected()),                        this, SLOT(tcpDisconnected()));
        QObject::disconnect(m_tcpsocket, SIGNAL(error(QAbstractSocket::SocketError)),   this, SLOT(displayError(QAbstractSocket::SocketError)));
        if(m_tcpsocket->state() == QAbstractSocket::ConnectedState)
        {
            m_tcpsocket->disconnectFromHost();
        }
        m_tcpsocket->deleteLater();
        m_tcpsocket = nullptr;
    }
}
<|endoftext|>


<commit_before><commit_msg>XubString->OUString<commit_after><|endoftext|>


<commit_before>#include "midivaluedelegate.h"

#include "enums.h"

#include <QApplication>
#include <QPushButton>
#include <QSpinBox>

#include <QtDebug>

MidiType midiType(const QModelIndex& index) {
    return static_cast<MidiType>(index.data(MidiDataRole::MidiValueType).toInt());
}

QWidget* createSpinboxEditor(QWidget* parent, int min, int max) {
    QSpinBox* ret = new QSpinBox(parent);
    ret->setFrame(false);
    ret->setMinimum(min);
    ret->setMaximum(max);
    return ret;
}

void setDefaultEditorData(QWidget* editor, const QModelIndex& index) {
    Q_CHECK_PTR(editor);

    QSpinBox* spinBox = qobject_cast<QSpinBox*>(editor);
    Q_CHECK_PTR(spinBox);

    Q_CHECK_PTR(index.model());
    const int value = index.model()->data(index).toInt();

    spinBox->setValue(value);
}

void setDefaultModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) {
    Q_CHECK_PTR(editor);
    Q_CHECK_PTR(model);

    QSpinBox* spinBox = qobject_cast<QSpinBox*>(editor);
    Q_CHECK_PTR(spinBox);

    spinBox->interpretText();
    model->setData(index, spinBox->value(), Qt::EditRole);
}

void paintToggle(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) {
    Q_CHECK_PTR(painter);

    QStyleOptionButton buttonOption;
    buttonOption.rect = option.rect;
    buttonOption.state = option.state;

    buttonOption.state |= index.data(Qt::CheckStateRole).toInt() == Qt::Unchecked ? QStyle::State_Off : QStyle::State_On;
    buttonOption.text = index.data().toString();
    QApplication* app = qobject_cast<QApplication*>(qGuiApp);
    Q_CHECK_PTR(app);
    app->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
}

MidiValueDelegate::MidiValueDelegate(QObject* parent):
    QStyledItemDelegate(parent)
{

}

void MidiValueDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    Q_CHECK_PTR(index.model());

    switch (midiType(index)) {
    case MidiType::ToggleType:
        paintToggle(painter, option, index);
        return;
    default:
        return QStyledItemDelegate::paint(painter, option, index);
    }
}

QWidget* MidiValueDelegate::createEditor(
        QWidget* parent,
        const QStyleOptionViewItem&,
        const QModelIndex& index) const {
    Q_CHECK_PTR(index.model());

    QWidget* ret = Q_NULLPTR;

    switch (midiType(index)) {
    case MidiType::ChannelType:
    case MidiType::DefaultType:
    case MidiType::NoteType:
        ret = createSpinboxEditor(
                  parent,
                  index.data(MidiDataRole::MidiValueMin).toInt(),
                  index.data(MidiDataRole::MidiValueMax).toInt()
        );
        break;
    default:
        ret = Q_NULLPTR;
        break;
    }

    return ret;
}

void MidiValueDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const {
    Q_CHECK_PTR(index.model());

    switch (midiType(index)) {
    case MidiType::ChannelType:
    case MidiType::DefaultType:
    case MidiType::NoteType:
        setDefaultEditorData(editor, index);
        break;
    default:
        break;
    }
}

void MidiValueDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
    Q_CHECK_PTR(editor);
    Q_CHECK_PTR(model);

    switch (midiType(index)) {
    case MidiType::ChannelType:
    case MidiType::DefaultType:
    case MidiType::NoteType:
        setDefaultModelData(editor, model, index);
        break;
    default:
        break;
    }
}

void MidiValueDelegate::updateEditorGeometry(
        QWidget* editor,
        const QStyleOptionViewItem& option,
        const QModelIndex&) const {
    Q_CHECK_PTR(editor);

    editor->setGeometry(option.rect);
}

bool MidiValueDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) {
    Q_CHECK_PTR(event);
    Q_CHECK_PTR(model);

    switch (midiType(index)) {
    case MidiType::ToggleType:
        if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) {
            const bool isChecked = model->data(index, Qt::CheckStateRole).toInt() == Qt::Checked;
            model->setData(index, !isChecked);
            return true;
        }
    default:
        break;
    }

    return QStyledItemDelegate::editorEvent(event, model, option, index);
}
<commit_msg>Reimplement toggle control from possible midi values<commit_after>#include "midivaluedelegate.h"

#include "enums.h"

#include <QApplication>
#include <QPushButton>
#include <QSpinBox>

#include <QtDebug>

MidiType midiType(const QModelIndex& index) {
    return static_cast<MidiType>(index.data(MidiDataRole::MidiValueType).toInt());
}

bool hasLut(const QModelIndex &index) {
    return index.data(MidiDataRole::MidiValues).isValid();
}

QStringList lut(const QModelIndex &index) {
    Q_ASSERT(hasLut(index));

    return index.data(MidiDataRole::MidiValues).toStringList();
}

bool isToggle(const QModelIndex &index) {
    return hasLut(index) && lut(index).size() == 2;
}

QWidget* createSpinboxEditor(QWidget* parent, int min, int max) {
    QSpinBox* ret = new QSpinBox(parent);
    ret->setFrame(false);
    ret->setMinimum(min);
    ret->setMaximum(max);
    return ret;
}

void setDefaultEditorData(QWidget* editor, const QModelIndex& index) {
    Q_CHECK_PTR(editor);

    QSpinBox* spinBox = qobject_cast<QSpinBox*>(editor);
    Q_CHECK_PTR(spinBox);

    Q_CHECK_PTR(index.model());
    const int value = index.model()->data(index).toInt();

    spinBox->setValue(value);
}

void setDefaultModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) {
    Q_CHECK_PTR(editor);
    Q_CHECK_PTR(model);

    QSpinBox* spinBox = qobject_cast<QSpinBox*>(editor);
    Q_CHECK_PTR(spinBox);

    spinBox->interpretText();
    model->setData(index, spinBox->value(), Qt::EditRole);
}

void paintToggle(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) {
    Q_CHECK_PTR(painter);

    QStyleOptionButton buttonOption;
    buttonOption.rect = option.rect;
    buttonOption.state = option.state;

    buttonOption.state |= index.data(Qt::EditRole).toInt() == 0 ? QStyle::State_Off : QStyle::State_On;
    buttonOption.text = index.data().toString();
    QApplication* app = qobject_cast<QApplication*>(qGuiApp);
    Q_CHECK_PTR(app);
    app->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
}

MidiValueDelegate::MidiValueDelegate(QObject* parent):
    QStyledItemDelegate(parent)
{

}

void MidiValueDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    Q_CHECK_PTR(index.model());

    isToggle(index) ? paintToggle(painter, option, index) : QStyledItemDelegate::paint(painter, option, index);
}

QWidget* MidiValueDelegate::createEditor(
        QWidget* /*parent*/,
        const QStyleOptionViewItem&,
        const QModelIndex& /*index*/) const {
//    Q_CHECK_PTR(index.model());

    QWidget* ret = Q_NULLPTR;

//    switch (midiType(index)) {
//    case MidiType::ChannelType:
//    case MidiType::DefaultType:
//    case MidiType::NoteType:
//        ret = createSpinboxEditor(
//                  parent,
//                  index.data(MidiDataRole::MidiValueMin).toInt(),
//                  index.data(MidiDataRole::MidiValueMax).toInt()
//        );
//        break;
//    default:
//        ret = Q_NULLPTR;
//        break;
//    }

    return ret;
}

void MidiValueDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const {
    Q_CHECK_PTR(index.model());

    switch (midiType(index)) {
    case MidiType::ChannelType:
    case MidiType::DefaultType:
    case MidiType::NoteType:
        setDefaultEditorData(editor, index);
        break;
    default:
        break;
    }
}

void MidiValueDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
    Q_CHECK_PTR(editor);
    Q_CHECK_PTR(model);

    switch (midiType(index)) {
    case MidiType::ChannelType:
    case MidiType::DefaultType:
    case MidiType::NoteType:
        setDefaultModelData(editor, model, index);
        break;
    default:
        break;
    }
}

void MidiValueDelegate::updateEditorGeometry(
        QWidget* editor,
        const QStyleOptionViewItem& option,
        const QModelIndex&) const {
    Q_CHECK_PTR(editor);

    editor->setGeometry(option.rect);
}

bool MidiValueDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) {
    Q_CHECK_PTR(event);
    Q_CHECK_PTR(model);

    const bool toggleClicked = isToggle(index) && (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick);
    if (toggleClicked) {
        const int currentValue = model->data(index, Qt::EditRole).toInt();
        const int newValue = currentValue == 0 ? 1 : 0;
        model->setData(index, newValue);
        return true;
    }

    return QStyledItemDelegate::editorEvent(event, model, option, index);
}
<|endoftext|>


<commit_before>#include <Util.hpp>

#include <iostream>
#include <iomanip>
#include <cstdlib>

namespace miniMAT {
    namespace util {

        // auto doesn't seem to work here, for some reason
        std::map<std::string, std::function<void(void)>> Util::funcs = std::map<std::string, std::function<void(void)>>();

        void Util::init(std::shared_ptr<std::map<std::string, Matrix>> vars) {
            funcs["quit"] = funcs["exit"] = funcs["bye!"] = []() {
                throw 1;
            };

            funcs["who"] = [vars]() {
            	using namespace std;

            	for (auto var : *vars)
                    cout << var.first << endl;
                cout  << endl;
            };

            funcs["whos"] = [vars]() {
                using namespace std;

                auto w = max_element(begin(*vars), end(*vars), [](pair<string, Matrix> p1, pair<string, Matrix> p2) {
                    return p1.first.size() < p2.first.size();
                })->first.size();

                cout << endl;
                for (auto var : *vars)
                    cout << setw(w) << var.first << " = " << var.second << endl;
                cout << endl;
            };

            funcs[""] = []() {
                return;
            };
        }

        void Util::PrintResult(std::string varname, Matrix val, bool suppressed) {
            if (!suppressed) {
                std::cout << varname << " =" << std::endl << std::endl;
                std::cout << "    " << val << std::endl << std::endl;
            }
        }

        std::function<void(void)> Util::GetFunction(const std::string& s) {
        	return funcs[s];
        }

        bool Util::HasFunction(const std::string& s) {
            return funcs.find(s) != funcs.end();
        }
	}
}<commit_msg>More formatting<commit_after>#include <Util.hpp>

#include <iostream>
#include <iomanip>
#include <cstdlib>

namespace miniMAT {
    namespace util {

        // auto doesn't seem to work here, for some reason
        std::map<std::string, std::function<void(void)>> Util::funcs = std::map<std::string, std::function<void(void)>>();

        void Util::init(std::shared_ptr<std::map<std::string, Matrix>> vars) {
            funcs["quit"] = funcs["exit"] = funcs["bye!"] = []() {
                throw 1;
            };

            funcs["who"] = [vars]() {
            	for (auto var : *vars)
                    std::cout << var.first << std::endl;
                std::cout  << std::endl;
            };

            funcs["whos"] = [vars]() {
                using namespace std;

                auto max_width = max_element(begin(*vars),
                                             end(*vars),
                                             [](pair<string, Matrix> p1,
                                                pair<string, Matrix> p2) {
                    // Compare by variable name length
                    return p1.first.size() < p2.first.size();
                })->first.size();

                cout << endl;
                for (auto var : *vars)
                    cout << setw(max_width) << var.first << " = " << var.second << endl;
                cout << endl;
            };

            funcs[""] = []() {
                return;
            };
        }

        void Util::PrintResult(std::string varname, Matrix val, bool suppressed) {
            if (!suppressed) {
                std::cout << varname << " =" << std::endl << std::endl;
                std::cout << "    " << val << std::endl << std::endl;
            }
        }

        std::function<void(void)> Util::GetFunction(const std::string& s) {
        	return funcs[s];
        }

        bool Util::HasFunction(const std::string& s) {
            return funcs.find(s) != funcs.end();
        }
    }
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: IDocumentSettingAccess.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-26 09:37:00 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef IDOCUMENTSETTINGACCESS_HXX_INCLUDED
#define IDOCUMENTSETTINGACCESS_HXX_INCLUDED

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif
#ifndef _VOS_REF_HXX
#include <vos/ref.hxx>
#endif
#ifndef _CHCMPRSE_HXX
#include <chcmprse.hxx>
#endif

class SvxForbiddenCharactersTable;
namespace com { namespace sun { namespace star { namespace i18n { struct ForbiddenCharacters; } } } }

 /** Provides access to settings of a document
 */
 class IDocumentSettingAccess
 {
 public:
     enum DocumentSettingId
     {
         // COMPATIBILITY FLAGS START
         PARA_SPACE_MAX,
         PARA_SPACE_MAX_AT_PAGES,

         TAB_COMPAT,

         ADD_FLY_OFFSETS,

         OLD_NUMBERING,

         ADD_EXT_LEADING,
         USE_VIRTUAL_DEVICE,
         USE_HIRES_VIRTUAL_DEVICE,
         OLD_LINE_SPACING,
         ADD_PARA_SPACING_TO_TABLE_CELLS,
         USE_FORMER_OBJECT_POS,
         USE_FORMER_TEXT_WRAPPING,
         CONSIDER_WRAP_ON_OBJECT_POSITION,

         IGNORE_FIRST_LINE_INDENT_IN_NUMBERING,
         DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK,
         DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT,
         OUTLINE_LEVEL_YIELDS_OUTLINE_RULE,

         DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE,
         TABLE_ROW_KEEP,
         IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION,
         CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME,

         UNIX_FORCE_ZERO_EXT_LEADING,
         // COMPATIBILITY FLAGS END

         BROWSE_MODE,
         HTML_MODE,
         GLOBAL_DOCUMENT,
         GLOBAL_DOCUMENT_SAVE_LINKS,
         LABEL_DOCUMENT,
         PURGE_OLE,
         KERN_ASIAN_PUNCTUATION
     };

 public:
    /** Return the specified document setting.

       @param id
       [in] the identifier of the document setting to be returned.
       See above for a list of valid document setting identifiers.

       @returns
       the value of the requested document setting.
    */
    virtual bool get(/*[in]*/ DocumentSettingId id) const = 0;

    /** Set the specified document setting.

        @param id
        [in] the identifier of the document setting to be set.
        See above for a list of valid document setting identifiers.

        @param value
        [in] the new value of the specified document setting.
    */
    virtual void set(/*[in]*/ DocumentSettingId id, /*[in]*/ bool value) = 0;

    /** Return the forbidden characters.

       @param nLang
       [in] the language for which the forbidden character list is returned.

       @param bLocaleData
       [in] if set and there is no user defined forbidden character list for
            language lang, the default list for language lang will be returned.

       @returns
       a list of forbidden characters.
    */
    virtual const com::sun::star::i18n::ForbiddenCharacters*
        getForbiddenCharacters(/*[in]*/ USHORT nLang, /*[in]*/ bool bLocaleData ) const = 0;

    /** Set the forbidden characters.

       @param nLang
       [in] the language for which the forbidden character list should be set.

       @param rForbiddenCharacters
       [in] the new list of forbidden characters for language lang.
    */
    virtual void setForbiddenCharacters(/*[in]*/ USHORT nLang,
                                        /*[in]*/ const com::sun::star::i18n::ForbiddenCharacters& rForbiddenCharacters ) = 0;

    /** Get the forbidden character table and creates one if necessary.

       @returns
       the forbidden characters table.
    */
    virtual vos::ORef<SvxForbiddenCharactersTable>& getForbiddenCharacterTable() = 0;

    /** Get the forbidden character table.

       @returns
       the forbidden characters table.
    */
    virtual const vos::ORef<SvxForbiddenCharactersTable>& getForbiddenCharacterTable() const = 0;

    /** Get the current link update mode.

       @param bGlobalSettings
       [in] if set, the link update mode is obtained from the module,
            if it is set to GLOBALSETTING

       @returns
       the current link update mode.
    */
    virtual sal_uInt16 getLinkUpdateMode( /*[in]*/bool bGlobalSettings ) const = 0;

    /** Set the current link update mode.

       @param nMode
       [in] the new link update mode.
    */
    virtual void setLinkUpdateMode( /*[in]*/ sal_uInt16 nMode ) = 0;

    /** Get the current field update mode.

       @param bGlobalSettings
       [in] if set, the field update mode is obtained from the module,
            if it is set to GLOBALSETTING

       @returns
       the current field update mode.
    */
    virtual sal_uInt16 getFieldUpdateFlags( /*[in]*/bool bGlobalSettings ) const = 0;

    /** Set the current field update mode.

       @param nMode
       [in] the new field update mode.
    */
    virtual void setFieldUpdateFlags( /*[in]*/ sal_uInt16 nMode )  = 0;

    /** Get the character compression type for Asian characters.

       @returns
       the current character compression mode.
    */
    virtual SwCharCompressType getCharacterCompressionType() const = 0;

    /** Set the character compression type for Asian characters.

       @param nMode
       [in] the new character compression type.
    */
    virtual void setCharacterCompressionType( /*[in]*/SwCharCompressType nType ) = 0;

protected:
    virtual ~IDocumentSettingAccess() {};
 };

 #endif // IDOCUMENTSETTINGACCESS_HXX_INCLUDED
<commit_msg>INTEGRATION: CWS pj77 (1.3.208); FILE MERGED 2007/04/25 17:52:33 pjanik 1.3.208.1: #i76688#: Remove deprecated SISSL.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: IDocumentSettingAccess.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 13:09:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef IDOCUMENTSETTINGACCESS_HXX_INCLUDED
#define IDOCUMENTSETTINGACCESS_HXX_INCLUDED

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif
#ifndef _VOS_REF_HXX
#include <vos/ref.hxx>
#endif
#ifndef _CHCMPRSE_HXX
#include <chcmprse.hxx>
#endif

class SvxForbiddenCharactersTable;
namespace com { namespace sun { namespace star { namespace i18n { struct ForbiddenCharacters; } } } }

 /** Provides access to settings of a document
 */
 class IDocumentSettingAccess
 {
 public:
     enum DocumentSettingId
     {
         // COMPATIBILITY FLAGS START
         PARA_SPACE_MAX,
         PARA_SPACE_MAX_AT_PAGES,

         TAB_COMPAT,

         ADD_FLY_OFFSETS,

         OLD_NUMBERING,

         ADD_EXT_LEADING,
         USE_VIRTUAL_DEVICE,
         USE_HIRES_VIRTUAL_DEVICE,
         OLD_LINE_SPACING,
         ADD_PARA_SPACING_TO_TABLE_CELLS,
         USE_FORMER_OBJECT_POS,
         USE_FORMER_TEXT_WRAPPING,
         CONSIDER_WRAP_ON_OBJECT_POSITION,

         IGNORE_FIRST_LINE_INDENT_IN_NUMBERING,
         DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK,
         DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT,
         OUTLINE_LEVEL_YIELDS_OUTLINE_RULE,

         DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE,
         TABLE_ROW_KEEP,
         IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION,
         CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME,

         UNIX_FORCE_ZERO_EXT_LEADING,
         // COMPATIBILITY FLAGS END

         BROWSE_MODE,
         HTML_MODE,
         GLOBAL_DOCUMENT,
         GLOBAL_DOCUMENT_SAVE_LINKS,
         LABEL_DOCUMENT,
         PURGE_OLE,
         KERN_ASIAN_PUNCTUATION
     };

 public:
    /** Return the specified document setting.

       @param id
       [in] the identifier of the document setting to be returned.
       See above for a list of valid document setting identifiers.

       @returns
       the value of the requested document setting.
    */
    virtual bool get(/*[in]*/ DocumentSettingId id) const = 0;

    /** Set the specified document setting.

        @param id
        [in] the identifier of the document setting to be set.
        See above for a list of valid document setting identifiers.

        @param value
        [in] the new value of the specified document setting.
    */
    virtual void set(/*[in]*/ DocumentSettingId id, /*[in]*/ bool value) = 0;

    /** Return the forbidden characters.

       @param nLang
       [in] the language for which the forbidden character list is returned.

       @param bLocaleData
       [in] if set and there is no user defined forbidden character list for
            language lang, the default list for language lang will be returned.

       @returns
       a list of forbidden characters.
    */
    virtual const com::sun::star::i18n::ForbiddenCharacters*
        getForbiddenCharacters(/*[in]*/ USHORT nLang, /*[in]*/ bool bLocaleData ) const = 0;

    /** Set the forbidden characters.

       @param nLang
       [in] the language for which the forbidden character list should be set.

       @param rForbiddenCharacters
       [in] the new list of forbidden characters for language lang.
    */
    virtual void setForbiddenCharacters(/*[in]*/ USHORT nLang,
                                        /*[in]*/ const com::sun::star::i18n::ForbiddenCharacters& rForbiddenCharacters ) = 0;

    /** Get the forbidden character table and creates one if necessary.

       @returns
       the forbidden characters table.
    */
    virtual vos::ORef<SvxForbiddenCharactersTable>& getForbiddenCharacterTable() = 0;

    /** Get the forbidden character table.

       @returns
       the forbidden characters table.
    */
    virtual const vos::ORef<SvxForbiddenCharactersTable>& getForbiddenCharacterTable() const = 0;

    /** Get the current link update mode.

       @param bGlobalSettings
       [in] if set, the link update mode is obtained from the module,
            if it is set to GLOBALSETTING

       @returns
       the current link update mode.
    */
    virtual sal_uInt16 getLinkUpdateMode( /*[in]*/bool bGlobalSettings ) const = 0;

    /** Set the current link update mode.

       @param nMode
       [in] the new link update mode.
    */
    virtual void setLinkUpdateMode( /*[in]*/ sal_uInt16 nMode ) = 0;

    /** Get the current field update mode.

       @param bGlobalSettings
       [in] if set, the field update mode is obtained from the module,
            if it is set to GLOBALSETTING

       @returns
       the current field update mode.
    */
    virtual sal_uInt16 getFieldUpdateFlags( /*[in]*/bool bGlobalSettings ) const = 0;

    /** Set the current field update mode.

       @param nMode
       [in] the new field update mode.
    */
    virtual void setFieldUpdateFlags( /*[in]*/ sal_uInt16 nMode )  = 0;

    /** Get the character compression type for Asian characters.

       @returns
       the current character compression mode.
    */
    virtual SwCharCompressType getCharacterCompressionType() const = 0;

    /** Set the character compression type for Asian characters.

       @param nMode
       [in] the new character compression type.
    */
    virtual void setCharacterCompressionType( /*[in]*/SwCharCompressType nType ) = 0;

protected:
    virtual ~IDocumentSettingAccess() {};
 };

 #endif // IDOCUMENTSETTINGACCESS_HXX_INCLUDED
<|endoftext|>


<commit_before><commit_msg>-Werror,-Wmismatched-tags<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: scriptinfo.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: obo $ $Date: 2005-04-18 14:33:25 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SCRIPTINFO_HXX
#define _SCRIPTINFO_HXX

#ifndef _SVSTDARR_HXX
#define _SVSTDARR_SHORTS
#define _SVSTDARR_BYTES
#define _SVSTDARR_USHORTS
#define _SVSTDARR_XUB_STRLEN
#include <svtools/svstdarr.hxx>
#endif

#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif
#include <list>

class SwWrongList;
class SwTxtNode;
class Point;
class MultiSelection;
typedef std::list< xub_StrLen > PositionList;

#define SPACING_PRECISION_FACTOR 100

/*************************************************************************
 *                class SwScanner
 * Hilfsklasse, die beim Spellen die Worte im gewuenschten Bereich
 * nacheinander zur Verfuegung stellt.
 *************************************************************************/

class SwScanner
{
    XubString aWord;
    const SwTxtNode& rNode;
    xub_StrLen nStartPos;
    xub_StrLen nEndPos;
    xub_StrLen nBegin;
    xub_StrLen nLen;
    LanguageType aCurrLang;
    USHORT nWordType;
    BOOL bStart;
    BOOL bClip;

public:
    SwScanner( const SwTxtNode& rNd, USHORT nWordType,
               xub_StrLen nStart, xub_StrLen nEnde, BOOL bClip = FALSE );

    // This next word function tries to find the language for the next word
    // It should currently _not_ be used for spell checking, and works only for
    // ! bReverse
    BOOL NextWord();

    const XubString& GetWord() const    { return aWord; }

    xub_StrLen GetBegin() const         { return nBegin; }
    xub_StrLen GetEnd() const           { return nBegin + nLen; }
    xub_StrLen GetLen() const           { return nLen; }

    LanguageType GetCurrentLanguage() const {return aCurrLang;}
};

/*************************************************************************
 *                      class SwScriptInfo
 *
 * encapsultes information about script changes
 *************************************************************************/

class SwScriptInfo
{
private:
    SvXub_StrLens aScriptChg;
    SvBytes aScriptType;
    SvXub_StrLens aDirChg;
    SvBytes aDirType;
    SvXub_StrLens aKashida;
    SvXub_StrLens aCompChg;
    SvXub_StrLens aCompLen;
    SvXub_StrLens aHiddenChg;
    SvBytes aCompType;
    xub_StrLen nInvalidityPos;
    BYTE nDefaultDir;

    void UpdateBidiInfo( const String& rTxt );

public:
    enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE };

    inline SwScriptInfo() : nInvalidityPos( 0 ), nDefaultDir( 0 ) {};

    // determines script changes
    void InitScriptInfo( const SwTxtNode& rNode, sal_Bool bRTL );
    void InitScriptInfo( const SwTxtNode& rNode );

    // set/get position from which data is invalid
    inline void SetInvalidity( const xub_StrLen nPos );
    inline xub_StrLen GetInvalidity() const { return nInvalidityPos; };

    // get default direction for paragraph
    inline BYTE GetDefaultDir() const { return nDefaultDir; };

    // array operations, nCnt refers to array position
    inline USHORT CountScriptChg() const;
    inline xub_StrLen GetScriptChg( const USHORT nCnt ) const;
    inline BYTE GetScriptType( const USHORT nCnt ) const;

    inline USHORT CountDirChg() const;
    inline xub_StrLen GetDirChg( const USHORT nCnt ) const;
    inline BYTE GetDirType( const USHORT nCnt ) const;

    inline USHORT CountKashida() const;
    inline xub_StrLen GetKashida( const USHORT nCnt ) const;

    inline USHORT CountCompChg() const;
    inline xub_StrLen GetCompStart( const USHORT nCnt ) const;
    inline xub_StrLen GetCompLen( const USHORT nCnt ) const;
    inline BYTE GetCompType( const USHORT nCnt ) const;

    inline USHORT CountHiddenChg() const;
    inline xub_StrLen GetHiddenChg( const USHORT nCnt ) const;
    static void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode,
                                                MultiSelection& rHiddenMulti );

    // "high" level operations, nPos refers to string position
    xub_StrLen NextScriptChg( const xub_StrLen nPos ) const;
    BYTE ScriptType( const xub_StrLen nPos ) const;

    // Returns the position of the next direction level change.
    // If bLevel is set, the position of the next level which is smaller
    // than the level at position nPos is returned. This is required to
    // obtain the end of a SwBidiPortion
    xub_StrLen NextDirChg( const xub_StrLen nPos,
                           const BYTE* pLevel = 0 ) const;
    BYTE DirType( const xub_StrLen nPos ) const;

#if OSL_DEBUG_LEVEL > 1
    BYTE CompType( const xub_StrLen nPos ) const;
#endif

    //
    // HIDDEN TEXT STUFF START
    //

/** Hidden text range information - static and non-version

    @descr  Determines if a given position is inside a hidden text range. The
            static version tries to obtain a valid SwScriptInfo object
            via the SwTxtNode, otherwise it calculates the values from scratch.
            The non-static version uses the internally cached informatio
            for the calculation.

    @param  rNode
                The text node.
    @param  nPos
                The given position that should be checked.
    @param  rnStartPos
                Return parameter for the start position of the hidden range.
                STRING_LEN if nPos is not inside a hidden range.
    @param  rnEndPos
                Return parameter for the end position of the hidden range.
                0 if nPos is not inside a hidden range.
    @param  rnEndPos
                Return parameter that contains all the hidden text ranges. Optional.
    @return
            returns true if there are any hidden characters in this paragraph.

*/
    static bool GetBoundsOfHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos,
                                        xub_StrLen& rnStartPos, xub_StrLen& rnEndPos,
                                        PositionList* pList = 0 );
    bool GetBoundsOfHiddenRange(  xub_StrLen nPos, xub_StrLen& rnStartPos,
                                  xub_StrLen& rnEndPos, PositionList* pList = 0 ) const;

    static bool IsInHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos );

/** Hidden text attribute handling

    @descr  Takes a string and either deletes the hidden ranges or sets
            a given character in place of the hidden characters.

    @param  rNode
                The text node.
    @param  nPos
                The string to modify.
    @param  cChar
                The character that should replace the hidden characters.
    @param  bDel
                If set, the hidden ranges will be deleted from the text node.
 */
    static USHORT MaskHiddenRanges( const SwTxtNode& rNode, XubString& rText,
                                    const xub_StrLen nStt, const xub_StrLen nEnd,
                                    const xub_Unicode cChar );

/** Hidden text attribute handling

    @descr  Takes a SwTxtNode and deletes the hidden ranges from the node.

    @param  rNode
                The text node.
 */
    static void DeleteHiddenRanges( SwTxtNode& rNode );

    //
    // HIDDEN TEXT STUFF END
    //

    // examines the range [ nStart, nStart + nEnd ] if there are kanas
    // returns start index of kana entry in array, otherwise USHRT_MAX
    USHORT HasKana( xub_StrLen nStart, const xub_StrLen nEnd ) const;

    // modifies the kerning array according to a given compress value
    long Compress( long* pKernArray, xub_StrLen nIdx, xub_StrLen nLen,
                   const USHORT nCompress, const USHORT nFontHeight,
                   Point* pPoint = NULL ) const;

/** Performes a kashida justification on the kerning array

    @descr  Add some extra space for kashida justification to the
            positions in the kerning array.
    @param  pKernArray
                The printers kerning array. Optional.
    @param  pScrArray
                The screen kerning array. Optional.
    @param  nIdx
                Start referring to the paragraph.
    @param  nLen
                The number of characters to be considered.
    @param  nSpaceAdd
                The value which has to be added to a kashida opportunity.
    @return The number of kashida opportunities in the given range
*/
    USHORT KashidaJustify( long* pKernArray ,long* pScrArray,
                           xub_StrLen nIdx, xub_StrLen nLen,
                           long nSpaceAdd = 0 ) const;

/** Checks if language is one of the 16 Arabic languages

    @descr  Checks if language is one of the 16 Arabic languages
    @param  aLang
                The language which has to be checked.
    @return Returns if the language is an Arabic language
*/
    static BOOL IsArabicLanguage( LanguageType aLang );

/** Performes a thai justification on the kerning array

    @descr  Add some extra space for thai justification to the
            positions in the kerning array.
    @param  rTxt
                The String
    @param  pKernArray
                The printers kerning array. Optional.
    @param  pScrArray
                The screen kerning array. Optional.
    @param  nIdx
                Start referring to the paragraph.
    @param  nLen
                The number of characters to be considered.
    @param  nSpaceAdd
                The value which has to be added to the cells.
    @return The number of extra spaces in the given range
*/
    static USHORT ThaiJustify( const XubString& rTxt, long* pKernArray,
                               long* pScrArray, xub_StrLen nIdx,
                               xub_StrLen nLen, xub_StrLen nNumberOfBlanks = 0,
                               long nSpaceAdd = 0 );

    static SwScriptInfo* GetScriptInfo( const SwTxtNode& rNode,
                                        sal_Bool bAllowInvalid = sal_False );

    static BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, const SwScriptInfo* pSI );
};

inline void SwScriptInfo::SetInvalidity( const xub_StrLen nPos )
{
    if ( nPos < nInvalidityPos )
        nInvalidityPos = nPos;
};
inline USHORT SwScriptInfo::CountScriptChg() const { return aScriptChg.Count(); }
inline xub_StrLen SwScriptInfo::GetScriptChg( const USHORT nCnt ) const
{
    ASSERT( nCnt < aScriptChg.Count(),"No ScriptChange today!");
    return aScriptChg[ nCnt ];
}
inline BYTE SwScriptInfo::GetScriptType( const xub_StrLen nCnt ) const
{
    ASSERT( nCnt < aScriptChg.Count(),"No ScriptType today!");
    return aScriptType[ nCnt ];
}

inline USHORT SwScriptInfo::CountDirChg() const { return aDirChg.Count(); }
inline xub_StrLen SwScriptInfo::GetDirChg( const USHORT nCnt ) const
{
    ASSERT( nCnt < aDirChg.Count(),"No DirChange today!");
    return aDirChg[ nCnt ];
}
inline BYTE SwScriptInfo::GetDirType( const xub_StrLen nCnt ) const
{
    ASSERT( nCnt < aDirChg.Count(),"No DirType today!");
    return aDirType[ nCnt ];
}

inline USHORT SwScriptInfo::CountKashida() const { return aKashida.Count(); }
inline xub_StrLen SwScriptInfo::GetKashida( const USHORT nCnt ) const
{
    ASSERT( nCnt < aKashida.Count(),"No Kashidas today!");
    return aKashida[ nCnt ];
}

inline USHORT SwScriptInfo::CountCompChg() const { return aCompChg.Count(); };
inline xub_StrLen SwScriptInfo::GetCompStart( const USHORT nCnt ) const
{
    ASSERT( nCnt < aCompChg.Count(),"No CompressionStart today!");
    return aCompChg[ nCnt ];
}
inline xub_StrLen SwScriptInfo::GetCompLen( const USHORT nCnt ) const
{
    ASSERT( nCnt < aCompChg.Count(),"No CompressionLen today!");
    return aCompLen[ nCnt ];
}

inline BYTE SwScriptInfo::GetCompType( const USHORT nCnt ) const
{
    ASSERT( nCnt < aCompChg.Count(),"No CompressionType today!");
    return aCompType[ nCnt ];
}

inline USHORT SwScriptInfo::CountHiddenChg() const { return aHiddenChg.Count(); };
inline xub_StrLen SwScriptInfo::GetHiddenChg( const USHORT nCnt ) const
{
    ASSERT( nCnt < aHiddenChg.Count(),"No HiddenChg today!");
    return aHiddenChg[ nCnt ];
}

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.11.184); FILE MERGED 2005/09/05 13:40:05 rt 1.11.184.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: scriptinfo.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 03:55:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SCRIPTINFO_HXX
#define _SCRIPTINFO_HXX

#ifndef _SVSTDARR_HXX
#define _SVSTDARR_SHORTS
#define _SVSTDARR_BYTES
#define _SVSTDARR_USHORTS
#define _SVSTDARR_XUB_STRLEN
#include <svtools/svstdarr.hxx>
#endif

#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif
#include <list>

class SwWrongList;
class SwTxtNode;
class Point;
class MultiSelection;
typedef std::list< xub_StrLen > PositionList;

#define SPACING_PRECISION_FACTOR 100

/*************************************************************************
 *                class SwScanner
 * Hilfsklasse, die beim Spellen die Worte im gewuenschten Bereich
 * nacheinander zur Verfuegung stellt.
 *************************************************************************/

class SwScanner
{
    XubString aWord;
    const SwTxtNode& rNode;
    xub_StrLen nStartPos;
    xub_StrLen nEndPos;
    xub_StrLen nBegin;
    xub_StrLen nLen;
    LanguageType aCurrLang;
    USHORT nWordType;
    BOOL bStart;
    BOOL bClip;

public:
    SwScanner( const SwTxtNode& rNd, USHORT nWordType,
               xub_StrLen nStart, xub_StrLen nEnde, BOOL bClip = FALSE );

    // This next word function tries to find the language for the next word
    // It should currently _not_ be used for spell checking, and works only for
    // ! bReverse
    BOOL NextWord();

    const XubString& GetWord() const    { return aWord; }

    xub_StrLen GetBegin() const         { return nBegin; }
    xub_StrLen GetEnd() const           { return nBegin + nLen; }
    xub_StrLen GetLen() const           { return nLen; }

    LanguageType GetCurrentLanguage() const {return aCurrLang;}
};

/*************************************************************************
 *                      class SwScriptInfo
 *
 * encapsultes information about script changes
 *************************************************************************/

class SwScriptInfo
{
private:
    SvXub_StrLens aScriptChg;
    SvBytes aScriptType;
    SvXub_StrLens aDirChg;
    SvBytes aDirType;
    SvXub_StrLens aKashida;
    SvXub_StrLens aCompChg;
    SvXub_StrLens aCompLen;
    SvXub_StrLens aHiddenChg;
    SvBytes aCompType;
    xub_StrLen nInvalidityPos;
    BYTE nDefaultDir;

    void UpdateBidiInfo( const String& rTxt );

public:
    enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE };

    inline SwScriptInfo() : nInvalidityPos( 0 ), nDefaultDir( 0 ) {};

    // determines script changes
    void InitScriptInfo( const SwTxtNode& rNode, sal_Bool bRTL );
    void InitScriptInfo( const SwTxtNode& rNode );

    // set/get position from which data is invalid
    inline void SetInvalidity( const xub_StrLen nPos );
    inline xub_StrLen GetInvalidity() const { return nInvalidityPos; };

    // get default direction for paragraph
    inline BYTE GetDefaultDir() const { return nDefaultDir; };

    // array operations, nCnt refers to array position
    inline USHORT CountScriptChg() const;
    inline xub_StrLen GetScriptChg( const USHORT nCnt ) const;
    inline BYTE GetScriptType( const USHORT nCnt ) const;

    inline USHORT CountDirChg() const;
    inline xub_StrLen GetDirChg( const USHORT nCnt ) const;
    inline BYTE GetDirType( const USHORT nCnt ) const;

    inline USHORT CountKashida() const;
    inline xub_StrLen GetKashida( const USHORT nCnt ) const;

    inline USHORT CountCompChg() const;
    inline xub_StrLen GetCompStart( const USHORT nCnt ) const;
    inline xub_StrLen GetCompLen( const USHORT nCnt ) const;
    inline BYTE GetCompType( const USHORT nCnt ) const;

    inline USHORT CountHiddenChg() const;
    inline xub_StrLen GetHiddenChg( const USHORT nCnt ) const;
    static void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode,
                                                MultiSelection& rHiddenMulti );

    // "high" level operations, nPos refers to string position
    xub_StrLen NextScriptChg( const xub_StrLen nPos ) const;
    BYTE ScriptType( const xub_StrLen nPos ) const;

    // Returns the position of the next direction level change.
    // If bLevel is set, the position of the next level which is smaller
    // than the level at position nPos is returned. This is required to
    // obtain the end of a SwBidiPortion
    xub_StrLen NextDirChg( const xub_StrLen nPos,
                           const BYTE* pLevel = 0 ) const;
    BYTE DirType( const xub_StrLen nPos ) const;

#if OSL_DEBUG_LEVEL > 1
    BYTE CompType( const xub_StrLen nPos ) const;
#endif

    //
    // HIDDEN TEXT STUFF START
    //

/** Hidden text range information - static and non-version

    @descr  Determines if a given position is inside a hidden text range. The
            static version tries to obtain a valid SwScriptInfo object
            via the SwTxtNode, otherwise it calculates the values from scratch.
            The non-static version uses the internally cached informatio
            for the calculation.

    @param  rNode
                The text node.
    @param  nPos
                The given position that should be checked.
    @param  rnStartPos
                Return parameter for the start position of the hidden range.
                STRING_LEN if nPos is not inside a hidden range.
    @param  rnEndPos
                Return parameter for the end position of the hidden range.
                0 if nPos is not inside a hidden range.
    @param  rnEndPos
                Return parameter that contains all the hidden text ranges. Optional.
    @return
            returns true if there are any hidden characters in this paragraph.

*/
    static bool GetBoundsOfHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos,
                                        xub_StrLen& rnStartPos, xub_StrLen& rnEndPos,
                                        PositionList* pList = 0 );
    bool GetBoundsOfHiddenRange(  xub_StrLen nPos, xub_StrLen& rnStartPos,
                                  xub_StrLen& rnEndPos, PositionList* pList = 0 ) const;

    static bool IsInHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos );

/** Hidden text attribute handling

    @descr  Takes a string and either deletes the hidden ranges or sets
            a given character in place of the hidden characters.

    @param  rNode
                The text node.
    @param  nPos
                The string to modify.
    @param  cChar
                The character that should replace the hidden characters.
    @param  bDel
                If set, the hidden ranges will be deleted from the text node.
 */
    static USHORT MaskHiddenRanges( const SwTxtNode& rNode, XubString& rText,
                                    const xub_StrLen nStt, const xub_StrLen nEnd,
                                    const xub_Unicode cChar );

/** Hidden text attribute handling

    @descr  Takes a SwTxtNode and deletes the hidden ranges from the node.

    @param  rNode
                The text node.
 */
    static void DeleteHiddenRanges( SwTxtNode& rNode );

    //
    // HIDDEN TEXT STUFF END
    //

    // examines the range [ nStart, nStart + nEnd ] if there are kanas
    // returns start index of kana entry in array, otherwise USHRT_MAX
    USHORT HasKana( xub_StrLen nStart, const xub_StrLen nEnd ) const;

    // modifies the kerning array according to a given compress value
    long Compress( long* pKernArray, xub_StrLen nIdx, xub_StrLen nLen,
                   const USHORT nCompress, const USHORT nFontHeight,
                   Point* pPoint = NULL ) const;

/** Performes a kashida justification on the kerning array

    @descr  Add some extra space for kashida justification to the
            positions in the kerning array.
    @param  pKernArray
                The printers kerning array. Optional.
    @param  pScrArray
                The screen kerning array. Optional.
    @param  nIdx
                Start referring to the paragraph.
    @param  nLen
                The number of characters to be considered.
    @param  nSpaceAdd
                The value which has to be added to a kashida opportunity.
    @return The number of kashida opportunities in the given range
*/
    USHORT KashidaJustify( long* pKernArray ,long* pScrArray,
                           xub_StrLen nIdx, xub_StrLen nLen,
                           long nSpaceAdd = 0 ) const;

/** Checks if language is one of the 16 Arabic languages

    @descr  Checks if language is one of the 16 Arabic languages
    @param  aLang
                The language which has to be checked.
    @return Returns if the language is an Arabic language
*/
    static BOOL IsArabicLanguage( LanguageType aLang );

/** Performes a thai justification on the kerning array

    @descr  Add some extra space for thai justification to the
            positions in the kerning array.
    @param  rTxt
                The String
    @param  pKernArray
                The printers kerning array. Optional.
    @param  pScrArray
                The screen kerning array. Optional.
    @param  nIdx
                Start referring to the paragraph.
    @param  nLen
                The number of characters to be considered.
    @param  nSpaceAdd
                The value which has to be added to the cells.
    @return The number of extra spaces in the given range
*/
    static USHORT ThaiJustify( const XubString& rTxt, long* pKernArray,
                               long* pScrArray, xub_StrLen nIdx,
                               xub_StrLen nLen, xub_StrLen nNumberOfBlanks = 0,
                               long nSpaceAdd = 0 );

    static SwScriptInfo* GetScriptInfo( const SwTxtNode& rNode,
                                        sal_Bool bAllowInvalid = sal_False );

    static BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, const SwScriptInfo* pSI );
};

inline void SwScriptInfo::SetInvalidity( const xub_StrLen nPos )
{
    if ( nPos < nInvalidityPos )
        nInvalidityPos = nPos;
};
inline USHORT SwScriptInfo::CountScriptChg() const { return aScriptChg.Count(); }
inline xub_StrLen SwScriptInfo::GetScriptChg( const USHORT nCnt ) const
{
    ASSERT( nCnt < aScriptChg.Count(),"No ScriptChange today!");
    return aScriptChg[ nCnt ];
}
inline BYTE SwScriptInfo::GetScriptType( const xub_StrLen nCnt ) const
{
    ASSERT( nCnt < aScriptChg.Count(),"No ScriptType today!");
    return aScriptType[ nCnt ];
}

inline USHORT SwScriptInfo::CountDirChg() const { return aDirChg.Count(); }
inline xub_StrLen SwScriptInfo::GetDirChg( const USHORT nCnt ) const
{
    ASSERT( nCnt < aDirChg.Count(),"No DirChange today!");
    return aDirChg[ nCnt ];
}
inline BYTE SwScriptInfo::GetDirType( const xub_StrLen nCnt ) const
{
    ASSERT( nCnt < aDirChg.Count(),"No DirType today!");
    return aDirType[ nCnt ];
}

inline USHORT SwScriptInfo::CountKashida() const { return aKashida.Count(); }
inline xub_StrLen SwScriptInfo::GetKashida( const USHORT nCnt ) const
{
    ASSERT( nCnt < aKashida.Count(),"No Kashidas today!");
    return aKashida[ nCnt ];
}

inline USHORT SwScriptInfo::CountCompChg() const { return aCompChg.Count(); };
inline xub_StrLen SwScriptInfo::GetCompStart( const USHORT nCnt ) const
{
    ASSERT( nCnt < aCompChg.Count(),"No CompressionStart today!");
    return aCompChg[ nCnt ];
}
inline xub_StrLen SwScriptInfo::GetCompLen( const USHORT nCnt ) const
{
    ASSERT( nCnt < aCompChg.Count(),"No CompressionLen today!");
    return aCompLen[ nCnt ];
}

inline BYTE SwScriptInfo::GetCompType( const USHORT nCnt ) const
{
    ASSERT( nCnt < aCompChg.Count(),"No CompressionType today!");
    return aCompType[ nCnt ];
}

inline USHORT SwScriptInfo::CountHiddenChg() const { return aHiddenChg.Count(); };
inline xub_StrLen SwScriptInfo::GetHiddenChg( const USHORT nCnt ) const
{
    ASSERT( nCnt < aHiddenChg.Count(),"No HiddenChg today!");
    return aHiddenChg[ nCnt ];
}

#endif
<|endoftext|>


<commit_before>/*
 * network.hpp
 *
 *  Created on: Feb 8, 2020
 *      Author: devel
 */

#ifndef SRC_LIBRARY_OS_NETWORK_HPP_
#define SRC_LIBRARY_OS_NETWORK_HPP_
#include <stdlib.h>
#include <vector>

#include "../base/base.h"

namespace license {
namespace os {

typedef enum { IFACE_TYPE_ETHERNET, IFACE_TYPE_WIRELESS } IFACE_TYPE;

#ifdef __unix__
#include <netdb.h>
#define LCC_ADAPTER_DESCRIPTION_LEN NI_MAXHOST
#else
#include <iphlpapi.h>
#define LCC_ADAPTER_DESCRIPTION_LEN MAX_ADAPTER_DESCRIPTION_LENGTH
#endif

typedef struct {
	int id;
	char description[LCC_ADAPTER_DESCRIPTION_LEN + 1];
	unsigned char mac_address[8];
	unsigned char ipv4_address[4];
	IFACE_TYPE type;
} OsAdapterInfo;

FUNCTION_RETURN getAdapterInfos(std::vector<OsAdapterInfo>& adapterInfos);

}  // namespace os
}  // namespace license
#endif /* SRC_LIBRARY_OS_NETWORK_HPP_ */
<commit_msg>fix mingw<commit_after>/*
 * network.hpp
 *
 *  Created on: Feb 8, 2020
 *      Author: devel
 */

#ifndef SRC_LIBRARY_OS_NETWORK_HPP_
#define SRC_LIBRARY_OS_NETWORK_HPP_
#include <stdlib.h>
#include <vector>
#ifdef __unix__
#include <netdb.h>
#define LCC_ADAPTER_DESCRIPTION_LEN NI_MAXHOST
#else
#include <iphlpapi.h>
#define LCC_ADAPTER_DESCRIPTION_LEN MAX_ADAPTER_DESCRIPTION_LENGTH
#endif

#include "../base/base.h"

namespace license {
namespace os {

typedef enum { IFACE_TYPE_ETHERNET, IFACE_TYPE_WIRELESS } IFACE_TYPE;

typedef struct {
	int id;
	char description[LCC_ADAPTER_DESCRIPTION_LEN + 1];
	unsigned char mac_address[8];
	unsigned char ipv4_address[4];
	IFACE_TYPE type;
} OsAdapterInfo;

FUNCTION_RETURN getAdapterInfos(std::vector<OsAdapterInfo>& adapterInfos);

}  // namespace os
}  // namespace license
#endif /* SRC_LIBRARY_OS_NETWORK_HPP_ */
<|endoftext|>


<commit_before><commit_msg>tdf#91228 Fix Writer crash<commit_after><|endoftext|>


<commit_before><commit_msg>use ranged for<commit_after><|endoftext|>


<commit_before><commit_msg>Resolves: fdo#84943 make fodt non crashy like odt for formulas inside shapes<commit_after><|endoftext|>