<commit_before>/***************************************************************************
    copyright            : (C) 2002 - 2008 by Scott Wheeler
    email                : wheeler@kde.org
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License version   *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
 *   02110-1301  USA                                                       *
 *                                                                         *
 *   Alternatively, this file is available under the Mozilla Public        *
 *   License Version 1.1.  You may obtain a copy of the License at         *
 *   http://www.mozilla.org/MPL/                                           *
 ***************************************************************************/

#include "tfilestream.h"
#include "tstring.h"
#include "tdebug.h"

#ifdef _WIN32
# include <windows.h>
#else
# include <stdio.h>
# include <unistd.h>
#endif

using namespace TagLib;

namespace
{
#ifdef _WIN32

  // Uses Win32 native API instead of POSIX API to reduce the resource consumption.

  typedef FileName FileNameHandle;
  typedef HANDLE FileHandle;

  const uint BufferSize = 8192;
  const FileHandle InvalidFileHandle = INVALID_HANDLE_VALUE;

  inline FileHandle openFile(const FileName &path, bool readOnly)
  {
    const DWORD access = readOnly ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE);

    if(!path.wstr().empty())
      return CreateFileW(path.wstr().c_str(), access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    else if(!path.str().empty())
      return CreateFileA(path.str().c_str(), access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    else
      return InvalidFileHandle;
  }

  inline void closeFile(FileHandle file)
  {
    CloseHandle(file);
  }

  inline size_t readFile(FileHandle file, ByteVector &buffer)
  {
    DWORD length;
    if(ReadFile(file, buffer.data(), static_cast<DWORD>(buffer.size()), &length, NULL))
      return static_cast<size_t>(length);
    else
      return 0;
  }

  inline size_t writeFile(FileHandle file, const ByteVector &buffer)
  {
    DWORD length;
    if(WriteFile(file, buffer.data(), static_cast<DWORD>(buffer.size()), &length, NULL))
      return static_cast<size_t>(length);
    else
      return 0;
  }

# ifndef NDEBUG

  // Convert a string in a local encoding into a UTF-16 string.

  // Debugging use only. In actual use, file names in local encodings are passed to
  // CreateFileA() without any conversions.

  String fileNameToString(const FileName &name)
  {
    if(!name.wstr().empty()) {
      return String(name.wstr());
    }
    else if(!name.str().empty()) {
      const int len = MultiByteToWideChar(CP_ACP, 0, name.str().c_str(), -1, NULL, 0);
      if(len == 0)
        return String::null;

      wstring wstr(len, L'\0');
      MultiByteToWideChar(CP_ACP, 0, name.str().c_str(), -1, &wstr[0], len);

      return String(wstr);
    }
    else {
      return String::null;
    }
  }

# endif

#else   // _WIN32

  struct FileNameHandle : public std::string
  {
    FileNameHandle(FileName name) : std::string(name) {}
    operator FileName () const { return c_str(); }
  };

  typedef FILE* FileHandle;

  const uint BufferSize = 8192;
  const FileHandle InvalidFileHandle = 0;

  inline FileHandle openFile(const FileName &path, bool readOnly)
  {
    return fopen(path, readOnly ? "rb" : "rb+");
  }

  inline void closeFile(FileHandle file)
  {
    fclose(file);
  }

  inline size_t readFile(FileHandle file, ByteVector &buffer)
  {
    return fread(buffer.data(), sizeof(char), buffer.size(), file);
  }

  inline size_t writeFile(FileHandle file, const ByteVector &buffer)
  {
    return fwrite(buffer.data(), sizeof(char), buffer.size(), file);
  }

#endif  // _WIN32
}

class FileStream::FileStreamPrivate
{
public:
  FileStreamPrivate(const FileName &fileName)
    : file(InvalidFileHandle)
    , name(fileName)
    , readOnly(true)
  {
  }

  FileHandle file;
  FileNameHandle name;
  bool readOnly;
};

////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////

FileStream::FileStream(FileName fileName, bool openReadOnly)
  : d(new FileStreamPrivate(fileName))
{
  // First try with read / write mode, if that fails, fall back to read only.

  if(!openReadOnly)
    d->file = openFile(fileName, false);

  if(d->file != InvalidFileHandle)
    d->readOnly = false;
  else
    d->file = openFile(fileName, true);

  if(d->file == InvalidFileHandle)
  {
# ifdef _WIN32
    debug("Could not open file " + fileNameToString(fileName));
# else
    debug("Could not open file " + String(static_cast<const char *>(d->name)));
# endif
  }
}

FileStream::~FileStream()
{
  if(isOpen())
    closeFile(d->file);

  delete d;
}

FileName FileStream::name() const
{
  return d->name;
}

ByteVector FileStream::readBlock(ulong length)
{
  if(!isOpen()) {
    debug("File::readBlock() -- invalid file.");
    return ByteVector::null;
  }

  if(length == 0)
    return ByteVector::null;

  const ulong streamLength = static_cast<ulong>(FileStream::length());
  if(length > bufferSize() && length > streamLength)
    length = streamLength;

  ByteVector buffer(static_cast<uint>(length));

  const size_t count = readFile(d->file, buffer);
  buffer.resize(static_cast<uint>(count));

  return buffer;
}

void FileStream::writeBlock(const ByteVector &data)
{
  if(!isOpen()) {
    debug("File::writeBlock() -- invalid file.");
    return;
  }

  if(readOnly()) {
    debug("File::writeBlock() -- read only file.");
    return;
  }

  writeFile(d->file, data);
}

void FileStream::insert(const ByteVector &data, ulong start, ulong replace)
{
  if(!isOpen()) {
    debug("File::insert() -- invalid file.");
    return;
  }

  if(readOnly()) {
    debug("File::insert() -- read only file.");
    return;
  }

  if(data.size() == replace) {
    seek(start);
    writeBlock(data);
    return;
  }
  else if(data.size() < replace) {
    seek(start);
    writeBlock(data);
    removeBlock(start + data.size(), replace - data.size());
    return;
  }

  // Woohoo!  Faster (about 20%) than id3lib at last.  I had to get hardcore
  // and avoid TagLib's high level API for rendering just copying parts of
  // the file that don't contain tag data.
  //
  // Now I'll explain the steps in this ugliness:

  // First, make sure that we're working with a buffer that is longer than
  // the *differnce* in the tag sizes.  We want to avoid overwriting parts
  // that aren't yet in memory, so this is necessary.

  ulong bufferLength = bufferSize();

  while(data.size() - replace > bufferLength)
    bufferLength += bufferSize();

  // Set where to start the reading and writing.

  long readPosition = start + replace;
  long writePosition = start;

  ByteVector buffer = data;
  ByteVector aboutToOverwrite(static_cast<uint>(bufferLength));

  while(true)
  {
    // Seek to the current read position and read the data that we're about
    // to overwrite.  Appropriately increment the readPosition.

    seek(readPosition);
    const size_t bytesRead = readFile(d->file, aboutToOverwrite);
    aboutToOverwrite.resize(bytesRead);
    readPosition += bufferLength;

    // Check to see if we just read the last block.  We need to call clear()
    // if we did so that the last write succeeds.

    if(bytesRead < bufferLength)
      clear();

    // Seek to the write position and write our buffer.  Increment the
    // writePosition.

    seek(writePosition);
    writeBlock(buffer);

    // We hit the end of the file.

    if(bytesRead == 0)
      break;

    writePosition += buffer.size();

    // Make the current buffer the data that we read in the beginning.

    buffer = aboutToOverwrite;
  }
}

void FileStream::removeBlock(ulong start, ulong length)
{
  if(!isOpen()) {
    debug("File::removeBlock() -- invalid file.");
    return;
  }

  ulong bufferLength = bufferSize();

  long readPosition = start + length;
  long writePosition = start;

  ByteVector buffer(static_cast<uint>(bufferLength));

  for(size_t bytesRead = -1; bytesRead != 0;)
  {
    seek(readPosition);
    bytesRead = readFile(d->file, buffer);
    readPosition += bytesRead;

    // Check to see if we just read the last block.  We need to call clear()
    // if we did so that the last write succeeds.

    if(bytesRead < buffer.size()) {
      clear();
      buffer.resize(bytesRead);
    }

    seek(writePosition);
    writeFile(d->file, buffer);

    writePosition += bytesRead;
  }

  truncate(writePosition);
}

bool FileStream::readOnly() const
{
  return d->readOnly;
}

bool FileStream::isOpen() const
{
  return (d->file != InvalidFileHandle);
}

void FileStream::seek(long offset, Position p)
{
  if(!isOpen()) {
    debug("File::seek() -- invalid file.");
    return;
  }

#ifdef _WIN32

  DWORD whence;
  switch(p) {
  case Beginning:
    whence = FILE_BEGIN;
    break;
  case Current:
    whence = FILE_CURRENT;
    break;
  case End:
    whence = FILE_END;
    break;
  default:
    debug("FileStream::seek() -- Invalid Position value.");
    return;
  }

  SetFilePointer(d->file, offset, NULL, whence);
  if(GetLastError() != NO_ERROR) {
    debug("File::seek() -- Failed to set the file pointer.");
  }

#else

  int whence;
  switch(p) {
  case Beginning:
    whence = SEEK_SET;
    break;
  case Current:
    whence = SEEK_CUR;
    break;
  case End:
    whence = SEEK_END;
    break;
  default:
    debug("FileStream::seek() -- Invalid Position value.");
    return;
  }

  fseek(d->file, offset, whence);

#endif
}

void FileStream::clear()
{
#ifdef _WIN32

  // NOP

#else

  clearerr(d->file);

#endif
}

long FileStream::tell() const
{
#ifdef _WIN32

  const DWORD position = SetFilePointer(d->file, 0, NULL, FILE_CURRENT);
  if(GetLastError() == NO_ERROR) {
    return static_cast<long>(position);
  }
  else {
    debug("File::tell() -- Failed to get the file pointer.");
    return 0;
  }

#else

  return ftell(d->file);

#endif
}

long FileStream::length()
{
  if(!isOpen()) {
    debug("File::length() -- invalid file.");
    return 0;
  }

#ifdef _WIN32

  const DWORD fileSize = GetFileSize(d->file, NULL);
  if(GetLastError() == NO_ERROR) {
    return static_cast<ulong>(fileSize);
  }
  else {
    debug("File::length() -- Failed to get the file size.");
    return 0;
  }

#else

  const long curpos = tell();

  seek(0, End);
  const long endpos = tell();

  seek(curpos, Beginning);

  return endpos;

#endif
}

////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////

void FileStream::truncate(long length)
{
#ifdef _WIN32

  const long currentPos = tell();

  seek(length);
  SetEndOfFile(d->file);
  if(GetLastError() != NO_ERROR) {
    debug("File::truncate() -- Failed to truncate the file.");
  }

  seek(currentPos);

#else

  const int error = ftruncate(fileno(d->file), length);
  if(error != 0) {
    debug("FileStream::truncate() -- Coundn't truncate the file.");
  }

#endif
}

TagLib::uint FileStream::bufferSize()
{
  return BufferSize;
}
<commit_msg>Fixed compilation error with GCC4.2<commit_after>/***************************************************************************
    copyright            : (C) 2002 - 2008 by Scott Wheeler
    email                : wheeler@kde.org
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License version   *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
 *   02110-1301  USA                                                       *
 *                                                                         *
 *   Alternatively, this file is available under the Mozilla Public        *
 *   License Version 1.1.  You may obtain a copy of the License at         *
 *   http://www.mozilla.org/MPL/                                           *
 ***************************************************************************/

#include "tfilestream.h"
#include "tstring.h"
#include "tdebug.h"

#ifdef _WIN32
# include <windows.h>
#else
# include <stdio.h>
# include <unistd.h>
#endif

using namespace TagLib;

namespace
{
#ifdef _WIN32

  // Uses Win32 native API instead of POSIX API to reduce the resource consumption.

  typedef FileName FileNameHandle;
  typedef HANDLE FileHandle;

  const TagLib::uint BufferSize = 8192;
  const FileHandle InvalidFileHandle = INVALID_HANDLE_VALUE;

  inline FileHandle openFile(const FileName &path, bool readOnly)
  {
    const DWORD access = readOnly ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE);

