<commit_before>#include "xchainer/numerical_gradient.h"

#include <algorithm>
#include <functional>
#include <vector>

#ifdef XCHAINER_ENABLE_CUDA
#include <cuda_runtime.h>
#endif  // XCHAINER_ENABLE_CUDA

#include "xchainer/array.h"
#include "xchainer/array_repr.h"
#include "xchainer/error.h"
#include "xchainer/indexable_array.h"
#include "xchainer/indexer.h"
#ifdef XCHAINER_ENABLE_CUDA
#include "xchainer/cuda/cuda_runtime.h"
#endif  // XCHAINER_ENABLE_CUDA
#include "xchainer/device.h"

namespace xchainer {
namespace numerical_gradient_internal {

// TODO(niboshi): These temporary implementation for primitive operations depend on that the data in arrays can be accessed directly
// (e.g. with unified memory). In order for numerical gradient calculation to work corretly on general devices, They should be replaced with
// full-featured operations.

Array& Subtract(const Array& lhs, const Array& rhs, Array& out) {
    lhs.device().Synchronize();
    rhs.device().Synchronize();
    out.device().Synchronize();

    VisitDtype(lhs.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        IndexableArray<const T> lhs_iarray{lhs};
        IndexableArray<const T> rhs_iarray{rhs};
        IndexableArray<T> out_iarray{out};
        Indexer indexer{out.shape()};

        for (int64_t i = 0; i < indexer.total_size(); ++i) {
            indexer.Set(i);
            out_iarray[indexer] = lhs_iarray[indexer] - rhs_iarray[indexer];
        }
    });
    return out;
}

Array& Divide(const Array& lhs, const Array& rhs, Array& out) {
    lhs.device().Synchronize();
    rhs.device().Synchronize();
    out.device().Synchronize();

    VisitDtype(lhs.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        IndexableArray<const T> lhs_iarray{lhs};
        IndexableArray<const T> rhs_iarray{rhs};
        IndexableArray<T> out_iarray{out};
        Indexer indexer{out.shape()};

        for (int64_t i = 0; i < indexer.total_size(); ++i) {
            indexer.Set(i);
            out_iarray[indexer] = lhs_iarray[indexer] / rhs_iarray[indexer];
        }
    });
    return out;
}

Array operator/(const Array& lhs, const Array& rhs) {
    Array out = Array::EmptyLike(lhs);
    Divide(lhs, rhs, out);
    return out;
}

// TODO(niboshi): Replace this with xchainer::Sum()
Scalar Sum(const Array& array) {
    array.device().Synchronize();

    return VisitDtype(array.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        IndexableArray<const T> iarray{array};
        Indexer indexer{array.shape()};

        T s = 0;
        for (int64_t i = 0; i < indexer.total_size(); ++i) {
            indexer.Set(i);
            s += iarray[indexer];
        }
        return Scalar{s};
    });
}

Scalar Norm(const Array& x) {
    Scalar s = Sum(x * x);
    return Scalar(std::sqrt(static_cast<double>(s)), x.dtype());
}

Scalar VectorDot(const Array& x, const Array& y) { return Sum(x * y); }

void Set(Array& out, int64_t flat_index, Scalar value) {
    out.device().Synchronize();

    VisitDtype(out.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        IndexableArray<T> iarray{out};
        Indexer indexer{out.shape()};
        indexer.Set(flat_index);
        iarray[indexer] = static_cast<T>(value);
    });
}

Scalar Get(const Array& out, int64_t flat_index) {
    out.device().Synchronize();

    return VisitDtype(out.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        IndexableArray<const T> iarray{out};
        Indexer indexer{out.shape()};
        indexer.Set(flat_index);
        return Scalar{iarray[indexer]};
    });
}

Arrays CalculateNumericalGradient(
        std::function<Arrays(const Arrays&)> func,
        const Arrays& inputs,
        const Arrays& grad_outputs,
        const Arrays& eps,
        const GraphId& graph_id) {
    // TODO(niboshi): Currently only elementwise functions are supported.
    // TODO(niboshi): Implement arithmetic operations and avoid manual synchronize
    const int nin = inputs.size();
    const int nout = grad_outputs.size();

    if (eps.size() != static_cast<size_t>(nin)) {
        throw XchainerError(
                "Invalid number of eps arrays where number of inputs: " + std::to_string(nin) + ", eps: " + std::to_string(eps.size()));
    }

    for (int i = 0; i < nin; ++i) {
        if (inputs.at(i).shape() != eps.at(i).shape()) {
            throw XchainerError("Invalid eps shape");
        }
        if (inputs.at(i).dtype() != eps.at(i).dtype()) {
            throw XchainerError("Invalid eps dtype");
        }
        // TODO(niboshi): Check: eps must not contain zeros.
    }

    Dtype dtype = inputs[0].dtype();

    auto eval = [&, graph_id](int i_in, int64_t in_flat_index, Scalar eps_scalar, float multiplier) -> Arrays {
        Arrays xs;
        std::transform(inputs.begin(), inputs.end(), std::back_inserter(xs), [graph_id](const Array& x) {
            return x.AsConstant(CopyKind::kCopy).RequireGrad(graph_id);
        });

        Set(xs.at(i_in), in_flat_index, Get(xs.at(i_in), in_flat_index) + Scalar(static_cast<float>(eps_scalar) * multiplier, dtype));
        return func(xs);
    };

    Arrays grads;
    for (int i = 0; i < nin; ++i) {
        Array grad_i = Array::ZerosLike(inputs.at(i));
        int64_t size = grad_i.GetTotalSize();

        for (int64_t in_flat_index = 0; in_flat_index < size; ++in_flat_index) {
            Scalar eps_scalar = Get(eps.at(i), in_flat_index);
            Arrays ys0 = eval(i, in_flat_index, eps_scalar, -1);
            Arrays ys1 = eval(i, in_flat_index, eps_scalar, 1);

            for (int j = 0; j < nout; ++j) {
                Array dy = ys1.at(j) - ys0.at(j);
                Array denom = Array::FullLike(dy, eps_scalar) * Array::FullLike(dy, Scalar(2, dtype));

                Scalar g = VectorDot((ys1.at(j) - ys0.at(j)) / denom, grad_outputs.at(j));
                Scalar g_ij = Get(grad_i, in_flat_index) + g;
                Set(grad_i, in_flat_index, g_ij);
            }
        }
        grads.push_back(grad_i);
    }

    return grads;
}

}  // namespace numerical_gradient_internal
}  // namespace xchainer
<commit_msg>Fix rebase error<commit_after>#include "xchainer/numerical_gradient.h"

#include <algorithm>
#include <functional>
#include <vector>

#ifdef XCHAINER_ENABLE_CUDA
#include <cuda_runtime.h>
#endif  // XCHAINER_ENABLE_CUDA

#include "xchainer/array.h"
#include "xchainer/array_repr.h"
#include "xchainer/error.h"
#include "xchainer/indexable_array.h"
#include "xchainer/indexer.h"
#ifdef XCHAINER_ENABLE_CUDA
#include "xchainer/cuda/cuda_runtime.h"
#endif  // XCHAINER_ENABLE_CUDA
#include "xchainer/device.h"

namespace xchainer {
namespace numerical_gradient_internal {

// TODO(niboshi): These temporary implementation for primitive operations depend on that the data in arrays can be accessed directly
// (e.g. with unified memory). In order for numerical gradient calculation to work corretly on general devices, They should be replaced with
// full-featured operations.

Array& Divide(const Array& lhs, const Array& rhs, Array& out) {
    lhs.device().Synchronize();
    rhs.device().Synchronize();
    out.device().Synchronize();

    VisitDtype(lhs.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        IndexableArray<const T> lhs_iarray{lhs};
        IndexableArray<const T> rhs_iarray{rhs};
        IndexableArray<T> out_iarray{out};
        Indexer indexer{out.shape()};

        for (int64_t i = 0; i < indexer.total_size(); ++i) {
            indexer.Set(i);
            out_iarray[indexer] = lhs_iarray[indexer] / rhs_iarray[indexer];
        }
    });
    return out;
}

Array operator/(const Array& lhs, const Array& rhs) {
    Array out = Array::EmptyLike(lhs);
    Divide(lhs, rhs, out);
    return out;
}

// TODO(niboshi): Replace this with xchainer::Sum()
Scalar Sum(const Array& array) {
    array.device().Synchronize();

    return VisitDtype(array.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        IndexableArray<const T> iarray{array};
        Indexer indexer{array.shape()};

        T s = 0;
        for (int64_t i = 0; i < indexer.total_size(); ++i) {
            indexer.Set(i);
            s += iarray[indexer];
        }
        return Scalar{s};
    });
}

Scalar Norm(const Array& x) {
    Scalar s = Sum(x * x);
    return Scalar(std::sqrt(static_cast<double>(s)), x.dtype());
}

Scalar VectorDot(const Array& x, const Array& y) { return Sum(x * y); }

void Set(Array& out, int64_t flat_index, Scalar value) {
    out.device().Synchronize();

    VisitDtype(out.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        IndexableArray<T> iarray{out};
        Indexer indexer{out.shape()};
        indexer.Set(flat_index);
        iarray[indexer] = static_cast<T>(value);
    });
}

Scalar Get(const Array& out, int64_t flat_index) {
    out.device().Synchronize();

    return VisitDtype(out.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        IndexableArray<const T> iarray{out};
        Indexer indexer{out.shape()};
        indexer.Set(flat_index);
        return Scalar{iarray[indexer]};
    });
}

Arrays CalculateNumericalGradient(
        std::function<Arrays(const Arrays&)> func,
        const Arrays& inputs,
        const Arrays& grad_outputs,
        const Arrays& eps,
        const GraphId& graph_id) {
    // TODO(niboshi): Currently only elementwise functions are supported.
    // TODO(niboshi): Implement arithmetic operations and avoid manual synchronize
    const int nin = inputs.size();
    const int nout = grad_outputs.size();

    if (eps.size() != static_cast<size_t>(nin)) {
        throw XchainerError(
                "Invalid number of eps arrays where number of inputs: " + std::to_string(nin) + ", eps: " + std::to_string(eps.size()));
    }

    for (int i = 0; i < nin; ++i) {
        if (inputs.at(i).shape() != eps.at(i).shape()) {
            throw XchainerError("Invalid eps shape");
        }
        if (inputs.at(i).dtype() != eps.at(i).dtype()) {
            throw XchainerError("Invalid eps dtype");
        }
        // TODO(niboshi): Check: eps must not contain zeros.
    }

    Dtype dtype = inputs[0].dtype();

    auto eval = [&, graph_id](int i_in, int64_t in_flat_index, Scalar eps_scalar, float multiplier) -> Arrays {
        Arrays xs;
        std::transform(inputs.begin(), inputs.end(), std::back_inserter(xs), [graph_id](const Array& x) {
            return x.AsConstant(CopyKind::kCopy).RequireGrad(graph_id);
        });

        Set(xs.at(i_in), in_flat_index, Get(xs.at(i_in), in_flat_index) + Scalar(static_cast<float>(eps_scalar) * multiplier, dtype));
        return func(xs);
    };

    Arrays grads;
    for (int i = 0; i < nin; ++i) {
        Array grad_i = Array::ZerosLike(inputs.at(i));
        int64_t size = grad_i.GetTotalSize();

        for (int64_t in_flat_index = 0; in_flat_index < size; ++in_flat_index) {
            Scalar eps_scalar = Get(eps.at(i), in_flat_index);
            Arrays ys0 = eval(i, in_flat_index, eps_scalar, -1);
            Arrays ys1 = eval(i, in_flat_index, eps_scalar, 1);

            for (int j = 0; j < nout; ++j) {
                Array dy = ys1.at(j) - ys0.at(j);
                Array denom = Array::FullLike(dy, eps_scalar) * Array::FullLike(dy, Scalar(2, dtype));

                Scalar g = VectorDot((ys1.at(j) - ys0.at(j)) / denom, grad_outputs.at(j));
                Scalar g_ij = Get(grad_i, in_flat_index) + g;
                Set(grad_i, in_flat_index, g_ij);
            }
        }
        grads.push_back(grad_i);
    }

    return grads;
}

}  // namespace numerical_gradient_internal
}  // namespace xchainer
<|endoftext|>


