<commit_before>/*
  Simple Logger for Qt

  Mario Ban, 05.2015

  GNU General Public License v2.0
  Copyright (C) 2015 Mario Ban
*/

#include "simpleQtLogger.h"

#include <QCoreApplication>
#include <QTimer>
#include <QDateTime>
#include <QFileInfo>
#include <QtDebug>

/* Log-level */
bool SQTL_LOG_ENABLE_FATAL = true;
bool SQTL_LOG_ENABLE_ERROR = true;
bool SQTL_LOG_ENABLE_WARNING = true;
bool SQTL_LOG_ENABLE_INFO = true;
bool SQTL_LOG_ENABLE_DEBUG = false;
bool SQTL_LOG_ENABLE_FUNCTION = false;

// -------------------------------------------------------------------------------------------------

SimpleQtLogger::SimpleQtLogger(QObject *parent)
  : QObject(parent)
  , _logFileSize(0)
  , _logFileMaxNumber(0)
  , _stackDepth(0)
  , _logFile(0)
  , _logFileActivity(false)
{
  qDebug("SimpleQtLogger::SimpleQtLogger");

  Qt::ConnectionType connectionType = Qt::DirectConnection;
  QObject::connect(this, SIGNAL(signalLog(const QString&, SQT_LOG_Level, const QString&, const QString&, unsigned int)),
    this, SLOT(slotLog(const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)), connectionType);
}

SimpleQtLogger::~SimpleQtLogger()
{
  qDebug("SimpleQtLogger::~SimpleQtLogger");

  // check close log file
  if(_logFile) {
    if(_logFile->isOpen()) {
      _logFile->close();
    }
    delete _logFile;
    _logFile = 0;
  }
}

void SimpleQtLogger::setLogFileName(const QString& logFileName, unsigned int logFileSize, unsigned int logFileMaxNumber)
{
  qDebug("SimpleQtLogger::setLogFileName");

  _logFileName = logFileName;
  _logFileSize = logFileSize;
  _logFileMaxNumber = logFileMaxNumber;

  // check valid log-file name ending
  if(_logFileName.right(4) != ".log") {
    qWarning() << "Name of log-file not ending with '.log'" << _logFileName;
    return;
  }

  // check valid number ranges
  if(_logFileSize < 100) {
    _logFileSize = 100;
  }
  if(_logFileMaxNumber < 1) {
    _logFileMaxNumber = 1;
  }
  if(_logFileMaxNumber > 99) {
    _logFileMaxNumber = 99;
  }

  checkLogFileOpen();

  log("Start logger", SQTL_LOG_INFO, "", "", 0);
}

void SimpleQtLogger::log(const QString& text, SQTL_LOG_Level level, const QString& functionName, const char* fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::log");

  emit signalLog(text, level, functionName, fileName, lineNumber);
}

void SimpleQtLogger::slotLog(const QString& text, SQTL_LOG_Level level, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::slotLog");

  // time-stamp
  QDateTime dateTime = QDateTime::currentDateTime(); // or better use QDateTime::currentDateTimeUtc() instead
  QString ts = dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");

  if(functionName.isEmpty()) {
    // stream (append) to log file
    if(_logFile && _logFile->isOpen()) {
      QTextStream out(_logFile);
      out << ts << " [" << LOG_LEVEL_CHAR[level] << "] " << (text.isEmpty() ? "?" : text.trimmed()) << '\n';
      _logFileActivity = true;
    }
    else {
      qDebug("%s", QString("%4: %1 [%2] %3").arg(ts).arg(LOG_LEVEL_CHAR[level]).arg(text.isEmpty() ? "?" : text.trimmed()).arg(_logFileName).toStdString().c_str());
    }
    return;
  }

  // stream (append) to log file
  if(_logFile && _logFile->isOpen()) {
    QTextStream out(_logFile);
    out << ts << " [" << LOG_LEVEL_CHAR[level] << "] " << (text.isEmpty() ? "?" : text.trimmed()) << " (" << functionName << "@" << fileName << ":" << lineNumber << ")" << '\n';
    _logFileActivity = true;
  }
  else {
    qDebug("%s", QString("%7: %1 [%2] %3 (%4@%5:%6)").arg(ts).arg(LOG_LEVEL_CHAR[level]).arg(text.isEmpty() ? "?" : text.trimmed()).arg(functionName).arg(fileName).arg(lineNumber).arg(_logFileName).toStdString().c_str());
  }
}

#if ENABLED_SQTL_LOG_FUNCTION > 0