    if(!path.wstr().empty())
      return CreateFileW(path.wstr().c_str(), access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    else if(!path.str().empty())
      return CreateFileA(path.str().c_str(), access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    else
      return InvalidFileHandle;
  }

  inline void closeFile(FileHandle file)
  {
    CloseHandle(file);
  }

  inline size_t readFile(FileHandle file, ByteVector &buffer)
  {
    DWORD length;
    if(ReadFile(file, buffer.data(), static_cast<DWORD>(buffer.size()), &length, NULL))
      return static_cast<size_t>(length);
    else
      return 0;
  }

  inline size_t writeFile(FileHandle file, const ByteVector &buffer)
  {
    DWORD length;
    if(WriteFile(file, buffer.data(), static_cast<DWORD>(buffer.size()), &length, NULL))
      return static_cast<size_t>(length);
    else
      return 0;
  }

# ifndef NDEBUG

  // Convert a string in a local encoding into a UTF-16 string.

  // Debugging use only. In actual use, file names in local encodings are passed to
  // CreateFileA() without any conversions.

  String fileNameToString(const FileName &name)
  {
    if(!name.wstr().empty()) {
      return String(name.wstr());
    }
    else if(!name.str().empty()) {
      const int len = MultiByteToWideChar(CP_ACP, 0, name.str().c_str(), -1, NULL, 0);
      if(len == 0)
        return String::null;

      wstring wstr(len, L'\0');
      MultiByteToWideChar(CP_ACP, 0, name.str().c_str(), -1, &wstr[0], len);

      return String(wstr);
    }
    else {
      return String::null;
    }
  }

# endif

#else   // _WIN32

  struct FileNameHandle : public std::string
  {
    FileNameHandle(FileName name) : std::string(name) {}
    operator FileName () const { return c_str(); }
  };

  typedef FILE* FileHandle;

  const TagLib::uint BufferSize = 8192;
  const FileHandle InvalidFileHandle = 0;

  inline FileHandle openFile(const FileName &path, bool readOnly)
  {
    return fopen(path, readOnly ? "rb" : "rb+");
  }

  inline void closeFile(FileHandle file)
  {
    fclose(file);
  }

  inline size_t readFile(FileHandle file, ByteVector &buffer)
  {
    return fread(buffer.data(), sizeof(char), buffer.size(), file);
  }

  inline size_t writeFile(FileHandle file, const ByteVector &buffer)
  {
    return fwrite(buffer.data(), sizeof(char), buffer.size(), file);
  }

#endif  // _WIN32
}

class FileStream::FileStreamPrivate
{
public:
  FileStreamPrivate(const FileName &fileName)
    : file(InvalidFileHandle)
    , name(fileName)
    , readOnly(true)
  {
  }