<commit_before>/*
 *
 *            kPPP: A pppd front end for the KDE project
 *
 * $Id$
 *
 * (c) 1998 Mario Weilguni <mweilguni@kde.org>
 *
 *            Copyright (C) 1997 Bernd Johannes Wuebben
 *                   wuebben@math.cornell.edu
 *
 * based on EzPPP:
 * Copyright (C) 1997  Jay Painter
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include <qlabel.h>
#include <qdir.h>
#include <qpushbutton.h>
//Added by qt3to4:
#include <QVBoxLayout>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>

#include <qdialog.h>
#include <qregexp.h>
#include <q3multilineedit.h>
#include <qlayout.h>

#include <kbuttonbox.h>
#include <kmessagebox.h>

#include "pppdata.h"
#include "requester.h"
#include <klocale.h>

int PPPL_MakeLog(QStringList &list) {
  int pid = -1, newpid;
  char buffer[1024], *p;
  const char *pidp;
  int fd;

  fd = Requester::rq->openSysLog();
  if(fd < 0) {
    list.append(i18n("Cannot open any of the following logfiles:"));
    const char * const * logFile = &kppp_syslog[0];
    while(*logFile) {
      list.append(*logFile);
      logFile++;
    }
    return 1;
  }

  FILE *f = fdopen(fd, "r");
  while(fgets(buffer, sizeof(buffer), f) != 0) {
    // pppd line ?
    p = (char *)strstr(buffer, "pppd[");
    if(p == 0)
      continue;
    pidp = p += strlen("pppd[");
    while(*p && isdigit(*p))
      p++;
    if(*p != ']')
      continue;

    /* find out pid of pppd */
    sscanf(pidp, "%d", &newpid);
    if(newpid != pid) {
      pid = newpid;
      list.clear();
    }
    if(buffer[strlen(buffer)-1] == '\n')
      buffer[strlen(buffer)-1] = '\0';
    list.append(buffer);
  }
  fclose(f);

  if(list.isEmpty())
    return 2;

  /* clear security related info */

  const char *keyword[] = {"name = \"",
		    "user=\"",
		    "password=\"",
		    0};

  for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
  {
    QByteArray tmp = (*it).toLocal8Bit();
    for(int j = 0; keyword[j] != 0; j++) {
      char *p;

      if( (p = (char *)strstr(tmp.data(), keyword[j])) != 0) {
	p += strlen(keyword[j]);
	while(*p && *p != '"')
	  *p++ = 'X';
      }
    }

  }

  return 0;
}

void PPPL_AnalyseLog(QStringList &list, QStringList &result) {
  QString msg;
  const char *rmsg = "Remote message: ";

  result.clear();

  // setup the analysis database
  struct {
    const char *regexp;
    const char *answer;
  } hints[] = {
    {"Receive serial link is not 8-bit clean",
     I18N_NOOP("You have launched pppd before the remote server " \
	  "was ready to establish a PPP connection.\n"
	  "Please use the terminal-based login to verify") },

    {"Serial line is looped back",
     I18N_NOOP("You have not started the PPP software on the peer system.") },

    {"AP authentication failed",
     I18N_NOOP("Check that you supplied the correct username and password.")} ,

    {"is locked by pid",
     I18N_NOOP("You should not pass 'lock' as an argument to pppd. "
	  "Check /etc/ppp/options and ~/.ppprc") },

    {"CP: timeout sending",
     I18N_NOOP("The remote system does not seem to answer to\n"
	  "configuration request. Contact your provider.") },

    {"unrecognized option",
     I18N_NOOP("You have passed an invalid option to pppd. See 'man pppd' "
          "for a complete list of valid arguments.") },

    // terminator
    {0,0}
  };

  // scan the log for keywords and try to offer any help
  for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
  {
    // look for remote message
    int pos = (*it).indexOf(rmsg);
    if (pos != -1)
    {
      QString str = (*it);
      str.remove(0, pos + strlen(rmsg));
      if(!str.isEmpty()) {
        msg = i18n("Notice that the remote system has sent the following"
                         " message:\n\"%1\"\nThis may give you a hint why the"
                         " the connection has failed.", str);
        result.append(msg);
      }
    }

    // check in the hint database
    for(uint k = 0; hints[k].regexp != 0; k++) {
      QRegExp rx(hints[k].regexp);
      QString l(*it);
      if(l.contains(rx)) {
	result.append(i18n(hints[k].answer));
	break;
      }
    }
  }

  if (result.isEmpty())
    result.append(i18n("Unable to provide help."));
}

void PPPL_ShowLog() {
  QStringList sl, result;

  PPPL_MakeLog(sl);

  bool foundConnect = false;
  bool foundLCP = gpppdata.getPPPDebug();
  QString lcp = QLatin1String("[LCP");
  QString conn = QLatin1String("Connect:");
  QStringList::ConstIterator it = sl.begin();
  for( ; it != sl.end(); it++) {
    if((*it).indexOf(lcp) >= 0) {
      foundLCP = true;
      break;
    }
    if((*it).contains(conn))
      foundConnect = true;
  }
  if(foundConnect && !foundLCP) {
    int result = KMessageBox::warningYesNo(0,
				i18n("KPPP could not prepare a PPP log. It is very likely "
				     "that pppd was started without the \"debug\" option.\n"
				     "Without this option it's difficult to find out PPP "
				     "problems, so you should turn on the debug option.\n"
				     "Shall I turn it on now?"), QString::null, i18n("Restart pppd"), i18n("Do Not Restart"));

    if(result == KMessageBox::Yes) {
      gpppdata.setPPPDebug(TRUE);
      KMessageBox::information(0,
		       i18n("The \"debug\" option has been added. You "
			    "should now try to reconnect. If that fails "
			    "again, you will get a PPP log that may help "
					"you to track down the connection problem."));
      //      return;
    }

    //    return;
  }

  PPPL_AnalyseLog(sl, result);

  QDialog *dlg = new QDialog(0, "", TRUE);

  dlg->setWindowTitle(i18n("PPP Log"));
  QVBoxLayout *tl = new QVBoxLayout(dlg);
  tl->setSpacing(10);
  tl->setMargin(10);
  Q3MultiLineEdit *edit = new Q3MultiLineEdit(dlg);
  edit->setReadOnly(TRUE);
  QLabel *label = new QLabel(i18n("kppp's diagnosis (just guessing):"), dlg);
  Q3MultiLineEdit *diagnosis = new Q3MultiLineEdit(dlg);
  diagnosis->setReadOnly(TRUE);
  KButtonBox *bbox = new KButtonBox(dlg);
  bbox->addStretch(1);
  QPushButton *write = bbox->addButton(i18n("Write to File"));
  QPushButton *close = bbox->addButton(KStdGuiItem::close());
  bbox->layout();
  edit->setMinimumSize(600, 250);
  label->setMinimumSize(600, 15);
  diagnosis->setMinimumSize(600, 60);

  tl->addWidget(edit, 1);
  tl->addWidget(label);
  tl->addWidget(diagnosis, 1);
  tl->addWidget(bbox);
  dlg->setFixedSize(dlg->sizeHint());

  for(int i = 0; i < sl.count(); i++)
    edit->append(sl.at(i));
  for(int i = 0; i < result.count(); i++)
    diagnosis->append(result.at(i));

  dlg->connect(close, SIGNAL(clicked()),
	       dlg, SLOT(reject()));
  dlg->connect(write, SIGNAL(clicked()),
	       dlg, SLOT(accept()));

  if(dlg->exec()) {
    QDir d = QDir::home();
    QString s = d.absolutePath() + "/PPP-logfile";
    int old_umask = umask(0077);

    FILE *f = fopen(QFile::encodeName(s), "w");
    for(int i = 0; i < sl.count(); i++)
      fprintf(f, "%s\n", sl.at(i).toLocal8Bit().data());
    fclose(f);
    umask(old_umask);

    QString msg = i18n("The PPP log has been saved\nas \"%1\".\n\nIf you want to send a bug report, or have\nproblems connecting to the Internet, please\nattach this file. It will help the maintainers\nto find the bug and to improve KPPP", s);
    KMessageBox::information(0, msg);
  }
  delete dlg;
}
<commit_msg>Deprecated--<commit_after>/*
 *
 *            kPPP: A pppd front end for the KDE project
 *
 * $Id$
 *
 * (c) 1998 Mario Weilguni <mweilguni@kde.org>
 *
 *            Copyright (C) 1997 Bernd Johannes Wuebben
 *                   wuebben@math.cornell.edu
 *
 * based on EzPPP:
 * Copyright (C) 1997  Jay Painter
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include <qlabel.h>
#include <qdir.h>
#include <qpushbutton.h>
//Added by qt3to4:
#include <QVBoxLayout>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>

#include <qdialog.h>
#include <qregexp.h>
#include <QTextEdit>
#include <qlayout.h>

#include <kbuttonbox.h>
#include <kmessagebox.h>

#include "pppdata.h"
#include "requester.h"
#include <klocale.h>

int PPPL_MakeLog(QStringList &list) {
  int pid = -1, newpid;
  char buffer[1024], *p;
  const char *pidp;
  int fd;

  fd = Requester::rq->openSysLog();
  if(fd < 0) {
    list.append(i18n("Cannot open any of the following logfiles:"));
    const char * const * logFile = &kppp_syslog[0];
    while(*logFile) {
      list.append(*logFile);
      logFile++;
    }
    return 1;
  }

  FILE *f = fdopen(fd, "r");
  while(fgets(buffer, sizeof(buffer), f) != 0) {
    // pppd line ?
    p = (char *)strstr(buffer, "pppd[");
    if(p == 0)
      continue;
    pidp = p += strlen("pppd[");
    while(*p && isdigit(*p))
      p++;
    if(*p != ']')
      continue;

    /* find out pid of pppd */
    sscanf(pidp, "%d", &newpid);
    if(newpid != pid) {
      pid = newpid;
      list.clear();
    }
    if(buffer[strlen(buffer)-1] == '\n')
      buffer[strlen(buffer)-1] = '\0';
    list.append(buffer);
  }
  fclose(f);

  if(list.isEmpty())
    return 2;

  /* clear security related info */

  const char *keyword[] = {"name = \"",
		    "user=\"",
		    "password=\"",
		    0};

  for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
  {
    QByteArray tmp = (*it).toLocal8Bit();
    for(int j = 0; keyword[j] != 0; j++) {
      char *p;

      if( (p = (char *)strstr(tmp.data(), keyword[j])) != 0) {
	p += strlen(keyword[j]);
	while(*p && *p != '"')
	  *p++ = 'X';
      }
    }

  }

  return 0;
}