void SimpleQtLogger::logFuncBegin(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::logFuncBegin");

  // TODO stack-trace depth (++ before) ... (thread-id-callback?)

  _stackDepth++; // adjust stack-trace depth

  QString stackDepth("");
  for(unsigned int i=1; i<_stackDepth; ++i) {
    stackDepth += STACK_DEPTH_CHAR;
  }
  if(text.isEmpty()) {
    log(QString("%1\\").arg(stackDepth), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
  else {
    log(QString("%1\\ %2").arg(stackDepth).arg(text), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
}

void SimpleQtLogger::logFuncEnd(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::logFuncEnd");

  // TODO stack-trace depth (-- after) ... (thread-id-callback?)

  QString stackDepth("");
  for(unsigned int i=1; i<_stackDepth; ++i) {
    stackDepth += STACK_DEPTH_CHAR;
  }
  if(text.isEmpty()) {
    log(QString("%1/").arg(stackDepth), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
  else {
    log(QString("%1/ %2").arg(stackDepth).arg(text), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }

  _stackDepth--; // adjust stack-trace depth
}

#endif

void SimpleQtLogger::checkLogFileOpen()
{
  // qDebug("SimpleQtLogger::checkLogFileOpen");

  // check close and open log file
  if(_logFile) {
    if(_logFile->isOpen()) {
      _logFile->close();
    }
    delete _logFile;
  }

  // open log-file
  _logFile = new QFile(_logFileName);
  if(!_logFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
    delete _logFile;
    _logFile = 0;
    qWarning() << "Open log-file failed!" << _logFileName;
  }

  if(!_logFile) {
    return;
  }

  qDebug() << "Current log-file:" << _logFileName;

  QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
}

void SimpleQtLogger::checkLogFileRolling()
{
  // qDebug("SimpleQtLogger::checkLogFileRolling");

  if(!_logFile) {
    return;
  }

  // check current log-file size
  QFileInfo logFileInfo(*_logFile);
  qint64 logFileSize = logFileInfo.size();

  if(logFileSize < _logFileSize) {
    QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
    return;
  }
  log(QString("Current log-file size=%1 (rolling-size=%2) --> rolling").arg(logFileSize).arg(_logFileSize), SQTL_LOG_INFO, "", "", 0);

  // handle file rolling

  // delete last file
  QString logFileName = _logFileName;
  logFileName.replace(".log", QString("_%1.log").arg(_logFileMaxNumber, 2, 10, QLatin1Char('0')));
  if(QFile::exists(logFileName)) {
    if(QFile::remove(logFileName)) {
      qDebug() << "Removed" << logFileName;
    }
    else {
      qWarning() << "ERROR: Remove" << logFileName;
    }
  }

  // rolling files
  for(int i=_logFileMaxNumber-1; i>0; --i) {
    QString logFileNameFrom = _logFileName;
    logFileNameFrom.replace(".log", QString("_%1.log").arg(i, 2, 10, QLatin1Char('0')));
    QString logFileNameTo = _logFileName;
    logFileNameTo.replace(".log", QString("_%1.log").arg(i+1, 2, 10, QLatin1Char('0')));
    if(QFile::exists(logFileNameFrom)) {
      if(QFile::rename(logFileNameFrom, logFileNameTo)) {
        qDebug() << "Moved" << logFileNameFrom << "to" << logFileNameTo;
      }
      else {
        qWarning() << "ERROR: Move" << logFileNameFrom << "to" << logFileNameTo;
      }
    }
  }

  _logFile->close();

  // move first file
  QString logFileNameTo = _logFileName;
  logFileNameTo.replace(".log", QString("_%1.log").arg(1, 2, 10, QLatin1Char('0')));
  if(QFile::exists(_logFileName)) {
    if(QFile::rename(_logFileName, logFileNameTo)) {
      qDebug() << "Moved" << _logFileName << "to" << logFileNameTo;
    }
    else {
      qWarning() << "ERROR: Move" << _logFileName << "to" << logFileNameTo;
    }
  }

  checkLogFileOpen();
}

void SimpleQtLogger::slotCheckLogFileActivity()
{
  // qDebug("SimpleQtLogger::slotCheckLogFileActivity");

  if(!_logFile) {
    return;
  }

  if(_logFileActivity) {
    _logFileActivity = false;
    checkLogFileRolling();
    return;
  }

  QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
}

// -------------------------------------------------------------------------------------------------

#if ENABLED_SQTL_LOG_FUNCTION > 0

SimpleQtLoggerFunc::SimpleQtLoggerFunc(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
  : _text(text)
  , _functionName(functionName)
  , _fileName(fileName)
  , _lineNumber(lineNumber)
{
  // qDebug("SimpleQtLoggerFunc::SimpleQtLoggerFunc");
  if(ENABLED_SQTL_LOG_FUNCTION && SQTL_LOG_ENABLE_FUNCTION) simpleQtLogger_.logFuncBegin(_text, _functionName, _fileName, _lineNumber);
}

SimpleQtLoggerFunc::~SimpleQtLoggerFunc()
{
  // qDebug("SimpleQtLoggerFunc::~SimpleQtLoggerFunc");
  if(ENABLED_SQTL_LOG_FUNCTION && SQTL_LOG_ENABLE_FUNCTION) simpleQtLogger_.logFuncEnd(_text, _functionName, _fileName, _lineNumber);
}

#endif
<commit_msg>Update (after merge branch 'log-signal-slot') changed global var prefix<commit_after>/*
  Simple Logger for Qt

  Mario Ban, 05.2015

  GNU General Public License v2.0
  Copyright (C) 2015 Mario Ban
*/

#include "simpleQtLogger.h"

#include <QCoreApplication>
#include <QTimer>
#include <QDateTime>
#include <QFileInfo>
#include <QtDebug>

/* Log-level */
bool SQTL_LOG_ENABLE_FATAL = true;
bool SQTL_LOG_ENABLE_ERROR = true;
bool SQTL_LOG_ENABLE_WARNING = true;
bool SQTL_LOG_ENABLE_INFO = true;
bool SQTL_LOG_ENABLE_DEBUG = false;
bool SQTL_LOG_ENABLE_FUNCTION = false;

// -------------------------------------------------------------------------------------------------

SimpleQtLogger::SimpleQtLogger(QObject *parent)
  : QObject(parent)
  , _logFileSize(0)
  , _logFileMaxNumber(0)
  , _stackDepth(0)
  , _logFile(0)
  , _logFileActivity(false)
{
  qDebug("SimpleQtLogger::SimpleQtLogger");

  Qt::ConnectionType connectionType = Qt::DirectConnection;
  QObject::connect(this, SIGNAL(signalLog(const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)),
    this, SLOT(slotLog(const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)), connectionType);
}

SimpleQtLogger::~SimpleQtLogger()
{
  qDebug("SimpleQtLogger::~SimpleQtLogger");

  // check close log file
  if(_logFile) {
    if(_logFile->isOpen()) {
      _logFile->close();
    }
    delete _logFile;
    _logFile = 0;
  }
}

void SimpleQtLogger::setLogFileName(const QString& logFileName, unsigned int logFileSize, unsigned int logFileMaxNumber)
{
  qDebug("SimpleQtLogger::setLogFileName");

  _logFileName = logFileName;
  _logFileSize = logFileSize;
  _logFileMaxNumber = logFileMaxNumber;

  // check valid log-file name ending
  if(_logFileName.right(4) != ".log") {
    qWarning() << "Name of log-file not ending with '.log'" << _logFileName;
    return;
  }

  // check valid number ranges
  if(_logFileSize < 100) {
    _logFileSize = 100;
  }
  if(_logFileMaxNumber < 1) {
    _logFileMaxNumber = 1;
  }
  if(_logFileMaxNumber > 99) {
    _logFileMaxNumber = 99;
  }

  checkLogFileOpen();

  log("Start logger", SQTL_LOG_INFO, "", "", 0);
}

void SimpleQtLogger::log(const QString& text, SQTL_LOG_Level level, const QString& functionName, const char* fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::log");

  emit signalLog(text, level, functionName, fileName, lineNumber);
}

void SimpleQtLogger::slotLog(const QString& text, SQTL_LOG_Level level, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::slotLog");

  // time-stamp
  QDateTime dateTime = QDateTime::currentDateTime(); // or better use QDateTime::currentDateTimeUtc() instead
  QString ts = dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");

  if(functionName.isEmpty()) {
    // stream (append) to log file
    if(_logFile && _logFile->isOpen()) {
      QTextStream out(_logFile);
      out << ts << " [" << LOG_LEVEL_CHAR[level] << "] " << (text.isEmpty() ? "?" : text.trimmed()) << '\n';
      _logFileActivity = true;
    }
    else {
      qDebug("%s", QString("%4: %1 [%2] %3").arg(ts).arg(LOG_LEVEL_CHAR[level]).arg(text.isEmpty() ? "?" : text.trimmed()).arg(_logFileName).toStdString().c_str());
    }
    return;
  }

  // stream (append) to log file
  if(_logFile && _logFile->isOpen()) {
    QTextStream out(_logFile);
    out << ts << " [" << LOG_LEVEL_CHAR[level] << "] " << (text.isEmpty() ? "?" : text.trimmed()) << " (" << functionName << "@" << fileName << ":" << lineNumber << ")" << '\n';
    _logFileActivity = true;
  }
  else {
    qDebug("%s", QString("%7: %1 [%2] %3 (%4@%5:%6)").arg(ts).arg(LOG_LEVEL_CHAR[level]).arg(text.isEmpty() ? "?" : text.trimmed()).arg(functionName).arg(fileName).arg(lineNumber).arg(_logFileName).toStdString().c_str());
  }
}

#if ENABLED_SQTL_LOG_FUNCTION > 0

void SimpleQtLogger::logFuncBegin(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::logFuncBegin");

  // TODO stack-trace depth (++ before) ... (thread-id-callback?)

  _stackDepth++; // adjust stack-trace depth

  QString stackDepth("");
  for(unsigned int i=1; i<_stackDepth; ++i) {
    stackDepth += STACK_DEPTH_CHAR;
  }
  if(text.isEmpty()) {
    log(QString("%1\\").arg(stackDepth), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
  else {
    log(QString("%1\\ %2").arg(stackDepth).arg(text), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
}

void SimpleQtLogger::logFuncEnd(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::logFuncEnd");

  // TODO stack-trace depth (-- after) ... (thread-id-callback?)

  QString stackDepth("");
  for(unsigned int i=1; i<_stackDepth; ++i) {
    stackDepth += STACK_DEPTH_CHAR;
  }
  if(text.isEmpty()) {
    log(QString("%1/").arg(stackDepth), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
  else {
    log(QString("%1/ %2").arg(stackDepth).arg(text), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }

  _stackDepth--; // adjust stack-trace depth
}

#endif

void SimpleQtLogger::checkLogFileOpen()
{
  // qDebug("SimpleQtLogger::checkLogFileOpen");

  // check close and open log file
  if(_logFile) {
    if(_logFile->isOpen()) {
      _logFile->close();
    }
    delete _logFile;
  }

  // open log-file
  _logFile = new QFile(_logFileName);
  if(!_logFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
    delete _logFile;
    _logFile = 0;
    qWarning() << "Open log-file failed!" << _logFileName;
  }

  if(!_logFile) {
    return;
  }

  qDebug() << "Current log-file:" << _logFileName;

  QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
}

void SimpleQtLogger::checkLogFileRolling()
{
  // qDebug("SimpleQtLogger::checkLogFileRolling");

  if(!_logFile) {
    return;
  }

  // check current log-file size
  QFileInfo logFileInfo(*_logFile);
  qint64 logFileSize = logFileInfo.size();

  if(logFileSize < _logFileSize) {
    QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
    return;
  }
  log(QString("Current log-file size=%1 (rolling-size=%2) --> rolling").arg(logFileSize).arg(_logFileSize), SQTL_LOG_INFO, "", "", 0);

  // handle file rolling

  // delete last file
  QString logFileName = _logFileName;
  logFileName.replace(".log", QString("_%1.log").arg(_logFileMaxNumber, 2, 10, QLatin1Char('0')));
  if(QFile::exists(logFileName)) {
    if(QFile::remove(logFileName)) {
      qDebug() << "Removed" << logFileName;
    }
    else {
      qWarning() << "ERROR: Remove" << logFileName;
    }
  }

  // rolling files
  for(int i=_logFileMaxNumber-1; i>0; --i) {
    QString logFileNameFrom = _logFileName;
    logFileNameFrom.replace(".log", QString("_%1.log").arg(i, 2, 10, QLatin1Char('0')));
    QString logFileNameTo = _logFileName;
    logFileNameTo.replace(".log", QString("_%1.log").arg(i+1, 2, 10, QLatin1Char('0')));
    if(QFile::exists(logFileNameFrom)) {
      if(QFile::rename(logFileNameFrom, logFileNameTo)) {
        qDebug() << "Moved" << logFileNameFrom << "to" << logFileNameTo;
      }
      else {
        qWarning() << "ERROR: Move" << logFileNameFrom << "to" << logFileNameTo;
      }
    }
  }

  _logFile->close();

  // move first file
  QString logFileNameTo = _logFileName;
  logFileNameTo.replace(".log", QString("_%1.log").arg(1, 2, 10, QLatin1Char('0')));
  if(QFile::exists(_logFileName)) {
    if(QFile::rename(_logFileName, logFileNameTo)) {
      qDebug() << "Moved" << _logFileName << "to" << logFileNameTo;
    }
    else {
      qWarning() << "ERROR: Move" << _logFileName << "to" << logFileNameTo;
    }
  }

  checkLogFileOpen();
}

void SimpleQtLogger::slotCheckLogFileActivity()
{
  // qDebug("SimpleQtLogger::slotCheckLogFileActivity");

  if(!_logFile) {
    return;
  }

  if(_logFileActivity) {
    _logFileActivity = false;
    checkLogFileRolling();
    return;
  }

  QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
}

// -------------------------------------------------------------------------------------------------

#if ENABLED_SQTL_LOG_FUNCTION > 0

SimpleQtLoggerFunc::SimpleQtLoggerFunc(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
  : _text(text)
  , _functionName(functionName)
  , _fileName(fileName)
  , _lineNumber(lineNumber)
{
  // qDebug("SimpleQtLoggerFunc::SimpleQtLoggerFunc");
  if(ENABLED_SQTL_LOG_FUNCTION && SQTL_LOG_ENABLE_FUNCTION) simpleQtLogger_.logFuncBegin(_text, _functionName, _fileName, _lineNumber);
}

SimpleQtLoggerFunc::~SimpleQtLoggerFunc()
{
  // qDebug("SimpleQtLoggerFunc::~SimpleQtLoggerFunc");
  if(ENABLED_SQTL_LOG_FUNCTION && SQTL_LOG_ENABLE_FUNCTION) simpleQtLogger_.logFuncEnd(_text, _functionName, _fileName, _lineNumber);
}

#endif
<|endoftext|>


<commit_before>//
// Copyright (c) 2018 Rokas Kupstys
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include <Urho3D/Core/ProcessUtils.h>
#include <Urho3D/IO/FileSystem.h>
#include <Urho3D/IO/Log.h>
#include "Project.h"
#include "ImportAssimp.h"

namespace Urho3D
{

ImportAssimp::ImportAssimp(Context* context)
    : ImportAsset(context)
{
}

bool ImportAssimp::Accepts(const String& path)
{
    String extension = GetExtension(path);
    return extension == ".fbx" || extension == ".blend";
}

bool ImportAssimp::Convert(const String& path)
{
    bool importedAny = false;
    auto* project = GetSubsystem<Project>();
    assert(path.StartsWith(project->GetResourcePath()));

    const auto& cachePath = project->GetCachePath();
    auto resourceName = path.Substring(project->GetResourcePath().Length());
    auto resourceFileName = GetFileName(path);
    auto outputDir = cachePath + AddTrailingSlash(resourceName);
    GetFileSystem()->CreateDirsRecursive(outputDir);

    // Import models
    {
        String outputPath = outputDir + resourceFileName + ".mdl";

        StringVector args{"model", path, outputPath, "-na", "-ns"};
        Process process(GetFileSystem()->GetProgramDir() + "AssetImporter", args);
        if (process.Run() == 0 && GetFileSystem()->FileExists(outputPath))
            importedAny = true;
    }

    // Import animations
    {
        String outputPath = cachePath + resourceName;

        StringVector args{"anim", path, outputPath, "-nm", "-nt", "-nc", "-ns"};
        Process process(GetFileSystem()->GetProgramDir() + "AssetImporter", args);
        if (process.Run() == 0 && GetFileSystem()->FileExists(outputPath))
            importedAny = true;
    }

    return importedAny;
}

}
<commit_msg>Editor: Use FileSystem::SystemRun() to import assets.<commit_after>//
// Copyright (c) 2018 Rokas Kupstys
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include <Urho3D/Core/ProcessUtils.h>
#include <Urho3D/IO/FileSystem.h>
#include <Urho3D/IO/Log.h>
#include "Project.h"
#include "ImportAssimp.h"

namespace Urho3D
{

ImportAssimp::ImportAssimp(Context* context)
    : ImportAsset(context)
{
}

bool ImportAssimp::Accepts(const String& path)
{
    String extension = GetExtension(path);
    return extension == ".fbx" || extension == ".blend";
}

bool ImportAssimp::Convert(const String& path)
{
    bool importedAny = false;
    auto* project = GetSubsystem<Project>();
    assert(path.StartsWith(project->GetResourcePath()));

    const auto& cachePath = project->GetCachePath();
    auto resourceName = path.Substring(project->GetResourcePath().Length());
    auto resourceFileName = GetFileName(path);
    auto outputDir = cachePath + AddTrailingSlash(resourceName);
    GetFileSystem()->CreateDirsRecursive(outputDir);

    // Import models
    {
        String outputPath = outputDir + resourceFileName + ".mdl";

        StringVector args{"model", path, outputPath, "-na", "-ns"};
        unsigned result = GetFileSystem()->SystemRun(GetFileSystem()->GetProgramDir() + "AssetImporter", args);
        if (result == 0 && GetFileSystem()->FileExists(outputPath))
            importedAny = true;
    }

    // Import animations
    {
        String outputPath = cachePath + resourceName;

        StringVector args{"anim", path, outputPath, "-nm", "-nt", "-nc", "-ns"};
        unsigned result = GetFileSystem()->SystemRun(GetFileSystem()->GetProgramDir() + "AssetImporter", args);
        if (result == 0 && GetFileSystem()->FileExists(outputPath))
            importedAny = true;
    }

    return importedAny;
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 Google Inc. 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 Google Inc. 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 "config.h"
#include "core/animation/css/CSSAnimations.h"

#include "core/animation/ActiveAnimations.h"
#include "core/animation/DocumentTimeline.h"
#include "core/animation/KeyframeAnimationEffect.h"
#include "core/css/CSSKeyframeRule.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Element.h"
#include "core/events/EventNames.h"
#include "core/events/WebKitAnimationEvent.h"
#include "core/platform/animation/CSSAnimationDataList.h"
#include "core/platform/animation/TimingFunction.h"
#include "wtf/HashSet.h"

namespace {

using namespace WebCore;

bool isEarlierPhase(TimedItem::Phase target, TimedItem::Phase reference)
{
    ASSERT(target != TimedItem::PhaseNone);
    ASSERT(reference != TimedItem::PhaseNone);
    return target < reference;
}

bool isLaterPhase(TimedItem::Phase target, TimedItem::Phase reference)
{
    ASSERT(target != TimedItem::PhaseNone);
    ASSERT(reference != TimedItem::PhaseNone);
    return target > reference;
}

} // namespace

namespace WebCore {

// Returns the default timing function.
const PassRefPtr<TimingFunction> timingFromAnimationData(const CSSAnimationData* animationData, Timing& timing)
{
    if (animationData->isDelaySet())
        timing.startDelay = animationData->delay();
    if (animationData->isDurationSet()) {
        timing.iterationDuration = animationData->duration();
        timing.hasIterationDuration = true;
    }
    if (animationData->isIterationCountSet()) {
        if (animationData->iterationCount() == CSSAnimationData::IterationCountInfinite)
            timing.iterationCount = std::numeric_limits<double>::infinity();
        else
            timing.iterationCount = animationData->iterationCount();
    }
    if (animationData->isFillModeSet()) {
        switch (animationData->fillMode()) {
        case AnimationFillModeForwards:
            timing.fillMode = Timing::FillModeForwards;
            break;
        case AnimationFillModeBackwards:
            timing.fillMode = Timing::FillModeBackwards;
            break;
        case AnimationFillModeBoth:
            timing.fillMode = Timing::FillModeBoth;
            break;
        case AnimationFillModeNone:
            timing.fillMode = Timing::FillModeNone;
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    }
    if (animationData->isDirectionSet()) {
        switch (animationData->direction()) {
        case CSSAnimationData::AnimationDirectionNormal:
            timing.direction = Timing::PlaybackDirectionNormal;
            break;
        case CSSAnimationData::AnimationDirectionAlternate:
            timing.direction = Timing::PlaybackDirectionAlternate;
            break;
        case CSSAnimationData::AnimationDirectionReverse:
            timing.direction = Timing::PlaybackDirectionReverse;
            break;
        case CSSAnimationData::AnimationDirectionAlternateReverse:
            timing.direction = Timing::PlaybackDirectionAlternateReverse;
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    }
    return animationData->isTimingFunctionSet() ? animationData->timingFunction() : CSSAnimationData::initialAnimationTimingFunction();
}

CSSAnimationUpdateScope::CSSAnimationUpdateScope(Element* target)
    : m_target(target)
{
    if (!m_target)
        return;
    ActiveAnimations* activeAnimations = m_target->activeAnimations();
    CSSAnimations* cssAnimations = activeAnimations ? activeAnimations->cssAnimations() : 0;
    // It's possible than an update was created outside an update scope. That's harmless
    // but we must clear it now to avoid applying it if an updated replacement is not
    // created in this scope.
    if (cssAnimations)
        cssAnimations->setPendingUpdate(nullptr);
}

CSSAnimationUpdateScope::~CSSAnimationUpdateScope()
{
    if (!m_target)
        return;
    ActiveAnimations* activeAnimations = m_target->activeAnimations();
    CSSAnimations* cssAnimations = activeAnimations ? activeAnimations->cssAnimations() : 0;
    if (cssAnimations)
        cssAnimations->maybeApplyPendingUpdate(m_target);
}

bool CSSAnimations::needsUpdate(const Element* element, const RenderStyle* style)
{
    ActiveAnimations* activeAnimations = element->activeAnimations();
    const CSSAnimationDataList* animations = style->animations();
    const CSSAnimations* cssAnimations = activeAnimations ? activeAnimations->cssAnimations() : 0;
    EDisplay display = style->display();
    return (display != NONE && animations && animations->size()) || (cssAnimations && !cssAnimations->isEmpty());
}

PassOwnPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(const Element* element, const RenderStyle* style, const CSSAnimations* cssAnimations, const CSSAnimationDataList* animationDataList, StyleResolver* resolver)
{
    OwnPtr<CSSAnimationUpdate> update;
    HashSet<AtomicString> inactive;
    if (cssAnimations)
        for (AnimationMap::const_iterator iter = cssAnimations->m_animations.begin(); iter != cssAnimations->m_animations.end(); ++iter)
            inactive.add(iter->key);

    RefPtr<MutableStylePropertySet> newStyles;
    if (style->display() != NONE) {
        for (size_t i = 0; animationDataList && i < animationDataList->size(); ++i) {
            const CSSAnimationData* animationData = animationDataList->animation(i);
            if (animationData->isNoneAnimation())
                continue;
            ASSERT(animationData->isValidAnimation());
            AtomicString animationName(animationData->name());

            if (cssAnimations) {
                AnimationMap::const_iterator existing(cssAnimations->m_animations.find(animationName));
                if (existing != cssAnimations->m_animations.end()) {
                    // FIXME: The play-state of this animation might have changed, record the change in the update.
                    inactive.remove(animationName);
                    continue;
                }
            }

            Timing timing;
            RefPtr<TimingFunction> defaultTimingFunction = timingFromAnimationData(animationData, timing);
            KeyframeAnimationEffect::KeyframeVector keyframes;
            resolver->resolveKeyframes(element, style, animationName, defaultTimingFunction.get(), keyframes, timing.timingFunction);
            if (!keyframes.isEmpty()) {
                if (!update)
                    update = adoptPtr(new CSSAnimationUpdate());
                // FIXME: crbug.com/268791 - Keyframes are already normalized, perhaps there should be a flag on KeyframeAnimationEffect to skip normalization.
                update->startAnimation(animationName, InertAnimation::create(KeyframeAnimationEffect::create(keyframes), timing).get());
            }
        }
    }

    if (!inactive.isEmpty() && !update)
        update = adoptPtr(new CSSAnimationUpdate());
    for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter != inactive.end(); ++iter)
        update->cancelAnimation(*iter, cssAnimations->m_animations.get(*iter));

    return update.release();
}

void CSSAnimations::maybeApplyPendingUpdate(Element* element)
{
    if (!element->renderer())
        m_pendingUpdate = nullptr;

    if (!m_pendingUpdate)
        return;

    OwnPtr<CSSAnimationUpdate> update = m_pendingUpdate.release();

    for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationNames().begin(); iter != update->cancelledAnimationNames().end(); ++iter)
        m_animations.take(*iter)->cancel();

    // FIXME: Apply updates to play-state.

    for (Vector<CSSAnimationUpdate::NewAnimation>::const_iterator iter = update->newAnimations().begin(); iter != update->newAnimations().end(); ++iter) {
        OwnPtr<CSSAnimations::EventDelegate> eventDelegate = adoptPtr(new EventDelegate(element, iter->name));
        RefPtr<Animation> animation = Animation::create(element, iter->animation->effect(), iter->animation->specified(), eventDelegate.release());
        RefPtr<Player> player = element->document().timeline()->play(animation.get());
        m_animations.set(iter->name, player.get());
    }
}

void CSSAnimations::cancel()
{
    for (AnimationMap::iterator iter = m_animations.begin(); iter != m_animations.end(); ++iter)
        iter->value->cancel();

    m_animations.clear();
    m_pendingUpdate = nullptr;
}

void CSSAnimations::EventDelegate::maybeDispatch(Document::ListenerType listenerType, AtomicString& eventName, double elapsedTime)
{
    if (m_target->document().hasListenerType(listenerType))
        m_target->document().timeline()->addEventToDispatch(m_target, WebKitAnimationEvent::create(eventName, m_name, elapsedTime));
}

void CSSAnimations::EventDelegate::onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration)
{
    // Events for a single document are queued and dispatched as a group at
    // the end of DocumentTimeline::serviceAnimations.
    // FIXME: Events which are queued outside of serviceAnimations should
    // trigger a timer to dispatch when control is released.
    const TimedItem::Phase currentPhase = timedItem->phase();
    const double currentIteration = timedItem->currentIteration();

    // Note that the elapsedTime is measured from when the animation starts playing.
    if (!isFirstSample && previousPhase == TimedItem::PhaseActive && currentPhase == TimedItem::PhaseActive && previousIteration != currentIteration) {
        ASSERT(!isNull(previousIteration));
        ASSERT(!isNull(currentIteration));
        // We fire only a single event for all iterations thast terminate
        // between a single pair of samples. See http://crbug.com/275263. For
        // compatibility with the existing implementation, this event uses
        // the elapsedTime for the first iteration in question.
        ASSERT(timedItem->specified().hasIterationDuration);
        const double elapsedTime = timedItem->specified().iterationDuration * (previousIteration + 1);
        maybeDispatch(Document::ANIMATIONITERATION_LISTENER, eventNames().animationiterationEvent, elapsedTime);
        return;
    }
    if ((isFirstSample || previousPhase == TimedItem::PhaseBefore) && isLaterPhase(currentPhase, TimedItem::PhaseBefore)) {
        ASSERT(timedItem->specified().startDelay > 0 || isFirstSample);
        // The spec states that the elapsed time should be
        // 'delay < 0 ? -delay : 0', but we always use 0 to match the existing
        // implementation. See crbug.com/279611
        maybeDispatch(Document::ANIMATIONSTART_LISTENER, eventNames().animationstartEvent, 0);
    }
    if ((isFirstSample || isEarlierPhase(previousPhase, TimedItem::PhaseAfter)) && currentPhase == TimedItem::PhaseAfter)
        maybeDispatch(Document::ANIMATIONEND_LISTENER, eventNames().animationendEvent, timedItem->activeDuration());
}

bool CSSAnimations::isAnimatableProperty(CSSPropertyID property)
{
    switch (property) {
    case CSSPropertyBackgroundColor:
    case CSSPropertyBackgroundImage:
    case CSSPropertyBackgroundPositionX:
    case CSSPropertyBackgroundPositionY:
    case CSSPropertyBackgroundSize:
    case CSSPropertyBaselineShift:
    case CSSPropertyBorderBottomColor:
    case CSSPropertyBorderBottomLeftRadius:
    case CSSPropertyBorderBottomRightRadius:
    case CSSPropertyBorderBottomWidth:
    case CSSPropertyBorderImageOutset:
    case CSSPropertyBorderImageSlice:
    case CSSPropertyBorderImageSource:
    case CSSPropertyBorderImageWidth:
    case CSSPropertyBorderLeftColor:
    case CSSPropertyBorderLeftWidth:
    case CSSPropertyBorderRightColor:
    case CSSPropertyBorderRightWidth:
    case CSSPropertyBorderTopColor:
    case CSSPropertyBorderTopLeftRadius:
    case CSSPropertyBorderTopRightRadius:
    case CSSPropertyBorderTopWidth:
    case CSSPropertyBottom:
    case CSSPropertyBoxShadow:
    case CSSPropertyClip:
    case CSSPropertyColor:
    case CSSPropertyFill:
    case CSSPropertyFillOpacity:
    case CSSPropertyFlex:
    case CSSPropertyFloodColor:
    case CSSPropertyFloodOpacity:
    case CSSPropertyFontSize:
    case CSSPropertyHeight:
    case CSSPropertyKerning:
    case CSSPropertyLeft:
    case CSSPropertyLetterSpacing:
    case CSSPropertyLightingColor:
    case CSSPropertyLineHeight:
    case CSSPropertyListStyleImage:
    case CSSPropertyMarginBottom:
    case CSSPropertyMarginLeft:
    case CSSPropertyMarginRight:
    case CSSPropertyMarginTop:
    case CSSPropertyMaxHeight:
    case CSSPropertyMaxWidth:
    case CSSPropertyMinHeight:
    case CSSPropertyMinWidth:
    case CSSPropertyObjectPosition:
    case CSSPropertyOpacity:
    case CSSPropertyOrphans:
    case CSSPropertyOutlineColor:
    case CSSPropertyOutlineOffset:
    case CSSPropertyOutlineWidth:
    case CSSPropertyPaddingBottom:
    case CSSPropertyPaddingLeft:
    case CSSPropertyPaddingRight:
    case CSSPropertyPaddingTop:
    case CSSPropertyRight:
    case CSSPropertyStopColor:
    case CSSPropertyStopOpacity:
    case CSSPropertyStroke:
    case CSSPropertyStrokeDasharray:
    case CSSPropertyStrokeDashoffset:
    case CSSPropertyStrokeMiterlimit:
    case CSSPropertyStrokeOpacity:
    case CSSPropertyStrokeWidth:
    case CSSPropertyTextIndent:
    case CSSPropertyTextShadow:
    case CSSPropertyTop:
    case CSSPropertyVisibility:
    case CSSPropertyWebkitBackgroundSize:
    case CSSPropertyWebkitBorderHorizontalSpacing:
    case CSSPropertyWebkitBorderVerticalSpacing:
    case CSSPropertyWebkitBoxShadow:
    case CSSPropertyWebkitClipPath:
    case CSSPropertyWebkitColumnCount:
    case CSSPropertyWebkitColumnGap:
    case CSSPropertyWebkitColumnRuleColor:
    case CSSPropertyWebkitColumnRuleWidth:
    case CSSPropertyWebkitColumnWidth:
    case CSSPropertyWebkitFilter:
    case CSSPropertyWebkitMaskBoxImage:
    case CSSPropertyWebkitMaskBoxImageSource:
    case CSSPropertyWebkitMaskImage:
    case CSSPropertyWebkitMaskPositionX:
    case CSSPropertyWebkitMaskPositionY:
    case CSSPropertyWebkitMaskSize:
    case CSSPropertyWebkitPerspective:
    case CSSPropertyWebkitPerspectiveOriginX:
    case CSSPropertyWebkitPerspectiveOriginY:
    case CSSPropertyWebkitShapeInside:
    case CSSPropertyWebkitTextFillColor:
    case CSSPropertyWebkitTextStrokeColor:
    case CSSPropertyWebkitTransform:
    case CSSPropertyWebkitTransformOriginX:
    case CSSPropertyWebkitTransformOriginY:
    case CSSPropertyWebkitTransformOriginZ:
    case CSSPropertyWidows:
    case CSSPropertyWidth:
    case CSSPropertyWordSpacing:
    case CSSPropertyZIndex:
    case CSSPropertyZoom:
        return true;
    default:
        return false;
    }
}

} // namespace WebCore
<commit_msg>Remove unused variable.<commit_after>/*
 * Copyright (C) 2013 Google Inc. 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 Google Inc. 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 "config.h"
#include "core/animation/css/CSSAnimations.h"

#include "core/animation/ActiveAnimations.h"
#include "core/animation/DocumentTimeline.h"
#include "core/animation/KeyframeAnimationEffect.h"
#include "core/css/CSSKeyframeRule.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Element.h"
#include "core/events/EventNames.h"
#include "core/events/WebKitAnimationEvent.h"
#include "core/platform/animation/CSSAnimationDataList.h"
#include "core/platform/animation/TimingFunction.h"
#include "wtf/HashSet.h"

namespace {

using namespace WebCore;

bool isEarlierPhase(TimedItem::Phase target, TimedItem::Phase reference)
{
    ASSERT(target != TimedItem::PhaseNone);
    ASSERT(reference != TimedItem::PhaseNone);
    return target < reference;
}

bool isLaterPhase(TimedItem::Phase target, TimedItem::Phase reference)
{
    ASSERT(target != TimedItem::PhaseNone);
    ASSERT(reference != TimedItem::PhaseNone);
    return target > reference;
}

} // namespace

namespace WebCore {

// Returns the default timing function.
const PassRefPtr<TimingFunction> timingFromAnimationData(const CSSAnimationData* animationData, Timing& timing)
{
    if (animationData->isDelaySet())
        timing.startDelay = animationData->delay();
    if (animationData->isDurationSet()) {
        timing.iterationDuration = animationData->duration();
        timing.hasIterationDuration = true;
    }
    if (animationData->isIterationCountSet()) {
        if (animationData->iterationCount() == CSSAnimationData::IterationCountInfinite)
            timing.iterationCount = std::numeric_limits<double>::infinity();
        else
            timing.iterationCount = animationData->iterationCount();
    }
    if (animationData->isFillModeSet()) {
        switch (animationData->fillMode()) {
        case AnimationFillModeForwards:
            timing.fillMode = Timing::FillModeForwards;
            break;
        case AnimationFillModeBackwards:
            timing.fillMode = Timing::FillModeBackwards;
            break;
        case AnimationFillModeBoth:
            timing.fillMode = Timing::FillModeBoth;
            break;
        case AnimationFillModeNone:
            timing.fillMode = Timing::FillModeNone;
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    }
    if (animationData->isDirectionSet()) {
        switch (animationData->direction()) {
        case CSSAnimationData::AnimationDirectionNormal:
            timing.direction = Timing::PlaybackDirectionNormal;
            break;
        case CSSAnimationData::AnimationDirectionAlternate:
            timing.direction = Timing::PlaybackDirectionAlternate;
            break;
        case CSSAnimationData::AnimationDirectionReverse:
            timing.direction = Timing::PlaybackDirectionReverse;
            break;
        case CSSAnimationData::AnimationDirectionAlternateReverse:
            timing.direction = Timing::PlaybackDirectionAlternateReverse;
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    }
    return animationData->isTimingFunctionSet() ? animationData->timingFunction() : CSSAnimationData::initialAnimationTimingFunction();
}

CSSAnimationUpdateScope::CSSAnimationUpdateScope(Element* target)
    : m_target(target)
{
    if (!m_target)
        return;
    ActiveAnimations* activeAnimations = m_target->activeAnimations();
    CSSAnimations* cssAnimations = activeAnimations ? activeAnimations->cssAnimations() : 0;
    // It's possible than an update was created outside an update scope. That's harmless
    // but we must clear it now to avoid applying it if an updated replacement is not
    // created in this scope.
    if (cssAnimations)
        cssAnimations->setPendingUpdate(nullptr);
}

CSSAnimationUpdateScope::~CSSAnimationUpdateScope()
{
    if (!m_target)
        return;
    ActiveAnimations* activeAnimations = m_target->activeAnimations();
    CSSAnimations* cssAnimations = activeAnimations ? activeAnimations->cssAnimations() : 0;
    if (cssAnimations)
        cssAnimations->maybeApplyPendingUpdate(m_target);
}

bool CSSAnimations::needsUpdate(const Element* element, const RenderStyle* style)
{
    ActiveAnimations* activeAnimations = element->activeAnimations();
    const CSSAnimationDataList* animations = style->animations();
    const CSSAnimations* cssAnimations = activeAnimations ? activeAnimations->cssAnimations() : 0;
    EDisplay display = style->display();
    return (display != NONE && animations && animations->size()) || (cssAnimations && !cssAnimations->isEmpty());
}

PassOwnPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(const Element* element, const RenderStyle* style, const CSSAnimations* cssAnimations, const CSSAnimationDataList* animationDataList, StyleResolver* resolver)
{
    OwnPtr<CSSAnimationUpdate> update;
    HashSet<AtomicString> inactive;
    if (cssAnimations)
        for (AnimationMap::const_iterator iter = cssAnimations->m_animations.begin(); iter != cssAnimations->m_animations.end(); ++iter)
            inactive.add(iter->key);

    if (style->display() != NONE) {
        for (size_t i = 0; animationDataList && i < animationDataList->size(); ++i) {
            const CSSAnimationData* animationData = animationDataList->animation(i);
            if (animationData->isNoneAnimation())
                continue;
            ASSERT(animationData->isValidAnimation());
            AtomicString animationName(animationData->name());

            if (cssAnimations) {
                AnimationMap::const_iterator existing(cssAnimations->m_animations.find(animationName));
                if (existing != cssAnimations->m_animations.end()) {
                    // FIXME: The play-state of this animation might have changed, record the change in the update.
                    inactive.remove(animationName);
                    continue;
                }
            }

            Timing timing;
            RefPtr<TimingFunction> defaultTimingFunction = timingFromAnimationData(animationData, timing);
            KeyframeAnimationEffect::KeyframeVector keyframes;
            resolver->resolveKeyframes(element, style, animationName, defaultTimingFunction.get(), keyframes, timing.timingFunction);
            if (!keyframes.isEmpty()) {
                if (!update)
                    update = adoptPtr(new CSSAnimationUpdate());
                // FIXME: crbug.com/268791 - Keyframes are already normalized, perhaps there should be a flag on KeyframeAnimationEffect to skip normalization.
                update->startAnimation(animationName, InertAnimation::create(KeyframeAnimationEffect::create(keyframes), timing).get());
            }
        }
    }

    if (!inactive.isEmpty() && !update)
        update = adoptPtr(new CSSAnimationUpdate());
    for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter != inactive.end(); ++iter)
        update->cancelAnimation(*iter, cssAnimations->m_animations.get(*iter));

    return update.release();
}

void CSSAnimations::maybeApplyPendingUpdate(Element* element)
{
    if (!element->renderer())
        m_pendingUpdate = nullptr;

    if (!m_pendingUpdate)
        return;

    OwnPtr<CSSAnimationUpdate> update = m_pendingUpdate.release();

    for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationNames().begin(); iter != update->cancelledAnimationNames().end(); ++iter)
        m_animations.take(*iter)->cancel();

    // FIXME: Apply updates to play-state.

    for (Vector<CSSAnimationUpdate::NewAnimation>::const_iterator iter = update->newAnimations().begin(); iter != update->newAnimations().end(); ++iter) {
        OwnPtr<CSSAnimations::EventDelegate> eventDelegate = adoptPtr(new EventDelegate(element, iter->name));
        RefPtr<Animation> animation = Animation::create(element, iter->animation->effect(), iter->animation->specified(), eventDelegate.release());
        RefPtr<Player> player = element->document().timeline()->play(animation.get());
        m_animations.set(iter->name, player.get());
    }
}

void CSSAnimations::cancel()
{
    for (AnimationMap::iterator iter = m_animations.begin(); iter != m_animations.end(); ++iter)
        iter->value->cancel();

    m_animations.clear();
    m_pendingUpdate = nullptr;
}

void CSSAnimations::EventDelegate::maybeDispatch(Document::ListenerType listenerType, AtomicString& eventName, double elapsedTime)
{
    if (m_target->document().hasListenerType(listenerType))
        m_target->document().timeline()->addEventToDispatch(m_target, WebKitAnimationEvent::create(eventName, m_name, elapsedTime));
}

void CSSAnimations::EventDelegate::onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration)
{
    // Events for a single document are queued and dispatched as a group at
    // the end of DocumentTimeline::serviceAnimations.
    // FIXME: Events which are queued outside of serviceAnimations should
    // trigger a timer to dispatch when control is released.
    const TimedItem::Phase currentPhase = timedItem->phase();
    const double currentIteration = timedItem->currentIteration();

    // Note that the elapsedTime is measured from when the animation starts playing.
    if (!isFirstSample && previousPhase == TimedItem::PhaseActive && currentPhase == TimedItem::PhaseActive && previousIteration != currentIteration) {
        ASSERT(!isNull(previousIteration));
        ASSERT(!isNull(currentIteration));
        // We fire only a single event for all iterations thast terminate
        // between a single pair of samples. See http://crbug.com/275263. For
        // compatibility with the existing implementation, this event uses
        // the elapsedTime for the first iteration in question.
        ASSERT(timedItem->specified().hasIterationDuration);
        const double elapsedTime = timedItem->specified().iterationDuration * (previousIteration + 1);
        maybeDispatch(Document::ANIMATIONITERATION_LISTENER, eventNames().animationiterationEvent, elapsedTime);
        return;
    }
    if ((isFirstSample || previousPhase == TimedItem::PhaseBefore) && isLaterPhase(currentPhase, TimedItem::PhaseBefore)) {
        ASSERT(timedItem->specified().startDelay > 0 || isFirstSample);
        // The spec states that the elapsed time should be
        // 'delay < 0 ? -delay : 0', but we always use 0 to match the existing
        // implementation. See crbug.com/279611
        maybeDispatch(Document::ANIMATIONSTART_LISTENER, eventNames().animationstartEvent, 0);
    }
    if ((isFirstSample || isEarlierPhase(previousPhase, TimedItem::PhaseAfter)) && currentPhase == TimedItem::PhaseAfter)
        maybeDispatch(Document::ANIMATIONEND_LISTENER, eventNames().animationendEvent, timedItem->activeDuration());
}

bool CSSAnimations::isAnimatableProperty(CSSPropertyID property)
{
    switch (property) {
    case CSSPropertyBackgroundColor:
    case CSSPropertyBackgroundImage:
    case CSSPropertyBackgroundPositionX:
    case CSSPropertyBackgroundPositionY:
    case CSSPropertyBackgroundSize:
    case CSSPropertyBaselineShift:
    case CSSPropertyBorderBottomColor:
    case CSSPropertyBorderBottomLeftRadius:
    case CSSPropertyBorderBottomRightRadius:
    case CSSPropertyBorderBottomWidth:
    case CSSPropertyBorderImageOutset:
    case CSSPropertyBorderImageSlice:
    case CSSPropertyBorderImageSource:
    case CSSPropertyBorderImageWidth:
    case CSSPropertyBorderLeftColor:
    case CSSPropertyBorderLeftWidth:
    case CSSPropertyBorderRightColor:
    case CSSPropertyBorderRightWidth:
    case CSSPropertyBorderTopColor:
    case CSSPropertyBorderTopLeftRadius:
    case CSSPropertyBorderTopRightRadius:
    case CSSPropertyBorderTopWidth:
    case CSSPropertyBottom:
    case CSSPropertyBoxShadow:
    case CSSPropertyClip:
    case CSSPropertyColor:
    case CSSPropertyFill:
    case CSSPropertyFillOpacity:
    case CSSPropertyFlex:
    case CSSPropertyFloodColor:
    case CSSPropertyFloodOpacity:
    case CSSPropertyFontSize:
    case CSSPropertyHeight:
    case CSSPropertyKerning:
    case CSSPropertyLeft:
    case CSSPropertyLetterSpacing:
    case CSSPropertyLightingColor:
    case CSSPropertyLineHeight:
    case CSSPropertyListStyleImage:
    case CSSPropertyMarginBottom:
    case CSSPropertyMarginLeft:
    case CSSPropertyMarginRight:
    case CSSPropertyMarginTop:
    case CSSPropertyMaxHeight:
    case CSSPropertyMaxWidth:
    case CSSPropertyMinHeight:
    case CSSPropertyMinWidth:
    case CSSPropertyObjectPosition:
    case CSSPropertyOpacity:
    case CSSPropertyOrphans:
    case CSSPropertyOutlineColor:
    case CSSPropertyOutlineOffset:
    case CSSPropertyOutlineWidth:
    case CSSPropertyPaddingBottom:
    case CSSPropertyPaddingLeft:
    case CSSPropertyPaddingRight:
    case CSSPropertyPaddingTop:
    case CSSPropertyRight:
    case CSSPropertyStopColor:
    case CSSPropertyStopOpacity:
    case CSSPropertyStroke:
    case CSSPropertyStrokeDasharray:
    case CSSPropertyStrokeDashoffset:
    case CSSPropertyStrokeMiterlimit:
    case CSSPropertyStrokeOpacity:
    case CSSPropertyStrokeWidth:
    case CSSPropertyTextIndent:
    case CSSPropertyTextShadow:
    case CSSPropertyTop:
    case CSSPropertyVisibility:
    case CSSPropertyWebkitBackgroundSize:
    case CSSPropertyWebkitBorderHorizontalSpacing:
    case CSSPropertyWebkitBorderVerticalSpacing:
    case CSSPropertyWebkitBoxShadow:
    case CSSPropertyWebkitClipPath:
    case CSSPropertyWebkitColumnCount:
    case CSSPropertyWebkitColumnGap:
    case CSSPropertyWebkitColumnRuleColor:
    case CSSPropertyWebkitColumnRuleWidth:
    case CSSPropertyWebkitColumnWidth:
    case CSSPropertyWebkitFilter:
    case CSSPropertyWebkitMaskBoxImage:
    case CSSPropertyWebkitMaskBoxImageSource:
    case CSSPropertyWebkitMaskImage:
    case CSSPropertyWebkitMaskPositionX:
    case CSSPropertyWebkitMaskPositionY:
    case CSSPropertyWebkitMaskSize:
    case CSSPropertyWebkitPerspective:
    case CSSPropertyWebkitPerspectiveOriginX:
    case CSSPropertyWebkitPerspectiveOriginY:
    case CSSPropertyWebkitShapeInside:
    case CSSPropertyWebkitTextFillColor:
    case CSSPropertyWebkitTextStrokeColor:
    case CSSPropertyWebkitTransform:
    case CSSPropertyWebkitTransformOriginX:
    case CSSPropertyWebkitTransformOriginY:
    case CSSPropertyWebkitTransformOriginZ:
    case CSSPropertyWidows:
    case CSSPropertyWidth:
    case CSSPropertyWordSpacing:
    case CSSPropertyZIndex:
    case CSSPropertyZoom:
        return true;
    default:
        return false;
    }
}

} // namespace WebCore
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_I18NISOLANG_MSLANGID_HXX
#define INCLUDED_I18NISOLANG_MSLANGID_HXX

#include <sal/config.h>

#include "i18npool/i18npooldllapi.h"
#include "i18npool/lang.h"
#include <com/sun/star/lang/Locale.hpp>

/** Methods related to Microsoft language IDs. For details about MS-LANGIDs
    please see lang.h */
class I18NISOLANG_DLLPUBLIC MsLangId
{
public:

    /// Create a LangID from a primary and a sublanguage.
    static inline LanguageType makeLangID( LanguageType nSubLangId, LanguageType nPriLangId)
    {
        return (nSubLangId << 10) | nPriLangId;
    }

    /// Get the primary language of a LangID.
    static inline LanguageType getPrimaryLanguage( LanguageType nLangID)
    {
        return nLangID & LANGUAGE_MASK_PRIMARY;
    }

    /// Get the sublanguage of a LangID.
    static inline LanguageType getSubLanguage( LanguageType nLangID)
    {
        return (nLangID & ~LANGUAGE_MASK_PRIMARY) >> 10;
    }

    /** Language/locale of category LC_CTYPE (on Unix, else the system
        language).
        Evaluation order: LC_ALL, LC_CTYPE, LANG */
    static LanguageType getSystemLanguage();

    /** Language/locale of category LC_MESSAGES (on Unix, else same as
        GetSystemLanguage()).
        Evaluation order: LANGUAGE, LC_ALL, LC_MESSAGES, LANG */
    static LanguageType getSystemUILanguage();

    /** @short: A proper language/locale if the nLang parameter designates some
                special value.

        @descr: NOTE: The "system" values may be overridden by the
                application's configuration.

        @returns
            case LANGUAGE_PROCESS_OR_USER_DEFAULT : configured or system language
            case LANGUAGE_SYSTEM_DEFAULT :          configured or system language
            case LANGUAGE_SYSTEM :                  configured or system language
            case LANGUAGE_NONE :                    configured or system UI language
            case LANGUAGE_DONTKNOW :                LANGUAGE_ENGLISH_US
            else: nLang

            In case the configured language is LANGUAGE_SYSTEM, which is also
            the initial default, the system language is obtained. In case the
            configured or resulting system language is LANGUAGE_DONTKNOW,
            LANGUAGE_ENGLISH_US is returned instead.
      */
    static LanguageType getRealLanguage( LanguageType nLang );

    /** @short: Convert a LanguageType to a Locale, resolving LANGUAGE_SYSTEM.

        @ATTENTION: A round trip convertLanguageToLocale(
                convertLocaleToLanguage( ...)) is NOT possible because this
                method substitutes LANGUAGE_SYSTEM and the like. If round-trip
                is desired, you MUST use convertLanguageToLocale( ..., false)
                instead.
     */
    static void convertLanguageToLocale( LanguageType nLang,
            ::com::sun::star::lang::Locale & rLocale );

    /** @short: Convert a LanguageType to a Locale with handling of
                getRealLanguage().

        @descr: If bResolveSystem==true don't use to convert a Language to a
                Locale for file storage because it substitutes LANGUAGE_SYSTEM
                and LANGUAGE_NONE and similar, use only at runtime! If
                bResolveSystem==false a LANGUAGE_SYSTEM results in an empty
                Locale.

        @ATTENTION: A round trip convertLanguageToLocale(
                convertLocaleToLanguage( ...)) using the default parameter is
                NOT possible because this method
                substitutes LANGUAGE_SYSTEM and the like. If round-trip is
                desired, you MUST use convertLanguageToLocale( ..., false)
                instead.
      */
    static ::com::sun::star::lang::Locale convertLanguageToLocale(
            LanguageType nLang, bool bResolveSystem = true );

    /** Convert a Locale to a LanguageType with handling of an empty language
        name designating the SYSTEM language.
      */
    static LanguageType convertLocaleToLanguage( const ::com::sun::star::lang::Locale & rLocale );

    /** Convert a LanguageType to a Locale, resolving LANGUAGE_SYSTEM, falling
        back to a default locale if no exact match was found.
     */
    static ::com::sun::star::lang::Locale convertLanguageToLocaleWithFallback( LanguageType nLang );

    /** Convert a Locale to a LanguageType with handling of an empty language
        name designating the SYSTEM language, falling back to a default locale
        if no exact match was found.
      */
    static LanguageType convertLocaleToLanguageWithFallback(
            const ::com::sun::star::lang::Locale & rLocale );

    /** Get fall-back Locale for Locale with handling of an empty language name
        designating the SYSTEM language. Returns the same Locale if an exact
        match was found.
      */
    static ::com::sun::star::lang::Locale getFallbackLocale(
            const ::com::sun::star::lang::Locale & rLocale );

    // -----------------------------
    // - ConvertLanguageToIsoNames -
    // -----------------------------

    static void convertLanguageToIsoNames( LanguageType nLang,
            rtl::OUString& rLangStr, rtl::OUString& rCountry );
    static void convertLanguageToIsoNames( LanguageType nLang,
            rtl::OString& rLangStr, rtl::OString& rCountry );
    static rtl::OUString convertLanguageToIsoString( LanguageType nLang,
            sal_Unicode cSep = '-' );
    static rtl::OString convertLanguageToIsoByteString( LanguageType nLang,
            sal_Char cSep = '-' );

    // -----------------------------
    // - ConvertIsoNamesToLanguage -
    // -----------------------------

    static LanguageType convertIsoNamesToLanguage( const rtl::OUString& rLang,
            const rtl::OUString& rCountry );
    static LanguageType convertIsoNamesToLanguage( const rtl::OString& rLang,
            const rtl::OString& rCountry );
    static LanguageType convertIsoStringToLanguage(
            const rtl::OUString& rString, sal_Unicode cSep = '-' );
    static LanguageType convertUnxByteStringToLanguage(
            const rtl::OString& rString );

    static LanguageType resolveSystemLanguageByScriptType( LanguageType nLang, sal_Int16 nType );

    /** Whether locale has a Right-To-Left orientation. */
    static bool isRightToLeft( LanguageType nLang );

    /** Whether locale is a CJK locale */
    static bool isCJK( LanguageType nLang );

    /** Whether locale is a chinese locale */
    static bool isChinese( LanguageType nLang );

    /** Whether locale is a simplified chinese locale */
    static bool isSimplifiedChinese( LanguageType nLang );

    /** Whether locale is a traditional chinese locale */
    static bool isTraditionalChinese( LanguageType nLang );

    /** Whether locale is a korean locale */
    static bool isKorean( LanguageType nLang );

    /** Whether locale is a simplified chinese locale */
    static bool isSimplifiedChinese( const ::com::sun::star::lang::Locale & rLocale );

    /** Whether locale is a traditional chinese locale */
    static bool isTraditionalChinese( const ::com::sun::star::lang::Locale & rLocale );

    /** Whether locale is one where family name comes first, e.g. Japan, Hungary, Samoa */
    static bool isFamilyNameFirst( LanguageType nLang );

    /** Whether there are "forbidden characters at start or end of line" in
        this locale. CJK locales.

        @see offapi/com/sun/star/i18n/ForbiddenCharacters.idl
      */
    static bool hasForbiddenCharacters( LanguageType nLang );

    /** Whether locale needs input sequence checking. CTL locales. */
    static bool needsSequenceChecking( LanguageType nLang );

    /** Get ::com::sun::star::i18n::ScriptType of locale. */
    static sal_Int16 getScriptType( LanguageType nLang );

    /** Map an obsolete user defined LANGID (see lang.h
        LANGUAGE_OBSOLETE_USER_...) to the new value defined by MS in the
        meantime.

        Also used to map UI localizations using reserved ISO codes to something
        "official" but not identical in order to not pollute documents with
        invalid ISO codes.

        @param bUserInterfaceSelection
            If TRUE, don't replace such UI-only locale. Only use for
                     Tools->Options->LanguageSettings->UserInterface listbox.
            If FALSE, do replace.
     */
    static LanguageType getReplacementForObsoleteLanguage( LanguageType nLang,
            bool bUserInterfaceSelection = false );

    /** @ATTENTION: these are _ONLY_ to be called by the application's
        configuration! */
    static void setConfiguredSystemLanguage( LanguageType nLang );
    static void setConfiguredSystemUILanguage( LanguageType nLang );
    static void setConfiguredWesternFallback( LanguageType nLang );
    static void setConfiguredComplexFallback( LanguageType nLang );
    static void setConfiguredAsianFallback( LanguageType nLang );

// ---------------------------------------------------------------------------

    /** @internal - Access to fields of an element of the simple conversion table.
        For resource compiler build environment usage only! */
    struct IsoLangEntry
    {
        LanguageType  mnLang;
        sal_Char      maLangStr[4];
        sal_Char      maCountry[3];
    };

    /** @internal - Return a pointer to the IsoLangEntry of the underlying table,
        matching the offset passed by nIndex. Only meaningful for the resource
        compiler to build a list of known languages.

        @returns address of IsoLangEntry, or NULL pointer if nIndex exceeds the
        table elements' count.
     */
    static const IsoLangEntry* getIsoLangEntry( size_t nIndex );

// ---------------------------------------------------------------------------

private:

    static LanguageType         nConfiguredSystemLanguage;
    static LanguageType         nConfiguredSystemUILanguage;

    static LanguageType         nConfiguredWesternFallback;
    static LanguageType         nConfiguredAsianFallback;
    static LanguageType         nConfiguredComplexFallback;

    static LanguageType getPlatformSystemLanguage();
    static LanguageType getPlatformSystemUILanguage();

    // Substitute LANGUAGE_SYSTEM for LANGUAGE_SYSTEM_DEFAULT and
    // LANGUAGE_PROCESS_OR_USER_DEFAULT, other values aren't touched.
    I18NISOLANG_DLLPRIVATE static inline LanguageType simplifySystemLanguages( LanguageType nLang );

    // Several locale lookups with fall-back
    I18NISOLANG_DLLPRIVATE static LanguageType lookupFallbackLanguage( LanguageType nLang );
    I18NISOLANG_DLLPRIVATE static LanguageType lookupFallbackLanguage(
            const ::com::sun::star::lang::Locale & rLocale );
    I18NISOLANG_DLLPRIVATE static ::com::sun::star::lang::Locale lookupFallbackLocale( LanguageType nLang );
    I18NISOLANG_DLLPRIVATE static ::com::sun::star::lang::Locale lookupFallbackLocale(
            const ::com::sun::star::lang::Locale & rLocale );
};

// static
inline LanguageType MsLangId::getSystemLanguage()
{
    return getPlatformSystemLanguage();
}

// static
inline LanguageType MsLangId::getSystemUILanguage()
{
    return getPlatformSystemUILanguage();
}

#endif // INCLUDED_I18NISOLANG_MSLANGID_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>LanguageTag conversion helper define<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_I18NISOLANG_MSLANGID_HXX
#define INCLUDED_I18NISOLANG_MSLANGID_HXX

#include <sal/config.h>

#include "i18npool/i18npooldllapi.h"
#include "i18npool/lang.h"
#include <com/sun/star/lang/Locale.hpp>

// 0 := normal usage
// 1 := force LanguageTag and make all conversion functions private to make the
// compiler bail out
#define I18NPOOL_FORCE_LANGUAGETAG 0

/** Methods related to Microsoft language IDs. For details about MS-LANGIDs
    please see lang.h */
class I18NISOLANG_DLLPUBLIC MsLangId
{

#if I18NPOOL_FORCE_LANGUAGETAG
    friend class LanguageTag;
#endif

public:

    /// Create a LangID from a primary and a sublanguage.
    static inline LanguageType makeLangID( LanguageType nSubLangId, LanguageType nPriLangId)
    {
        return (nSubLangId << 10) | nPriLangId;
    }

    /// Get the primary language of a LangID.
    static inline LanguageType getPrimaryLanguage( LanguageType nLangID)
    {
        return nLangID & LANGUAGE_MASK_PRIMARY;
    }

    /// Get the sublanguage of a LangID.
    static inline LanguageType getSubLanguage( LanguageType nLangID)
    {
        return (nLangID & ~LANGUAGE_MASK_PRIMARY) >> 10;
    }

    /** Language/locale of category LC_CTYPE (on Unix, else the system
        language).
        Evaluation order: LC_ALL, LC_CTYPE, LANG */
    static LanguageType getSystemLanguage();

    /** Language/locale of category LC_MESSAGES (on Unix, else same as
        GetSystemLanguage()).
        Evaluation order: LANGUAGE, LC_ALL, LC_MESSAGES, LANG */
    static LanguageType getSystemUILanguage();

    /** @short: A proper language/locale if the nLang parameter designates some
                special value.

        @descr: NOTE: The "system" values may be overridden by the
                application's configuration.

        @returns
            case LANGUAGE_PROCESS_OR_USER_DEFAULT : configured or system language
            case LANGUAGE_SYSTEM_DEFAULT :          configured or system language
            case LANGUAGE_SYSTEM :                  configured or system language
            case LANGUAGE_NONE :                    configured or system UI language
            case LANGUAGE_DONTKNOW :                LANGUAGE_ENGLISH_US
            else: nLang

            In case the configured language is LANGUAGE_SYSTEM, which is also
            the initial default, the system language is obtained. In case the
            configured or resulting system language is LANGUAGE_DONTKNOW,
            LANGUAGE_ENGLISH_US is returned instead.
      */
    static LanguageType getRealLanguage( LanguageType nLang );

#if I18NPOOL_FORCE_LANGUAGETAG
private:
#endif

    /** @short: Convert a LanguageType to a Locale, resolving LANGUAGE_SYSTEM.

        @ATTENTION: A round trip convertLanguageToLocale(
                convertLocaleToLanguage( ...)) is NOT possible because this
                method substitutes LANGUAGE_SYSTEM and the like. If round-trip
                is desired, you MUST use convertLanguageToLocale( ..., false)
                instead.
     */
    static void convertLanguageToLocale( LanguageType nLang,
            ::com::sun::star::lang::Locale & rLocale );

    /** @short: Convert a LanguageType to a Locale with handling of
                getRealLanguage().

        @descr: If bResolveSystem==true don't use to convert a Language to a
                Locale for file storage because it substitutes LANGUAGE_SYSTEM
                and LANGUAGE_NONE and similar, use only at runtime! If
                bResolveSystem==false a LANGUAGE_SYSTEM results in an empty
                Locale.

        @ATTENTION: A round trip convertLanguageToLocale(
                convertLocaleToLanguage( ...)) using the default parameter is
                NOT possible because this method
                substitutes LANGUAGE_SYSTEM and the like. If round-trip is
                desired, you MUST use convertLanguageToLocale( ..., false)
                instead.
      */
    static ::com::sun::star::lang::Locale convertLanguageToLocale(
            LanguageType nLang, bool bResolveSystem = true );

    /** Convert a Locale to a LanguageType with handling of an empty language
        name designating the SYSTEM language.
      */
    static LanguageType convertLocaleToLanguage( const ::com::sun::star::lang::Locale & rLocale );

    /** Convert a LanguageType to a Locale, resolving LANGUAGE_SYSTEM, falling
        back to a default locale if no exact match was found.
     */
    static ::com::sun::star::lang::Locale convertLanguageToLocaleWithFallback( LanguageType nLang );

    /** Convert a Locale to a LanguageType with handling of an empty language
        name designating the SYSTEM language, falling back to a default locale
        if no exact match was found.
      */
    static LanguageType convertLocaleToLanguageWithFallback(
            const ::com::sun::star::lang::Locale & rLocale );

#if I18NPOOL_FORCE_LANGUAGETAG
public:
#endif
    // TODO: refactor to LanguageTag? Used only in
    // i18npool/source/localedata/localedata.cxx

    /** Get fall-back Locale for Locale with handling of an empty language name
        designating the SYSTEM language. Returns the same Locale if an exact
        match was found.
      */
    static ::com::sun::star::lang::Locale getFallbackLocale(
            const ::com::sun::star::lang::Locale & rLocale );

#if I18NPOOL_FORCE_LANGUAGETAG
private:
#endif

    // -----------------------------
    // - ConvertLanguageToIsoNames -
    // -----------------------------

    static void convertLanguageToIsoNames( LanguageType nLang,
            rtl::OUString& rLangStr, rtl::OUString& rCountry );
    static void convertLanguageToIsoNames( LanguageType nLang,
            rtl::OString& rLangStr, rtl::OString& rCountry );
    static rtl::OUString convertLanguageToIsoString( LanguageType nLang,
            sal_Unicode cSep = '-' );
    static rtl::OString convertLanguageToIsoByteString( LanguageType nLang,
            sal_Char cSep = '-' );

    // -----------------------------
    // - ConvertIsoNamesToLanguage -
    // -----------------------------

    static LanguageType convertIsoNamesToLanguage( const rtl::OUString& rLang,
            const rtl::OUString& rCountry );
    static LanguageType convertIsoNamesToLanguage( const rtl::OString& rLang,
            const rtl::OString& rCountry );
    static LanguageType convertIsoStringToLanguage(
            const rtl::OUString& rString, sal_Unicode cSep = '-' );

#if I18NPOOL_FORCE_LANGUAGETAG
public:
#endif
    // TODO: refactor to LanguageTag, used only in
    // i18npool/source/isolang/inunx.cxx to convert Unix locale string

    static LanguageType convertUnxByteStringToLanguage( const rtl::OString& rString );

#if I18NPOOL_FORCE_LANGUAGETAG
private:
#endif

#if I18NPOOL_FORCE_LANGUAGETAG
public:
#endif

    static LanguageType resolveSystemLanguageByScriptType( LanguageType nLang, sal_Int16 nType );

    /** Whether locale has a Right-To-Left orientation. */
    static bool isRightToLeft( LanguageType nLang );

    /** Whether locale is a CJK locale */
    static bool isCJK( LanguageType nLang );

    /** Whether locale is a chinese locale */
    static bool isChinese( LanguageType nLang );

    /** Whether locale is a simplified chinese locale */
    static bool isSimplifiedChinese( LanguageType nLang );

    /** Whether locale is a traditional chinese locale */
    static bool isTraditionalChinese( LanguageType nLang );

    /** Whether locale is a korean locale */
    static bool isKorean( LanguageType nLang );

    /** Whether locale is a simplified chinese locale */
    static bool isSimplifiedChinese( const ::com::sun::star::lang::Locale & rLocale );

    /** Whether locale is a traditional chinese locale */
    static bool isTraditionalChinese( const ::com::sun::star::lang::Locale & rLocale );

    /** Whether locale is one where family name comes first, e.g. Japan, Hungary, Samoa */
    static bool isFamilyNameFirst( LanguageType nLang );

    /** Whether there are "forbidden characters at start or end of line" in
        this locale. CJK locales.

        @see offapi/com/sun/star/i18n/ForbiddenCharacters.idl
      */
    static bool hasForbiddenCharacters( LanguageType nLang );

    /** Whether locale needs input sequence checking. CTL locales. */
    static bool needsSequenceChecking( LanguageType nLang );

    /** Get ::com::sun::star::i18n::ScriptType of locale. */
    static sal_Int16 getScriptType( LanguageType nLang );

    /** Map an obsolete user defined LANGID (see lang.h
        LANGUAGE_OBSOLETE_USER_...) to the new value defined by MS in the
        meantime.

        Also used to map UI localizations using reserved ISO codes to something
        "official" but not identical in order to not pollute documents with
        invalid ISO codes.

        @param bUserInterfaceSelection
            If TRUE, don't replace such UI-only locale. Only use for
                     Tools->Options->LanguageSettings->UserInterface listbox.
            If FALSE, do replace.
     */
    static LanguageType getReplacementForObsoleteLanguage( LanguageType nLang,
            bool bUserInterfaceSelection = false );

    /** @ATTENTION: these are _ONLY_ to be called by the application's
        configuration! */
    static void setConfiguredSystemLanguage( LanguageType nLang );
    static void setConfiguredSystemUILanguage( LanguageType nLang );
    static void setConfiguredWesternFallback( LanguageType nLang );
    static void setConfiguredComplexFallback( LanguageType nLang );
    static void setConfiguredAsianFallback( LanguageType nLang );

// ---------------------------------------------------------------------------

    /** @internal - Access to fields of an element of the simple conversion table.
        For resource compiler build environment usage only! */
    struct IsoLangEntry
    {
        LanguageType  mnLang;
        sal_Char      maLangStr[4];
        sal_Char      maCountry[3];
    };

    /** @internal - Return a pointer to the IsoLangEntry of the underlying table,
        matching the offset passed by nIndex. Only meaningful for the resource
        compiler to build a list of known languages.

        @returns address of IsoLangEntry, or NULL pointer if nIndex exceeds the
        table elements' count.
     */
    static const IsoLangEntry* getIsoLangEntry( size_t nIndex );

// ---------------------------------------------------------------------------

private:

    static LanguageType         nConfiguredSystemLanguage;
    static LanguageType         nConfiguredSystemUILanguage;

    static LanguageType         nConfiguredWesternFallback;
    static LanguageType         nConfiguredAsianFallback;
    static LanguageType         nConfiguredComplexFallback;

    static LanguageType getPlatformSystemLanguage();
    static LanguageType getPlatformSystemUILanguage();

    // Substitute LANGUAGE_SYSTEM for LANGUAGE_SYSTEM_DEFAULT and
    // LANGUAGE_PROCESS_OR_USER_DEFAULT, other values aren't touched.
    I18NISOLANG_DLLPRIVATE static inline LanguageType simplifySystemLanguages( LanguageType nLang );

    // Several locale lookups with fall-back
    I18NISOLANG_DLLPRIVATE static LanguageType lookupFallbackLanguage( LanguageType nLang );
    I18NISOLANG_DLLPRIVATE static LanguageType lookupFallbackLanguage(
            const ::com::sun::star::lang::Locale & rLocale );
    I18NISOLANG_DLLPRIVATE static ::com::sun::star::lang::Locale lookupFallbackLocale( LanguageType nLang );
    I18NISOLANG_DLLPRIVATE static ::com::sun::star::lang::Locale lookupFallbackLocale(
            const ::com::sun::star::lang::Locale & rLocale );
};

// static
inline LanguageType MsLangId::getSystemLanguage()
{
    return getPlatformSystemLanguage();
}

// static
inline LanguageType MsLangId::getSystemUILanguage()
{
    return getPlatformSystemUILanguage();
}

#endif // INCLUDED_I18NISOLANG_MSLANGID_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*** Copyright (c), The Regents of the University of California            ***
 *** For more information please refer to files in the COPYRIGHT directory ***/
/* fileOpen.h - This file may be generated by a program or script
 */

#ifndef FILE_OPEN_HPP
#define FILE_OPEN_HPP

/* This is a low level file type API call */

#include "rods.hpp"
#include "rcMisc.hpp"
#include "procApiRequest.hpp"
#include "apiNumber.hpp"
#include "initServer.hpp"

/* definition for otherFlags */

#define NO_CHK_PERM_FLAG                0x1 // JMC - backport 4758
#define UNIQUE_REM_COMM_FLAG    0x2
#define FORCE_FLAG                      0x4

typedef struct {

    char resc_name_[MAX_NAME_LEN];
    char resc_hier_[MAX_NAME_LEN];
    char objPath[MAX_NAME_LEN];

    int otherFlags;     /* for chkPerm, uniqueRemoteConn */
    rodsHostAddr_t addr;
    char fileName[MAX_NAME_LEN];
    int flags;
    int mode;
    keyValPair_t condInput;
    char in_pdmo[MAX_NAME_LEN];
    rodsLong_t dataSize;
} fileOpenInp_t;

#define fileOpenInp_PI "str resc_name_[MAX_NAME_LEN]; str resc_hier_[MAX_NAME_LEN]; str objPath[MAX_NAME_LEN]; int otherFlags; struct RHostAddr_PI; str fileName[MAX_NAME_LEN]; int flags; int mode; struct KeyValPair_PI; str in_pdmo[MAX_NAME_LEN]; double dataSize;"

#if defined(RODS_SERVER)
#define RS_FILE_OPEN rsFileOpen
/* prototype for the server handler */
int
rsFileOpen( rsComm_t *rsComm, fileOpenInp_t *fileOpenInp );
int
rsFileOpenByHost( rsComm_t *rsComm, fileOpenInp_t *fileOpenInp,
                  rodsServerHost_t *rodsServerHost );
int
_rsFileOpen( rsComm_t *rsComm, fileOpenInp_t *fileOpenInp );
int
remoteFileOpen( rsComm_t *rsComm, fileOpenInp_t *fileOpenInp,
                rodsServerHost_t *rodsServerHost );
#else
#define RS_FILE_OPEN NULL
#endif

/* prototype for the client call */
#ifdef __cplusplus
extern "C" {
#endif
    int
    rcFileOpen( rcComm_t *conn, fileOpenInp_t *fileOpenInp );
#ifdef __cplusplus
}
#endif

#endif  /* FILE_OPEN_H */
<commit_msg>[#2248] [#858] a comment for safety - and astyle<commit_after>/*** Copyright (c), The Regents of the University of California            ***
 *** For more information please refer to files in the COPYRIGHT directory ***/
/* fileOpen.h - This file may be generated by a program or script
 */

#ifndef FILE_OPEN_HPP
#define FILE_OPEN_HPP

/* This is a low level file type API call */

#include "rods.hpp"
#include "rcMisc.hpp"
#include "procApiRequest.hpp"
#include "apiNumber.hpp"
#include "initServer.hpp"

/* definition for otherFlags */

#define NO_CHK_PERM_FLAG                0x1 // JMC - backport 4758
#define UNIQUE_REM_COMM_FLAG    0x2
#define FORCE_FLAG                      0x4

typedef struct {

    char resc_name_[MAX_NAME_LEN];
    char resc_hier_[MAX_NAME_LEN];
    char objPath[MAX_NAME_LEN];

    int otherFlags;     /* for chkPerm, uniqueRemoteConn */
    rodsHostAddr_t addr;
    char fileName[MAX_NAME_LEN];
    int flags;
    int mode;
    keyValPair_t condInput;
    char in_pdmo[MAX_NAME_LEN];
    rodsLong_t dataSize; /* must be on the end because packing instructions do not handle doubles correctly on MacOSX"
} fileOpenInp_t;

#define fileOpenInp_PI "str resc_name_[MAX_NAME_LEN]; str resc_hier_[MAX_NAME_LEN]; str objPath[MAX_NAME_LEN]; int otherFlags; struct RHostAddr_PI; str fileName[MAX_NAME_LEN]; int flags; int mode; struct KeyValPair_PI; str in_pdmo[MAX_NAME_LEN]; double dataSize;"

#if defined(RODS_SERVER)
#define RS_FILE_OPEN rsFileOpen
/* prototype for the server handler */
    int
    rsFileOpen( rsComm_t *rsComm, fileOpenInp_t *fileOpenInp );
    int
    rsFileOpenByHost( rsComm_t *rsComm, fileOpenInp_t *fileOpenInp,
                      rodsServerHost_t *rodsServerHost );
    int
    _rsFileOpen( rsComm_t *rsComm, fileOpenInp_t *fileOpenInp );
    int
    remoteFileOpen( rsComm_t *rsComm, fileOpenInp_t *fileOpenInp,
                    rodsServerHost_t *rodsServerHost );
#else
#define RS_FILE_OPEN NULL
#endif

    /* prototype for the client call */
#ifdef __cplusplus
    extern "C" {
#endif
        int
        rcFileOpen( rcComm_t *conn, fileOpenInp_t *fileOpenInp );
#ifdef __cplusplus
    }
#endif

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


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>

#define SERVER_PORT 1018
#define MAX_MSG_SIZE 1024

int main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in addr;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1)
    {
	return 0;
    }
    bzero(&addr, sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(SERVER_PORT);
    if (bind(sockfd, (struct sockaddr *)(&addr), sizeof(struct sockaddr)) == -1)
    {
	return 0;
    }
    if (listen(sockfd, 5) == -1)
    {
	return 0;
    }
    while (true)
    {
	int acceptfd = accept(sockfd, NULL, NULL);
	if (acceptfd <0)
	{
	    continue;
	}

    }
    return 0;

}
<commit_msg>modify server<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>

#define SERVER_PORT 3230
#define LISTEN_LEN 100

bool SetNonBlock(int nSock)
{
    int nFlags = 0;
    int nTmp = 0;
    if ((nFlags = fcnt(nSock, F_GETFL, 0)) == -1)
    {
	return false;
    }
    nFlags |= O_NONBLOCK;
    if (fcntl(nSock, F_SETFL, nFlags) == -1)
    {
	return false;
    }
    return true;
}

int main(int argc, char *argv[])
{
    int nSock = 0;
    if ((nSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
	return 0;
    }
    struct sockaddr_in servAddr;
    bzero(&servAddr, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htnos(SERVER_PORT);
    servAddr.sin_addr.s_addr = htons(INADDR_ANY);
    if (bind(nSock, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
    {
	return 0;
    }
    if (!SetNonBlock(nSock))
    {
	return 0;
    }
    if (listen(nSock, LISTEN_LEN) < 0)
    {
	return 0;
    }
    int efd = 0;
    if ((efd = epoll_create1(0)) == -1)
    {
	return 0;
    }
    struct epoll_event event;
    struct epoll_event *events;
    return 0;

}
<|endoftext|>


<commit_before>#include "server.h"

SERVER::SERVER ()
{
        struct addrinfo hints, *servinfo, *p;
        int rv; // return value
        int yes = 1;

        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE; // use my IP

        if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
                exit(EXIT_FAILURE);
	}

	// loop through all the results and bind to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
			perror("server: socket");
			continue;
		}
		if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
			perror("setsockopt");
			exit(1);
		}
		if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(sockfd);
			perror("server: bind");
			continue;
		}
		break;
	}

        if (p == NULL)  {
		std::cerr << "server: failed to bind" << std::endl;
		exit (EXIT_FAILURE);
	}

	freeaddrinfo(servinfo); // all done with this structure

	if (listen(sockfd, BACKLOG) == -1) {
		perror("listen");
		exit(1);
	}
}

SERVER::~SERVER ()
{

}

bool SERVER::addMessage (MESAJ &m)
{
	listamesaje.push_back(m);
	return true;
}

bool SERVER::addClient (CLIENT &c)
{
	listaclienti.push_back(c);
	return true;
}

bool SERVER::removeClient (CLIENT &c)
{
        listaclienti.remove((const CLIENT &)c);
        return true;
}

std::string SERVER::decryptMSG (std::string &msg, CLIENT &sender)
{
	std::string m = crypto_box_open (msg, sender.getCI().getNonce(), sender.getCI().getPK(), cryptinfo.getSK());

	return m;
}

std::string SERVER::decryptMSG (std::string &msg, std::string &pk, std::string &nonce)
{
	std::string m = crypto_box_open (msg, nonce, pk, cryptinfo.getSK());

	return m;
}

std::string SERVER::encryptMSG (std::string &msg, CLIENT &receiver)
{
	std::string c = crypto_box(msg, cryptinfo.getNonce(), receiver.getCI().getPK(), cryptinfo.getSK());

	return c;
}

bool SERVER::sendMessage (std::string &msg, CLIENT &sender)
{
	//std::string m = decryptMSG (msg, sender);

	for(std::list<CLIENT>::iterator it = listaclienti.begin(); it != listaclienti.end(); it++){
		if(*it != sender){
			//std::string c = encryptMSG (m, *it);
                        //std::string cname = encryptMSG (sender.getNume(), *it);
                        //sendMsgToClient (cname, *it, false);
      			//sendMsgToClient (c, *it, true);
                        sendMsgToClient (sender.getNume(), *it, false);
                        sendMsgToClient (msg, *it, false);

		}
	}

	return true;
}

bool SERVER::sendMsgToClient (std::string &msg, CLIENT &receiver, bool sendendl)
{
        if(write(receiver.getSFD(), msg.c_str(), msg.size()) == -1){
                std::cerr << "write() error" << std::endl;
                exit (EXIT_FAILURE);
        }
        if(sendendl){
                if(write(receiver.getSFD(), "\n", 1) == -1){
                        std::cerr << "write() error" << std::endl;
                        exit (EXIT_FAILURE);
                }
        }
	return true;
}

bool SERVER::sendMessageList (CLIENT &receiver)
{
        for(std::list<MESAJ>::iterator it = listamesaje.begin(); it != listamesaje.end(); it++){
               //std::string cname = encryptMSG ((*it).getName(), receiver);
               //std::string enc_comment = encryptMSG ((*it).getComment(), receiver);
               //sendMsgToClient (cname, receiver, false);
               //sendMsgToClient (enc_comment, receiver, true);
               sendMsgToClient ((*it).getName(), receiver, false);
               sendMsgToClient ((*it).getComment(), receiver, false);
        }

        return true;
}

bool SERVER::verifyName (std::string &nume)
{
        for(std::list<CLIENT>::iterator it = listaclienti.begin(); it != listaclienti.end(); it++){
                if(!nume.compare((*it).getNume()))
                       return false;
        }
        return true;
}

void SERVER::mtxLock ()
{
        mtx.lock();
}

void SERVER::mtxUnlock ()
{
        mtx.unlock();
}

void SERVER::Play ()
{
        int sfd;
        socklen_t sin_size;
        struct sockaddr their_addr; // connector's address information

        while (true){
                sfd = accept(sockfd, &their_addr, &sin_size);
                if(sfd == -1){
                    	perror("accept");
			continue;
                }

                std::thread (client_Communication, this, sfd).detach();
        }
}

void exchangeCI (CLIENT &c)
{

}

// do all the communication with the clients in this thread function
void client_Communication (SERVER *server_p, int sockfd)
{
        char buffer[6];

        // create fictive client for testing, as we don't have the client program yet... using telnet as client
        CRYPTO client_CI;

        std::string numeclient = "client";
        snprintf (buffer, 6, "%d: ", sockfd);
        numeclient += buffer;

        CLIENT client(client_CI, sockfd, numeclient);

        server_p->mtxLock();
        server_p->addClient(client);
        server_p->sendMessageList(client);
        server_p->mtxUnlock();

        write(sockfd, "Welcome to HYPERION Chat Server\n", 32);

        while (1){
                char bufread[1024];
                memset (bufread, 0, 1024);
                if(!read(sockfd, bufread, 1024)){
                        server_p->removeClient(client);
                        close (sockfd);
                        return;
                }    // blocks until a message arrives

                std::string msg = bufread;

                //construct MESAJ object
                MESAJ mes(numeclient, msg);

                server_p->mtxLock();
                server_p->addMessage(mes);  // add message to message list
                server_p->sendMessage(msg, client); // send message to the other clients
                server_p->mtxUnlock();
        }
}<commit_msg>Another error corrected<commit_after>#include "server.h"

SERVER::SERVER ()
{
        struct addrinfo hints, *servinfo, *p;
        int rv; // return value
        int yes = 1;

        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE; // use my IP

        if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
                exit(EXIT_FAILURE);
	}

	// loop through all the results and bind to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
			perror("server: socket");
			continue;
		}
		if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
			perror("setsockopt");
			exit(1);
		}
		if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(sockfd);
			perror("server: bind");
			continue;
		}
		break;
	}

        if (p == NULL)  {
		std::cerr << "server: failed to bind" << std::endl;
		exit (EXIT_FAILURE);
	}

	freeaddrinfo(servinfo); // all done with this structure

	if (listen(sockfd, BACKLOG) == -1) {
		perror("listen");
		exit(1);
	}
}

SERVER::~SERVER ()
{

}

bool SERVER::addMessage (MESAJ &m)
{
	listamesaje.push_back(m);
	return true;
}

bool SERVER::addClient (CLIENT &c)
{
	listaclienti.push_back(c);
	return true;
}

bool SERVER::removeClient (CLIENT &c)
{
        listaclienti.remove((const CLIENT &)c);
        return true;
}

std::string SERVER::decryptMSG (std::string &msg, CLIENT &sender)
{
	std::string m = crypto_box_open (msg, sender.getCI().getNonce(), sender.getCI().getPK(), cryptinfo.getSK());

	return m;
}

std::string SERVER::decryptMSG (std::string &msg, std::string &pk, std::string &nonce)
{
	std::string m = crypto_box_open (msg, nonce, pk, cryptinfo.getSK());

	return m;
}

std::string SERVER::encryptMSG (std::string &msg, CLIENT &receiver)
{
	std::string c = crypto_box(msg, cryptinfo.getNonce(), receiver.getCI().getPK(), cryptinfo.getSK());

	return c;
}

bool SERVER::sendMessage (std::string &msg, CLIENT &sender)
{
	//std::string m = decryptMSG (msg, sender);

	for(std::list<CLIENT>::iterator it = listaclienti.begin(); it != listaclienti.end(); it++){
		if(*it != sender){
			//std::string c = encryptMSG (m, *it);
                        //std::string cname = encryptMSG (sender.getNume(), *it);
                        //sendMsgToClient (cname, *it, false);
      			//sendMsgToClient (c, *it, true);
                        sendMsgToClient (sender.getNume(), *it, false);
                        sendMsgToClient (msg, *it, false);

		}
	}

	return true;
}

bool SERVER::sendMsgToClient (std::string &msg, CLIENT &receiver, bool sendendl)
{
        if(write(receiver.getSFD(), msg.c_str(), msg.size()) == -1){
                std::cerr << "write() error" << std::endl;
                exit (EXIT_FAILURE);
        }
        if(sendendl){
                if(write(receiver.getSFD(), "\n", 1) == -1){
                        std::cerr << "write() error" << std::endl;
                        exit (EXIT_FAILURE);
                }
        }
	return true;
}

bool SERVER::sendMessageList (CLIENT &receiver)
{
        for(std::list<MESAJ>::iterator it = listamesaje.begin(); it != listamesaje.end(); it++){
               //std::string cname = encryptMSG ((*it).getName(), receiver);
               //std::string enc_comment = encryptMSG ((*it).getComment(), receiver);
               //sendMsgToClient (cname, receiver, false);
               //sendMsgToClient (enc_comment, receiver, true);
               sendMsgToClient ((*it).getName(), receiver, false);
               sendMsgToClient ((*it).getComment(), receiver, false);
        }

        return true;
}

bool SERVER::verifyName (std::string &nume)
{
        for(std::list<CLIENT>::iterator it = listaclienti.begin(); it != listaclienti.end(); it++){
                if(!nume.compare((*it).getNume()))
                       return false;
        }
        return true;
}

void SERVER::mtxLock ()
{
        mtx.lock();
}

void SERVER::mtxUnlock ()
{
        mtx.unlock();
}

void SERVER::Play ()
{
        int sfd;
        socklen_t sin_size;
        struct sockaddr their_addr; // connector's address information

        while (true){
                sfd = accept(sockfd, &their_addr, &sin_size);
                if(sfd == -1){
                    	perror("accept");
			continue;
                }

                std::thread (client_Communication, this, sfd).detach();
        }
}

void SERVER::exchangeCI (CLIENT &c)
{

}

// do all the communication with the clients in this thread function
void client_Communication (SERVER *server_p, int sockfd)
{
        char buffer[6];

        // create fictive client for testing, as we don't have the client program yet... using telnet as client
        CRYPTO client_CI;

        std::string numeclient = "client";
        snprintf (buffer, 6, "%d: ", sockfd);
        numeclient += buffer;

        CLIENT client(client_CI, sockfd, numeclient);

        server_p->mtxLock();
        server_p->addClient(client);
        server_p->sendMessageList(client);
        server_p->mtxUnlock();

        write(sockfd, "Welcome to HYPERION Chat Server\n", 32);

        while (1){
                char bufread[1024];
                memset (bufread, 0, 1024);
                if(!read(sockfd, bufread, 1024)){
                        server_p->removeClient(client);
                        close (sockfd);
                        return;
                }    // blocks until a message arrives

                std::string msg = bufread;

                //construct MESAJ object
                MESAJ mes(numeclient, msg);

                server_p->mtxLock();
                server_p->addMessage(mes);  // add message to message list
                server_p->sendMessage(msg, client); // send message to the other clients
                server_p->mtxUnlock();
        }
}<|endoftext|>