  FileHandle file;
  FileNameHandle name;
  bool readOnly;
};

////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////

FileStream::FileStream(FileName fileName, bool openReadOnly)
  : d(new FileStreamPrivate(fileName))
{
  // First try with read / write mode, if that fails, fall back to read only.

  if(!openReadOnly)
    d->file = openFile(fileName, false);

  if(d->file != InvalidFileHandle)
    d->readOnly = false;
  else
    d->file = openFile(fileName, true);

  if(d->file == InvalidFileHandle)
  {
# ifdef _WIN32
    debug("Could not open file " + fileNameToString(fileName));
# else
    debug("Could not open file " + String(static_cast<const char *>(d->name)));
# endif
  }
}

FileStream::~FileStream()
{
  if(isOpen())
    closeFile(d->file);

  delete d;
}

FileName FileStream::name() const
{
  return d->name;
}

ByteVector FileStream::readBlock(ulong length)
{
  if(!isOpen()) {
    debug("File::readBlock() -- invalid file.");
    return ByteVector::null;
  }

  if(length == 0)
    return ByteVector::null;

  const ulong streamLength = static_cast<ulong>(FileStream::length());
  if(length > bufferSize() && length > streamLength)
    length = streamLength;

  ByteVector buffer(static_cast<uint>(length));

  const size_t count = readFile(d->file, buffer);
  buffer.resize(static_cast<uint>(count));

  return buffer;
}

void FileStream::writeBlock(const ByteVector &data)
{
  if(!isOpen()) {
    debug("File::writeBlock() -- invalid file.");
    return;
  }

  if(readOnly()) {
    debug("File::writeBlock() -- read only file.");
    return;
  }

  writeFile(d->file, data);
}

void FileStream::insert(const ByteVector &data, ulong start, ulong replace)
{
  if(!isOpen()) {
    debug("File::insert() -- invalid file.");
    return;
  }

  if(readOnly()) {
    debug("File::insert() -- read only file.");
    return;
  }

  if(data.size() == replace) {
    seek(start);
    writeBlock(data);
    return;
  }
  else if(data.size() < replace) {
    seek(start);
    writeBlock(data);
    removeBlock(start + data.size(), replace - data.size());
    return;
  }

  // Woohoo!  Faster (about 20%) than id3lib at last.  I had to get hardcore
  // and avoid TagLib's high level API for rendering just copying parts of
  // the file that don't contain tag data.
  //
  // Now I'll explain the steps in this ugliness:

  // First, make sure that we're working with a buffer that is longer than
  // the *differnce* in the tag sizes.  We want to avoid overwriting parts
  // that aren't yet in memory, so this is necessary.

  ulong bufferLength = bufferSize();

  while(data.size() - replace > bufferLength)
    bufferLength += bufferSize();

  // Set where to start the reading and writing.

  long readPosition = start + replace;
  long writePosition = start;

  ByteVector buffer = data;
  ByteVector aboutToOverwrite(static_cast<uint>(bufferLength));

  while(true)
  {
    // Seek to the current read position and read the data that we're about
    // to overwrite.  Appropriately increment the readPosition.

    seek(readPosition);
    const size_t bytesRead = readFile(d->file, aboutToOverwrite);
    aboutToOverwrite.resize(bytesRead);
    readPosition += bufferLength;

    // Check to see if we just read the last block.  We need to call clear()
    // if we did so that the last write succeeds.

    if(bytesRead < bufferLength)
      clear();

    // Seek to the write position and write our buffer.  Increment the
    // writePosition.

    seek(writePosition);
    writeBlock(buffer);

    // We hit the end of the file.

    if(bytesRead == 0)
      break;

    writePosition += buffer.size();

    // Make the current buffer the data that we read in the beginning.

    buffer = aboutToOverwrite;
  }
}

void FileStream::removeBlock(ulong start, ulong length)
{
  if(!isOpen()) {
    debug("File::removeBlock() -- invalid file.");
    return;
  }

  ulong bufferLength = bufferSize();

  long readPosition = start + length;
  long writePosition = start;

  ByteVector buffer(static_cast<uint>(bufferLength));

  for(size_t bytesRead = -1; bytesRead != 0;)
  {
    seek(readPosition);
    bytesRead = readFile(d->file, buffer);
    readPosition += bytesRead;

    // Check to see if we just read the last block.  We need to call clear()
    // if we did so that the last write succeeds.

    if(bytesRead < buffer.size()) {
      clear();
      buffer.resize(bytesRead);
    }

    seek(writePosition);
    writeFile(d->file, buffer);

    writePosition += bytesRead;
  }

  truncate(writePosition);
}

bool FileStream::readOnly() const
{
  return d->readOnly;
}

bool FileStream::isOpen() const
{
  return (d->file != InvalidFileHandle);
}

void FileStream::seek(long offset, Position p)
{
  if(!isOpen()) {
    debug("File::seek() -- invalid file.");
    return;
  }

#ifdef _WIN32

  DWORD whence;
  switch(p) {
  case Beginning:
    whence = FILE_BEGIN;
    break;
  case Current:
    whence = FILE_CURRENT;
    break;
  case End:
    whence = FILE_END;
    break;
  default:
    debug("FileStream::seek() -- Invalid Position value.");
    return;
  }

  SetFilePointer(d->file, offset, NULL, whence);
  if(GetLastError() != NO_ERROR) {
    debug("File::seek() -- Failed to set the file pointer.");
  }

#else

  int whence;
  switch(p) {
  case Beginning:
    whence = SEEK_SET;
    break;
  case Current:
    whence = SEEK_CUR;
    break;
  case End:
    whence = SEEK_END;
    break;
  default:
    debug("FileStream::seek() -- Invalid Position value.");
    return;
  }

  fseek(d->file, offset, whence);

#endif
}

void FileStream::clear()
{
#ifdef _WIN32

  // NOP

#else

  clearerr(d->file);

#endif
}

long FileStream::tell() const
{
#ifdef _WIN32

  const DWORD position = SetFilePointer(d->file, 0, NULL, FILE_CURRENT);
  if(GetLastError() == NO_ERROR) {
    return static_cast<long>(position);
  }
  else {
    debug("File::tell() -- Failed to get the file pointer.");
    return 0;
  }

#else

  return ftell(d->file);

#endif
}

long FileStream::length()
{
  if(!isOpen()) {
    debug("File::length() -- invalid file.");
    return 0;
  }

#ifdef _WIN32

  const DWORD fileSize = GetFileSize(d->file, NULL);
  if(GetLastError() == NO_ERROR) {
    return static_cast<ulong>(fileSize);
  }
  else {
    debug("File::length() -- Failed to get the file size.");
    return 0;
  }

#else

  const long curpos = tell();

  seek(0, End);
  const long endpos = tell();

  seek(curpos, Beginning);

  return endpos;

#endif
}

////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////

void FileStream::truncate(long length)
{
#ifdef _WIN32

  const long currentPos = tell();

  seek(length);
  SetEndOfFile(d->file);
  if(GetLastError() != NO_ERROR) {
    debug("File::truncate() -- Failed to truncate the file.");
  }

  seek(currentPos);

#else

  const int error = ftruncate(fileno(d->file), length);
  if(error != 0) {
    debug("FileStream::truncate() -- Coundn't truncate the file.");
  }

#endif
}

TagLib::uint FileStream::bufferSize()
{
  return BufferSize;
}
<|endoftext|>


<commit_before>#ifndef UNIQUE_EVERSEEN_HPP
#define UNIQUE_EVERSEEN_HPP

#include "filter.hpp"

#include <type_traits>
#include <functional>
#include <utility>
#include <unordered_set>
#include <iterator>

namespace iter
{
    //the container type must be usable in an unordered_map to achieve constant
    //performance checking if it has ever been seen
    template <typename Container>
    auto unique_everseen(Container&& container)
        -> Filter<std::function<bool(decltype(container.front()))>,Container>
    {
        using elem_t = decltype(container.front());
        std::unordered_set<typename std::remove_reference<elem_t>::type> elem_seen;
        std::function<bool(elem_t)> func = [elem_seen](elem_t e) mutable
        //has to be captured by value because it goes out of scope when the
        //function returns
                {
                    if (elem_seen.find(e) == std::end(elem_seen)){
                        elem_seen.insert(e);
                        return true;
                    } else {
                        return false;
                    }
                };
        return filter(func,std::forward<Container>(container));
    }
}

#endif //UNIQUE_EVERSEEN_HPP
<commit_msg>removes .front() requirement on Container<commit_after>#ifndef UNIQUE_EVERSEEN_HPP
#define UNIQUE_EVERSEEN_HPP

#include "iterbase.hpp"
#include "filter.hpp"

#include <type_traits>
#include <functional>
#include <utility>
#include <unordered_set>
#include <iterator>

namespace iter
{
    //the container type must be usable in an unordered_map to achieve constant
    //performance checking if it has ever been seen
    template <typename Container>
    auto unique_everseen(Container&& container)
        -> Filter<std::function<bool(iterator_deref<Container>)>,Container>
    {
        using elem_t = iterator_deref<Container>;
        std::unordered_set<typename std::remove_reference<elem_t>::type> elem_seen;
        std::function<bool(elem_t)> func = [elem_seen](elem_t e) mutable
        //has to be captured by value because it goes out of scope when the
        //function returns
                {
                    if (elem_seen.find(e) == std::end(elem_seen)){
                        elem_seen.insert(e);
                        return true;
                    } else {
                        return false;
                    }
                };
        return filter(func,std::forward<Container>(container));
    }
}

#endif //UNIQUE_EVERSEEN_HPP
<|endoftext|>


<commit_before>/*===================================================================

BlueBerry Platform

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#ifndef NOMINMAX
#define NOMINMAX
#endif

#include "berryInternalPlatform.h"

#include "berryLog.h"
#include "berryLogImpl.h"
#include "berryPlatform.h"
#include "berryPlatformException.h"
#include "berryDebugUtil.h"
#include "berryPlatformException.h"
#include "berryCTKPluginActivator.h"
#include "berryPlatformException.h"
#include "berryApplicationContainer.h"
#include "berryProduct.h"

#include "berryIBranding.h"

//#include "event/berryPlatformEvents.h"
//#include "berryPlatformLogChannel.h"

#include <berryIApplicationContext.h>
#include <berryIPreferencesService.h>
#include <berryIExtensionRegistry.h>
#include <berryIProduct.h>

#include <service/datalocation/ctkLocation.h>
#include <service/debug/ctkDebugOptions.h>

#include <ctkPluginContext.h>
#include <ctkPlugin.h>
#include <ctkPluginException.h>
#include <ctkPluginFrameworkLauncher.h>

#include <QCoreApplication>
#include <QDesktopServices>
#include <QDebug>
#include <QMutexLocker>

namespace berry {

QMutex InternalPlatform::m_Mutex;

bool InternalPlatform::DEBUG = false;
bool InternalPlatform::DEBUG_PLUGIN_PREFERENCES = false;

InternalPlatform::InternalPlatform()
  : m_Initialized(false)
  , m_ConsoleLog(false)
  , m_Context(nullptr)
{
}

InternalPlatform::~InternalPlatform()
{

}

InternalPlatform* InternalPlatform::GetInstance()
{
  QMutexLocker lock(&m_Mutex);
  static InternalPlatform instance;
  return &instance;
}

bool InternalPlatform::ConsoleLog() const
{
  return m_ConsoleLog;
}

QVariant InternalPlatform::GetOption(const QString& option, const QVariant& defaultValue) const
{
  ctkDebugOptions* options = GetDebugOptions();
  if (options != nullptr)
  {
    return options->getOption(option, defaultValue);
  }
  return QVariant();
}

IAdapterManager* InternalPlatform::GetAdapterManager() const
{
  AssertInitialized();
  return nullptr;
}

SmartPointer<IProduct> InternalPlatform::GetProduct() const
{
  if (product.IsNotNull()) return product;
  ApplicationContainer* container = org_blueberry_core_runtime_Activator::GetContainer();
  IBranding* branding = container == nullptr ? nullptr : container->GetBranding();
  if (branding == nullptr) return IProduct::Pointer();
  IProduct::Pointer brandingProduct = branding->GetProduct();
  if (!brandingProduct)
  {
    brandingProduct = new Product(branding);
  }
  product = brandingProduct;
  return product;
}

void InternalPlatform::InitializePluginPaths()
{
  QMutexLocker lock(&m_Mutex);

  // Add search paths for Qt plugins
  foreach(QString qtPluginPath, m_Context->getProperty(Platform::PROP_QTPLUGIN_PATH).toStringList())
  {
    if (QFile::exists(qtPluginPath))
    {
      QCoreApplication::addLibraryPath(qtPluginPath);
    }
    else if (m_ConsoleLog)
    {
      BERRY_WARN << "Qt plugin path does not exist: " << qtPluginPath.toStdString();
    }
  }

  // Add a default search path. It is assumed that installed applications
  // provide their Qt plugins in that path.
  static const QString defaultQtPluginPath = QCoreApplication::applicationDirPath() + "/plugins";
  if (QFile::exists(defaultQtPluginPath))
  {
    QCoreApplication::addLibraryPath(defaultQtPluginPath);
  }

  if (m_ConsoleLog)
  {
    std::string pathList;
    foreach(QString libPath, QCoreApplication::libraryPaths())
    {
      pathList += (pathList.empty() ? "" : ", ") + libPath.toStdString();
    }
    BERRY_INFO << "Qt library search paths: " << pathList;
  }

  /*
  m_ConfigPath.setPath(m_Context->getProperty("application.configDir").toString());
  m_InstancePath.setPath(m_Context->getProperty("application.dir").toString());
  QString installPath = m_Context->getProperty(Platform::PROP_HOME).toString();
  if (installPath.isEmpty())
  {
    m_InstallPath = m_InstancePath;
  }
  else {
    m_InstallPath.setPath(installPath);
  }

  QString dataLocation = m_Context->getProperty(Platform::PROP_STORAGE_DIR).toString();
  if (!storageDir.isEmpty())
  {
    if (dataLocation.at(dataLocation.size()-1) != '/')
    {
      dataLocation += '/';
    }
    m_UserPath.setPath(dataLocation);
  }
  else
  {
    // Append a hash value of the absolute path of the executable to the data location.
    // This allows to start the same application from different build or install trees.
    dataLocation = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + this->getOrganizationName() + "/" + this->getApplicationName() + '_';
    dataLocation += QString::number(qHash(QCoreApplication::applicationDirPath())) + "/";
    m_UserPath.setPath(dataLocation);
  }
  BERRY_INFO(m_ConsoleLog) << "Framework storage dir: " << m_UserPath.absolutePath();

  QFileInfo userFile(m_UserPath.absolutePath());

  if (!QDir().mkpath(userFile.absoluteFilePath()) || !userFile.isWritable())
  {
    QString tmpPath = QDir::temp().absoluteFilePath(QString::fromStdString(this->commandName()));
    BERRY_WARN << "Storage dir " << userFile.absoluteFilePath() << " is not writable. Falling back to temporary path " << tmpPath;
    QDir().mkpath(tmpPath);
    userFile.setFile(tmpPath);
  }

  m_BaseStatePath.setPath(m_UserPath.absolutePath() + "/bb-metadata/bb-plugins");

  QString logPath(m_UserPath.absoluteFilePath(QString::fromStdString(this->commandName()) + ".log"));
  m_PlatformLogChannel = new Poco::SimpleFileChannel(logPath.toStdString());
*/
}

ctkDebugOptions* InternalPlatform::GetDebugOptions() const
{
  return m_DebugTracker.isNull() ? nullptr : m_DebugTracker->getService();
}

IApplicationContext* InternalPlatform::GetApplicationContext() const
{
  QList<ctkServiceReference> refs;
  try
  {
    refs = m_Context->getServiceReferences<IApplicationContext>("(blueberry.application.type=main.thread)");
  }
  catch (const std::invalid_argument&)
  {
    return nullptr;
  }
  if (refs.isEmpty()) return nullptr;

  // assumes the application context is available as a service
  IApplicationContext* result = m_Context->getService<IApplicationContext>(refs.front());
  if (result != nullptr)
  {
    m_Context->ungetService(refs.front());
    return result;
  }
  return nullptr;
}

void InternalPlatform::Start(ctkPluginContext* context)
{
  this->m_Context = context;

  m_ConsoleLog = m_Context->getProperty(ctkPluginFrameworkLauncher::PROP_CONSOLE_LOG).toBool();

  OpenServiceTrackers();

  this->InitializePluginPaths();

#ifdef BLUEBERRY_DEBUG_SMARTPOINTER
  DebugUtil::RestoreState(m_UserPath);
#endif

  InitializeDebugFlags();
  this->m_Initialized = true;
}

void InternalPlatform::Stop(ctkPluginContext* /*context*/)
{
  AssertInitialized();

  this->m_Initialized = false;
  CloseServiceTrackers();

#ifdef BLUEBERRY_DEBUG_SMARTPOINTER
  DebugUtil::SaveState(m_UserPath);
#endif

  this->m_Context = nullptr;
}

void InternalPlatform::AssertInitialized() const
{
  if (!m_Initialized)
  {
    throw PlatformException("The Platform has not been initialized yet!");
  }
}

void InternalPlatform::OpenServiceTrackers()
{
  ctkPluginContext* context = this->m_Context;

  instanceLocation.reset(new ctkServiceTracker<ctkLocation*>(context, ctkLDAPSearchFilter(ctkLocation::INSTANCE_FILTER)));
  instanceLocation->open();

  userLocation.reset(new ctkServiceTracker<ctkLocation*>(context, ctkLDAPSearchFilter(ctkLocation::USER_FILTER)));
  userLocation->open();

  configurationLocation.reset(new ctkServiceTracker<ctkLocation*>(context, ctkLDAPSearchFilter(ctkLocation::CONFIGURATION_FILTER)));
  configurationLocation->open();

  installLocation.reset(new ctkServiceTracker<ctkLocation*>(context, ctkLDAPSearchFilter(ctkLocation::INSTALL_FILTER)));
  installLocation->open();

  m_PreferencesTracker.reset(new ctkServiceTracker<berry::IPreferencesService*>(context));
  m_PreferencesTracker->open();

  m_RegistryTracker.reset(new ctkServiceTracker<berry::IExtensionRegistry*>(context));
  m_RegistryTracker->open();

  m_DebugTracker.reset(new ctkServiceTracker<ctkDebugOptions*>(context));
  m_DebugTracker->open();
}

void InternalPlatform::CloseServiceTrackers()
{
  if (!m_PreferencesTracker.isNull())
  {
    m_PreferencesTracker->close();
    m_PreferencesTracker.reset();
  }
  if (!m_RegistryTracker.isNull())
  {
    m_RegistryTracker->close();
    m_RegistryTracker.reset();
  }
  if (!m_DebugTracker.isNull())
  {
    m_DebugTracker->close();
    m_DebugTracker.reset();
  }

  if (!configurationLocation.isNull()) {
    configurationLocation->close();
    configurationLocation.reset();
  }

  if (!installLocation.isNull()) {
    installLocation->close();
    installLocation.reset();
  }

  if (!instanceLocation.isNull()) {
    instanceLocation->close();
    instanceLocation.reset();
  }

  if (!userLocation.isNull()) {
    userLocation->close();
    userLocation.reset();
  }
}

void InternalPlatform::InitializeDebugFlags()
{
  DEBUG = this->GetOption(Platform::PI_RUNTIME + "/debug", false).toBool();
  if (DEBUG)
  {
    DEBUG_PLUGIN_PREFERENCES = GetOption(Platform::PI_RUNTIME + "/preferences/plugin", false).toBool();
  }
}

IExtensionRegistry* InternalPlatform::GetExtensionRegistry()
{
  return m_RegistryTracker.isNull() ? nullptr : m_RegistryTracker->getService();
}

IPreferencesService *InternalPlatform::GetPreferencesService()
{
  return m_PreferencesTracker.isNull() ? nullptr : m_PreferencesTracker->getService();
}

ctkLocation* InternalPlatform::GetConfigurationLocation()
{
  this->AssertInitialized();
  return configurationLocation->getService();
}

ctkLocation* InternalPlatform::GetInstallLocation()
{
  this->AssertInitialized();
  return installLocation->getService();
}

ctkLocation* InternalPlatform::GetInstanceLocation()
{
  this->AssertInitialized();
  return instanceLocation->getService();
}

QDir InternalPlatform::GetStateLocation(const QSharedPointer<ctkPlugin>& plugin)
{
  ctkLocation* service = GetInstanceLocation();
  if (service == nullptr)
  {
    throw ctkIllegalStateException("No instance data can be specified.");
  }

  QUrl url = GetInstanceLocation()->getDataArea(plugin->getSymbolicName());
  if (!url.isValid())
  {
    throw ctkIllegalStateException("The instance data location has not been specified yet.");
  }

  QDir location(url.toLocalFile());
  if (!location.exists())
  {
    if (!location.mkpath(location.absolutePath()))
    {
      throw PlatformException(QString("Could not create plugin state location \"%1\"").arg(location.absolutePath()));
    }
  }
  return location;
}

//PlatformEvents& InternalPlatform::GetEvents()
//{
//  return m_Events;
//}

ctkLocation* InternalPlatform::GetUserLocation()
{
  this->AssertInitialized();
  return userLocation->getService();
}

ILog *InternalPlatform::GetLog(const QSharedPointer<ctkPlugin> &plugin) const
{
  LogImpl* result = m_Logs.value(plugin->getPluginId());
  if (result != nullptr)
    return result;

//  ExtendedLogService logService = (ExtendedLogService) extendedLogTracker.getService();
//  Logger logger = logService == null ? null : logService.getLogger(bundle, PlatformLogWriter.EQUINOX_LOGGER_NAME);
//  result = new Log(bundle, logger);
//  ExtendedLogReaderService logReader = (ExtendedLogReaderService) logReaderTracker.getService();
//  logReader.addLogListener(result, result);
//  logs.put(bundle, result);
//  return result;

  result = new LogImpl(plugin);
  m_Logs.insert(plugin->getPluginId(), result);
  return result;
}

bool InternalPlatform::IsRunning() const
{
  QMutexLocker lock(&m_Mutex);
  try
  {
    return m_Initialized && m_Context && m_Context->getPlugin()->getState() == ctkPlugin::ACTIVE;
  }
  catch (const ctkIllegalStateException&)
  {
    return false;
  }
}

QSharedPointer<ctkPlugin> InternalPlatform::GetPlugin(const QString &symbolicName)
{
  QList<QSharedPointer<ctkPlugin> > plugins = m_Context->getPlugins();

  QSharedPointer<ctkPlugin> res(nullptr);
  foreach(QSharedPointer<ctkPlugin> plugin, plugins)
  {
    if ((plugin->getState() & (ctkPlugin::INSTALLED | ctkPlugin::UNINSTALLED)) == 0 &&
        plugin->getSymbolicName() == symbolicName)
    {
      if (res.isNull())
      {
        res = plugin;
      }
      else if (res->getVersion().compare(plugin->getVersion()) < 0)
      {
        res = plugin;
      }
    }
  }
  return res;
}

QList<QSharedPointer<ctkPlugin> > InternalPlatform::GetPlugins(const QString &symbolicName, const QString &version)
{
  QList<QSharedPointer<ctkPlugin> > plugins = m_Context->getPlugins();

  QMap<ctkVersion, QSharedPointer<ctkPlugin> > selected;
  ctkVersion versionObj(version);
  foreach(QSharedPointer<ctkPlugin> plugin, plugins)
  {
    if ((plugin->getState() & (ctkPlugin::INSTALLED | ctkPlugin::UNINSTALLED)) == 0 &&
        plugin->getSymbolicName() == symbolicName)
    {
      if (plugin->getVersion().compare(versionObj) > -1)
      {
        selected.insert(plugin->getVersion(), plugin);
      }
    }
  }
  QList<QSharedPointer<ctkPlugin> > sortedPlugins = selected.values();
  QList<QSharedPointer<ctkPlugin> > reversePlugins;
  qCopyBackward(sortedPlugins.begin(), sortedPlugins.end(), reversePlugins.end());
  return reversePlugins;
}

QStringList InternalPlatform::GetApplicationArgs() const
{
  QStringList result;

  IApplicationContext* appContext = this->GetApplicationContext();
  if (appContext)
  {
    QHash<QString, QVariant> args = appContext->GetArguments();
    result = args[IApplicationContext::APPLICATION_ARGS].toStringList();
  }
  return result;
}

}
<commit_msg>Skip empty Qt plugin paths<commit_after>/*===================================================================

BlueBerry Platform

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#ifndef NOMINMAX
#define NOMINMAX
#endif

#include "berryInternalPlatform.h"

#include "berryLog.h"
#include "berryLogImpl.h"
#include "berryPlatform.h"
#include "berryPlatformException.h"
#include "berryDebugUtil.h"
#include "berryPlatformException.h"
#include "berryCTKPluginActivator.h"
#include "berryPlatformException.h"
#include "berryApplicationContainer.h"
#include "berryProduct.h"

#include "berryIBranding.h"

//#include "event/berryPlatformEvents.h"
//#include "berryPlatformLogChannel.h"

#include <berryIApplicationContext.h>
#include <berryIPreferencesService.h>
#include <berryIExtensionRegistry.h>
#include <berryIProduct.h>

#include <service/datalocation/ctkLocation.h>
#include <service/debug/ctkDebugOptions.h>

#include <ctkPluginContext.h>
#include <ctkPlugin.h>
#include <ctkPluginException.h>
#include <ctkPluginFrameworkLauncher.h>

#include <QCoreApplication>
#include <QDesktopServices>
#include <QDebug>
#include <QMutexLocker>

namespace berry {

QMutex InternalPlatform::m_Mutex;

bool InternalPlatform::DEBUG = false;
bool InternalPlatform::DEBUG_PLUGIN_PREFERENCES = false;

InternalPlatform::InternalPlatform()
  : m_Initialized(false)
  , m_ConsoleLog(false)
  , m_Context(nullptr)
{
}

InternalPlatform::~InternalPlatform()
{

}

InternalPlatform* InternalPlatform::GetInstance()
{
  QMutexLocker lock(&m_Mutex);
  static InternalPlatform instance;
  return &instance;
}

bool InternalPlatform::ConsoleLog() const
{
  return m_ConsoleLog;
}

QVariant InternalPlatform::GetOption(const QString& option, const QVariant& defaultValue) const
{
  ctkDebugOptions* options = GetDebugOptions();
  if (options != nullptr)
  {
    return options->getOption(option, defaultValue);
  }
  return QVariant();
}

IAdapterManager* InternalPlatform::GetAdapterManager() const
{
  AssertInitialized();
  return nullptr;
}

SmartPointer<IProduct> InternalPlatform::GetProduct() const
{
  if (product.IsNotNull()) return product;
  ApplicationContainer* container = org_blueberry_core_runtime_Activator::GetContainer();
  IBranding* branding = container == nullptr ? nullptr : container->GetBranding();
  if (branding == nullptr) return IProduct::Pointer();
  IProduct::Pointer brandingProduct = branding->GetProduct();
  if (!brandingProduct)
  {
    brandingProduct = new Product(branding);
  }
  product = brandingProduct;
  return product;
}

void InternalPlatform::InitializePluginPaths()
{
  QMutexLocker lock(&m_Mutex);

  // Add search paths for Qt plugins
  for(const auto qtPluginPath : m_Context->getProperty(Platform::PROP_QTPLUGIN_PATH).toStringList())
  {
    if (qtPluginPath.isEmpty())
      continue;

    if (QFile::exists(qtPluginPath))
    {
      QCoreApplication::addLibraryPath(qtPluginPath);
    }
    else if (m_ConsoleLog)
    {
      BERRY_WARN << "Qt plugin path does not exist: " << qtPluginPath.toStdString();
    }
  }

  // Add a default search path. It is assumed that installed applications
  // provide their Qt plugins in that path.
  static const QString defaultQtPluginPath = QCoreApplication::applicationDirPath() + "/plugins";
  if (QFile::exists(defaultQtPluginPath))
  {
    QCoreApplication::addLibraryPath(defaultQtPluginPath);
  }

  if (m_ConsoleLog)
  {
    std::string pathList;
    foreach(QString libPath, QCoreApplication::libraryPaths())
    {
      pathList += (pathList.empty() ? "" : ", ") + libPath.toStdString();
    }
    BERRY_INFO << "Qt library search paths: " << pathList;
  }

  /*
  m_ConfigPath.setPath(m_Context->getProperty("application.configDir").toString());
  m_InstancePath.setPath(m_Context->getProperty("application.dir").toString());
  QString installPath = m_Context->getProperty(Platform::PROP_HOME).toString();
  if (installPath.isEmpty())
  {
    m_InstallPath = m_InstancePath;
  }
  else {
    m_InstallPath.setPath(installPath);
  }

  QString dataLocation = m_Context->getProperty(Platform::PROP_STORAGE_DIR).toString();
  if (!storageDir.isEmpty())
  {
    if (dataLocation.at(dataLocation.size()-1) != '/')
    {
      dataLocation += '/';
    }
    m_UserPath.setPath(dataLocation);
  }
  else
  {
    // Append a hash value of the absolute path of the executable to the data location.
    // This allows to start the same application from different build or install trees.
    dataLocation = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + this->getOrganizationName() + "/" + this->getApplicationName() + '_';
    dataLocation += QString::number(qHash(QCoreApplication::applicationDirPath())) + "/";
    m_UserPath.setPath(dataLocation);
  }
  BERRY_INFO(m_ConsoleLog) << "Framework storage dir: " << m_UserPath.absolutePath();

  QFileInfo userFile(m_UserPath.absolutePath());

  if (!QDir().mkpath(userFile.absoluteFilePath()) || !userFile.isWritable())
  {
    QString tmpPath = QDir::temp().absoluteFilePath(QString::fromStdString(this->commandName()));
    BERRY_WARN << "Storage dir " << userFile.absoluteFilePath() << " is not writable. Falling back to temporary path " << tmpPath;
    QDir().mkpath(tmpPath);
    userFile.setFile(tmpPath);
  }

  m_BaseStatePath.setPath(m_UserPath.absolutePath() + "/bb-metadata/bb-plugins");

  QString logPath(m_UserPath.absoluteFilePath(QString::fromStdString(this->commandName()) + ".log"));
  m_PlatformLogChannel = new Poco::SimpleFileChannel(logPath.toStdString());
*/
}