void PPPL_AnalyseLog(QStringList &list, QStringList &result) {
  QString msg;
  const char *rmsg = "Remote message: ";

  result.clear();

  // setup the analysis database
  struct {
    const char *regexp;
    const char *answer;
  } hints[] = {
    {"Receive serial link is not 8-bit clean",
     I18N_NOOP("You have launched pppd before the remote server " \
	  "was ready to establish a PPP connection.\n"
	  "Please use the terminal-based login to verify") },

    {"Serial line is looped back",
     I18N_NOOP("You have not started the PPP software on the peer system.") },

    {"AP authentication failed",
     I18N_NOOP("Check that you supplied the correct username and password.")} ,

    {"is locked by pid",
     I18N_NOOP("You should not pass 'lock' as an argument to pppd. "
	  "Check /etc/ppp/options and ~/.ppprc") },

    {"CP: timeout sending",
     I18N_NOOP("The remote system does not seem to answer to\n"
	  "configuration request. Contact your provider.") },

    {"unrecognized option",
     I18N_NOOP("You have passed an invalid option to pppd. See 'man pppd' "
          "for a complete list of valid arguments.") },

    // terminator
    {0,0}
  };

  // scan the log for keywords and try to offer any help
  for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
  {
    // look for remote message
    int pos = (*it).indexOf(rmsg);
    if (pos != -1)
    {
      QString str = (*it);
      str.remove(0, pos + strlen(rmsg));
      if(!str.isEmpty()) {
        msg = i18n("Notice that the remote system has sent the following"
                         " message:\n\"%1\"\nThis may give you a hint why the"
                         " the connection has failed.", str);
        result.append(msg);
      }
    }

    // check in the hint database
    for(uint k = 0; hints[k].regexp != 0; k++) {
      QRegExp rx(hints[k].regexp);
      QString l(*it);
      if(l.contains(rx)) {
	result.append(i18n(hints[k].answer));
	break;
      }
    }
  }

  if (result.isEmpty())
    result.append(i18n("Unable to provide help."));
}

void PPPL_ShowLog() {
  QStringList sl, result;

  PPPL_MakeLog(sl);

  bool foundConnect = false;
  bool foundLCP = gpppdata.getPPPDebug();
  QString lcp = QLatin1String("[LCP");
  QString conn = QLatin1String("Connect:");
  QStringList::ConstIterator it = sl.begin();
  for( ; it != sl.end(); it++) {
    if((*it).indexOf(lcp) >= 0) {
      foundLCP = true;
      break;
    }
    if((*it).contains(conn))
      foundConnect = true;
  }
  if(foundConnect && !foundLCP) {
    int result = KMessageBox::warningYesNo(0,
				i18n("KPPP could not prepare a PPP log. It is very likely "
				     "that pppd was started without the \"debug\" option.\n"
				     "Without this option it's difficult to find out PPP "
				     "problems, so you should turn on the debug option.\n"
				     "Shall I turn it on now?"), QString::null, i18n("Restart pppd"), i18n("Do Not Restart"));

    if(result == KMessageBox::Yes) {
      gpppdata.setPPPDebug(TRUE);
      KMessageBox::information(0,
		       i18n("The \"debug\" option has been added. You "
			    "should now try to reconnect. If that fails "
			    "again, you will get a PPP log that may help "
					"you to track down the connection problem."));
      //      return;
    }

    //    return;
  }

  PPPL_AnalyseLog(sl, result);

  QDialog *dlg = new QDialog(0, "", TRUE);

  dlg->setWindowTitle(i18n("PPP Log"));
  QVBoxLayout *tl = new QVBoxLayout(dlg);
  tl->setSpacing(10);
  tl->setMargin(10);
  QTextEdit *edit = new QTextEdit(dlg);
  edit->setReadOnly(TRUE);
  QLabel *label = new QLabel(i18n("kppp's diagnosis (just guessing):"), dlg);
  QTextEdit *diagnosis = new QTextEdit(dlg);
  diagnosis->setReadOnly(TRUE);
  KButtonBox *bbox = new KButtonBox(dlg);
  bbox->addStretch(1);
  QPushButton *write = bbox->addButton(i18n("Write to File"));
  QPushButton *close = bbox->addButton(KStdGuiItem::close());
  bbox->layout();
  edit->setMinimumSize(600, 250);
  label->setMinimumSize(600, 15);
  diagnosis->setMinimumSize(600, 60);

  tl->addWidget(edit, 1);
  tl->addWidget(label);
  tl->addWidget(diagnosis, 1);
  tl->addWidget(bbox);
  dlg->setFixedSize(dlg->sizeHint());

  for(int i = 0; i < sl.count(); i++)
    edit->append(sl.at(i));
  for(int i = 0; i < result.count(); i++)
    diagnosis->append(result.at(i));

  dlg->connect(close, SIGNAL(clicked()),
	       dlg, SLOT(reject()));
  dlg->connect(write, SIGNAL(clicked()),
	       dlg, SLOT(accept()));

  if(dlg->exec()) {
    QDir d = QDir::home();
    QString s = d.absolutePath() + "/PPP-logfile";
    int old_umask = umask(0077);

    FILE *f = fopen(QFile::encodeName(s), "w");
    for(int i = 0; i < sl.count(); i++)
      fprintf(f, "%s\n", sl.at(i).toLocal8Bit().data());
    fclose(f);
    umask(old_umask);

    QString msg = i18n("The PPP log has been saved\nas \"%1\".\n\nIf you want to send a bug report, or have\nproblems connecting to the Internet, please\nattach this file. It will help the maintainers\nto find the bug and to improve KPPP", s);
    KMessageBox::information(0, msg);
  }
  delete dlg;
}
<|endoftext|>


<commit_before>//
//  Set.h
//  Set
//
//  Created by Antonio Seprano on 10/08/14.
//  Copyright (c) 2014 Antonio Seprano. All rights reserved.
//

#include <vector>
#include <functional>
#include <utility>
#include <algorithm>

#ifndef _SET_HPP
#define _SET_HPP

template<class _T, class _Allocator = std::allocator<_T> >
class Set {
public:
	typedef _T				  value_type;
	typedef _Allocator	allocator_type;

private:
	typedef Set<value_type,allocator_type> _SET;

public:
	typedef typename std::vector<value_type,allocator_type>::iterator				iterator;
	typedef typename std::vector<value_type,allocator_type>::const_iterator	const_iterator;

	// Empty set
	Set() {};

	// Set with initializer list
	Set(std::initializer_list<value_type> l) {
		_set.insert(_set.begin(), l);
	}

	// Copy constructor
	Set(const _SET& s) {
		_set = s._set;
	}

	// Move constructor
	Set(_SET&& s) {
		_set = std::move(s._set);
	}

	// Copy assignment
	_SET& operator=(const _SET& s) noexcept {
		_set = s._set;
		return *this;
	}

	// Move assignment
	_SET& operator=(_SET&& s) noexcept {
		_set = std::move(s._set);
		return *this;
	}

	iterator begin() noexcept {
		return _set.begin();
	}

	const_iterator begin() const noexcept {
		return _set.begin();
	}

	iterator end() noexcept {
		return _set.end();
	};

	const_iterator end() const noexcept {
		return _set.end();
	}

	size_t size() const noexcept {
		return _set.size();
	}

	bool empty() const noexcept {
		return _set.empty();
	}

	void clear() noexcept {
		_set.clear();
	}

	iterator find(const value_type& value) noexcept {
		for (auto it = _set.begin(); it != _set.end(); it++) {
			if (*it == value) return it;
		}

		return _set.end();
	}

	const_iterator find(const value_type& value) const noexcept {
		return (const_iterator)find(value);
	}

	size_t count(const value_type& value) const noexcept {
		size_t ret{};

		for (const auto& v : _set) {
			if (v == value) {
				ret++;
			}
		}

		return ret;
	}

	bool operator==(const _SET& s) const noexcept {
		return this->contains(s, false) && s.contains(*this, false);
	}

	bool operator!=(const _SET& s) const noexcept {
		return !(*this == s);
	};

	/*
	bool operator<(const _SET& s) const noexcept {
		if (size() != s.size()) {
			return size() < s.size();
		}

		auto it1=begin(), it2=s.begin();

		while (it1 != end() && it2 != s.end()) {
			if (*it1 < *it2) {
				return true;
			}
			else if (*it1 > *it2) {
				return false;
			}

			it1++;
			it2++;
		};

		return false;
	}
	*/

	// Insert new value
	// unique = true => values must be unique (no duplicate values allowed)
	void insert(const value_type& value, bool unique = false) noexcept {
		if (!unique || find(value) == _set.end()) {
			_set.push_back(value);
		}
	}

	void insert(value_type&& value, bool unique = false) noexcept {
		if (!unique || find(value) == _set.end()) {
			_set.push_back(std::move(value));
		}
	}

	_SET operator+(const value_type& value) const noexcept {
		return _SET{*this}+_SET{value};
	}

	_SET operator+(value_type&& value) const noexcept {
		return _SET{*this}+_SET{std::move(value)};
	}

	_SET operator+(const _SET& s) const noexcept {
		_SET ret{*this};

		for (const auto& value : s) {
			ret.insert(value);
		}

		return ret;
	}

	_SET operator+(_SET&& s) const noexcept {
		_SET ret{*this};

		for (auto& value : s) {
			ret.insert(std::move(value));
		}

		return ret;
	}

	_SET& operator+=(const value_type& value) noexcept {
		insert(value);
		return *this;
	}

	_SET& operator+=(value_type&& value) noexcept {
		insert(std::move(value));
		return *this;
	}

	_SET& operator+=(const _SET& s) noexcept {
		for (const auto& value : s) {
			insert(value);
		}

		return *this;
	}

	_SET& operator+=(_SET&& s) noexcept {
		for (auto& value : s) {
			insert(std::move(value));
		}

		return *this;
	}

	_SET operator-(const value_type& value) const noexcept {
		_SET ret{*this};
		ret.erase(value);
		return ret;
	}

	_SET operator-(const _SET& s) const noexcept {
		_SET ret{*this};
		for (const auto& v : s) {
			ret.erase(v);
		}
		return ret;
	}

	_SET& operator-=(const value_type& value) noexcept {
		_set.erase(value);
		return *this;
	}

	_SET& operator-=(const _SET& s) noexcept {
		for (const auto& value : s) {
			_set.erase(value);
		}
		return *this;
	}

	Set<_SET> operator*(const _SET& other) noexcept {
		Set<_SET> ret;

		if (!this->empty() && !other.empty()) {
			for (const auto& v1 : _set) {
				for (const auto& v2 : other) {
					ret.insert(_SET{v1,v2});
				}
			}
		}

		return ret;
	}

	_SET intersection(const _SET& s) noexcept {
		_SET s1, s2;

		if (s.size() <= size()) {
			s1 = s;
			s2 = *this;
		}
		else {
			s1 = *this;
			s2 = s;
		}

		for (const auto &v : s1) {
			if (!s2.contains(v)) s1.erase(v);
		}

		return s1;
	}

	bool contains(const value_type& value) const noexcept {
		return contains(_SET{value});
	}

	bool contains(const _SET& s, bool strict = false) const noexcept {
		for (const auto& value : s) {
			bool found{false};

			for (const auto& v : _set) {
				if (v == value) {
					found = true;
					break;
				}
			}

			if (!found) {
				return false;
			}
		}

		return strict ? (s.size() != size()) : true;
	}

	template<class InputIterator>
	void insert(InputIterator first, InputIterator last) {
		for (auto it = first; it != last; it++) {
			_set.insert(*it);
		}
	};

	iterator erase(const_iterator position) {
		return _set.erase(position);
	}

	iterator erase(const_iterator first, const_iterator last) {
		return _set.erase(first,last);
	}

	size_t erase(const value_type& value, bool all = true) {
		size_t ret{};

		if (!all) {
			auto it = find(value);

			if (it != end()) {
				erase(it);
				ret++;
			}

			return ret;
		}

		for (auto it = _set.begin(); it != _set.end(); it++) {
			if (*it == value) {
				_set.erase(it);
				++ret;
			}
		}

		return ret;
	}

	_SET& unique() noexcept {
		for (auto i = begin(); i != end(); i++) {
			auto j = i+1;

			while (j != end()) {
				if (*i == *j) {
					_set.erase(j);
				}
				else {
					j++;
				}
			}
		}

		return *this;
	}

private:
	std::vector<value_type,allocator_type> _set;
};

#endif /* defined(_SET_HPP) */
<commit_msg>[ref] Small refactor on Set remove<commit_after>//
//  Set.h
//  Set
//
//  Created by Antonio Seprano on 10/08/14.
//  Copyright (c) 2014 Antonio Seprano. All rights reserved.
//

#include <vector>
#include <functional>
#include <utility>
#include <algorithm>

#ifndef _SET_HPP
#define _SET_HPP

template<class _T, class _Allocator = std::allocator<_T> >
class Set {
public:
	typedef _T				  value_type;
	typedef _Allocator	allocator_type;

private:
	typedef Set<value_type,allocator_type> _SET;

public:
	typedef typename std::vector<value_type,allocator_type>::iterator				iterator;
	typedef typename std::vector<value_type,allocator_type>::const_iterator	const_iterator;

	// Empty set
	Set() {};

	// Set with initializer list
	Set(std::initializer_list<value_type> l) {
		_set.insert(_set.begin(), l);
	}

	// Copy constructor
	Set(const _SET& s) {
		_set = s._set;
	}

	// Move constructor
	Set(_SET&& s) {
		_set = std::move(s._set);
	}

	// Copy assignment
	_SET& operator=(const _SET& s) noexcept {
		_set = s._set;
		return *this;
	}

	// Move assignment
	_SET& operator=(_SET&& s) noexcept {
		_set = std::move(s._set);
		return *this;
	}

	iterator begin() noexcept {
		return _set.begin();
	}

	const_iterator begin() const noexcept {
		return _set.begin();
	}

	iterator end() noexcept {
		return _set.end();
	};

	const_iterator end() const noexcept {
		return _set.end();
	}

	size_t size() const noexcept {
		return _set.size();
	}

	bool empty() const noexcept {
		return _set.empty();
	}

	void clear() noexcept {
		_set.clear();
	}

	iterator find(const value_type& value) noexcept {
		for (auto it = _set.begin(); it != _set.end(); it++) {
			if (*it == value) return it;
		}

		return _set.end();
	}

	const_iterator find(const value_type& value) const noexcept {
		return (const_iterator)find(value);
	}

	size_t count(const value_type& value) const noexcept {
		size_t ret{};

		for (const auto& v : _set) {
			if (v == value) {
				ret++;
			}
		}

		return ret;
	}

	bool operator==(const _SET& s) const noexcept {
		return this->contains(s, false) && s.contains(*this, false);
	}

	bool operator!=(const _SET& s) const noexcept {
		return !(*this == s);
	};

	/*
	bool operator<(const _SET& s) const noexcept {
		if (size() != s.size()) {
			return size() < s.size();
		}

		auto it1=begin(), it2=s.begin();

		while (it1 != end() && it2 != s.end()) {
			if (*it1 < *it2) {
				return true;
			}
			else if (*it1 > *it2) {
				return false;
			}

			it1++;
			it2++;
		};

		return false;
	}
	*/

	// Insert new value
	// unique = true => values must be unique (no duplicate values allowed)
	_SET& insert(const value_type& value, bool unique = false) noexcept {
		if (!unique || find(value) == _set.end()) {
			_set.push_back(value);
		}

		return *this;
	}

	_SET& insert(value_type&& value, bool unique = false) noexcept {
		if (!unique || find(value) == _set.end()) {
			_set.push_back(std::move(value));
		}

		return *this;
	}

	_SET operator+(const value_type& value) const noexcept {
		return _SET{*this}+_SET{value};
	}

	_SET operator+(value_type&& value) const noexcept {
		return _SET{*this}+_SET{std::move(value)};
	}

	_SET operator+(const _SET& s) const noexcept {
		_SET ret{*this};

		for (const auto& value : s) {
			ret.insert(value);
		}

		return ret;
	}

	_SET operator+(_SET&& s) const noexcept {
		_SET ret{*this};

		for (auto& value : s) {
			ret.insert(std::move(value));
		}

		return ret;
	}

	_SET& operator+=(const value_type& value) noexcept {
		insert(value);
		return *this;
	}

	_SET& operator+=(value_type&& value) noexcept {
		insert(std::move(value));
		return *this;
	}

	_SET& operator+=(const _SET& s) noexcept {
		for (const auto& value : s) {
			insert(value);
		}

		return *this;
	}

	_SET& operator+=(_SET&& s) noexcept {
		for (auto& value : s) {
			insert(std::move(value));
		}

		return *this;
	}

	_SET operator-(const value_type& value) const noexcept {
		_SET ret{*this};
		ret.erase(value);
		return ret;
	}

	_SET operator-(const _SET& s) const noexcept {
		_SET ret{*this};
		for (const auto& v : s) {
			ret.erase(v);
		}
		return ret;
	}

	_SET& operator-=(const value_type& value) noexcept {
		_set.erase(value);
		return *this;
	}

	_SET& operator-=(const _SET& s) noexcept {
		for (const auto& value : s) {
			_set.erase(value);
		}
		return *this;
	}

	Set<_SET> operator*(const _SET& other) noexcept {
		Set<_SET> ret;

		if (!this->empty() && !other.empty()) {
			for (const auto& v1 : _set) {
				for (const auto& v2 : other) {
					ret.insert(_SET{v1,v2});
				}
			}
		}

		return ret;
	}

	_SET intersection(const _SET& s) noexcept {
		_SET s1, s2;

		if (s.size() <= size()) {
			s1 = s;
			s2 = *this;
		}
		else {
			s1 = *this;
			s2 = s;
		}

		for (const auto &v : s1) {
			if (!s2.contains(v)) s1.erase(v);
		}

		return s1;
	}

	bool contains(const value_type& value) const noexcept {
		return contains(_SET{value});
	}

	bool contains(const _SET& s, bool strict = false) const noexcept {
		for (const auto& value : s) {
			bool found{false};

			for (const auto& v : _set) {
				if (v == value) {
					found = true;
					break;
				}
			}

			if (!found) {
				return false;
			}
		}

		return strict ? (s.size() != size()) : true;
	}

	template<class InputIterator>
	void insert(InputIterator first, InputIterator last) {
		for (auto it = first; it != last; it++) {
			_set.insert(*it);
		}
	};

	iterator erase(const_iterator position) {
		return _set.erase(position);
	}

	iterator erase(const_iterator first, const_iterator last) {
		return _set.erase(first,last);
	}

	size_t erase(const value_type& value, bool all = false) {
		size_t ret{};

		if (!all) {
			auto it = find(value);

			if (it != end()) {
				erase(it);
				ret++;
			}

			return ret;
		}

		for (auto it = _set.begin(); it != _set.end(); it++) {
			if (*it == value) {
				_set.erase(it);
				++ret;
			}
		}

		return ret;
	}

	_SET& unique() noexcept {
		for (auto i = begin(); i != end(); i++) {
			auto j = i+1;

			while (j != end()) {
				if (*i == *j) {
					_set.erase(j);
				}
				else {
					j++;
				}
			}
		}

		return *this;
	}

private:
	std::vector<value_type,allocator_type> _set;
};

#endif /* defined(_SET_HPP) */
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#ifdef _WIN32
// windows part
#include "libtorrent/utf8.hpp"

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef _MODE_T_
typedef int mode_t;
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

#else
// unix part
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#include <boost/static_assert.hpp>
// make sure the _FILE_OFFSET_BITS define worked
// on this platform
BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8);

#endif

#include <boost/filesystem/operations.hpp>
#include "libtorrent/file.hpp"
#include <sstream>

#ifndef O_BINARY
#define O_BINARY 0
#endif

#ifndef O_RANDOM
#define O_RANDOM 0
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

#include "libtorrent/assert.hpp"

namespace
{
	enum { mode_in = 1, mode_out = 2 };

	mode_t map_open_mode(int m)
	{
		if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM;
		TORRENT_ASSERT(false);
		return 0;
	}

#ifdef WIN32
	std::string utf8_native(std::string const& s)
	{
		try
		{
			std::wstring ws;
			libtorrent::utf8_wchar(s, ws);
			std::size_t size = wcstombs(0, ws.c_str(), 0);
			if (size == std::size_t(-1)) return s;
			std::string ret;
			ret.resize(size);
			size = wcstombs(&ret[0], ws.c_str(), size + 1);
			if (size == wchar_t(-1)) return s;
			ret.resize(size);
			return ret;
		}
		catch(std::exception)
		{
			return s;
		}
	}
#else
	std::string utf8_native(std::string const& s)
	{
		return s;
	}
#endif

}

namespace libtorrent
{

	namespace fs = boost::filesystem;

	const file::open_mode file::in(mode_in);
	const file::open_mode file::out(mode_out);

	const file::seek_mode file::begin(1);
	const file::seek_mode file::end(2);

	struct file::impl
	{
		impl()
			: m_fd(-1)
			, m_open_mode(0)
		{}

		impl(fs::path const& path, int mode)
			: m_fd(-1)
			, m_open_mode(0)
		{
			open(path, mode);
		}

		~impl()
		{
			close();
		}