ctkDebugOptions* InternalPlatform::GetDebugOptions() const
{
  return m_DebugTracker.isNull() ? nullptr : m_DebugTracker->getService();
}

IApplicationContext* InternalPlatform::GetApplicationContext() const
{
  QList<ctkServiceReference> refs;
  try
  {
    refs = m_Context->getServiceReferences<IApplicationContext>("(blueberry.application.type=main.thread)");
  }
  catch (const std::invalid_argument&)
  {
    return nullptr;
  }
  if (refs.isEmpty()) return nullptr;

  // assumes the application context is available as a service
  IApplicationContext* result = m_Context->getService<IApplicationContext>(refs.front());
  if (result != nullptr)
  {
    m_Context->ungetService(refs.front());
    return result;
  }
  return nullptr;
}

void InternalPlatform::Start(ctkPluginContext* context)
{
  this->m_Context = context;

  m_ConsoleLog = m_Context->getProperty(ctkPluginFrameworkLauncher::PROP_CONSOLE_LOG).toBool();

  OpenServiceTrackers();

  this->InitializePluginPaths();

#ifdef BLUEBERRY_DEBUG_SMARTPOINTER
  DebugUtil::RestoreState(m_UserPath);
#endif

  InitializeDebugFlags();
  this->m_Initialized = true;
}

void InternalPlatform::Stop(ctkPluginContext* /*context*/)
{
  AssertInitialized();

  this->m_Initialized = false;
  CloseServiceTrackers();

#ifdef BLUEBERRY_DEBUG_SMARTPOINTER
  DebugUtil::SaveState(m_UserPath);
#endif

  this->m_Context = nullptr;
}

void InternalPlatform::AssertInitialized() const
{
  if (!m_Initialized)
  {
    throw PlatformException("The Platform has not been initialized yet!");
  }
}

void InternalPlatform::OpenServiceTrackers()
{
  ctkPluginContext* context = this->m_Context;

  instanceLocation.reset(new ctkServiceTracker<ctkLocation*>(context, ctkLDAPSearchFilter(ctkLocation::INSTANCE_FILTER)));
  instanceLocation->open();

  userLocation.reset(new ctkServiceTracker<ctkLocation*>(context, ctkLDAPSearchFilter(ctkLocation::USER_FILTER)));
  userLocation->open();

  configurationLocation.reset(new ctkServiceTracker<ctkLocation*>(context, ctkLDAPSearchFilter(ctkLocation::CONFIGURATION_FILTER)));
  configurationLocation->open();

  installLocation.reset(new ctkServiceTracker<ctkLocation*>(context, ctkLDAPSearchFilter(ctkLocation::INSTALL_FILTER)));
  installLocation->open();

  m_PreferencesTracker.reset(new ctkServiceTracker<berry::IPreferencesService*>(context));
  m_PreferencesTracker->open();

  m_RegistryTracker.reset(new ctkServiceTracker<berry::IExtensionRegistry*>(context));
  m_RegistryTracker->open();

  m_DebugTracker.reset(new ctkServiceTracker<ctkDebugOptions*>(context));
  m_DebugTracker->open();
}

void InternalPlatform::CloseServiceTrackers()
{
  if (!m_PreferencesTracker.isNull())
  {
    m_PreferencesTracker->close();
    m_PreferencesTracker.reset();
  }
  if (!m_RegistryTracker.isNull())
  {
    m_RegistryTracker->close();
    m_RegistryTracker.reset();
  }
  if (!m_DebugTracker.isNull())
  {
    m_DebugTracker->close();
    m_DebugTracker.reset();
  }

  if (!configurationLocation.isNull()) {
    configurationLocation->close();
    configurationLocation.reset();
  }

  if (!installLocation.isNull()) {
    installLocation->close();
    installLocation.reset();
  }

  if (!instanceLocation.isNull()) {
    instanceLocation->close();
    instanceLocation.reset();
  }

  if (!userLocation.isNull()) {
    userLocation->close();
    userLocation.reset();
  }
}

void InternalPlatform::InitializeDebugFlags()
{
  DEBUG = this->GetOption(Platform::PI_RUNTIME + "/debug", false).toBool();
  if (DEBUG)
  {
    DEBUG_PLUGIN_PREFERENCES = GetOption(Platform::PI_RUNTIME + "/preferences/plugin", false).toBool();
  }
}

IExtensionRegistry* InternalPlatform::GetExtensionRegistry()
{
  return m_RegistryTracker.isNull() ? nullptr : m_RegistryTracker->getService();
}

IPreferencesService *InternalPlatform::GetPreferencesService()
{
  return m_PreferencesTracker.isNull() ? nullptr : m_PreferencesTracker->getService();
}

ctkLocation* InternalPlatform::GetConfigurationLocation()
{
  this->AssertInitialized();
  return configurationLocation->getService();
}

ctkLocation* InternalPlatform::GetInstallLocation()
{
  this->AssertInitialized();
  return installLocation->getService();
}

ctkLocation* InternalPlatform::GetInstanceLocation()
{
  this->AssertInitialized();
  return instanceLocation->getService();
}

QDir InternalPlatform::GetStateLocation(const QSharedPointer<ctkPlugin>& plugin)
{
  ctkLocation* service = GetInstanceLocation();
  if (service == nullptr)
  {
    throw ctkIllegalStateException("No instance data can be specified.");
  }

  QUrl url = GetInstanceLocation()->getDataArea(plugin->getSymbolicName());
  if (!url.isValid())
  {
    throw ctkIllegalStateException("The instance data location has not been specified yet.");
  }

  QDir location(url.toLocalFile());
  if (!location.exists())
  {
    if (!location.mkpath(location.absolutePath()))
    {
      throw PlatformException(QString("Could not create plugin state location \"%1\"").arg(location.absolutePath()));
    }
  }
  return location;
}