		void open(fs::path const& path, int mode)
		{
			TORRENT_ASSERT(path.is_complete());
			close();
#if defined(_WIN32) && defined(UNICODE)
			std::wstring wpath(safe_convert(path.native_file_string()));
			m_fd = ::_wopen(
				wpath.c_str()
				, map_open_mode(mode)
				, S_IREAD | S_IWRITE);
#else
#ifdef _WIN32
			m_fd = ::_open(
#else
			m_fd = ::open(
#endif
				utf8_native(path.native_file_string()).c_str()
				, map_open_mode(mode)
#ifdef _WIN32
				, S_IREAD | S_IWRITE);
#else
				, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
#endif
#endif
			if (m_fd == -1)
			{
				std::stringstream msg;
				msg << "open failed: '" << path.native_file_string() << "'. "
					<< strerror(errno);
				throw file_error(msg.str());
			}
			m_open_mode = mode;
		}

		void close()
		{
			if (m_fd == -1) return;

#ifdef _WIN32
			::_close(m_fd);
#else
			::close(m_fd);
#endif
			m_fd = -1;
			m_open_mode = 0;
		}

		size_type read(char* buf, size_type num_bytes)
		{
			TORRENT_ASSERT(m_open_mode & mode_in);
			TORRENT_ASSERT(m_fd != -1);

#ifdef _WIN32
			size_type ret = ::_read(m_fd, buf, num_bytes);
#else
			size_type ret = ::read(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "read failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type write(const char* buf, size_type num_bytes)
		{
			TORRENT_ASSERT(m_open_mode & mode_out);
			TORRENT_ASSERT(m_fd != -1);

			// TODO: Test this a bit more, what happens with random failures in
			// the files?
//			if ((rand() % 100) > 80)
//				throw file_error("debug");

#ifdef _WIN32
			size_type ret = ::_write(m_fd, buf, num_bytes);
#else
			size_type ret = ::write(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "write failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		void set_size(size_type s)
		{
#ifdef _WIN32
#error file.cpp is for posix systems only. use file_win.cpp on windows
#else
			if (ftruncate(m_fd, s) < 0)
			{
				std::stringstream msg;
				msg << "ftruncate failed: '" << strerror(errno);
				throw file_error(msg.str());
			}
#endif
		}

		size_type seek(size_type offset, int m = 1)
		{
			TORRENT_ASSERT(m_open_mode);
			TORRENT_ASSERT(m_fd != -1);

			int seekdir = (m == 1)?SEEK_SET:SEEK_END;
#ifdef _WIN32
			size_type ret = _lseeki64(m_fd, offset, seekdir);
#else
			size_type ret = lseek(m_fd, offset, seekdir);
#endif

			// For some strange reason this fails
			// on win32. Use windows specific file
			// wrapper instead.
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "seek failed: '" << strerror(errno)
					<< "' fd: " << m_fd
					<< " offset: " << offset
					<< " seekdir: " << seekdir;
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type tell()
		{
			TORRENT_ASSERT(m_open_mode);
			TORRENT_ASSERT(m_fd != -1);

#ifdef _WIN32
			return _telli64(m_fd);
#else
			return lseek(m_fd, 0, SEEK_CUR);
#endif
		}

		int m_fd;
		int m_open_mode;
	};

	// pimpl forwardings

	file::file() : m_impl(new impl()) {}

	file::file(fs::path const& p, file::open_mode m)
		: m_impl(new impl(p, m.m_mask))
	{}

	file::~file() {}

	void file::open(fs::path const& p, file::open_mode m)
	{
		m_impl->open(p, m.m_mask);
	}

	void file::close()
	{
		m_impl->close();
	}

	size_type file::write(const char* buf, size_type num_bytes)
	{
		return m_impl->write(buf, num_bytes);
	}

	size_type file::read(char* buf, size_type num_bytes)
	{
		return m_impl->read(buf, num_bytes);
	}

	void file::set_size(size_type s)
	{
		m_impl->set_size(s);
	}

	size_type file::seek(size_type pos, file::seek_mode m)
	{
		return m_impl->seek(pos, m.m_val);
	}

	size_type file::tell()
	{
		return m_impl->tell();
	}

}
<commit_msg>include fixes in file.cpp<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#ifdef _WIN32
// windows part
#include "libtorrent/utf8.hpp"

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef _MODE_T_
typedef int mode_t;
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

#else
// unix part
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#include <boost/static_assert.hpp>
// make sure the _FILE_OFFSET_BITS define worked
// on this platform
BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8);

#endif

#include <boost/filesystem/operations.hpp>
#include "libtorrent/file.hpp"
#include <sstream>
#include <cstring>

#ifndef O_BINARY
#define O_BINARY 0
#endif

#ifndef O_RANDOM
#define O_RANDOM 0
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

#include "libtorrent/assert.hpp"

namespace
{
	enum { mode_in = 1, mode_out = 2 };

	mode_t map_open_mode(int m)
	{
		if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM;
		TORRENT_ASSERT(false);
		return 0;
	}

#ifdef WIN32
	std::string utf8_native(std::string const& s)
	{
		try
		{
			std::wstring ws;
			libtorrent::utf8_wchar(s, ws);
			std::size_t size = wcstombs(0, ws.c_str(), 0);
			if (size == std::size_t(-1)) return s;
			std::string ret;
			ret.resize(size);
			size = wcstombs(&ret[0], ws.c_str(), size + 1);
			if (size == wchar_t(-1)) return s;
			ret.resize(size);
			return ret;
		}
		catch(std::exception)
		{
			return s;
		}
	}
#else
	std::string utf8_native(std::string const& s)
	{
		return s;
	}
#endif

}

namespace libtorrent
{

	namespace fs = boost::filesystem;

	const file::open_mode file::in(mode_in);
	const file::open_mode file::out(mode_out);

	const file::seek_mode file::begin(1);
	const file::seek_mode file::end(2);

	struct file::impl
	{
		impl()
			: m_fd(-1)
			, m_open_mode(0)
		{}

		impl(fs::path const& path, int mode)
			: m_fd(-1)
			, m_open_mode(0)
		{
			open(path, mode);
		}

		~impl()
		{
			close();
		}

		void open(fs::path const& path, int mode)
		{
			TORRENT_ASSERT(path.is_complete());
			close();
#if defined(_WIN32) && defined(UNICODE)
			std::wstring wpath(safe_convert(path.native_file_string()));
			m_fd = ::_wopen(
				wpath.c_str()
				, map_open_mode(mode)
				, S_IREAD | S_IWRITE);
#else
#ifdef _WIN32
			m_fd = ::_open(
#else
			m_fd = ::open(
#endif
				utf8_native(path.native_file_string()).c_str()
				, map_open_mode(mode)
#ifdef _WIN32
				, S_IREAD | S_IWRITE);
#else
				, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
#endif
#endif
			if (m_fd == -1)
			{
				std::stringstream msg;
				msg << "open failed: '" << path.native_file_string() << "'. "
					<< std::strerror(errno);
				throw file_error(msg.str());
			}
			m_open_mode = mode;
		}

		void close()
		{
			if (m_fd == -1) return;

#ifdef _WIN32
			::_close(m_fd);
#else
			::close(m_fd);
#endif
			m_fd = -1;
			m_open_mode = 0;
		}

		size_type read(char* buf, size_type num_bytes)
		{
			TORRENT_ASSERT(m_open_mode & mode_in);
			TORRENT_ASSERT(m_fd != -1);

#ifdef _WIN32
			size_type ret = ::_read(m_fd, buf, num_bytes);
#else
			size_type ret = ::read(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "read failed: " << std::strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type write(const char* buf, size_type num_bytes)
		{
			TORRENT_ASSERT(m_open_mode & mode_out);
			TORRENT_ASSERT(m_fd != -1);

			// TODO: Test this a bit more, what happens with random failures in
			// the files?
//			if ((rand() % 100) > 80)
//				throw file_error("debug");

#ifdef _WIN32
			size_type ret = ::_write(m_fd, buf, num_bytes);
#else
			size_type ret = ::write(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "write failed: " << std::strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		void set_size(size_type s)
		{
#ifdef _WIN32
#error file.cpp is for posix systems only. use file_win.cpp on windows
#else
			if (ftruncate(m_fd, s) < 0)
			{
				std::stringstream msg;
				msg << "ftruncate failed: '" << std::strerror(errno);
				throw file_error(msg.str());
			}
#endif
		}

		size_type seek(size_type offset, int m = 1)
		{
			TORRENT_ASSERT(m_open_mode);
			TORRENT_ASSERT(m_fd != -1);

			int seekdir = (m == 1)?SEEK_SET:SEEK_END;
#ifdef _WIN32
			size_type ret = _lseeki64(m_fd, offset, seekdir);
#else
			size_type ret = lseek(m_fd, offset, seekdir);
#endif

			// For some strange reason this fails
			// on win32. Use windows specific file
			// wrapper instead.
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "seek failed: '" << std::strerror(errno)
					<< "' fd: " << m_fd
					<< " offset: " << offset
					<< " seekdir: " << seekdir;
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type tell()
		{
			TORRENT_ASSERT(m_open_mode);
			TORRENT_ASSERT(m_fd != -1);

#ifdef _WIN32
			return _telli64(m_fd);
#else
			return lseek(m_fd, 0, SEEK_CUR);
#endif
		}

		int m_fd;
		int m_open_mode;
	};

	// pimpl forwardings

	file::file() : m_impl(new impl()) {}

	file::file(fs::path const& p, file::open_mode m)
		: m_impl(new impl(p, m.m_mask))
	{}

	file::~file() {}

	void file::open(fs::path const& p, file::open_mode m)
	{
		m_impl->open(p, m.m_mask);
	}

	void file::close()
	{
		m_impl->close();
	}

	size_type file::write(const char* buf, size_type num_bytes)
	{
		return m_impl->write(buf, num_bytes);
	}

	size_type file::read(char* buf, size_type num_bytes)
	{
		return m_impl->read(buf, num_bytes);
	}

	void file::set_size(size_type s)
	{
		m_impl->set_size(s);
	}

	size_type file::seek(size_type pos, file::seek_mode m)
	{
		return m_impl->seek(pos, m.m_val);
	}

	size_type file::tell()
	{
		return m_impl->tell();
	}

}
<|endoftext|>


<commit_before>#include <nan.h>

#include <windows.h>

using namespace v8;
using namespace node;

NAN_METHOD(GetFileStats) {
  NanScope();

  Local<Object> returnObj = NanNew<Object>();

  String::Utf8Value filePathV8(args[0]->ToString());
  const char* filePath = std::string(*filePathV8).c_str();

  int fileAttributes = GetFileAttributes(filePath);
  int lastError = GetLastError();

  returnObj->Set(NanNew<String>("errorCode"), NanNew<Number>(lastError));

  if (lastError == 0) {
    bool isNormal = false, isHidden = false, isReadOnly = false, isSystem = false, isDirectory = false, isArchive = false;

    if ((fileAttributes & FILE_ATTRIBUTE_NORMAL) != 0){
      isNormal = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0){
      isArchive = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0){
      isHidden = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_READONLY) != 0){
      isReadOnly = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0){
      isSystem = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0){
      isDirectory = true;
    }

    returnObj->Set(NanNew<String>("isNormal"), NanNew<Boolean>(isNormal));
    returnObj->Set(NanNew<String>("isArchive"), NanNew<Boolean>(isArchive));
    returnObj->Set(NanNew<String>("isHidden"), NanNew<Boolean>(isHidden));
    returnObj->Set(NanNew<String>("isSystem"), NanNew<Boolean>(isSystem));
    returnObj->Set(NanNew<String>("isReadOnly"), NanNew<Boolean>(isReadOnly));
    returnObj->Set(NanNew<String>("isDirectory"), NanNew<Boolean>(isDirectory));
  }

  NanReturnValue(returnObj);
}

void init(Handle<Object> exports) {
  exports->Set(NanNew<String>("getFileStats"),
    NanNew<FunctionTemplate>(GetFileStats)->GetFunction());
}

NODE_MODULE(file, init)
<commit_msg>fixed using v8<commit_after>#include <nan.h>

#include <windows.h>

using v8::FunctionTemplate;
using v8::Handle;
using v8::Object;
using v8::String;
using v8::Boolean;
using v8::Number;
using v8::Local;

NAN_METHOD(GetFileStats) {
  NanScope();

  Local<Object> returnObj = NanNew<Object>();

  String::Utf8Value filePathV8(args[0]->ToString());
  const char* filePath = std::string(*filePathV8).c_str();

  int fileAttributes = GetFileAttributes(filePath);
  int lastError = GetLastError();

  returnObj->Set(NanNew<String>("errorCode"), NanNew<Number>(lastError));

  if (lastError == 0) {
    bool isNormal = false, isHidden = false, isReadOnly = false, isSystem = false, isDirectory = false, isArchive = false;

    if ((fileAttributes & FILE_ATTRIBUTE_NORMAL) != 0){
      isNormal = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0){
      isArchive = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0){
      isHidden = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_READONLY) != 0){
      isReadOnly = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0){
      isSystem = true;
    }

    if ((fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0){
      isDirectory = true;
    }

    returnObj->Set(NanNew<String>("isNormal"), NanNew<Boolean>(isNormal));
    returnObj->Set(NanNew<String>("isArchive"), NanNew<Boolean>(isArchive));
    returnObj->Set(NanNew<String>("isHidden"), NanNew<Boolean>(isHidden));
    returnObj->Set(NanNew<String>("isSystem"), NanNew<Boolean>(isSystem));
    returnObj->Set(NanNew<String>("isReadOnly"), NanNew<Boolean>(isReadOnly));
    returnObj->Set(NanNew<String>("isDirectory"), NanNew<Boolean>(isDirectory));
  }

  NanReturnValue(returnObj);
}

void init(Handle<Object> exports) {
  exports->Set(NanNew<String>("getFileStats"),
    NanNew<FunctionTemplate>(GetFileStats)->GetFunction());
}

NODE_MODULE(file, init)
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"
#include "libtorrent/assert.hpp"

#ifdef _WIN32
// windows part
#include "libtorrent/utf8.hpp"

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef _MODE_T_
typedef int mode_t;
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

#else
// unix part
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#include <boost/static_assert.hpp>
// make sure the _FILE_OFFSET_BITS define worked
// on this platform
BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8);

#endif

#include <boost/filesystem/operations.hpp>
#include "libtorrent/file.hpp"
#include <sstream>

#ifndef O_BINARY
#define O_BINARY 0
#endif

#ifndef O_RANDOM
#define O_RANDOM 0
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

namespace
{
	enum { mode_in = 1, mode_out = 2 };

	mode_t map_open_mode(int m)
	{
		if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM;
		TORRENT_ASSERT(false);
		return 0;
	}

#ifdef WIN32
	std::string utf8_native(std::string const& s)
	{
		try
		{
			std::wstring ws;
			libtorrent::utf8_wchar(s, ws);
			std::size_t size = wcstombs(0, ws.c_str(), 0);
			if (size == std::size_t(-1)) return s;
			std::string ret;
			ret.resize(size);
			size = wcstombs(&ret[0], ws.c_str(), size + 1);
			if (size == wchar_t(-1)) return s;
			ret.resize(size);
			return ret;
		}
		catch(std::exception)
		{
			return s;
		}
	}
#else
	std::string utf8_native(std::string const& s)
	{
		return s;
	}
#endif

}

namespace libtorrent
{

	namespace fs = boost::filesystem;

	const file::open_mode file::in(mode_in);
	const file::open_mode file::out(mode_out);

	const file::seek_mode file::begin(1);
	const file::seek_mode file::end(2);

	struct file::impl
	{
		impl()
			: m_fd(-1)
			, m_open_mode(0)
		{}

		impl(fs::path const& path, int mode)
			: m_fd(-1)
			, m_open_mode(0)
		{
			open(path, mode);
		}

		~impl()
		{
			close();
		}

		void open(fs::path const& path, int mode)
		{
			TORRENT_ASSERT(path.is_complete());
			close();
#if defined(_WIN32) && defined(UNICODE)
			std::wstring wpath(safe_convert(path.native_file_string()));
			m_fd = ::_wopen(
				wpath.c_str()
				, map_open_mode(mode)
				, S_IREAD | S_IWRITE);
#else
#ifdef _WIN32
			m_fd = ::_open(
#else
			m_fd = ::open(
#endif
				utf8_native(path.native_file_string()).c_str()
				, map_open_mode(mode)
#ifdef _WIN32
				, S_IREAD | S_IWRITE);
#else
				, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
#endif
#endif
			if (m_fd == -1)
			{
				std::stringstream msg;
				msg << "open failed: '" << path.native_file_string() << "'. "
					<< strerror(errno);
				throw file_error(msg.str());
			}
			m_open_mode = mode;
		}

		void close()
		{
			if (m_fd == -1) return;

#ifdef _WIN32
			::_close(m_fd);
#else
			::close(m_fd);
#endif
			m_fd = -1;
			m_open_mode = 0;
		}

		size_type read(char* buf, size_type num_bytes)
		{
			TORRENT_ASSERT(m_open_mode & mode_in);
			TORRENT_ASSERT(m_fd != -1);

#ifdef _WIN32
			size_type ret = ::_read(m_fd, buf, num_bytes);
#else
			size_type ret = ::read(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "read failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type write(const char* buf, size_type num_bytes)
		{
			TORRENT_ASSERT(m_open_mode & mode_out);
			TORRENT_ASSERT(m_fd != -1);

			// TODO: Test this a bit more, what happens with random failures in
			// the files?
//			if ((rand() % 100) > 80)
//				throw file_error("debug");

#ifdef _WIN32
			size_type ret = ::_write(m_fd, buf, num_bytes);
#else
			size_type ret = ::write(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "write failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		void set_size(size_type s)
		{
#ifdef _WIN32
#error file.cpp is for posix systems only. use file_win.cpp on windows
#else
			if (ftruncate(m_fd, s) < 0)
			{
				std::stringstream msg;
				msg << "ftruncate failed: '" << strerror(errno);
				throw file_error(msg.str());
			}
#endif
		}

		size_type seek(size_type offset, int m = 1)
		{
			TORRENT_ASSERT(m_open_mode);
			TORRENT_ASSERT(m_fd != -1);

			int seekdir = (m == 1)?SEEK_SET:SEEK_END;
#ifdef _WIN32
			size_type ret = _lseeki64(m_fd, offset, seekdir);
#else
			size_type ret = lseek(m_fd, offset, seekdir);
#endif

			// For some strange reason this fails
			// on win32. Use windows specific file
			// wrapper instead.
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "seek failed: '" << strerror(errno)
					<< "' fd: " << m_fd
					<< " offset: " << offset
					<< " seekdir: " << seekdir;
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type tell()
		{
			TORRENT_ASSERT(m_open_mode);
			TORRENT_ASSERT(m_fd != -1);

#ifdef _WIN32
			return _telli64(m_fd);
#else
			return lseek(m_fd, 0, SEEK_CUR);
#endif
		}

		int m_fd;
		int m_open_mode;
	};

	// pimpl forwardings

	file::file() : m_impl(new impl()) {}

	file::file(fs::path const& p, file::open_mode m)
		: m_impl(new impl(p, m.m_mask))
	{}

	file::~file() {}

	void file::open(fs::path const& p, file::open_mode m)
	{
		m_impl->open(p, m.m_mask);
	}

	void file::close()
	{
		m_impl->close();
	}

	size_type file::write(const char* buf, size_type num_bytes)
	{
		return m_impl->write(buf, num_bytes);
	}

	size_type file::read(char* buf, size_type num_bytes)
	{
		return m_impl->read(buf, num_bytes);
	}

	void file::set_size(size_type s)
	{
		m_impl->set_size(s);
	}

	size_type file::seek(size_type pos, file::seek_mode m)
	{
		return m_impl->seek(pos, m.m_val);
	}

	size_type file::tell()
	{
		return m_impl->tell();
	}

}
<commit_msg>fixed static assert being hit on linux systems<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#ifdef _WIN32
// windows part
#include "libtorrent/utf8.hpp"

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef _MODE_T_
typedef int mode_t;
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

#else
// unix part
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#include <boost/static_assert.hpp>
// make sure the _FILE_OFFSET_BITS define worked
// on this platform
BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8);

#endif

#include <boost/filesystem/operations.hpp>
#include "libtorrent/file.hpp"
#include <sstream>

#ifndef O_BINARY
#define O_BINARY 0
#endif

#ifndef O_RANDOM
#define O_RANDOM 0
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

#include "libtorrent/assert.hpp"

namespace
{
	enum { mode_in = 1, mode_out = 2 };

	mode_t map_open_mode(int m)
	{
		if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM;
		TORRENT_ASSERT(false);
		return 0;
	}

#ifdef WIN32
	std::string utf8_native(std::string const& s)
	{
		try
		{
			std::wstring ws;
			libtorrent::utf8_wchar(s, ws);
			std::size_t size = wcstombs(0, ws.c_str(), 0);
			if (size == std::size_t(-1)) return s;
			std::string ret;
			ret.resize(size);
			size = wcstombs(&ret[0], ws.c_str(), size + 1);
			if (size == wchar_t(-1)) return s;
			ret.resize(size);
			return ret;
		}
		catch(std::exception)
		{
			return s;
		}
	}
#else
	std::string utf8_native(std::string const& s)
	{
		return s;
	}
#endif

}

namespace libtorrent
{

	namespace fs = boost::filesystem;

	const file::open_mode file::in(mode_in);
	const file::open_mode file::out(mode_out);

	const file::seek_mode file::begin(1);
	const file::seek_mode file::end(2);

	struct file::impl
	{
		impl()
			: m_fd(-1)
			, m_open_mode(0)
		{}

		impl(fs::path const& path, int mode)
			: m_fd(-1)
			, m_open_mode(0)
		{
			open(path, mode);
		}

		~impl()
		{
			close();
		}

		void open(fs::path const& path, int mode)
		{
			TORRENT_ASSERT(path.is_complete());
			close();
#if defined(_WIN32) && defined(UNICODE)
			std::wstring wpath(safe_convert(path.native_file_string()));
			m_fd = ::_wopen(
				wpath.c_str()
				, map_open_mode(mode)
				, S_IREAD | S_IWRITE);
#else
#ifdef _WIN32
			m_fd = ::_open(
#else
			m_fd = ::open(
#endif
				utf8_native(path.native_file_string()).c_str()
				, map_open_mode(mode)
#ifdef _WIN32
				, S_IREAD | S_IWRITE);
#else
				, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
#endif
#endif
			if (m_fd == -1)
			{
				std::stringstream msg;
				msg << "open failed: '" << path.native_file_string() << "'. "
					<< strerror(errno);
				throw file_error(msg.str());
			}
			m_open_mode = mode;
		}

		void close()
		{
			if (m_fd == -1) return;

#ifdef _WIN32
			::_close(m_fd);
#else
			::close(m_fd);
#endif
			m_fd = -1;
			m_open_mode = 0;
		}

		size_type read(char* buf, size_type num_bytes)
		{
			TORRENT_ASSERT(m_open_mode & mode_in);
			TORRENT_ASSERT(m_fd != -1);

#ifdef _WIN32
			size_type ret = ::_read(m_fd, buf, num_bytes);
#else
			size_type ret = ::read(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "read failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type write(const char* buf, size_type num_bytes)
		{
			TORRENT_ASSERT(m_open_mode & mode_out);
			TORRENT_ASSERT(m_fd != -1);

			// TODO: Test this a bit more, what happens with random failures in
			// the files?
//			if ((rand() % 100) > 80)
//				throw file_error("debug");

#ifdef _WIN32
			size_type ret = ::_write(m_fd, buf, num_bytes);
#else
			size_type ret = ::write(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "write failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		void set_size(size_type s)
		{
#ifdef _WIN32
#error file.cpp is for posix systems only. use file_win.cpp on windows
#else
			if (ftruncate(m_fd, s) < 0)
			{
				std::stringstream msg;
				msg << "ftruncate failed: '" << strerror(errno);
				throw file_error(msg.str());
			}
#endif
		}

		size_type seek(size_type offset, int m = 1)
		{
			TORRENT_ASSERT(m_open_mode);
			TORRENT_ASSERT(m_fd != -1);

			int seekdir = (m == 1)?SEEK_SET:SEEK_END;
#ifdef _WIN32
			size_type ret = _lseeki64(m_fd, offset, seekdir);
#else
			size_type ret = lseek(m_fd, offset, seekdir);
#endif

			// For some strange reason this fails
			// on win32. Use windows specific file
			// wrapper instead.
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "seek failed: '" << strerror(errno)
					<< "' fd: " << m_fd
					<< " offset: " << offset
					<< " seekdir: " << seekdir;
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type tell()
		{
			TORRENT_ASSERT(m_open_mode);
			TORRENT_ASSERT(m_fd != -1);

#ifdef _WIN32
			return _telli64(m_fd);
#else
			return lseek(m_fd, 0, SEEK_CUR);
#endif
		}

		int m_fd;
		int m_open_mode;
	};

	// pimpl forwardings

	file::file() : m_impl(new impl()) {}

	file::file(fs::path const& p, file::open_mode m)
		: m_impl(new impl(p, m.m_mask))
	{}

	file::~file() {}

	void file::open(fs::path const& p, file::open_mode m)
	{
		m_impl->open(p, m.m_mask);
	}

	void file::close()
	{
		m_impl->close();
	}

	size_type file::write(const char* buf, size_type num_bytes)
	{
		return m_impl->write(buf, num_bytes);
	}

	size_type file::read(char* buf, size_type num_bytes)
	{
		return m_impl->read(buf, num_bytes);
	}

	void file::set_size(size_type s)
	{
		m_impl->set_size(s);
	}

	size_type file::seek(size_type pos, file::seek_mode m)
	{
		return m_impl->seek(pos, m.m_val);
	}

	size_type file::tell()
	{
		return m_impl->tell();
	}

}
<|endoftext|>


<commit_before>/******************************************************************
*
* Round for C++
*
* Copyright (C) Satoshi Konno 2015
*
* This is licensed under BSD-style license, see file COPYING.
*
******************************************************************/

#include <boost/test/unit_test.hpp>
#include <roundc/round.h>

BOOST_AUTO_TEST_CASE(MutexTest) {
  RoundMutex *mutex;

  mutex = round_mutex_new();
  BOOST_CHECK(mutex);
  BOOST_CHECK(round_mutex_lock(mutex));
  BOOST_CHECK(round_mutex_unlock(mutex));
  BOOST_CHECK(round_mutex_delete(mutex));
}
<commit_msg>* Added tests for mutex functions.<commit_after>/******************************************************************
*
* Round for C++
*
* Copyright (C) Satoshi Konno 2015
*
* This is licensed under BSD-style license, see file COPYING.
*
******************************************************************/

#include <boost/test/unit_test.hpp>
#include <roundc/round.h>

BOOST_AUTO_TEST_CASE(MutexTest)
{
  RoundMutex *mutex;

  mutex = round_mutex_new();
  BOOST_CHECK(mutex);
  BOOST_CHECK(round_mutex_lock(mutex));
  BOOST_CHECK(round_mutex_unlock(mutex));
  BOOST_CHECK(round_mutex_delete(mutex));
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by FThauer FHammer   *
 *   f.thauer@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "game.h"
#include "gamedata.h"

#include <enginefactory.h>
#include <guiinterface.h>

#include <iostream>
#include <sstream>

using namespace std;

Game::Game(GuiInterface* gui, boost::shared_ptr<EngineFactory> factory,
		   const PlayerDataList &playerDataList, const GameData &gameData,
		   const StartData &startData, int gameId)
: myFactory(factory), myGui(gui), actualHand(0), actualBoard(0),
  startQuantityPlayers(startData.numberOfPlayers),
  startCash(gameData.startMoney), startSmallBlind(gameData.smallBlind),
  startHandsBeforeRaiseSmallBlind(gameData.handsBeforeRaise),
  myGameID(gameId), actualSmallBlind(gameData.smallBlind), actualHandID(0), dealerPosition(0)
{
// 	cout << "Create Game Object" << "\n";
	int i;

	actualHandID = 0;

// 	for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
// 		playerArray[i] = 0;
// 	}

	// Dealer Position bestimmen
	PlayerDataList::const_iterator player_i = playerDataList.begin();
	PlayerDataList::const_iterator player_end = playerDataList.end();

	bool dealerFound = false;
	i = 0;
	while (player_i != player_end)
	{
		if ((*player_i)->GetUniqueId() == startData.startDealerPlayerId)
		{
			dealerPosition = i;
			dealerFound = true;
			break;
		}
		++player_i;
		++i;
	}
	assert(dealerFound);

	// Board erstellen
	actualBoard = myFactory->createBoard();

	// Player erstellen
	activePlayerList = PlayerList(new std::list<boost::shared_ptr<PlayerInterface> >);
	runningPlayerList = PlayerList(new std::list<boost::shared_ptr<PlayerInterface> >);

	player_i = playerDataList.begin();
	player_end = playerDataList.end();
	for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {

		string myName;
		string myAvatarFile;
		unsigned uniqueId = 0;
		PlayerType type = PLAYER_TYPE_COMPUTER;
		boost::shared_ptr<SessionData> myNetSession;

		if (player_i != player_end)
		{
			uniqueId = (*player_i)->GetUniqueId();
			type = (*player_i)->GetType();
			myName = (*player_i)->GetName();
			myAvatarFile = (*player_i)->GetAvatarFile();
			myNetSession = (*player_i)->GetNetSessionData();
			// TODO: set player type
			++player_i;
		}

		// create Player Objects
		boost::shared_ptr<PlayerInterface> tmpPlayer = myFactory->createPlayer(actualBoard, i, uniqueId, type, myName, myAvatarFile, startCash, startQuantityPlayers > i, 0);

		// fill player lists
		playerArray.push_back(tmpPlayer);
		if(startQuantityPlayers > i) {
			activePlayerList->push_back(tmpPlayer);
		}

		(*runningPlayerList) = (*activePlayerList);

		playerArray[i]->setNetSessionData(myNetSession);
	}
	actualBoard->setPlayerLists(playerArray, activePlayerList, runningPlayerList);
}

Game::~Game()
{
// 	cout << "Delete Game Object" << "\n";

	delete actualBoard;
	actualBoard = 0;
	delete actualHand;
	actualHand = 0;

}

HandInterface *Game::getCurrentHand()
{
	return actualHand;
}

const HandInterface *Game::getCurrentHand() const
{
	return actualHand;
}

void Game::initHand()
{

	int i;

	// eventuell vorhandene Hand löschen
	if(actualHand) {
		delete actualHand;
		actualHand = 0;
	}

	actualHandID++;

	// smallBlind alle x Runden erhöhen
	if((actualHandID-1)%startHandsBeforeRaiseSmallBlind == 0 && actualHandID > 1) { actualSmallBlind *= 2; }

	// Spieler mit leerem Cash auf inactive setzen
	PlayerListIterator it;

	for(it = activePlayerList->begin(); it != activePlayerList->end(); it++) {
		if((*it)->getMyCash() == 0) {
			(*it)->setMyActiveStatus(0);
			it = activePlayerList->erase(it);
		}
	}

	//Spieler Action auf 0 setzen
	for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
		playerArray[i]->setMyAction(0);
	}

	runningPlayerList->clear();
	(*runningPlayerList) = (*activePlayerList);

	// Hand erstellen
	actualHand = myFactory->createHand(myFactory, myGui, actualBoard, playerArray, activePlayerList, runningPlayerList, actualHandID, startQuantityPlayers, dealerPosition, actualSmallBlind, startCash);

	// Dealer-Button weiterschieben --> Achtung inactive
	for(i=0; (i<MAX_NUMBER_OF_PLAYERS && !(playerArray[dealerPosition]->getMyActiveStatus())) || i==0; i++) {

		dealerPosition = (dealerPosition+1)%(MAX_NUMBER_OF_PLAYERS);
	}

	// Abfrage Cash==0 -> player inactive -> actualQuantityPlayer--
}

void Game::startHand()
{
	assert(actualHand);

	//GUI bereinigen
	myGui->nextRoundCleanGui();

	myGui->logNewGameHandMsg(myGameID, actualHandID);

	actualHand->start();
}

boost::shared_ptr<PlayerInterface> Game::getPlayerByUniqueId(unsigned id)
{
	boost::shared_ptr<PlayerInterface> tmpPlayer;
	for (int i = 0; i < startQuantityPlayers; i++)
	{
		if (playerArray[i]->getMyUniqueID() == id)
		{
			tmpPlayer = playerArray[i];
			break;
		}
	}
	return tmpPlayer;
}

boost::shared_ptr<PlayerInterface> Game::getCurrentPlayer()
{
	int curPlayerNum = getCurrentHand()->getCurrentBeRo()->getPlayersTurn();
	assert(curPlayerNum < getStartQuantityPlayers());
	return getPlayerArray()[curPlayerNum];
}

<commit_msg>adds activePlayerList and runningPlayerList (VII) - BUGGY !!! please checkout rev856 for game play<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by FThauer FHammer   *
 *   f.thauer@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "game.h"
#include "gamedata.h"

#include <enginefactory.h>
#include <guiinterface.h>

#include <iostream>
#include <sstream>

using namespace std;

Game::Game(GuiInterface* gui, boost::shared_ptr<EngineFactory> factory,
		   const PlayerDataList &playerDataList, const GameData &gameData,
		   const StartData &startData, int gameId)
: myFactory(factory), myGui(gui), actualHand(0), actualBoard(0),
  startQuantityPlayers(startData.numberOfPlayers),
  startCash(gameData.startMoney), startSmallBlind(gameData.smallBlind),
  startHandsBeforeRaiseSmallBlind(gameData.handsBeforeRaise),
  myGameID(gameId), actualSmallBlind(gameData.smallBlind), actualHandID(0), dealerPosition(0)
{
// 	cout << "Create Game Object" << "\n";
	int i;

	actualHandID = 0;

// 	for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
// 		playerArray[i] = 0;
// 	}

	// Dealer Position bestimmen
	PlayerDataList::const_iterator player_i = playerDataList.begin();
	PlayerDataList::const_iterator player_end = playerDataList.end();

	bool dealerFound = false;
	i = 0;
	while (player_i != player_end)
	{
		if ((*player_i)->GetUniqueId() == startData.startDealerPlayerId)
		{
			dealerPosition = i;
			dealerFound = true;
			break;
		}
		++player_i;
		++i;
	}
	assert(dealerFound);

	// Board erstellen
	actualBoard = myFactory->createBoard();

	// Player erstellen
	activePlayerList = PlayerList(new std::list<boost::shared_ptr<PlayerInterface> >);
	runningPlayerList = PlayerList(new std::list<boost::shared_ptr<PlayerInterface> >);

	player_i = playerDataList.begin();
	player_end = playerDataList.end();
	for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {

		string myName;
		string myAvatarFile;
		unsigned uniqueId = 0;
		PlayerType type = PLAYER_TYPE_COMPUTER;
		boost::shared_ptr<SessionData> myNetSession;

		if (player_i != player_end)
		{
			uniqueId = (*player_i)->GetUniqueId();
			type = (*player_i)->GetType();
			myName = (*player_i)->GetName();
			myAvatarFile = (*player_i)->GetAvatarFile();
			myNetSession = (*player_i)->GetNetSessionData();
			// TODO: set player type
			++player_i;
		}

		// create Player Objects
		boost::shared_ptr<PlayerInterface> tmpPlayer = myFactory->createPlayer(actualBoard, i, uniqueId, type, myName, myAvatarFile, startCash, startQuantityPlayers > i, 0);

		// fill player lists
		playerArray.push_back(tmpPlayer);
		if(startQuantityPlayers > i) {
			activePlayerList->push_back(tmpPlayer);
		}

		(*runningPlayerList) = (*activePlayerList);

		playerArray[i]->setNetSessionData(myNetSession);
	}
	actualBoard->setPlayerLists(playerArray, activePlayerList, runningPlayerList);
}

Game::~Game()
{
// 	cout << "Delete Game Object" << "\n";

	delete actualBoard;
	actualBoard = 0;
	delete actualHand;
	actualHand = 0;

}

HandInterface *Game::getCurrentHand()
{
	return actualHand;
}

const HandInterface *Game::getCurrentHand() const
{
	return actualHand;
}

void Game::initHand()
{

	int i;

	// eventuell vorhandene Hand löschen
	if(actualHand) {
		delete actualHand;
		actualHand = 0;
	}

	actualHandID++;

	// smallBlind alle x Runden erhöhen
	if((actualHandID-1)%startHandsBeforeRaiseSmallBlind == 0 && actualHandID > 1) { actualSmallBlind *= 2; }

	// Spieler mit leerem Cash auf inactive setzen
	PlayerListIterator it;

// 	cout << "id: " << actualHandID << endl;

	for(it=activePlayerList->begin(); it!=activePlayerList->end(); it++) {

// 		cout << "player" << (*it)->getMyID() << ": " << (*it)->getMyCash() << endl;

		if((*it)->getMyCash() == 0) {
			(*it)->setMyActiveStatus(0);
			it = activePlayerList->erase(it);
		}
	}

// 	cout << activePlayerList->size() << endl;

	//Spieler Action auf 0 setzen
	for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
		playerArray[i]->setMyAction(0);
	}

	runningPlayerList->clear();
	(*runningPlayerList) = (*activePlayerList);

	// Hand erstellen
	actualHand = myFactory->createHand(myFactory, myGui, actualBoard, playerArray, activePlayerList, runningPlayerList, actualHandID, startQuantityPlayers, dealerPosition, actualSmallBlind, startCash);

	// Dealer-Button weiterschieben --> Achtung inactive
	for(i=0; (i<MAX_NUMBER_OF_PLAYERS && !(playerArray[dealerPosition]->getMyActiveStatus())) || i==0; i++) {

		dealerPosition = (dealerPosition+1)%(MAX_NUMBER_OF_PLAYERS);
	}

	// Abfrage Cash==0 -> player inactive -> actualQuantityPlayer--
}

void Game::startHand()
{
	assert(actualHand);

	//GUI bereinigen
	myGui->nextRoundCleanGui();

	myGui->logNewGameHandMsg(myGameID, actualHandID);

	actualHand->start();
}

boost::shared_ptr<PlayerInterface> Game::getPlayerByUniqueId(unsigned id)
{
	boost::shared_ptr<PlayerInterface> tmpPlayer;
	for (int i = 0; i < startQuantityPlayers; i++)
	{
		if (playerArray[i]->getMyUniqueID() == id)
		{
			tmpPlayer = playerArray[i];
			break;
		}
	}
	return tmpPlayer;
}

boost::shared_ptr<PlayerInterface> Game::getCurrentPlayer()
{
	int curPlayerNum = getCurrentHand()->getCurrentBeRo()->getPlayersTurn();
	assert(curPlayerNum < getStartQuantityPlayers());
	return getPlayerArray()[curPlayerNum];
}

<|endoftext|>


<commit_before>
#include "game.hpp"

Game::Game()
: window(sf::VideoMode(720,480), "SFML App")
{
    frameTime = sf::seconds(1.f / 60.f);
}

void Game::run()
{
    sf::Clock clock;
    sf::Time lastUpdateTime = sf::Time::Zero;
    while (window.isOpen())
    {
        lastUpdateTime += clock.restart();
        while (lastUpdateTime > frameTime)
        {
            lastUpdateTime -= frameTime;
            processEvents();
            update(frameTime);
        }
        draw();
    }
}

void Game::processEvents()
{
    sf::Event event;
    while (window.pollEvent(event))
    {
        switch (event.type)
        {
        case sf::Event::Closed:
            window.close();
            break;
        case sf::Event::KeyPressed:
            handlePlayerInput(event.key.code, true);
            break;
        case sf::Event::KeyReleased:
            handlePlayerInput(event.key.code, false);
            break;
		default:
			break;
        }
    }
}

void Game::update(sf::Time deltaTime)
{
}

void Game::draw()
{
}

void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
{
}
<commit_msg>Got rid of accidental tabs instead of spaces.<commit_after>
#include "game.hpp"

Game::Game()
: window(sf::VideoMode(720,480), "SFML App")
{
    frameTime = sf::seconds(1.f / 60.f);
}

void Game::run()
{
    sf::Clock clock;
    sf::Time lastUpdateTime = sf::Time::Zero;
    while (window.isOpen())
    {
        lastUpdateTime += clock.restart();
        while (lastUpdateTime > frameTime)
        {
            lastUpdateTime -= frameTime;
            processEvents();
            update(frameTime);
        }
        draw();
    }
}

void Game::processEvents()
{
    sf::Event event;
    while (window.pollEvent(event))
    {
        switch (event.type)
        {
        case sf::Event::Closed:
            window.close();
            break;
        case sf::Event::KeyPressed:
            handlePlayerInput(event.key.code, true);
            break;
        case sf::Event::KeyReleased:
            handlePlayerInput(event.key.code, false);
            break;
        default:
            break;
        }
    }
}

void Game::update(sf::Time deltaTime)
{
}

void Game::draw()
{
}

void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
{
}
<|endoftext|>


<commit_before>#ifndef GAME_HXX_
#define GAME_HXX_

#include "tunnel.hxx"
#include "distortion.hxx"

class Game {
  Tunnel tunnel;
  Distortion distortion;

public:
  Game();
  ~Game();

  void update(float);
  void configureGL();
  void draw();
  void motion(float,float);
  void button(unsigned);
  bool running() const;
};

#endif /* GAME_HXX_ */
<commit_msg>Add field member to Game.<commit_after>#ifndef GAME_HXX_
#define GAME_HXX_

#include "tunnel.hxx"
#include "distortion.hxx"
#include "game_field.hxx"

class Game {
  Tunnel tunnel;
  Distortion distortion;
  GameField field;

public:
  Game();
  ~Game();

  void update(float);
  void configureGL();
  void draw();
  void motion(float,float);
  void button(unsigned);
  bool running() const;
};

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


<commit_before>#ifndef __NODE_GDAL_GLOBAL_H__
#define __NODE_GDAL_GLOBAL_H__

// node
#include <node.h>

// nan
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <nan.h>
#pragma GCC diagnostic pop

// ogr
#include <ogr_api.h>
#include <ogrsf_frmts.h>

// gdal
#include "gdal_common.hpp"
#include "gdal_driver.hpp"
#include "gdal_dataset.hpp"

using namespace v8;
using namespace node;

namespace node_gdal {

	static NAN_METHOD(open)
	{
		Nan::HandleScope scope;

		std::string path;
		std::string mode = "r";

		NODE_ARG_STR(0, "path", path);
		NODE_ARG_OPT_STR(1, "mode", mode);

		#if GDAL_VERSION_MAJOR < 2
			GDALAccess access = GA_ReadOnly;
			if (mode == "r+") {
				access = GA_Update;
			} else if (mode != "r") {
				Nan::ThrowError("Invalid open mode. Must be \"r\" or \"r+\"");
				return;
			}

			OGRDataSource *ogr_ds = OGRSFDriverRegistrar::Open(path.c_str(), static_cast<int>(access));
			if(ogr_ds) {
				info.GetReturnValue().Set(NanNewDataset::New(ogr_ds));
				return;
			}

			GDALDataset *gdal_ds = (GDALDataset*) GDALOpen(path.c_str(), access);
			if(gdal_ds) {
				info.GetReturnValue().Set(Dataset::New(gdal_ds));
				return;
			}
		#else
			unsigned int flags = 0;
			if (mode == "r+") {
				flags |= GDAL_OF_UPDATE;
			} else if (mode == "r") {
				flags |= GDAL_OF_READONLY;
			} else {
				Nan::ThrowError("Invalid open mode. Must be \"r\" or \"r+\"");
				return;
			}

			GDALDataset *ds = (GDALDataset*) GDALOpenEx(path.c_str(), flags, NULL, NULL, NULL);
			if(ds) {
				info.GetReturnValue().Set(Dataset::New(ds));
				return;
			}
		#endif

		Nan::ThrowError("Error opening dataset");
		return;
	}

	static NAN_METHOD(setConfigOption)
	{
		Nan::HandleScope scope;

		std::string name;

		NODE_ARG_STR(0, "name", name);

		if (info.Length() < 2) {
			Nan::ThrowError("string or null value must be provided");
			return;
		}
		if(info[1]->IsString()){
			std::string val = *Nan::Utf8String(info[1]);
			CPLSetConfigOption(name.c_str(), val.c_str());
		} else if(info[1]->IsNull() || info[1]->IsUndefined()) {
			CPLSetConfigOption(name.c_str(), NULL);
		} else {
			Nan::ThrowError("value must be a string or null");
			return;
		}

		return;
	}

	static NAN_METHOD(getConfigOption)
	{
		Nan::HandleScope scope;

		std::string name;
		NODE_ARG_STR(0, "name", name);

		info.GetReturnValue().Set(SafeString::New(CPLGetConfigOption(name.c_str(), NULL)));
	}

	/**
	 * Convert decimal degrees to degrees, minutes, and seconds string
	 *
	 * @for gdal
	 * @static
	 * @method decToDMS
	 * @param {Number} angle
	 * @param {String} axis `"lat"` or `"long"`
	 * @param {Integer} [precision=2]
	 * @return {String} A string nndnn'nn.nn'"L where n is a number and L is either N or E
	 */
	static NAN_METHOD(decToDMS){
		Nan::HandleScope scope;

		double angle;
		std::string axis;
		int precision = 2;
		NODE_ARG_DOUBLE(0, "angle", angle);
		NODE_ARG_STR(1, "axis", axis);
		NODE_ARG_INT_OPT(2, "precision", precision);

		if (axis.length() > 0) {
			axis[0] = toupper(axis[0]);
		}
		if (axis != "Lat" && axis != "Long") {
			Nan::ThrowError("Axis must be 'lat' or 'long'");
			return;
		}

		info.GetReturnValue().Set(SafeString::New(GDALDecToDMS(angle, axis.c_str(), precision)));
	}
}

#endif
<commit_msg>Fixing compiler errors for GDAL versions < 2.0<commit_after>#ifndef __NODE_GDAL_GLOBAL_H__
#define __NODE_GDAL_GLOBAL_H__

// node
#include <node.h>

// nan
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <nan.h>
#pragma GCC diagnostic pop

// ogr
#include <ogr_api.h>
#include <ogrsf_frmts.h>

// gdal
#include "gdal_common.hpp"
#include "gdal_driver.hpp"
#include "gdal_dataset.hpp"

using namespace v8;
using namespace node;

namespace node_gdal {

	static NAN_METHOD(open)
	{
		Nan::HandleScope scope;

		std::string path;
		std::string mode = "r";

		NODE_ARG_STR(0, "path", path);
		NODE_ARG_OPT_STR(1, "mode", mode);

		#if GDAL_VERSION_MAJOR < 2
			GDALAccess access = GA_ReadOnly;
			if (mode == "r+") {
				access = GA_Update;
			} else if (mode != "r") {
				Nan::ThrowError("Invalid open mode. Must be \"r\" or \"r+\"");
				return;
			}

			OGRDataSource *ogr_ds = OGRSFDriverRegistrar::Open(path.c_str(), static_cast<int>(access));
			if(ogr_ds) {
				info.GetReturnValue().Set(Dataset::New(ogr_ds));
				return;
			}

			GDALDataset *gdal_ds = (GDALDataset*) GDALOpen(path.c_str(), access);
			if(gdal_ds) {
				info.GetReturnValue().Set(Dataset::New(gdal_ds));
				return;
			}
		#else
			unsigned int flags = 0;
			if (mode == "r+") {
				flags |= GDAL_OF_UPDATE;
			} else if (mode == "r") {
				flags |= GDAL_OF_READONLY;
			} else {
				Nan::ThrowError("Invalid open mode. Must be \"r\" or \"r+\"");
				return;
			}

			GDALDataset *ds = (GDALDataset*) GDALOpenEx(path.c_str(), flags, NULL, NULL, NULL);
			if(ds) {
				info.GetReturnValue().Set(Dataset::New(ds));
				return;
			}
		#endif

		Nan::ThrowError("Error opening dataset");
		return;
	}

	static NAN_METHOD(setConfigOption)
	{
		Nan::HandleScope scope;

		std::string name;

		NODE_ARG_STR(0, "name", name);

		if (info.Length() < 2) {
			Nan::ThrowError("string or null value must be provided");
			return;
		}
		if(info[1]->IsString()){
			std::string val = *Nan::Utf8String(info[1]);
			CPLSetConfigOption(name.c_str(), val.c_str());
		} else if(info[1]->IsNull() || info[1]->IsUndefined()) {
			CPLSetConfigOption(name.c_str(), NULL);
		} else {
			Nan::ThrowError("value must be a string or null");
			return;
		}

		return;
	}

	static NAN_METHOD(getConfigOption)
	{
		Nan::HandleScope scope;

		std::string name;
		NODE_ARG_STR(0, "name", name);

		info.GetReturnValue().Set(SafeString::New(CPLGetConfigOption(name.c_str(), NULL)));
	}

	/**
	 * Convert decimal degrees to degrees, minutes, and seconds string
	 *
	 * @for gdal
	 * @static
	 * @method decToDMS
	 * @param {Number} angle
	 * @param {String} axis `"lat"` or `"long"`
	 * @param {Integer} [precision=2]
	 * @return {String} A string nndnn'nn.nn'"L where n is a number and L is either N or E
	 */
	static NAN_METHOD(decToDMS){
		Nan::HandleScope scope;

		double angle;
		std::string axis;
		int precision = 2;
		NODE_ARG_DOUBLE(0, "angle", angle);
		NODE_ARG_STR(1, "axis", axis);
		NODE_ARG_INT_OPT(2, "precision", precision);

		if (axis.length() > 0) {
			axis[0] = toupper(axis[0]);
		}
		if (axis != "Lat" && axis != "Long") {
			Nan::ThrowError("Axis must be 'lat' or 'long'");
			return;
		}

		info.GetReturnValue().Set(SafeString::New(GDALDecToDMS(angle, axis.c_str(), precision)));
	}
}

#endif
<|endoftext|>