//PlatformEvents& InternalPlatform::GetEvents()
//{
//  return m_Events;
//}

ctkLocation* InternalPlatform::GetUserLocation()
{
  this->AssertInitialized();
  return userLocation->getService();
}

ILog *InternalPlatform::GetLog(const QSharedPointer<ctkPlugin> &plugin) const
{
  LogImpl* result = m_Logs.value(plugin->getPluginId());
  if (result != nullptr)
    return result;

//  ExtendedLogService logService = (ExtendedLogService) extendedLogTracker.getService();
//  Logger logger = logService == null ? null : logService.getLogger(bundle, PlatformLogWriter.EQUINOX_LOGGER_NAME);
//  result = new Log(bundle, logger);
//  ExtendedLogReaderService logReader = (ExtendedLogReaderService) logReaderTracker.getService();
//  logReader.addLogListener(result, result);
//  logs.put(bundle, result);
//  return result;

  result = new LogImpl(plugin);
  m_Logs.insert(plugin->getPluginId(), result);
  return result;
}

bool InternalPlatform::IsRunning() const
{
  QMutexLocker lock(&m_Mutex);
  try
  {
    return m_Initialized && m_Context && m_Context->getPlugin()->getState() == ctkPlugin::ACTIVE;
  }
  catch (const ctkIllegalStateException&)
  {
    return false;
  }
}

QSharedPointer<ctkPlugin> InternalPlatform::GetPlugin(const QString &symbolicName)
{
  QList<QSharedPointer<ctkPlugin> > plugins = m_Context->getPlugins();

  QSharedPointer<ctkPlugin> res(nullptr);
  foreach(QSharedPointer<ctkPlugin> plugin, plugins)
  {
    if ((plugin->getState() & (ctkPlugin::INSTALLED | ctkPlugin::UNINSTALLED)) == 0 &&
        plugin->getSymbolicName() == symbolicName)
    {
      if (res.isNull())
      {
        res = plugin;
      }
      else if (res->getVersion().compare(plugin->getVersion()) < 0)
      {
        res = plugin;
      }
    }
  }
  return res;
}

QList<QSharedPointer<ctkPlugin> > InternalPlatform::GetPlugins(const QString &symbolicName, const QString &version)
{
  QList<QSharedPointer<ctkPlugin> > plugins = m_Context->getPlugins();

  QMap<ctkVersion, QSharedPointer<ctkPlugin> > selected;
  ctkVersion versionObj(version);
  foreach(QSharedPointer<ctkPlugin> plugin, plugins)
  {
    if ((plugin->getState() & (ctkPlugin::INSTALLED | ctkPlugin::UNINSTALLED)) == 0 &&
        plugin->getSymbolicName() == symbolicName)
    {
      if (plugin->getVersion().compare(versionObj) > -1)
      {
        selected.insert(plugin->getVersion(), plugin);
      }
    }
  }
  QList<QSharedPointer<ctkPlugin> > sortedPlugins = selected.values();
  QList<QSharedPointer<ctkPlugin> > reversePlugins;
  qCopyBackward(sortedPlugins.begin(), sortedPlugins.end(), reversePlugins.end());
  return reversePlugins;
}

QStringList InternalPlatform::GetApplicationArgs() const
{
  QStringList result;

  IApplicationContext* appContext = this->GetApplicationContext();
  if (appContext)
  {
    QHash<QString, QVariant> args = appContext->GetArguments();
    result = args[IApplicationContext::APPLICATION_ARGS].toStringList();
  }
  return result;
}

}
<|endoftext|>


<commit_before>
#include "../../Flare.h"
#include "FlareWeaponStatus.h"
#include "../Components/FlareRoundButton.h"
#include "../../Spacecrafts/FlareWeapon.h"
#include "../../Spacecrafts/FlareSpacecraft.h"

#define LOCTEXT_NAMESPACE "FlareWeaponStatus"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareWeaponStatus::Construct(const FArguments& InArgs)
{
	// Args
	PlayerShip = InArgs._PlayerShip;
	TargetWeaponGroupIndex = InArgs._TargetWeaponGroupIndex;

	// Setup
	ComponentHealth = 1.0;
	CurrentAlpha = 0;
	FadeInTime = 0.5f;
	FadeOutTime = 1.0f;

	// Content
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	const FSlateBrush* Icon = FFlareStyleSet::GetIcon("Mouse_Nothing_Black");
	if (PlayerShip && TargetWeaponGroupIndex >= 0)
	{
		TargetWeaponGroup = PlayerShip->GetWeaponsSystem()->GetWeaponGroup(TargetWeaponGroupIndex);
		Icon = &TargetWeaponGroup->Description->MeshPreviewBrush;
	}
	else
	{
		TargetWeaponGroup = NULL;
	}

	// Structure
	ChildSlot
	.VAlign(VAlign_Center)
	.HAlign(HAlign_Left)
	.Padding(Theme.ContentPadding)
	[
		SNew(SHorizontalBox)

		// Button
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SFlareRoundButton)
			.ShowText(false)
			.InvertedBackground(true)
			.Icon(Icon)
			.IconColor(this, &SFlareWeaponStatus::GetIconColor)
			.HighlightColor(this, &SFlareWeaponStatus::GetHighlightColor)
		]

		// Text
		+ SHorizontalBox::Slot()
		.AutoWidth()
		.VAlign(VAlign_Center)
		.Padding(Theme.ContentPadding)
		[
			SNew(STextBlock)
			.TextStyle(&Theme.SmallFont)
			.Text(this, &SFlareWeaponStatus::GetText)
			.ColorAndOpacity(this, &SFlareWeaponStatus::GetTextColor)
			.ShadowColorAndOpacity(this, &SFlareWeaponStatus::GetShadowColor)
		]
	];
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

void SFlareWeaponStatus::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
	SCompoundWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);

	// Get the selection state for this weapon
	float IsSelected = false;
	float IsSelecting = false;
	if (PlayerShip)
	{
		IsSelected = (PlayerShip->GetWeaponsSystem()->GetActiveWeaponGroupIndex() == TargetWeaponGroupIndex);
		AFlarePlayerController* PC = PlayerShip->GetPC();
		if (PC)
		{
			IsSelecting = PC->IsSelectingWeapon();
		}
	}

	// Health
	if (PlayerShip && TargetWeaponGroupIndex >= 0)
	{
		ComponentHealth = PlayerShip->GetDamageSystem()->GetWeaponGroupHealth(TargetWeaponGroupIndex);
	}
	else
	{
		ComponentHealth = 1.0;
	}

	// Update animation state
	if (IsSelected)
	{
		CurrentAlpha += InDeltaTime / FadeInTime;
	}
	else if (IsSelecting)
	{
		if (CurrentAlpha >= 0.5f)
		{
			CurrentAlpha -= InDeltaTime / FadeOutTime;
		}
		else
		{
			CurrentAlpha += InDeltaTime / FadeInTime;
			CurrentAlpha = FMath::Clamp(CurrentAlpha, 0.0f, 0.5f);
		}
	}
	else
	{
		CurrentAlpha -= InDeltaTime / FadeOutTime;
	}
	CurrentAlpha = FMath::Clamp(CurrentAlpha, 0.0f, 1.0f);
}

FText SFlareWeaponStatus::GetText() const
{
	FText Text;

	if (TargetWeaponGroup)
	{
		// Generic info
		FString NameInfo = TargetWeaponGroup->Description->Name.ToString();
		FString CountInfo = FString::FromInt(TargetWeaponGroup->Weapons.Num()) + "x ";
		FString HealthInfo = FString::FromInt(100 * ComponentHealth) + "%";

		// Get ammo count
		int32 RemainingAmmo = 0;
		for (int32 i = 0; i < TargetWeaponGroup->Weapons.Num(); i++)
		{
			RemainingAmmo += TargetWeaponGroup->Weapons[i]->GetCurrentAmmo();
		}
		FString AmmoInfo = FString::FromInt(RemainingAmmo) + " " + LOCTEXT("Rounds", "rounds").ToString();

		// Final string
		Text = FText::FromString(CountInfo + NameInfo + "\n" + AmmoInfo + "\n" + HealthInfo);
	}

	return Text;
}

FSlateColor SFlareWeaponStatus::GetHighlightColor() const
{
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	FLinearColor NormalColor = Theme.NeutralColor;
	FLinearColor DamageColor = Theme.EnemyColor;

	// Update alpha
	FLinearColor Color = FMath::Lerp(DamageColor, NormalColor, ComponentHealth);
	Color.A *= Theme.DefaultAlpha * CurrentAlpha;
	return Color;
}

FSlateColor SFlareWeaponStatus::GetIconColor() const
{
	FLinearColor NormalColor = FLinearColor::White;
	NormalColor.A *= CurrentAlpha;
	return NormalColor;
}

FSlateColor SFlareWeaponStatus::GetTextColor() const
{
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	FLinearColor NormalColor = Theme.NeutralColor;
	NormalColor.A *= Theme.DefaultAlpha * CurrentAlpha;
	return NormalColor;
}

FLinearColor SFlareWeaponStatus::GetShadowColor() const
{
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	FLinearColor NormalColor = Theme.InvertedColor;
	NormalColor.A *= Theme.DefaultAlpha * CurrentAlpha;
	return NormalColor;
}

#undef LOCTEXT_NAMESPACE
<commit_msg>Don't count ammo from destroyed weapons<commit_after>
#include "../../Flare.h"
#include "FlareWeaponStatus.h"
#include "../Components/FlareRoundButton.h"
#include "../../Spacecrafts/FlareWeapon.h"
#include "../../Spacecrafts/FlareSpacecraft.h"

#define LOCTEXT_NAMESPACE "FlareWeaponStatus"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareWeaponStatus::Construct(const FArguments& InArgs)
{
	// Args
	PlayerShip = InArgs._PlayerShip;
	TargetWeaponGroupIndex = InArgs._TargetWeaponGroupIndex;

	// Setup
	ComponentHealth = 1.0;
	CurrentAlpha = 0;
	FadeInTime = 0.5f;
	FadeOutTime = 1.0f;

	// Content
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	const FSlateBrush* Icon = FFlareStyleSet::GetIcon("Mouse_Nothing_Black");
	if (PlayerShip && TargetWeaponGroupIndex >= 0)
	{
		TargetWeaponGroup = PlayerShip->GetWeaponsSystem()->GetWeaponGroup(TargetWeaponGroupIndex);
		Icon = &TargetWeaponGroup->Description->MeshPreviewBrush;
	}
	else
	{
		TargetWeaponGroup = NULL;
	}

	// Structure
	ChildSlot
	.VAlign(VAlign_Center)
	.HAlign(HAlign_Left)
	.Padding(Theme.ContentPadding)
	[
		SNew(SHorizontalBox)

		// Button
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SFlareRoundButton)
			.ShowText(false)
			.InvertedBackground(true)
			.Icon(Icon)
			.IconColor(this, &SFlareWeaponStatus::GetIconColor)
			.HighlightColor(this, &SFlareWeaponStatus::GetHighlightColor)
		]

		// Text
		+ SHorizontalBox::Slot()
		.AutoWidth()
		.VAlign(VAlign_Center)
		.Padding(Theme.ContentPadding)
		[
			SNew(STextBlock)
			.TextStyle(&Theme.SmallFont)
			.Text(this, &SFlareWeaponStatus::GetText)
			.ColorAndOpacity(this, &SFlareWeaponStatus::GetTextColor)
			.ShadowColorAndOpacity(this, &SFlareWeaponStatus::GetShadowColor)
		]
	];
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

void SFlareWeaponStatus::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
	SCompoundWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);

	// Get the selection state for this weapon
	float IsSelected = false;
	float IsSelecting = false;
	if (PlayerShip)
	{
		IsSelected = (PlayerShip->GetWeaponsSystem()->GetActiveWeaponGroupIndex() == TargetWeaponGroupIndex);
		AFlarePlayerController* PC = PlayerShip->GetPC();
		if (PC)
		{
			IsSelecting = PC->IsSelectingWeapon();
		}
	}

	// Health
	if (PlayerShip && TargetWeaponGroupIndex >= 0)
	{
		ComponentHealth = PlayerShip->GetDamageSystem()->GetWeaponGroupHealth(TargetWeaponGroupIndex);
	}
	else
	{
		ComponentHealth = 1.0;
	}

	// Update animation state
	if (IsSelected)
	{
		CurrentAlpha += InDeltaTime / FadeInTime;
	}
	else if (IsSelecting)
	{
		if (CurrentAlpha >= 0.5f)
		{
			CurrentAlpha -= InDeltaTime / FadeOutTime;
		}
		else
		{
			CurrentAlpha += InDeltaTime / FadeInTime;
			CurrentAlpha = FMath::Clamp(CurrentAlpha, 0.0f, 0.5f);
		}
	}
	else
	{
		CurrentAlpha -= InDeltaTime / FadeOutTime;
	}
	CurrentAlpha = FMath::Clamp(CurrentAlpha, 0.0f, 1.0f);
}

FText SFlareWeaponStatus::GetText() const
{
	FText Text;

	if (TargetWeaponGroup)
	{
		// Generic info
		FString NameInfo = TargetWeaponGroup->Description->Name.ToString();
		FString CountInfo = FString::FromInt(TargetWeaponGroup->Weapons.Num()) + "x ";
		FString HealthInfo = FString::FromInt(100 * ComponentHealth) + "%";

		// Get ammo count
		int32 RemainingAmmo = 0;
		for (int32 i = 0; i < TargetWeaponGroup->Weapons.Num(); i++)
		{
			if(TargetWeaponGroup->Weapons[i]->GetDamageRatio() <= 0.)
			{
				// Don't count ammo from destroyed components
				continue;
			}
			RemainingAmmo += TargetWeaponGroup->Weapons[i]->GetCurrentAmmo();
		}
		FString AmmoInfo = FString::FromInt(RemainingAmmo) + " " + LOCTEXT("Rounds", "rounds").ToString();

		// Final string
		Text = FText::FromString(CountInfo + NameInfo + "\n" + AmmoInfo + "\n" + HealthInfo);
	}

	return Text;
}

FSlateColor SFlareWeaponStatus::GetHighlightColor() const
{
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	FLinearColor NormalColor = Theme.NeutralColor;
	FLinearColor DamageColor = Theme.EnemyColor;

	// Update alpha
	FLinearColor Color = FMath::Lerp(DamageColor, NormalColor, ComponentHealth);
	Color.A *= Theme.DefaultAlpha * CurrentAlpha;
	return Color;
}

FSlateColor SFlareWeaponStatus::GetIconColor() const
{
	FLinearColor NormalColor = FLinearColor::White;
	NormalColor.A *= CurrentAlpha;
	return NormalColor;
}

FSlateColor SFlareWeaponStatus::GetTextColor() const
{
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	FLinearColor NormalColor = Theme.NeutralColor;
	NormalColor.A *= Theme.DefaultAlpha * CurrentAlpha;
	return NormalColor;
}

FLinearColor SFlareWeaponStatus::GetShadowColor() const
{
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	FLinearColor NormalColor = Theme.InvertedColor;
	NormalColor.A *= Theme.DefaultAlpha * CurrentAlpha;
	return NormalColor;
}

#undef LOCTEXT_NAMESPACE
<|endoftext|>


<commit_before>/*************************************************************************
*    UrBackup - Client/Server backup system
*    Copyright (C) 2011  Martin Raiber
*
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/

#ifndef CLIENT_ONLY

#include "server.h"
#include "../Interface/Server.h"
#include "../Interface/Database.h"
#include "../Interface/ThreadPool.h"
#include "server_get.h"
#include "database.h"
#include "../Interface/SettingsReader.h"
#include "server_status.h"
#include "../stringtools.h"
#include "os_functions.h"
#include <memory.h>

const unsigned int waittime=50*1000; //1 min
const int max_offline=5;

BackupServer::BackupServer(IPipe *pExitpipe)
{
	exitpipe=pExitpipe;
}

void BackupServer::operator()(void)
{
	IDatabase *db=Server->getDatabase(Server->getThreadID(),URBACKUPDB_SERVER);
	ISettingsReader *settings=Server->createDBSettingsReader(Server->getDatabase(Server->getThreadID(),URBACKUPDB_SERVER), "settings");

#ifdef _WIN32
	std::wstring tmpdir;
	if(settings->getValue(L"tmpdir", &tmpdir) && !tmpdir.empty())
	{
		os_remove_nonempty_dir(tmpdir+os_file_sep()+L"urbackup_tmp");
		os_create_dir(tmpdir+os_file_sep()+L"urbackup_tmp");
		Server->setTemporaryDirectory(tmpdir+os_file_sep()+L"urbackup_tmp");
	}
	else
	{
		wchar_t tmpp[MAX_PATH];
		DWORD l;
		if((l=GetTempPathW(MAX_PATH, tmpp))==0 || l>MAX_PATH )
		{
			wcscpy_s(tmpp,L"C:\\");
		}

		std::wstring w_tmp=tmpp;

		if(!w_tmp.empty() && w_tmp[w_tmp.size()-1]=='\\')
		{
			w_tmp.erase(w_tmp.size()-1, 1);		}

		os_remove_nonempty_dir(w_tmp+os_file_sep()+L"urbackup_tmp");
		os_create_dir(w_tmp+os_file_sep()+L"urbackup_tmp");
		Server->setTemporaryDirectory(w_tmp+os_file_sep()+L"urbackup_tmp");
	}
#endif

	q_get_extra_hostnames=db->Prepare("SELECT id,hostname FROM extra_clients");
	q_update_extra_ip=db->Prepare("UPDATE extra_clients SET lastip=? WHERE id=?");

	FileClient fc;

	while(true)
	{
		findClients(fc);
		startClients(fc);

		if(!ServerStatus::isActive() && settings->getValue("autoshutdown", "false")=="true")
		{
			writestring("true", "urbackup/shutdown_now");
#ifdef _WIN32
			ExitWindowsEx(EWX_POWEROFF|EWX_FORCEIFHUNG, SHTDN_REASON_MAJOR_APPLICATION|SHTDN_REASON_MINOR_OTHER );
#endif
		}

		std::string r;
		exitpipe->Read(&r, waittime);
		if(r=="exit")
		{
			removeAllClients();
			exitpipe->Write("ok");
			Server->destroy(settings);
			db->destroyAllQueries();
			delete this;
			return;
		}
	}
}

void BackupServer::findClients(FileClient &fc)
{
	db_results res=q_get_extra_hostnames->Read();
	q_get_extra_hostnames->Reset();

	std::vector<in_addr> addr_hints;

	for(size_t i=0;i<res.size();++i)
	{
		unsigned int dest;
		bool b=os_lookuphostname(Server->ConvertToUTF8(res[i][L"hostname"]), &dest);
		if(b)
		{
			q_update_extra_ip->Bind((_i64)dest);
			q_update_extra_ip->Bind(res[i][L"id"]);
			q_update_extra_ip->Write();
			q_update_extra_ip->Reset();

			in_addr tmp;
			tmp.s_addr=dest;
			addr_hints.push_back(tmp);
		}
	}

	_u32 rc=fc.GetServers(true, addr_hints);
	while(rc==ERR_CONTINUE)
	{
		Server->wait(50);
		rc=fc.GetServers(false, addr_hints);
	}

	if(rc==ERR_ERROR)
	{
		Server->Log("Error in BackupServer::findClients rc==ERR_ERROR",LL_ERROR);
	}
}

void BackupServer::startClients(FileClient &fc)
{
	std::vector<std::wstring> names=fc.getServerNames();
	std::vector<sockaddr_in> servers=fc.getServers();

	for(size_t i=0;i<names.size();++i)
	{
		std::map<std::wstring, SClient>::iterator it=clients.find(names[i]);
		if( it==clients.end() )
		{
			Server->Log(L"New Backupclient: "+names[i]);
			ServerStatus::setOnline(names[i], true);
			IPipe *np=Server->createMemoryPipe();

			BackupServerGet *client=new BackupServerGet(np, servers[i], names[i]);
			Server->getThreadPool()->execute(client);

			SClient c;
			c.pipe=np;
			c.offlinecount=0;
			c.addr=servers[i];

			ServerStatus::setIP(names[i], c.addr.sin_addr.s_addr);

			clients.insert(std::pair<std::wstring, SClient>(names[i], c) );
		}
		else if(it->second.offlinecount<max_offline)
		{
			if(it->second.addr.sin_addr.s_addr==servers[i].sin_addr.s_addr)
			{
				it->second.offlinecount=0;
			}
			else
			{
				bool last=true;
				for(size_t j=i+1;j<names.size();++j)
				{
					if(names[j]==names[i])
					{
						last=false;
						break;
					}
				}
				if(last)
				{
					it->second.addr=servers[i];
					std::string msg;
					msg.resize(7+sizeof(sockaddr_in));
					msg[0]='a'; msg[1]='d'; msg[2]='d'; msg[3]='r'; msg[4]='e'; msg[5]='s'; msg[6]='s';
					memcpy(&msg[7], &it->second.addr, sizeof(sockaddr_in));
					it->second.pipe->Write(msg);

					char *ip=(char*)it->second.addr.sin_addr.s_addr;

					Server->Log("New client address: "+nconvert(ip[3])+"."+nconvert(ip[2])+"."+nconvert(ip[1])+"."+nconvert(ip[0]), LL_INFO);

					ServerStatus::setIP(names[i], it->second.addr.sin_addr.s_addr);
				}
			}
		}
	}

	bool c=true;
	size_t maxi=0;
	while(c && !clients.empty())
	{
		c=false;

		size_t i_c=0;
		for(std::map<std::wstring, SClient>::iterator it=clients.begin();it!=clients.end();++it)
		{
			bool found=false;
			for(size_t i=0;i<names.size();++i)
			{
				if( it->first==names[i] )
				{
					found=true;
					break;
				}
			}
			if( found==false || it->second.offlinecount>max_offline)
			{
				if(it->second.offlinecount==max_offline)
				{
					Server->Log(L"Client exitet: "+it->first);
					it->second.pipe->Write("exit");
					++it->second.offlinecount;
					ServerStatus::setOnline(it->first, false);
				}
				else if(it->second.offlinecount>max_offline)
				{
					std::string msg;
					std::vector<std::string> msgs;
					while(it->second.pipe->Read(&msg,0)>0)
					{
						if(msg!="ok")
						{
							msgs.push_back(msg);
						}
						else
						{
							Server->Log(L"Client finished: "+it->first);
							ServerStatus::setDone(it->first, true);
							Server->destroy(it->second.pipe);
							clients.erase(it);
							maxi=i_c;
							c=true;
							break;
						}
					}
					if( c==false )
					{
						for(size_t i=0;i<msgs.size();++i)
						{
							it->second.pipe->Write(msgs[i]);
						}
					}
					else
					{
						break;
					}
				}
				else if(i_c>=maxi)
				{
					++it->second.offlinecount;
				}
			}
			++i_c;
		}
	}
}

void BackupServer::removeAllClients(void)
{
	for(std::map<std::wstring, SClient>::iterator it=clients.begin();it!=clients.end();++it)
	{
		it->second.pipe->Write("exitnow");
		std::string msg;
		while(msg!="ok")
		{
			it->second.pipe->Read(&msg);
			it->second.pipe->Write(msg);
			Server->wait(500);
		}
		Server->destroy(it->second.pipe);
	}
}

#endif //CLIENT_ONLY<commit_msg>Fixed memory access bug<commit_after>/*************************************************************************
*    UrBackup - Client/Server backup system
*    Copyright (C) 2011  Martin Raiber
*
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/

#ifndef CLIENT_ONLY

#include "server.h"
#include "../Interface/Server.h"
#include "../Interface/Database.h"
#include "../Interface/ThreadPool.h"
#include "server_get.h"
#include "database.h"
#include "../Interface/SettingsReader.h"
#include "server_status.h"
#include "../stringtools.h"
#include "os_functions.h"
#include <memory.h>

const unsigned int waittime=50*1000; //1 min
const int max_offline=5;

BackupServer::BackupServer(IPipe *pExitpipe)
{
	exitpipe=pExitpipe;
}

void BackupServer::operator()(void)
{
	IDatabase *db=Server->getDatabase(Server->getThreadID(),URBACKUPDB_SERVER);
	ISettingsReader *settings=Server->createDBSettingsReader(Server->getDatabase(Server->getThreadID(),URBACKUPDB_SERVER), "settings");

#ifdef _WIN32
	std::wstring tmpdir;
	if(settings->getValue(L"tmpdir", &tmpdir) && !tmpdir.empty())
	{
		os_remove_nonempty_dir(tmpdir+os_file_sep()+L"urbackup_tmp");
		os_create_dir(tmpdir+os_file_sep()+L"urbackup_tmp");
		Server->setTemporaryDirectory(tmpdir+os_file_sep()+L"urbackup_tmp");
	}
	else
	{
		wchar_t tmpp[MAX_PATH];
		DWORD l;
		if((l=GetTempPathW(MAX_PATH, tmpp))==0 || l>MAX_PATH )
		{
			wcscpy_s(tmpp,L"C:\\");
		}

		std::wstring w_tmp=tmpp;

		if(!w_tmp.empty() && w_tmp[w_tmp.size()-1]=='\\')
		{
			w_tmp.erase(w_tmp.size()-1, 1);		}

		os_remove_nonempty_dir(w_tmp+os_file_sep()+L"urbackup_tmp");
		os_create_dir(w_tmp+os_file_sep()+L"urbackup_tmp");
		Server->setTemporaryDirectory(w_tmp+os_file_sep()+L"urbackup_tmp");
	}
#endif

	q_get_extra_hostnames=db->Prepare("SELECT id,hostname FROM extra_clients");
	q_update_extra_ip=db->Prepare("UPDATE extra_clients SET lastip=? WHERE id=?");

	FileClient fc;

	while(true)
	{
		findClients(fc);
		startClients(fc);

		if(!ServerStatus::isActive() && settings->getValue("autoshutdown", "false")=="true")
		{
			writestring("true", "urbackup/shutdown_now");
#ifdef _WIN32
			ExitWindowsEx(EWX_POWEROFF|EWX_FORCEIFHUNG, SHTDN_REASON_MAJOR_APPLICATION|SHTDN_REASON_MINOR_OTHER );
#endif
		}

		std::string r;
		exitpipe->Read(&r, waittime);
		if(r=="exit")
		{
			removeAllClients();
			exitpipe->Write("ok");
			Server->destroy(settings);
			db->destroyAllQueries();
			delete this;
			return;
		}
	}
}

void BackupServer::findClients(FileClient &fc)
{
	db_results res=q_get_extra_hostnames->Read();
	q_get_extra_hostnames->Reset();

	std::vector<in_addr> addr_hints;

	for(size_t i=0;i<res.size();++i)
	{
		unsigned int dest;
		bool b=os_lookuphostname(Server->ConvertToUTF8(res[i][L"hostname"]), &dest);
		if(b)
		{
			q_update_extra_ip->Bind((_i64)dest);
			q_update_extra_ip->Bind(res[i][L"id"]);
			q_update_extra_ip->Write();
			q_update_extra_ip->Reset();

			in_addr tmp;
			tmp.s_addr=dest;
			addr_hints.push_back(tmp);
		}
	}

	_u32 rc=fc.GetServers(true, addr_hints);
	while(rc==ERR_CONTINUE)
	{
		Server->wait(50);
		rc=fc.GetServers(false, addr_hints);
	}

	if(rc==ERR_ERROR)
	{
		Server->Log("Error in BackupServer::findClients rc==ERR_ERROR",LL_ERROR);
	}
}

void BackupServer::startClients(FileClient &fc)
{
	std::vector<std::wstring> names=fc.getServerNames();
	std::vector<sockaddr_in> servers=fc.getServers();

	for(size_t i=0;i<names.size();++i)
	{
		std::map<std::wstring, SClient>::iterator it=clients.find(names[i]);
		if( it==clients.end() )
		{
			Server->Log(L"New Backupclient: "+names[i]);
			ServerStatus::setOnline(names[i], true);
			IPipe *np=Server->createMemoryPipe();

			BackupServerGet *client=new BackupServerGet(np, servers[i], names[i]);
			Server->getThreadPool()->execute(client);

			SClient c;
			c.pipe=np;
			c.offlinecount=0;
			c.addr=servers[i];

			ServerStatus::setIP(names[i], c.addr.sin_addr.s_addr);

			clients.insert(std::pair<std::wstring, SClient>(names[i], c) );
		}
		else if(it->second.offlinecount<max_offline)
		{
			if(it->second.addr.sin_addr.s_addr==servers[i].sin_addr.s_addr)
			{
				it->second.offlinecount=0;
			}
			else
			{
				bool last=true;
				for(size_t j=i+1;j<names.size();++j)
				{
					if(names[j]==names[i])
					{
						last=false;
						break;
					}
				}
				if(last)
				{
					it->second.addr=servers[i];
					std::string msg;
					msg.resize(7+sizeof(sockaddr_in));
					msg[0]='a'; msg[1]='d'; msg[2]='d'; msg[3]='r'; msg[4]='e'; msg[5]='s'; msg[6]='s';
					memcpy(&msg[7], &it->second.addr, sizeof(sockaddr_in));
					it->second.pipe->Write(msg);

					char *ip=(char*)&it->second.addr.sin_addr.s_addr;

					Server->Log("New client address: "+nconvert(ip[3])+"."+nconvert(ip[2])+"."+nconvert(ip[1])+"."+nconvert(ip[0]), LL_INFO);

					ServerStatus::setIP(names[i], it->second.addr.sin_addr.s_addr);
				}
			}
		}
	}

	bool c=true;
	size_t maxi=0;
	while(c && !clients.empty())
	{
		c=false;

		size_t i_c=0;
		for(std::map<std::wstring, SClient>::iterator it=clients.begin();it!=clients.end();++it)
		{
			bool found=false;
			for(size_t i=0;i<names.size();++i)
			{
				if( it->first==names[i] )
				{
					found=true;
					break;
				}
			}
			if( found==false || it->second.offlinecount>max_offline)
			{
				if(it->second.offlinecount==max_offline)
				{
					Server->Log(L"Client exitet: "+it->first);
					it->second.pipe->Write("exit");
					++it->second.offlinecount;
					ServerStatus::setOnline(it->first, false);
				}
				else if(it->second.offlinecount>max_offline)
				{
					std::string msg;
					std::vector<std::string> msgs;
					while(it->second.pipe->Read(&msg,0)>0)
					{
						if(msg!="ok")
						{
							msgs.push_back(msg);
						}
						else
						{
							Server->Log(L"Client finished: "+it->first);
							ServerStatus::setDone(it->first, true);
							Server->destroy(it->second.pipe);
							clients.erase(it);
							maxi=i_c;
							c=true;
							break;
						}
					}
					if( c==false )
					{
						for(size_t i=0;i<msgs.size();++i)
						{
							it->second.pipe->Write(msgs[i]);
						}
					}
					else
					{
						break;
					}
				}
				else if(i_c>=maxi)
				{
					++it->second.offlinecount;
				}
			}
			++i_c;
		}
	}
}

void BackupServer::removeAllClients(void)
{
	for(std::map<std::wstring, SClient>::iterator it=clients.begin();it!=clients.end();++it)
	{
		it->second.pipe->Write("exitnow");
		std::string msg;
		while(msg!="ok")
		{
			it->second.pipe->Read(&msg);
			it->second.pipe->Write(msg);
			Server->wait(500);
		}
		Server->destroy(it->second.pipe);
	}
}

#endif //CLIENT_ONLY<|endoftext|>


<commit_before>#include "Camera.h"
#include "../../Window.h"
#include "../GameObject.h"
#include "../../graphics/Skybox.h"
#include "../../graphics/TextRender.h"
#include "Transform.h"
#include "../../graphics/Renderer.h"
#include <algorithm>
#include "../../Input.h"
#include "../../editor/gizmos/Gizmos.h"
namespace thomas
{
	namespace object
	{
		namespace component
		{
			std::vector<Camera*> Camera::s_allCameras;
			void Camera::UpdateProjMatrix()
			{
				m_projMatrix = math::Matrix::CreatePerspectiveFieldOfView(math::DegreesToRadians(m_fov), GetViewport().AspectRatio(), m_near, m_far);
				m_frustrum = math::BoundingFrustum(m_projMatrix);
			}

			Camera::Camera(bool dontAddTolist)
			{
				m_fov = 70;
				m_near = 0.1;
				m_far = 10000;
				m_viewport = math::Viewport(0, 0, 1, 1);
				m_targetDisplay = -1;
				UpdateProjMatrix();
			}

			Camera::Camera()
			{
				m_fov = 70;
				m_near = 0.5;
				m_far = 10000;
				m_viewport = math::Viewport(0, 0, 1,1);
				m_targetDisplay = 0;
				UpdateProjMatrix();
				s_allCameras.push_back(this);
				std::sort(s_allCameras.begin(), s_allCameras.end(), [](Camera* a, Camera* b)
				{
					return a->GetTargetDisplayIndex() < b->GetTargetDisplayIndex();
				});
			}
			Camera::~Camera()
			{
				for (int i = 0; i < s_allCameras.size(); i++)
				{
					if (s_allCameras[i] == this)
					{
						s_allCameras.erase(s_allCameras.begin() + i);
						break;
					}

				}
			}

			math::Matrix Camera::GetProjMatrix()
			{
				return m_projMatrix;
			}

			math::Matrix Camera::GetViewMatrix()
			{
				math::Matrix viewMatrix =  m_gameObject->m_transform->GetWorldMatrix();
				return viewMatrix.Invert();
			}

			math::Matrix Camera::GetViewProjMatrix()
			{
				return GetViewMatrix() * m_projMatrix;
			}

			math::Vector3 Camera::GetPosition()
			{
				return m_gameObject->m_transform->GetPosition();
			}

			math::Ray Camera::ScreenPointToRay(math::Vector2 point)
			{
				// Move the mouse cursor coordinates into the -1 to +1 range.
				Window* window = Window::GetWindow(m_targetDisplay);
				float pointX = ((2.0f * (float)point.x) / (float)window->GetWidth()) - 1.0f;
				float pointY = (((2.0f * (float)point.y) / (float)window->GetHeight()) - 1.0f) * -1.0f;
				// Adjust the points using the projection matrix to account for the aspect ratio of the viewport.
				pointX /= m_projMatrix._11;
				pointY /= m_projMatrix.Transpose()._22;

				// Get the inverse of the view matrix.
				math::Matrix inverseViewMatrix = GetViewMatrix().Invert();

				math::Vector3 direction(pointX, pointY, -1.0f);

				// Calculate the direction of the picking ray in view space.
				direction = math::Vector3::TransformNormal(direction, inverseViewMatrix);

				// Get the origin of the picking ray which is the position of the camera
				math::Vector3 origin = GetPosition();
				direction.Normalize();
				return math::Ray(origin, direction);
			}

			float Camera::GetFov()
			{
				return m_fov;
			}

			float Camera::GetNear()
			{
				return m_near;
			}

			float Camera::GetFar()
			{
				return m_far;
			}

			void Camera::SetFov(float fov)
			{
				m_fov = fov;
				UpdateProjMatrix();
			}

			void Camera::SetNear(float viewNear)
			{
				if (viewNear > 0)
					m_near = viewNear;
				UpdateProjMatrix();
			}

			void Camera::SetFar(float viewFar)
			{
				if (viewFar > 0)
					m_far = viewFar;
				UpdateProjMatrix();
			}

			math::Viewport Camera::GetViewport()
			{
				Window* window = Window::GetWindow(m_targetDisplay);
				if (window)
					return math::Viewport(m_viewport.x, m_viewport.y, m_viewport.width * window->GetWidth(), m_viewport.height * window->GetHeight());
				else
					return m_viewport;
			}

			void Camera::SetViewport(math::Viewport viewport)
			{
				m_viewport = viewport;
				UpdateProjMatrix();
			}

			void Camera::SetViewport(float x, float y, float width, float height)
			{
				SetViewport(math::Viewport(x, y, width, height));
			}

			float Camera::GetAspectRatio()
			{
				return m_viewport.AspectRatio();
			}

			void Camera::Render()
			{
				graphics::Renderer::BindCamera(this);
				graphics::Renderer::Render();
			}

			void Camera::OnDrawGizmos()
			{

			}

			void Camera::OnDrawGizmosSelected()
			{
				//editor::Gizmos::SetMatrix(m_gameObject->m_transform->GetWorldMatrix().Transpose());
				editor::Gizmos::SetColor(math::Color(0.6, 0.6, 0.6));
				editor::Gizmos::DrawFrustum(GetFrustrum());

			}

			void Camera::SetTargetDisplay(int index)
			{
				if (Window::GetWindows().size() < index)
				{
					m_targetDisplay = index;
					UpdateProjMatrix();
				}

			}

			int Camera::GetTargetDisplayIndex()
			{
				return m_targetDisplay;
			}

			math::BoundingFrustum Camera::GetFrustrum()
			{
				math::BoundingFrustum frustrum;
				m_frustrum.Transform(frustrum, m_gameObject->m_transform->GetWorldMatrix());
				return frustrum;
			}

		}
	}
}<commit_msg>Fixed aspect ratio bug<commit_after>#include "Camera.h"
#include "../../Window.h"
#include "../GameObject.h"
#include "../../graphics/Skybox.h"
#include "../../graphics/TextRender.h"
#include "Transform.h"
#include "../../graphics/Renderer.h"
#include <algorithm>
#include "../../Input.h"
#include "../../editor/gizmos/Gizmos.h"
namespace thomas
{
	namespace object
	{
		namespace component
		{
			std::vector<Camera*> Camera::s_allCameras;
			void Camera::UpdateProjMatrix()
			{
				m_projMatrix = math::Matrix::CreatePerspectiveFieldOfView(math::DegreesToRadians(m_fov), GetViewport().AspectRatio(), m_near, m_far);
				m_frustrum = math::BoundingFrustum(m_projMatrix);
			}

			Camera::Camera(bool dontAddTolist)
			{
				m_fov = 70;
				m_near = 0.1;
				m_far = 10000;
				m_viewport = math::Viewport(0, 0, 1, 1);
				m_targetDisplay = -1;
				UpdateProjMatrix();
			}

			Camera::Camera()
			{
				m_fov = 70;
				m_near = 0.5;
				m_far = 10000;
				m_viewport = math::Viewport(0, 0, 1,1);
				m_targetDisplay = 0;
				UpdateProjMatrix();
				s_allCameras.push_back(this);
				std::sort(s_allCameras.begin(), s_allCameras.end(), [](Camera* a, Camera* b)
				{
					return a->GetTargetDisplayIndex() < b->GetTargetDisplayIndex();
				});
			}
			Camera::~Camera()
			{
				for (int i = 0; i < s_allCameras.size(); i++)
				{
					if (s_allCameras[i] == this)
					{
						s_allCameras.erase(s_allCameras.begin() + i);
						break;
					}

				}
			}

			math::Matrix Camera::GetProjMatrix()
			{
				UpdateProjMatrix();
				return m_projMatrix;
			}

			math::Matrix Camera::GetViewMatrix()
			{
				math::Matrix viewMatrix =  m_gameObject->m_transform->GetWorldMatrix();
				return viewMatrix.Invert();
			}

			math::Matrix Camera::GetViewProjMatrix()
			{
				return GetViewMatrix() * m_projMatrix;
			}

			math::Vector3 Camera::GetPosition()
			{
				return m_gameObject->m_transform->GetPosition();
			}

			math::Ray Camera::ScreenPointToRay(math::Vector2 point)
			{
				// Move the mouse cursor coordinates into the -1 to +1 range.
				Window* window = Window::GetWindow(m_targetDisplay);
				float pointX = ((2.0f * (float)point.x) / (float)window->GetWidth()) - 1.0f;
				float pointY = (((2.0f * (float)point.y) / (float)window->GetHeight()) - 1.0f) * -1.0f;
				// Adjust the points using the projection matrix to account for the aspect ratio of the viewport.
				pointX /= m_projMatrix._11;
				pointY /= m_projMatrix.Transpose()._22;

				// Get the inverse of the view matrix.
				math::Matrix inverseViewMatrix = GetViewMatrix().Invert();

				math::Vector3 direction(pointX, pointY, -1.0f);

				// Calculate the direction of the picking ray in view space.
				direction = math::Vector3::TransformNormal(direction, inverseViewMatrix);

				// Get the origin of the picking ray which is the position of the camera
				math::Vector3 origin = GetPosition();
				direction.Normalize();
				return math::Ray(origin, direction);
			}

			float Camera::GetFov()
			{
				return m_fov;
			}

			float Camera::GetNear()
			{
				return m_near;
			}

			float Camera::GetFar()
			{
				return m_far;
			}

			void Camera::SetFov(float fov)
			{
				m_fov = fov;
				UpdateProjMatrix();
			}

			void Camera::SetNear(float viewNear)
			{
				if (viewNear > 0)
					m_near = viewNear;
				UpdateProjMatrix();
			}

			void Camera::SetFar(float viewFar)
			{
				if (viewFar > 0)
					m_far = viewFar;
				UpdateProjMatrix();
			}

			math::Viewport Camera::GetViewport()
			{
				Window* window = Window::GetWindow(m_targetDisplay);
				if (window)
					return math::Viewport(m_viewport.x, m_viewport.y, m_viewport.width * window->GetWidth(), m_viewport.height * window->GetHeight());
				else
					return m_viewport;
			}

			void Camera::SetViewport(math::Viewport viewport)
			{
				m_viewport = viewport;
				UpdateProjMatrix();
			}

			void Camera::SetViewport(float x, float y, float width, float height)
			{
				SetViewport(math::Viewport(x, y, width, height));
			}

			float Camera::GetAspectRatio()
			{
				return m_viewport.AspectRatio();
			}

			void Camera::Render()
			{
				graphics::Renderer::BindCamera(this);
				graphics::Renderer::Render();
			}

			void Camera::OnDrawGizmos()
			{

			}

			void Camera::OnDrawGizmosSelected()
			{
				//editor::Gizmos::SetMatrix(m_gameObject->m_transform->GetWorldMatrix().Transpose());
				editor::Gizmos::SetColor(math::Color(0.6, 0.6, 0.6));
				editor::Gizmos::DrawFrustum(GetFrustrum());

			}

			void Camera::SetTargetDisplay(int index)
			{
				if (Window::GetWindows().size() < index)
				{
					m_targetDisplay = index;
					UpdateProjMatrix();
				}

			}

			int Camera::GetTargetDisplayIndex()
			{
				return m_targetDisplay;
			}

			math::BoundingFrustum Camera::GetFrustrum()
			{
				math::BoundingFrustum frustrum;
				m_frustrum.Transform(frustrum, m_gameObject->m_transform->GetWorldMatrix());
				return frustrum;
			}

		}
	}
}<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "otbMacro.h"
#include "otbImage.h"
#include "otbMapProjections.h"

//TODO add control baseline
int otbMapProjection( int argc, char* argv[] )
{
  const char * outFileName = argv[1];
  std::ofstream file;
  file.open(outFileName);

  otb::UtmInverseProjection::Pointer lUtmProjection = otb::UtmInverseProjection::New();
  file << lUtmProjection->GetWkt() << std::endl << std::endl;

  otb::UtmForwardProjection::Pointer lUtmProjection2 = otb::UtmForwardProjection::New();
  file << lUtmProjection2->GetWkt() << std::endl << std::endl;

  otb::Lambert2EtenduInverseProjection::Pointer lLambert2Etendu = otb::Lambert2EtenduInverseProjection::New();
  file << lLambert2Etendu->GetWkt() << std::endl << std::endl;

  otb::Lambert2EtenduForwardProjection::Pointer lLambert2Etendu2 = otb::Lambert2EtenduForwardProjection::New();
  file << lLambert2Etendu2->GetWkt() << std::endl << std::endl;

  otb::Lambert93InverseProjection::Pointer lLambert93 = otb::Lambert93InverseProjection::New();
  file << lLambert93->GetWkt() << std::endl << std::endl;

  otb::Lambert93ForwardProjection::Pointer lLambert93_2 = otb::Lambert93ForwardProjection::New();
  file << lLambert93_2->GetWkt() << std::endl << std::endl;

  otb::MercatorInverseProjection::Pointer lMercatorProjection = otb::MercatorInverseProjection::New();
  file << lMercatorProjection->GetWkt() << std::endl << std::endl;

  otb::MercatorForwardProjection::Pointer lMercatorProjection2 = otb::MercatorForwardProjection::New();
  file << lMercatorProjection2->GetWkt() << std::endl << std::endl;

  file.close();
  return EXIT_SUCCESS;

}<commit_msg>WRG : add a new line at the end of otbMapProjection.cxx<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "otbMacro.h"
#include "otbImage.h"
#include "otbMapProjections.h"

//TODO add control baseline
int otbMapProjection( int argc, char* argv[] )
{
  const char * outFileName = argv[1];
  std::ofstream file;
  file.open(outFileName);

  otb::UtmInverseProjection::Pointer lUtmProjection = otb::UtmInverseProjection::New();
  file << lUtmProjection->GetWkt() << std::endl << std::endl;

  otb::UtmForwardProjection::Pointer lUtmProjection2 = otb::UtmForwardProjection::New();
  file << lUtmProjection2->GetWkt() << std::endl << std::endl;

  otb::Lambert2EtenduInverseProjection::Pointer lLambert2Etendu = otb::Lambert2EtenduInverseProjection::New();
  file << lLambert2Etendu->GetWkt() << std::endl << std::endl;

  otb::Lambert2EtenduForwardProjection::Pointer lLambert2Etendu2 = otb::Lambert2EtenduForwardProjection::New();
  file << lLambert2Etendu2->GetWkt() << std::endl << std::endl;

  otb::Lambert93InverseProjection::Pointer lLambert93 = otb::Lambert93InverseProjection::New();
  file << lLambert93->GetWkt() << std::endl << std::endl;

  otb::Lambert93ForwardProjection::Pointer lLambert93_2 = otb::Lambert93ForwardProjection::New();
  file << lLambert93_2->GetWkt() << std::endl << std::endl;

  otb::MercatorInverseProjection::Pointer lMercatorProjection = otb::MercatorInverseProjection::New();
  file << lMercatorProjection->GetWkt() << std::endl << std::endl;

  otb::MercatorForwardProjection::Pointer lMercatorProjection2 = otb::MercatorForwardProjection::New();
  file << lMercatorProjection2->GetWkt() << std::endl << std::endl;

  file.close();
  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>

using namespace std;

int main() {
	// Declara as variavéis A B MEDIA
	double A, B, MEDIA;
	// Leiura das var A e B
	cin >> A;
	cin >> B;
	// Produto dos pesos e cálcula a média e armazenada na var MEDIA
	MEDIA = ((A*3.5)+(B*7.5))/11;
	// Setar a precisao para 5 casas
	cout << fixed << setprecision(5);
	// Mostra o resultado em MEDIA
	cout << "MEDIA = " << MEDIA << endl;
    return 0;
}<commit_msg>Delete 1005.cpp<commit_after><|endoftext|>


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

#include "base/sync_socket.h"

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <sys/types.h>

#include "base/logging.h"

namespace base {

const SyncSocket::Handle SyncSocket::kInvalidHandle = -1;

SyncSocket::SyncSocket() : handle_(kInvalidHandle) {
}

SyncSocket::~SyncSocket() {
}

// static
bool SyncSocket::CreatePair(SyncSocket* socket_a, SyncSocket* socket_b) {
  return false;
}

bool SyncSocket::Close() {
  if (handle_ != kInvalidHandle) {
    if (close(handle_) < 0)
      DPLOG(ERROR) << "close";
    handle_ = -1;
  }
  return true;
}

size_t SyncSocket::Send(const void* buffer, size_t length) {
  // Not implemented since it's not needed by any client code yet.
  return -1;
}

size_t SyncSocket::Receive(void* buffer, size_t length) {
  return read(handle_, buffer, length);
}

size_t SyncSocket::ReceiveWithTimeout(void* buffer, size_t length, TimeDelta) {
  NOTIMPLEMENTED();
  return 0;
}

size_t SyncSocket::Peek() {
  return -1;
}

CancelableSyncSocket::CancelableSyncSocket() {
}

CancelableSyncSocket::CancelableSyncSocket(Handle handle)
    : SyncSocket(handle) {
}

size_t CancelableSyncSocket::Send(const void* buffer, size_t length) {
  return -1;
}

bool CancelableSyncSocket::Shutdown() {
  return false;
}

// static
bool CancelableSyncSocket::CreatePair(CancelableSyncSocket* socket_a,
                                      CancelableSyncSocket* socket_b) {
  return SyncSocket::CreatePair(socket_a, socket_b);
}

}  // namespace base
<commit_msg>Add write() impl to SyncSocket for NaCl.  Fix shutdown leaks.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/sync_socket.h"

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <sys/types.h>

#include "base/logging.h"

namespace base {

const SyncSocket::Handle SyncSocket::kInvalidHandle = -1;

SyncSocket::SyncSocket() : handle_(kInvalidHandle) {
}

SyncSocket::~SyncSocket() {
  Close();
}

// static
bool SyncSocket::CreatePair(SyncSocket* socket_a, SyncSocket* socket_b) {
  return false;
}

bool SyncSocket::Close() {
  if (handle_ != kInvalidHandle) {
    if (close(handle_) < 0)
      DPLOG(ERROR) << "close";
    handle_ = kInvalidHandle;
  }
  return true;
}

size_t SyncSocket::Send(const void* buffer, size_t length) {
  const ssize_t bytes_written = write(handle_, buffer, length);
  return bytes_written > 0 ? bytes_written : 0;
}

size_t SyncSocket::Receive(void* buffer, size_t length) {
  const ssize_t bytes_read = read(handle_, buffer, length);
  return bytes_read > 0 ? bytes_read : 0;
}

size_t SyncSocket::ReceiveWithTimeout(void* buffer, size_t length, TimeDelta) {
  NOTIMPLEMENTED();
  return 0;
}

size_t SyncSocket::Peek() {
  NOTIMPLEMENTED();
  return 0;
}

CancelableSyncSocket::CancelableSyncSocket() {
}

CancelableSyncSocket::CancelableSyncSocket(Handle handle)
    : SyncSocket(handle) {
}

size_t CancelableSyncSocket::Send(const void* buffer, size_t length) {
  return Send(buffer, length);
}

bool CancelableSyncSocket::Shutdown() {
  return Close();
}

// static
bool CancelableSyncSocket::CreatePair(CancelableSyncSocket* socket_a,
                                      CancelableSyncSocket* socket_b) {
  return SyncSocket::CreatePair(socket_a, socket_b);
}

}  // namespace base
<|endoftext|>