<commit_before>/*
 * main.cpp -- This file is part of primesieve
 *
 * Copyright (C) 2011 Kim Walisch, <kim.walisch@gmail.com>
 *
 * 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/>
 */

/**
 * @file  main.cpp
 * @brief Command-line version of primesieve, multi-threaded (OpenMP),
 *        compiles on many platforms.
 *
 * primesieve is a highly optimized implementation of the sieve of
 * Eratosthenes that generates prime numbers and prime k-tuplets (twin
 * primes, prime triplets, ...) up to 2^64 maximum.
 */

#include "../expr/ExpressionParser.h"
#include "../soe/ParallelPrimeSieve.h"
#include "../soe/pmath.h"

/// declared in test.cpp
void test();

#include <stdint.h>
#include <exception>
#include <iostream>
#include <iomanip>    /* std::setw(int) */
#include <cstdlib>    /* std::exit(int) */
#include <string>
#include <cctype>     /* std::tolower(int) */

namespace {
  // Unfortunately there is no easy way to get the CPU L1 and L2 cache
  // size, these values are close for most x86-64 CPUs in 2011
  const uint32_t L1_CACHE_SIZE = 64;
  const uint32_t L2_CACHE_SIZE = 512;
  const uint64_t L2_THRESHOLD = ipow(10, 13);

  bool quietMode = false;
  bool showExpressionResults = false;

  uint64_t numbers[2] = {0, 0};  /* start and stop number for sieving */
  uint32_t sieveSize = 0;        /* sieve size in KiloBytes */
  uint32_t flags = 0;            /* settings */

  int maxThreads = ParallelPrimeSieve::getMaxThreads();
  int threads    = ParallelPrimeSieve::USE_IDEAL_NUM_THREADS;

  std::string primes[7] = { "Prime numbers", "Twin primes", "Prime triplets",
    "Prime quadruplets", "Prime quintuplets", "Prime sextuplets",
    "Prime septuplets" };
}

void version() {
  std::cout << "primesieve 2.1, <http://primesieve.googlecode.com>" << std::endl
            << "Copyright (C) 2011 Kim Walisch" << std::endl
            << "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>." << std::endl
            << "This is free software: you are free to change and redistribute it." << std::endl
            << "There is NO WARRANTY, to the extent permitted by law." << std::endl;
  std::exit(EXIT_SUCCESS);
}

void help() {
  std::cout << "Usage: primesieve START STOP [OPTION]..." << std::endl
            << "Use the sieve of Eratosthenes to find the prime numbers and prime" << std::endl
            << "k-tuplets between START and STOP < 2^64" << std::endl
            << std::endl
            << "Examples:" << std::endl
            << "  primesieve 1 10000000 -p1" << std::endl
            << "  primesieve 1 1e11 -s 32" << std::endl
            << "  primesieve 1e18 1e18+2**32 -c1234567" << std::endl
            << std::endl
            << "Options:" << std::endl
            << "  -c[N]        Count prime numbers and/or prime k-tuplets," << std::endl
            << "               e.g -c1 count prime numbers, -c3 count prime triplets, ..." << std::endl
            << "               N >= 1 and N <= 7" << std::endl
            << "  -p[N]        Print prime numbers or prime k-tuplets," << std::endl
            << "               e.g -p1 print prime numbers, -p2 print twin primes, ..." << std::endl
            << "               N >= 1 and N <= 7" << std::endl
            << "  -q           Quiet mode, print less output" << std::endl
            << "  -s <SIZE>    Set the sieve size in KiloBytes, e.g. -s 256," << std::endl
            << "               set SIZE to your CPU's L1/L2 cache size for best performance" << std::endl
            << "               SIZE >= 1 and SIZE <= 8192" << std::endl
            << "  -t <THREADS> Set the number of threads for sieving, e.g. -t 4," << std::endl
            << "               THREADS >= 1 and THREADS <= " << maxThreads << " (CPU max threads)" << std::endl
            << "  -test        Run various sieving tests and exit" << std::endl
            << "  -v           Print version and license information and exit" << std::endl;
  std::exit(EXIT_SUCCESS);
}

bool isDigits(const std::string &str) {
  if (str.length() == 0)
    return false;
  return str.find_first_not_of("0123456789") == std::string::npos;
}

/**
 * Process the command-line options.
 * @see help(void)
 */
void processOptions(int argc, char* argv[]) {
  if (argc < 2 || argc > 20)
    help();
  ExpressionParser<uint64_t> parser;
  int i = 1;

  // process the START and STOP numbers
  if (argc > 2)
    for (; i <= 2; i++) {
      if (!parser.eval(argv[i])) {
        std::cerr << "Error: \"" << argv[i]  << "\" is not a valid arithmetic expression" << std::endl
                  << "Try `primesieve -help' for more information." << std::endl;
        std::exit(EXIT_FAILURE);
      }
      numbers[i-1] = parser.getResult();
      if (!isDigits(argv[i]))
        showExpressionResults = true;
    }

  // process the options ([OPTION]...)
  for (; i < argc; i++) {
    char* c = argv[i];
    if (*c != '-' && *c != '/')
      help();
    switch (std::tolower(*(++c)++)) {
      case 'c': do {
                  if (*c < '1' || *c > '7')
                    help();
                  flags |= COUNT_PRIMES << (*c - '1');
                } while (*(++c) != 0);
                break;
      case 'p': if (*c < '1' || *c > '7')
                  help();
                flags |= PRINT_PRIMES << (*c - '1');
                quietMode = true;
                break;
      case 'q': quietMode = true;
                break;
      case 's': if (++i >= argc || !parser.eval(argv[i]))
                  help();
                sieveSize = static_cast<uint32_t> (parser.getResult());
                sieveSize = nextHighestPowerOf2(sieveSize);
                break;
      case 't': if (std::string("test").compare(++argv[i]) == 0) {
                  test();
                  std::exit(EXIT_SUCCESS);
                }
                if (++i >= argc || !parser.eval(argv[i]))
                  help();
                threads = static_cast<int> (parser.getResult());
                break;
      case 'v': version();
      default : help();
    }
  }
}

/**
 * Process the command-line options and start sieving.
 */
int main(int argc, char* argv[]) {
  processOptions(argc, argv);
  std::cout.setf(std::ios::left);

  // display expression results
  if (!quietMode && showExpressionResults)
    std::cout << std::setw(10) << "START" << " = " << numbers[0] << std::endl
              << std::setw(10) << "STOP"  << " = " << numbers[1]  << std::endl;

  // set default settings
  if ((flags & COUNT_FLAGS) == 0 && (flags & PRINT_FLAGS) == 0)
    flags |= COUNT_PRIMES;
  if (!quietMode && (flags & PRINT_FLAGS) == 0)
    flags |= PRINT_STATUS;
  if (sieveSize == 0)
    sieveSize = (numbers[1] < L2_THRESHOLD) ?L1_CACHE_SIZE :L2_CACHE_SIZE;
  if (!quietMode)
    std::cout << std::setw(10) << "Sieve size" << " = " << sieveSize
              << " KiloBytes" << std::endl;
  try {
    // init primeSieve
    ParallelPrimeSieve primeSieve;
    primeSieve.setStartNumber(numbers[0]);
    primeSieve.setStopNumber(numbers[1]);
    primeSieve.setSieveSize(sieveSize);
    primeSieve.setFlags(flags);
    primeSieve.setNumThreads(threads);

    if (!quietMode)
      std::cout << std::setw(10) << "Threads" << " = " << primeSieve.getNumThreads() << std::endl;

    // start sieving primes
    primeSieve.sieve();

    // print new line
    if ((flags & PRINT_STATUS) || (
        (flags & PRINT_FLAGS) &&
        (flags & COUNT_FLAGS) ))
      std::cout << std::endl;

    // get max output width
    std::size_t width = (quietMode) ?0 :12;
    for (int i = 0; i < primeSieve.COUNTS_SIZE; i++)
      if ((flags & (COUNT_PRIMES << i)) && width < primes[i].length())
        width = primes[i].length();

    // print prime count results
    for (int i = 0; i < primeSieve.COUNTS_SIZE; i++)
      if (flags & (COUNT_PRIMES << i))
        std::cout << std::setw(static_cast<int> (width)) << primes[i] << " : "
                  << primeSieve.getCounts(i) << std::endl;

    // print time elapsed
    if (!quietMode)
      std::cout << std::setw(static_cast<int> (width)) << "Time elapsed" << " : "
                << primeSieve.getTimeElapsed() << " sec" << std::endl;
  }
  catch (std::exception& ex) {
    std::cerr << "Error: " << ex.what() << std::endl
              << "Try `primesieve -help' for more information." << std::endl;
    std::exit(EXIT_FAILURE);
  }
  return 0;
}
<commit_msg>updated version number<commit_after>/*
 * main.cpp -- This file is part of primesieve
 *
 * Copyright (C) 2011 Kim Walisch, <kim.walisch@gmail.com>
 *
 * 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/>
 */

/**
 * @file  main.cpp
 * @brief Command-line version of primesieve, multi-threaded (OpenMP),
 *        compiles on many platforms.
 *
 * primesieve is a highly optimized implementation of the sieve of
 * Eratosthenes that generates prime numbers and prime k-tuplets (twin
 * primes, prime triplets, ...) up to 2^64 maximum.
 */

#include "../expr/ExpressionParser.h"
#include "../soe/ParallelPrimeSieve.h"
#include "../soe/pmath.h"

/// declared in test.cpp
void test();

#include <stdint.h>
#include <exception>
#include <iostream>
#include <iomanip>    /* std::setw(int) */
#include <cstdlib>    /* std::exit(int) */
#include <string>
#include <cctype>     /* std::tolower(int) */

namespace {
  // Unfortunately there is no easy way to get the CPU L1 and L2 cache
  // size, these values are close for most x86-64 CPUs in 2011
  const uint32_t L1_CACHE_SIZE = 64;
  const uint32_t L2_CACHE_SIZE = 512;
  const uint64_t L2_THRESHOLD = ipow(10, 13);

  bool quietMode = false;
  bool showExpressionResults = false;

  uint64_t numbers[2] = {0, 0};  /* start and stop number for sieving */
  uint32_t sieveSize = 0;        /* sieve size in KiloBytes */
  uint32_t flags = 0;            /* settings */

  int maxThreads = ParallelPrimeSieve::getMaxThreads();
  int threads    = ParallelPrimeSieve::USE_IDEAL_NUM_THREADS;

  std::string primes[7] = { "Prime numbers", "Twin primes", "Prime triplets",
    "Prime quadruplets", "Prime quintuplets", "Prime sextuplets",
    "Prime septuplets" };
}

void version() {
  std::cout << "primesieve 2.2, <http://primesieve.googlecode.com>" << std::endl
            << "Copyright (C) 2011 Kim Walisch" << std::endl
            << "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>." << std::endl
            << "This is free software: you are free to change and redistribute it." << std::endl
            << "There is NO WARRANTY, to the extent permitted by law." << std::endl;
  std::exit(EXIT_SUCCESS);
}

void help() {
  std::cout << "Usage: primesieve START STOP [OPTION]..." << std::endl
            << "Use the sieve of Eratosthenes to find the prime numbers and prime" << std::endl
            << "k-tuplets between START and STOP < 2^64" << std::endl
            << std::endl
            << "Examples:" << std::endl
            << "  primesieve 1 10000000 -p1" << std::endl
            << "  primesieve 1 1e11 -s 32" << std::endl
            << "  primesieve 1e18 1e18+2**32 -c1234567" << std::endl
            << std::endl
            << "Options:" << std::endl
            << "  -c[N]        Count prime numbers and/or prime k-tuplets," << std::endl
            << "               e.g -c1 count prime numbers, -c3 count prime triplets, ..." << std::endl
            << "               N >= 1 and N <= 7" << std::endl
            << "  -p[N]        Print prime numbers or prime k-tuplets," << std::endl
            << "               e.g -p1 print prime numbers, -p2 print twin primes, ..." << std::endl
            << "               N >= 1 and N <= 7" << std::endl
            << "  -q           Quiet mode, print less output" << std::endl
            << "  -s <SIZE>    Set the sieve size in KiloBytes, e.g. -s 256," << std::endl
            << "               set SIZE to your CPU's L1/L2 cache size for best performance" << std::endl
            << "               SIZE >= 1 and SIZE <= 8192" << std::endl
            << "  -t <THREADS> Set the number of threads for sieving, e.g. -t 4," << std::endl
            << "               THREADS >= 1 and THREADS <= " << maxThreads << " (CPU max threads)" << std::endl
            << "  -test        Run various sieving tests and exit" << std::endl
            << "  -v           Print version and license information and exit" << std::endl;
  std::exit(EXIT_SUCCESS);
}

bool isDigits(const std::string &str) {
  if (str.length() == 0)
    return false;
  return str.find_first_not_of("0123456789") == std::string::npos;
}

/**
 * Process the command-line options.
 * @see help(void)
 */
void processOptions(int argc, char* argv[]) {
  if (argc < 2 || argc > 20)
    help();
  ExpressionParser<uint64_t> parser;
  int i = 1;

  // process the START and STOP numbers
  if (argc > 2)
    for (; i <= 2; i++) {
      if (!parser.eval(argv[i])) {
        std::cerr << "Error: \"" << argv[i]  << "\" is not a valid arithmetic expression" << std::endl
                  << "Try `primesieve -help' for more information." << std::endl;
        std::exit(EXIT_FAILURE);
      }
      numbers[i-1] = parser.getResult();
      if (!isDigits(argv[i]))
        showExpressionResults = true;
    }

  // process the options ([OPTION]...)
  for (; i < argc; i++) {
    char* c = argv[i];
    if (*c != '-' && *c != '/')
      help();
    switch (std::tolower(*(++c)++)) {
      case 'c': do {
                  if (*c < '1' || *c > '7')
                    help();
                  flags |= COUNT_PRIMES << (*c - '1');
                } while (*(++c) != 0);
                break;
      case 'p': if (*c < '1' || *c > '7')
                  help();
                flags |= PRINT_PRIMES << (*c - '1');
                quietMode = true;
                break;
      case 'q': quietMode = true;
                break;
      case 's': if (++i >= argc || !parser.eval(argv[i]))
                  help();
                sieveSize = static_cast<uint32_t> (parser.getResult());
                sieveSize = nextHighestPowerOf2(sieveSize);
                break;
      case 't': if (std::string("test").compare(++argv[i]) == 0) {
                  test();
                  std::exit(EXIT_SUCCESS);
                }
                if (++i >= argc || !parser.eval(argv[i]))
                  help();
                threads = static_cast<int> (parser.getResult());
                break;
      case 'v': version();
      default : help();
    }
  }
}

/**
 * Process the command-line options and start sieving.
 */
int main(int argc, char* argv[]) {
  processOptions(argc, argv);
  std::cout.setf(std::ios::left);

  // display expression results
  if (!quietMode && showExpressionResults)
    std::cout << std::setw(10) << "START" << " = " << numbers[0] << std::endl
              << std::setw(10) << "STOP"  << " = " << numbers[1]  << std::endl;

  // set default settings
  if ((flags & COUNT_FLAGS) == 0 && (flags & PRINT_FLAGS) == 0)
    flags |= COUNT_PRIMES;
  if (!quietMode && (flags & PRINT_FLAGS) == 0)
    flags |= PRINT_STATUS;
  if (sieveSize == 0)
    sieveSize = (numbers[1] < L2_THRESHOLD) ?L1_CACHE_SIZE :L2_CACHE_SIZE;
  if (!quietMode)
    std::cout << std::setw(10) << "Sieve size" << " = " << sieveSize
              << " KiloBytes" << std::endl;
  try {
    // init primeSieve
    ParallelPrimeSieve primeSieve;
    primeSieve.setStartNumber(numbers[0]);
    primeSieve.setStopNumber(numbers[1]);
    primeSieve.setSieveSize(sieveSize);
    primeSieve.setFlags(flags);
    primeSieve.setNumThreads(threads);

    if (!quietMode)
      std::cout << std::setw(10) << "Threads" << " = " << primeSieve.getNumThreads() << std::endl;

    // start sieving primes
    primeSieve.sieve();

    // print new line
    if ((flags & PRINT_STATUS) || (
        (flags & PRINT_FLAGS) &&
        (flags & COUNT_FLAGS) ))
      std::cout << std::endl;

    // get max output width
    std::size_t width = (quietMode) ?0 :12;
    for (int i = 0; i < primeSieve.COUNTS_SIZE; i++)
      if ((flags & (COUNT_PRIMES << i)) && width < primes[i].length())
        width = primes[i].length();

    // print prime count results
    for (int i = 0; i < primeSieve.COUNTS_SIZE; i++)
      if (flags & (COUNT_PRIMES << i))
        std::cout << std::setw(static_cast<int> (width)) << primes[i] << " : "
                  << primeSieve.getCounts(i) << std::endl;

    // print time elapsed
    if (!quietMode)
      std::cout << std::setw(static_cast<int> (width)) << "Time elapsed" << " : "
                << primeSieve.getTimeElapsed() << " sec" << std::endl;
  }
  catch (std::exception& ex) {
    std::cerr << "Error: " << ex.what() << std::endl
              << "Try `primesieve -help' for more information." << std::endl;
    std::exit(EXIT_FAILURE);
  }
  return 0;
}
<|endoftext|>


<commit_before><commit_msg>mpImplWin only exists for dropdown ListBoxes<commit_after><|endoftext|>


<commit_before>/*
  This file is part of Pack My Sprites.

  Pack My Sprites is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
  the Free Software Foundation, either version 3 of the License.

  Pack My Sprites 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 Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <boost/spirit/include/classic_ast.hpp>

template <typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::
error_report_parser::error_report_parser()
{

}

template <typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::
error_report_parser::error_report_parser( const std::string msg )
  : m_msg(msg)
{

}

template <typename ScannerT>
template <typename LocalScanner>
int
pms::serialization::spritedesc::grammar::definition<ScannerT>::
error_report_parser::operator()
  (const LocalScanner& scan, result_t& /*result*/) const
{
  boost::spirit::classic::file_position fpos = scan.first.get_position();

  std::cerr << fpos.file << ": " << fpos.line << ": "
            << fpos.column << ": " << m_msg << std::endl;

  return -1;
}

template <typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::
char_error_report_parser::char_error_report_parser()
{

}

template <typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::
char_error_report_parser::char_error_report_parser( char c )
  : error_report_parser( std::string("Missing character '") + c + "'." )
{

}

template<typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::definition
( const grammar& self )
{
  initialize_error_parsers();

  m_file = m_atlas;

  m_atlas =
    boost::spirit::classic::no_node_d
    [ boost::spirit::classic::strlit<>("atlas") ]
    >> ( m_string | m_error_atlas )
    >> ( ( boost::spirit::classic::uint_p
           >> boost::spirit::classic::no_node_d
           [ boost::spirit::classic::ch_p('x') ]
           >> boost::spirit::classic::uint_p )
         | m_error_size )
    >> !m_margin
    >> !m_order
    >> *m_image_declaration >> *m_sprite_atlas_page;

  m_margin =
    boost::spirit::classic::no_node_d
    [ boost::spirit::classic::strlit<>("margin") ]
    >> boost::spirit::classic::uint_p
    ;

  m_order =
    boost::spirit::classic::no_node_d
    [ boost::spirit::classic::strlit<>("order") ]
    >> (m_string | m_error_string)
    ;

  m_image_declaration =
    m_identifier >> (m_string | m_error_string);

  m_sprite_atlas_page = m_sprite_declaration;

  m_sprite_declaration =
    !m_properties
    >> m_string
    >> ( m_sprite_size | m_error_autosize )
    >> boost::spirit::classic::no_node_d
       [ boost::spirit::classic::strlit<>("with") ]
    >> m_identifier
    >> m_layer_list
    >> !m_mask
    >> ( boost::spirit::classic::no_node_d
         [ boost::spirit::classic::ch_p(';') ] | m_error_semicolon )
    ;

  m_mask =
    boost::spirit::classic::no_node_d
    [ boost::spirit::classic::strlit<>("mask") ]
    >> m_layer_list;
    ;

  m_layer_list =
    *m_layer_reference;

  m_layer_reference =
    ( !m_properties >> (m_string | m_glob) )
    | m_exclude;

  m_properties =
    boost::spirit::classic::no_node_d[ boost::spirit::classic::ch_p('[') ]
    >> *m_identifier
    >> boost::spirit::classic::no_node_d[ boost::spirit::classic::ch_p(']') ]
    ;

  m_glob =
    boost::spirit::classic::strlit<>("glob")
    >> m_string;
    ;

  m_exclude =
    boost::spirit::classic::strlit<>("exclude")
    >> (m_string | m_glob);

  m_sprite_size =
    ( m_identifier | m_string )
    >> !( boost::spirit::classic::no_node_d[ boost::spirit::classic::ch_p('*') ]
          >> boost::spirit::classic::real_p );

  m_identifier =
    boost::spirit::classic::no_node_d[ *boost::spirit::classic::blank_p ]
    >>    boost::spirit::classic::token_node_d
    [ boost::spirit::classic::lexeme_d[ (boost::spirit::classic::alpha_p | '_')
                               >> *(boost::spirit::classic::alnum_p | '_') ]
      ];

  m_string =
    boost::spirit::classic::lexeme_d
    [ boost::spirit::classic::no_node_d[ boost::spirit::classic::ch_p('"') ]
      >> boost::spirit::classic::token_node_d
      [ *(boost::spirit::classic::strlit<>("\\\"")
          | (boost::spirit::classic::anychar_p - '"') ) ]
      >> boost::spirit::classic::no_node_d
      [ ( '"' | m_error_not_terminated_string ) ]
    ];
}

template<typename ScannerT>
void pms::serialization::spritedesc::grammar::definition<ScannerT>::
initialize_error_parsers()
{
  m_error_autosize =
    error_report_parser( "Size expected, like: autosize * 0.5." );
  m_error_identifier = error_report_parser( "Identifier expected." );
  m_error_string = error_report_parser( "String expected." );
  m_error_not_terminated_string =
    error_report_parser( "Not terminated string." );

  m_error_atlas = error_report_parser( "atlas expected" );
  m_error_size = error_report_parser( "Size expected (width x height)." );

  m_error_semicolon = char_error_report_parser( ';' );
}
<commit_msg>Fix string replacement error in the grammar.<commit_after>/*
  This file is part of Pack My Sprites.

  Pack My Sprites is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
  the Free Software Foundation, either version 3 of the License.

  Pack My Sprites 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 Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <boost/spirit/include/classic_ast.hpp>

template <typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::
error_report_parser::error_report_parser()
{

}

template <typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::
error_report_parser::error_report_parser( const std::string msg )
  : m_msg(msg)
{

}

template <typename ScannerT>
template <typename LocalScanner>
int
pms::serialization::spritedesc::grammar::definition<ScannerT>::
error_report_parser::operator()
  (const LocalScanner& scan, result_t& /*result*/) const
{
  boost::spirit::classic::file_position fpos = scan.first.get_position();

  std::cerr << fpos.file << ": " << fpos.line << ": "
            << fpos.column << ": " << m_msg << std::endl;

  return -1;
}

template <typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::
char_error_report_parser::char_error_report_parser()
{

}

template <typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::
char_error_report_parser::char_error_report_parser( char c )
  : error_report_parser( std::string("Missing character '") + c + "'." )
{

}

template<typename ScannerT>
pms::serialization::spritedesc::grammar::definition<ScannerT>::definition
( const grammar& self )
{
  initialize_error_parsers();

  m_file = m_atlas;

  m_atlas =
    boost::spirit::classic::no_node_d
    [ boost::spirit::classic::strlit<>("sprite_sheet") ]
    >> ( m_string | m_error_atlas )
    >> ( ( boost::spirit::classic::uint_p
           >> boost::spirit::classic::no_node_d
           [ boost::spirit::classic::ch_p('x') ]
           >> boost::spirit::classic::uint_p )
         | m_error_size )
    >> !m_margin
    >> !m_order
    >> *m_image_declaration >> *m_sprite_atlas_page;

  m_margin =
    boost::spirit::classic::no_node_d
    [ boost::spirit::classic::strlit<>("margin") ]
    >> boost::spirit::classic::uint_p
    ;

  m_order =
    boost::spirit::classic::no_node_d
    [ boost::spirit::classic::strlit<>("order") ]
    >> (m_string | m_error_string)
    ;

  m_image_declaration =
    m_identifier >> (m_string | m_error_string);

  m_sprite_atlas_page = m_sprite_declaration;

  m_sprite_declaration =
    !m_properties
    >> m_string
    >> ( m_sprite_size | m_error_autosize )
    >> boost::spirit::classic::no_node_d
       [ boost::spirit::classic::strlit<>("with") ]
    >> m_identifier
    >> m_layer_list
    >> !m_mask
    >> ( boost::spirit::classic::no_node_d
         [ boost::spirit::classic::ch_p(';') ] | m_error_semicolon )
    ;

  m_mask =
    boost::spirit::classic::no_node_d
    [ boost::spirit::classic::strlit<>("mask") ]
    >> m_layer_list;
    ;

  m_layer_list =
    *m_layer_reference;

  m_layer_reference =
    ( !m_properties >> (m_string | m_glob) )
    | m_exclude;

  m_properties =
    boost::spirit::classic::no_node_d[ boost::spirit::classic::ch_p('[') ]
    >> *m_identifier
    >> boost::spirit::classic::no_node_d[ boost::spirit::classic::ch_p(']') ]
    ;

  m_glob =
    boost::spirit::classic::strlit<>("glob")
    >> m_string;
    ;

  m_exclude =
    boost::spirit::classic::strlit<>("exclude")
    >> (m_string | m_glob);

  m_sprite_size =
    ( m_identifier | m_string )
    >> !( boost::spirit::classic::no_node_d[ boost::spirit::classic::ch_p('*') ]
          >> boost::spirit::classic::real_p );

  m_identifier =
    boost::spirit::classic::no_node_d[ *boost::spirit::classic::blank_p ]
    >>    boost::spirit::classic::token_node_d
    [ boost::spirit::classic::lexeme_d[ (boost::spirit::classic::alpha_p | '_')
                               >> *(boost::spirit::classic::alnum_p | '_') ]
      ];

  m_string =
    boost::spirit::classic::lexeme_d
    [ boost::spirit::classic::no_node_d[ boost::spirit::classic::ch_p('"') ]
      >> boost::spirit::classic::token_node_d
      [ *(boost::spirit::classic::strlit<>("\\\"")
          | (boost::spirit::classic::anychar_p - '"') ) ]
      >> boost::spirit::classic::no_node_d
      [ ( '"' | m_error_not_terminated_string ) ]
    ];
}

template<typename ScannerT>
void pms::serialization::spritedesc::grammar::definition<ScannerT>::
initialize_error_parsers()
{
  m_error_autosize =
    error_report_parser( "Size expected, like: autosize * 0.5." );
  m_error_identifier = error_report_parser( "Identifier expected." );
  m_error_string = error_report_parser( "String expected." );
  m_error_not_terminated_string =
    error_report_parser( "Not terminated string." );

  m_error_atlas = error_report_parser( "atlas expected" );
  m_error_size = error_report_parser( "Size expected (width x height)." );

  m_error_semicolon = char_error_report_parser( ';' );
}
<|endoftext|>


<commit_before>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Main
#include <boost/test/unit_test.hpp>
#include <net/client.h>
#include <net/server.h>

const dariadb::net::Server::Param server_param(2001);
const dariadb::net::Client::Param client_param("127.0.0.1", 2001);

BOOST_AUTO_TEST_CASE(Instance) {
  dariadb::net::Server s(server_param);
  BOOST_CHECK_EQUAL(s.connections_accepted(),size_t(0));

  dariadb::net::Client c(client_param);
  c.connect();

  while(s.connections_accepted()!=size_t(1)){

  }
}
<commit_msg>lock on test<commit_after>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Main
#include <boost/test/unit_test.hpp>
#include <net/client.h>
#include <net/server.h>
#include <utils/locker.h>

const dariadb::net::Server::Param server_param(2001);
const dariadb::net::Client::Param client_param("127.0.0.1", 2001);

BOOST_AUTO_TEST_CASE(Instance) {
    dariadb::utils::Locker lock;
    std::lock_guard<dariadb::utils::Locker> lg(lock);
  dariadb::net::Server s(server_param);
  BOOST_CHECK_EQUAL(s.connections_accepted(),size_t(0));

  dariadb::net::Client c(client_param);
  c.connect();

  while(s.connections_accepted()!=size_t(1)){

  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "webkit/glue/plugins/pepper_file_io.h"

#include "base/callback.h"
#include "base/file_util.h"
#include "base/file_util_proxy.h"
#include "base/message_loop_proxy.h"
#include "base/platform_file.h"
#include "base/logging.h"
#include "base/time.h"
#include "third_party/ppapi/c/dev/ppb_file_io_dev.h"
#include "third_party/ppapi/c/dev/ppb_file_io_trusted_dev.h"
#include "third_party/ppapi/c/pp_completion_callback.h"
#include "third_party/ppapi/c/pp_errors.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"

namespace pepper {

namespace {

PP_Resource Create(PP_Module module_id) {
  PluginModule* module = PluginModule::FromPPModule(module_id);
  if (!module)
    return 0;

  FileIO* file_io = new FileIO(module);
  return file_io->GetReference();
}

bool IsFileIO(PP_Resource resource) {
  return !!Resource::GetAs<FileIO>(resource);
}

int32_t Open(PP_Resource file_io_id,
             PP_Resource file_ref_id,
             int32_t open_flags,
             PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;

  scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id));
  if (!file_ref)
    return PP_ERROR_BADRESOURCE;

  return file_io->Open(file_ref, open_flags, callback);
}

int32_t Query(PP_Resource file_io_id,
              PP_FileInfo_Dev* info,
              PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Query(info, callback);
}

int32_t Touch(PP_Resource file_io_id,
              PP_Time last_access_time,
              PP_Time last_modified_time,
              PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Touch(last_access_time, last_modified_time, callback);
}

int32_t Read(PP_Resource file_io_id,
             int64_t offset,
             char* buffer,
             int32_t bytes_to_read,
             PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Read(offset, buffer, bytes_to_read, callback);
}

int32_t Write(PP_Resource file_io_id,
              int64_t offset,
              const char* buffer,
              int32_t bytes_to_write,
              PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Write(offset, buffer, bytes_to_write, callback);
}

int32_t SetLength(PP_Resource file_io_id,
                  int64_t length,
                  PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->SetLength(length, callback);
}

int32_t Flush(PP_Resource file_io_id,
              PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Flush(callback);
}

void Close(PP_Resource file_io_id) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return;
  file_io->Close();
}

const PPB_FileIO_Dev ppb_fileio = {
  &Create,
  &IsFileIO,
  &Open,
  &Query,
  &Touch,
  &Read,
  &Write,
  &SetLength,
  &Flush,
  &Close
};

int32_t GetOSFileDescriptor(PP_Resource file_io_id) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->GetOSFileDescriptor();
}

int32_t WillWrite(PP_Resource file_io_id,
                  int64_t offset,
                  int32_t bytes_to_write,
                  PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->WillWrite(offset, bytes_to_write, callback);
}

int32_t WillSetLength(PP_Resource file_io_id,
                      int64_t length,
                      PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->WillSetLength(length, callback);
}

const PPB_FileIOTrusted_Dev ppb_fileiotrusted = {
  &GetOSFileDescriptor,
  &WillWrite,
  &WillSetLength
};

int PlatformFileErrorToPepperError(base::PlatformFileError error_code) {
  switch (error_code) {
    case base::PLATFORM_FILE_OK:
      return PP_OK;
    case base::PLATFORM_FILE_ERROR_EXISTS:
      return PP_ERROR_FILEEXISTS;
    case base::PLATFORM_FILE_ERROR_NOT_FOUND:
      return PP_ERROR_FILENOTFOUND;
    case base::PLATFORM_FILE_ERROR_ACCESS_DENIED:
      return PP_ERROR_NOACCESS;
    case base::PLATFORM_FILE_ERROR_NO_MEMORY:
      return PP_ERROR_NOMEMORY;
    case base::PLATFORM_FILE_ERROR_NO_SPACE:
      return PP_ERROR_NOSPACE;
    case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
      NOTREACHED();
      return PP_ERROR_FAILED;
    default:
      return PP_ERROR_FAILED;
  }
}

}  // namespace

FileIO::FileIO(PluginModule* module)
    : Resource(module),
      delegate_(module->GetSomeInstance()->delegate()),
      ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)),
      file_(base::kInvalidPlatformFileValue),
      callback_(),
      info_(NULL) {
}

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

// static
const PPB_FileIO_Dev* FileIO::GetInterface() {
  return &ppb_fileio;
}

// static
const PPB_FileIOTrusted_Dev* FileIO::GetTrustedInterface() {
  return &ppb_fileiotrusted;
}

int32_t FileIO::Open(FileRef* file_ref,
                     int32_t open_flags,
                     PP_CompletionCallback callback) {
  if (file_ != base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  int flags = 0;
  if (open_flags & PP_FILEOPENFLAG_READ)
    flags |= base::PLATFORM_FILE_READ;
  if (open_flags & PP_FILEOPENFLAG_WRITE) {
    flags |= base::PLATFORM_FILE_WRITE;
    flags |= base::PLATFORM_FILE_WRITE_ATTRIBUTES;
  }
  if (open_flags & PP_FILEOPENFLAG_TRUNCATE) {
    DCHECK(flags & PP_FILEOPENFLAG_WRITE);
    flags |= base::PLATFORM_FILE_TRUNCATE;
  }

  if (open_flags & PP_FILEOPENFLAG_CREATE) {
    if (open_flags & PP_FILEOPENFLAG_EXCLUSIVE)
      flags |= base::PLATFORM_FILE_CREATE;
    else
      flags |= base::PLATFORM_FILE_OPEN_ALWAYS;
  } else
    flags |= base::PLATFORM_FILE_OPEN;

  file_system_type_ = file_ref->file_system_type();
  if (!delegate_->AsyncOpenFile(
          file_ref->system_path(), flags,
          callback_factory_.NewCallback(&FileIO::AsyncOpenFileCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Query(PP_FileInfo_Dev* info,
                      PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  DCHECK(!info_);
  DCHECK(info);
  info_ = info;

  if (!base::FileUtilProxy::GetFileInfoFromPlatformFile(
          delegate_->GetFileThreadMessageLoopProxy(), file_,
          callback_factory_.NewCallback(&FileIO::QueryInfoCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Touch(PP_Time last_access_time,
                      PP_Time last_modified_time,
                      PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Touch(
          delegate_->GetFileThreadMessageLoopProxy(),
          file_, base::Time::FromDoubleT(last_access_time),
          base::Time::FromDoubleT(last_modified_time),
          callback_factory_.NewCallback(&FileIO::StatusCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Read(int64_t offset,
                     char* buffer,
                     int32_t bytes_to_read,
                     PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Read(
          delegate_->GetFileThreadMessageLoopProxy(),
          file_, offset, buffer, bytes_to_read,
          callback_factory_.NewCallback(&FileIO::ReadWriteCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Write(int64_t offset,
                      const char* buffer,
                      int32_t bytes_to_write,
                      PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Write(
          delegate_->GetFileThreadMessageLoopProxy(),
          file_, offset, buffer, bytes_to_write,
          callback_factory_.NewCallback(&FileIO::ReadWriteCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::SetLength(int64_t length,
                          PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Truncate(
          delegate_->GetFileThreadMessageLoopProxy(),
          file_, length,
          callback_factory_.NewCallback(&FileIO::StatusCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Flush(PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Flush(
          delegate_->GetFileThreadMessageLoopProxy(), file_,
          callback_factory_.NewCallback(&FileIO::StatusCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

void FileIO::Close() {
  if (file_ != base::kInvalidPlatformFileValue)
    base::FileUtilProxy::Close(
        delegate_->GetFileThreadMessageLoopProxy(), file_, NULL);
}

int32_t FileIO::GetOSFileDescriptor() {
  return reinterpret_cast<uintptr_t>(base::kInvalidPlatformFileValue);
}

int32_t FileIO::WillWrite(int64_t offset,
                          int32_t bytes_to_write,
                          PP_CompletionCallback callback) {
  // TODO(dumi): implement me
  return PP_OK;
}

int32_t FileIO::WillSetLength(int64_t length,
                              PP_CompletionCallback callback) {
  // TODO(dumi): implement me
  return PP_OK;
}

void FileIO::RunPendingCallback(int result) {
  if (!callback_.func)
    return;

  PP_CompletionCallback callback = {0};
  std::swap(callback, callback_);
  PP_RunCompletionCallback(&callback, result);
}

void FileIO::StatusCallback(base::PlatformFileError error_code) {
  RunPendingCallback(PlatformFileErrorToPepperError(error_code));
}

void FileIO::AsyncOpenFileCallback(base::PlatformFileError error_code,
                                   base::PlatformFile file) {
  DCHECK(file_ == base::kInvalidPlatformFileValue);
  file_ = file;
  RunPendingCallback(PlatformFileErrorToPepperError(error_code));
}

void FileIO::QueryInfoCallback(base::PlatformFileError error_code,
                               const base::PlatformFileInfo& file_info) {
  DCHECK(info_);
  if (error_code == base::PLATFORM_FILE_OK) {
    info_->size = file_info.size;
    info_->creation_time = file_info.creation_time.ToDoubleT();
    info_->last_access_time = file_info.last_accessed.ToDoubleT();
    info_->last_modified_time = file_info.last_modified.ToDoubleT();
    info_->system_type = file_system_type_;
    if (file_info.is_directory)
      info_->type = PP_FILETYPE_DIRECTORY;
    else
      info_->type = PP_FILETYPE_REGULAR;
  }
  RunPendingCallback(PlatformFileErrorToPepperError(error_code));
}

void FileIO::ReadWriteCallback(base::PlatformFileError error_code,
                               int bytes_read_or_written) {
  if (error_code != base::PLATFORM_FILE_OK)
    RunPendingCallback(PlatformFileErrorToPepperError(error_code));
  else
    RunPendingCallback(bytes_read_or_written);
}

}  // namespace pepper
<commit_msg>Fixing pepper::FileIO::GetOSFileDescriptor(): 1. Return the actual file descriptor. 2. int cannot be converted to uintptr_t on Linux and Mac (and we don't need to do this).<commit_after>// Copyright (c) 2010 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 "webkit/glue/plugins/pepper_file_io.h"

#include "base/callback.h"
#include "base/file_util.h"
#include "base/file_util_proxy.h"
#include "base/message_loop_proxy.h"
#include "base/platform_file.h"
#include "base/logging.h"
#include "base/time.h"
#include "third_party/ppapi/c/dev/ppb_file_io_dev.h"
#include "third_party/ppapi/c/dev/ppb_file_io_trusted_dev.h"
#include "third_party/ppapi/c/pp_completion_callback.h"
#include "third_party/ppapi/c/pp_errors.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"

namespace pepper {

namespace {

PP_Resource Create(PP_Module module_id) {
  PluginModule* module = PluginModule::FromPPModule(module_id);
  if (!module)
    return 0;

  FileIO* file_io = new FileIO(module);
  return file_io->GetReference();
}

bool IsFileIO(PP_Resource resource) {
  return !!Resource::GetAs<FileIO>(resource);
}

int32_t Open(PP_Resource file_io_id,
             PP_Resource file_ref_id,
             int32_t open_flags,
             PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;

  scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id));
  if (!file_ref)
    return PP_ERROR_BADRESOURCE;

  return file_io->Open(file_ref, open_flags, callback);
}

int32_t Query(PP_Resource file_io_id,
              PP_FileInfo_Dev* info,
              PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Query(info, callback);
}

int32_t Touch(PP_Resource file_io_id,
              PP_Time last_access_time,
              PP_Time last_modified_time,
              PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Touch(last_access_time, last_modified_time, callback);
}

int32_t Read(PP_Resource file_io_id,
             int64_t offset,
             char* buffer,
             int32_t bytes_to_read,
             PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Read(offset, buffer, bytes_to_read, callback);
}

int32_t Write(PP_Resource file_io_id,
              int64_t offset,
              const char* buffer,
              int32_t bytes_to_write,
              PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Write(offset, buffer, bytes_to_write, callback);
}

int32_t SetLength(PP_Resource file_io_id,
                  int64_t length,
                  PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->SetLength(length, callback);
}

int32_t Flush(PP_Resource file_io_id,
              PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->Flush(callback);
}

void Close(PP_Resource file_io_id) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return;
  file_io->Close();
}

const PPB_FileIO_Dev ppb_fileio = {
  &Create,
  &IsFileIO,
  &Open,
  &Query,
  &Touch,
  &Read,
  &Write,
  &SetLength,
  &Flush,
  &Close
};

int32_t GetOSFileDescriptor(PP_Resource file_io_id) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->GetOSFileDescriptor();
}

int32_t WillWrite(PP_Resource file_io_id,
                  int64_t offset,
                  int32_t bytes_to_write,
                  PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->WillWrite(offset, bytes_to_write, callback);
}

int32_t WillSetLength(PP_Resource file_io_id,
                      int64_t length,
                      PP_CompletionCallback callback) {
  scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id));
  if (!file_io)
    return PP_ERROR_BADRESOURCE;
  return file_io->WillSetLength(length, callback);
}

const PPB_FileIOTrusted_Dev ppb_fileiotrusted = {
  &GetOSFileDescriptor,
  &WillWrite,
  &WillSetLength
};

int PlatformFileErrorToPepperError(base::PlatformFileError error_code) {
  switch (error_code) {
    case base::PLATFORM_FILE_OK:
      return PP_OK;
    case base::PLATFORM_FILE_ERROR_EXISTS:
      return PP_ERROR_FILEEXISTS;
    case base::PLATFORM_FILE_ERROR_NOT_FOUND:
      return PP_ERROR_FILENOTFOUND;
    case base::PLATFORM_FILE_ERROR_ACCESS_DENIED:
      return PP_ERROR_NOACCESS;
    case base::PLATFORM_FILE_ERROR_NO_MEMORY:
      return PP_ERROR_NOMEMORY;
    case base::PLATFORM_FILE_ERROR_NO_SPACE:
      return PP_ERROR_NOSPACE;
    case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
      NOTREACHED();
      return PP_ERROR_FAILED;
    default:
      return PP_ERROR_FAILED;
  }
}

}  // namespace

FileIO::FileIO(PluginModule* module)
    : Resource(module),
      delegate_(module->GetSomeInstance()->delegate()),
      ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)),
      file_(base::kInvalidPlatformFileValue),
      callback_(),
      info_(NULL) {
}

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

// static
const PPB_FileIO_Dev* FileIO::GetInterface() {
  return &ppb_fileio;
}

// static
const PPB_FileIOTrusted_Dev* FileIO::GetTrustedInterface() {
  return &ppb_fileiotrusted;
}

int32_t FileIO::Open(FileRef* file_ref,
                     int32_t open_flags,
                     PP_CompletionCallback callback) {
  if (file_ != base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  int flags = 0;
  if (open_flags & PP_FILEOPENFLAG_READ)
    flags |= base::PLATFORM_FILE_READ;
  if (open_flags & PP_FILEOPENFLAG_WRITE) {
    flags |= base::PLATFORM_FILE_WRITE;
    flags |= base::PLATFORM_FILE_WRITE_ATTRIBUTES;
  }
  if (open_flags & PP_FILEOPENFLAG_TRUNCATE) {
    DCHECK(flags & PP_FILEOPENFLAG_WRITE);
    flags |= base::PLATFORM_FILE_TRUNCATE;
  }

  if (open_flags & PP_FILEOPENFLAG_CREATE) {
    if (open_flags & PP_FILEOPENFLAG_EXCLUSIVE)
      flags |= base::PLATFORM_FILE_CREATE;
    else
      flags |= base::PLATFORM_FILE_OPEN_ALWAYS;
  } else
    flags |= base::PLATFORM_FILE_OPEN;

  file_system_type_ = file_ref->file_system_type();
  if (!delegate_->AsyncOpenFile(
          file_ref->system_path(), flags,
          callback_factory_.NewCallback(&FileIO::AsyncOpenFileCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Query(PP_FileInfo_Dev* info,
                      PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  DCHECK(!info_);
  DCHECK(info);
  info_ = info;

  if (!base::FileUtilProxy::GetFileInfoFromPlatformFile(
          delegate_->GetFileThreadMessageLoopProxy(), file_,
          callback_factory_.NewCallback(&FileIO::QueryInfoCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Touch(PP_Time last_access_time,
                      PP_Time last_modified_time,
                      PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Touch(
          delegate_->GetFileThreadMessageLoopProxy(),
          file_, base::Time::FromDoubleT(last_access_time),
          base::Time::FromDoubleT(last_modified_time),
          callback_factory_.NewCallback(&FileIO::StatusCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Read(int64_t offset,
                     char* buffer,
                     int32_t bytes_to_read,
                     PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Read(
          delegate_->GetFileThreadMessageLoopProxy(),
          file_, offset, buffer, bytes_to_read,
          callback_factory_.NewCallback(&FileIO::ReadWriteCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Write(int64_t offset,
                      const char* buffer,
                      int32_t bytes_to_write,
                      PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Write(
          delegate_->GetFileThreadMessageLoopProxy(),
          file_, offset, buffer, bytes_to_write,
          callback_factory_.NewCallback(&FileIO::ReadWriteCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::SetLength(int64_t length,
                          PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Truncate(
          delegate_->GetFileThreadMessageLoopProxy(),
          file_, length,
          callback_factory_.NewCallback(&FileIO::StatusCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

int32_t FileIO::Flush(PP_CompletionCallback callback) {
  if (file_ == base::kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  DCHECK(!callback_.func);
  callback_ = callback;

  if (!base::FileUtilProxy::Flush(
          delegate_->GetFileThreadMessageLoopProxy(), file_,
          callback_factory_.NewCallback(&FileIO::StatusCallback)))
    return PP_ERROR_FAILED;

  return PP_ERROR_WOULDBLOCK;
}

void FileIO::Close() {
  if (file_ != base::kInvalidPlatformFileValue)
    base::FileUtilProxy::Close(
        delegate_->GetFileThreadMessageLoopProxy(), file_, NULL);
}

int32_t FileIO::GetOSFileDescriptor() {
#if defined(OS_POSIX)
  return file_;
#else
  return reinterpret_cast<uintptr_t>(file_);
#endif
}

int32_t FileIO::WillWrite(int64_t offset,
                          int32_t bytes_to_write,
                          PP_CompletionCallback callback) {
  // TODO(dumi): implement me
  return PP_OK;
}

int32_t FileIO::WillSetLength(int64_t length,
                              PP_CompletionCallback callback) {
  // TODO(dumi): implement me
  return PP_OK;
}

void FileIO::RunPendingCallback(int result) {
  if (!callback_.func)
    return;

  PP_CompletionCallback callback = {0};
  std::swap(callback, callback_);
  PP_RunCompletionCallback(&callback, result);
}

void FileIO::StatusCallback(base::PlatformFileError error_code) {
  RunPendingCallback(PlatformFileErrorToPepperError(error_code));
}

void FileIO::AsyncOpenFileCallback(base::PlatformFileError error_code,
                                   base::PlatformFile file) {
  DCHECK(file_ == base::kInvalidPlatformFileValue);
  file_ = file;
  RunPendingCallback(PlatformFileErrorToPepperError(error_code));
}

void FileIO::QueryInfoCallback(base::PlatformFileError error_code,
                               const base::PlatformFileInfo& file_info) {
  DCHECK(info_);
  if (error_code == base::PLATFORM_FILE_OK) {
    info_->size = file_info.size;
    info_->creation_time = file_info.creation_time.ToDoubleT();
    info_->last_access_time = file_info.last_accessed.ToDoubleT();
    info_->last_modified_time = file_info.last_modified.ToDoubleT();
    info_->system_type = file_system_type_;
    if (file_info.is_directory)
      info_->type = PP_FILETYPE_DIRECTORY;
    else
      info_->type = PP_FILETYPE_REGULAR;
  }
  RunPendingCallback(PlatformFileErrorToPepperError(error_code));
}

void FileIO::ReadWriteCallback(base::PlatformFileError error_code,
                               int bytes_read_or_written) {
  if (error_code != base::PLATFORM_FILE_OK)
    RunPendingCallback(PlatformFileErrorToPepperError(error_code));
  else
    RunPendingCallback(bytes_read_or_written);
}

}  // namespace pepper
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXDE-Qt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Kuzma Shapran <kuzma.shapran@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "lxqtsysstatconfiguration.h"
#include "ui_lxqtsysstatconfiguration.h"
#include "lxqtsysstatutils.h"
#include "lxqtsysstatcolours.h"

#include <SysStat/CpuStat>
#include <SysStat/MemStat>
#include <SysStat/NetStat>

//Note: strings can't actually be translated here (in static initialization time)
//      the QT_TR_NOOP here is just for qt translate tools to get the strings for translation
const QStringList LxQtSysStatConfiguration::msStatTypes = {
    QStringLiteral(QT_TR_NOOP("CPU"))
    , QStringLiteral(QT_TR_NOOP("Memory"))
    , QStringLiteral(QT_TR_NOOP("Network"))
};

namespace
{
    //Note: workaround for making source strings translatable
    //  (no need to ever call this function)
    void localizationWorkaround();
    auto t = localizationWorkaround;//avoid unused function warning
    void localizationWorkaround()
    {
        const char * loc;
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu1");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu2");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu3");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu4");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu5");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu6");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu7");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu8");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu9");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu11");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu12");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu13");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu14");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu15");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu16");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu17");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu18");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu19");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu20");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu21");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu22");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu23");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu24");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "memory");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "swap");
        static_cast<void>(t);//avoid unused variable warning
    }
}

LxQtSysStatConfiguration::LxQtSysStatConfiguration(QSettings *settings, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::LxQtSysStatConfiguration),
    mSettings(settings),
    oldSettings(settings),
    mStat(NULL),
    mColoursDialog(NULL)
{
    setAttribute(Qt::WA_DeleteOnClose);
    setObjectName("SysStatConfigurationWindow");
    ui->setupUi(this);

    //Note: translation is needed here in runtime (translator is attached already)
    for (auto const & type : msStatTypes)
        ui->typeCOB->addItem(tr(type.toStdString().c_str()), type);

    loadSettings();

    connect(ui->typeCOB, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->intervalSB, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->sizeSB, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->linesSB, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->titleLE, &QLineEdit::editingFinished, this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->useFrequencyCB, &QCheckBox::toggled, this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->logarithmicCB, &QCheckBox::toggled, this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->sourceCOB, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->useThemeColoursRB, &QRadioButton::toggled, this, &LxQtSysStatConfiguration::saveSettings);
}

LxQtSysStatConfiguration::~LxQtSysStatConfiguration()
{
    delete ui;
}

void LxQtSysStatConfiguration::loadSettings()
{
    ui->intervalSB->setValue(mSettings->value("graph/updateInterval", 1.0).toDouble());
    ui->sizeSB->setValue(mSettings->value("graph/minimalSize", 30).toInt());

    ui->linesSB->setValue(mSettings->value("grid/lines", 1).toInt());

    ui->titleLE->setText(mSettings->value("title/label", QString()).toString());

    int typeIndex = ui->typeCOB->findData(mSettings->value("data/type", msStatTypes[0]));
    ui->typeCOB->setCurrentIndex((typeIndex >= 0) ? typeIndex : 0);
    on_typeCOB_currentIndexChanged(ui->typeCOB->currentIndex());

    int sourceIndex = ui->sourceCOB->findText(mSettings->value("data/source", QString()).toString());
    ui->sourceCOB->setCurrentIndex((sourceIndex >= 0) ? sourceIndex : 0);

    ui->useFrequencyCB->setChecked(mSettings->value("cpu/useFrequency", true).toBool());
    ui->maximumHS->setValue(PluginSysStat::netSpeedFromString(mSettings->value("net/maximumSpeed", "1 MB/s").toString()));
    on_maximumHS_valueChanged(ui->maximumHS->value());
    ui->logarithmicCB->setChecked(mSettings->value("net/logarithmicScale", true).toBool());
    ui->logScaleSB->setValue(mSettings->value("net/logarithmicScaleSteps", 4).toInt());

    bool useThemeColours = mSettings->value("graph/useThemeColours", true).toBool();
    ui->useThemeColoursRB->setChecked(useThemeColours);
    ui->useCustomColoursRB->setChecked(!useThemeColours);
    ui->customColoursB->setEnabled(!useThemeColours);
}

void LxQtSysStatConfiguration::saveSettings()
{
    mSettings->setValue("graph/useThemeColours", ui->useThemeColoursRB->isChecked());
    mSettings->setValue("graph/updateInterval", ui->intervalSB->value());
    mSettings->setValue("graph/minimalSize", ui->sizeSB->value());

    mSettings->setValue("grid/lines", ui->linesSB->value());

    mSettings->setValue("title/label", ui->titleLE->text());

    //Note:
    // need to make a realy deep copy of the msStatTypes[x] because of SEGFAULTs
    // occuring in static finalization time (don't know the real reason...maybe ordering of static finalizers/destructors)
    QString type = ui->typeCOB->itemData(ui->typeCOB->currentIndex(), Qt::UserRole).toString().toStdString().c_str();
    mSettings->setValue("data/type", type);
    mSettings->setValue("data/source", ui->sourceCOB->currentText());

    mSettings->setValue("cpu/useFrequency", ui->useFrequencyCB->isChecked());

    mSettings->setValue("net/maximumSpeed", PluginSysStat::netSpeedToString(ui->maximumHS->value()));
    mSettings->setValue("net/logarithmicScale", ui->logarithmicCB->isChecked());
    mSettings->setValue("net/logarithmicScaleSteps", ui->logScaleSB->value());
}

void LxQtSysStatConfiguration::on_buttons_clicked(QAbstractButton *btn)
{
    if (ui->buttons->buttonRole(btn) == QDialogButtonBox::ResetRole)
    {
        oldSettings.loadToSettings();
        loadSettings();
    }
    else
        close();
}

void LxQtSysStatConfiguration::on_typeCOB_currentIndexChanged(int index)
{
    if (mStat)
        mStat->deleteLater();
    switch (index)
    {
    case 0:
        mStat = new SysStat::CpuStat(this);
        break;

    case 1:
        mStat = new SysStat::MemStat(this);
        break;

    case 2:
        mStat = new SysStat::NetStat(this);
        break;
    }

    ui->sourceCOB->blockSignals(true);
    ui->sourceCOB->clear();
    for (auto const & s : mStat->sources())
        ui->sourceCOB->addItem(tr(s.toStdString().c_str()));
    ui->sourceCOB->blockSignals(false);
    ui->sourceCOB->setCurrentIndex(0);
}

void LxQtSysStatConfiguration::on_maximumHS_valueChanged(int value)
{
    ui->maximumValueL->setText(PluginSysStat::netSpeedToString(value));
}

void LxQtSysStatConfiguration::coloursChanged()
{
    const LxQtSysStatColours::Colours &colours = mColoursDialog->colours();

    mSettings->setValue("grid/colour",  colours["grid"].name());
    mSettings->setValue("title/colour", colours["title"].name());

    mSettings->setValue("cpu/systemColour",    colours["cpuSystem"].name());
    mSettings->setValue("cpu/userColour",      colours["cpuUser"].name());
    mSettings->setValue("cpu/niceColour",      colours["cpuNice"].name());
    mSettings->setValue("cpu/otherColour",     colours["cpuOther"].name());
    mSettings->setValue("cpu/frequencyColour", colours["cpuFrequency"].name());

    mSettings->setValue("mem/appsColour",    colours["memApps"].name());
    mSettings->setValue("mem/buffersColour", colours["memBuffers"].name());
    mSettings->setValue("mem/cachedColour",  colours["memCached"].name());
    mSettings->setValue("mem/swapColour",    colours["memSwap"].name());

    mSettings->setValue("net/receivedColour",    colours["netReceived"].name());
    mSettings->setValue("net/transmittedColour", colours["netTransmitted"].name());
}

void LxQtSysStatConfiguration::on_customColoursB_clicked()
{
    if (!mColoursDialog)
    {
        mColoursDialog = new LxQtSysStatColours(this);
        connect(mColoursDialog, SIGNAL(coloursChanged()), SLOT(coloursChanged()));
    }

    LxQtSysStatColours::Colours colours;

    const LxQtSysStatColours::Colours &defaultColours = mColoursDialog->defaultColours();

    colours["grid"]  = QColor(mSettings->value("grid/colour",  defaultColours["grid"] .name()).toString());
    colours["title"] = QColor(mSettings->value("title/colour", defaultColours["title"].name()).toString());

    colours["cpuSystem"]    = QColor(mSettings->value("cpu/systemColour",    defaultColours["cpuSystem"]   .name()).toString());
    colours["cpuUser"]      = QColor(mSettings->value("cpu/userColour",      defaultColours["cpuUser"]     .name()).toString());
    colours["cpuNice"]      = QColor(mSettings->value("cpu/niceColour",      defaultColours["cpuNice"]     .name()).toString());
    colours["cpuOther"]     = QColor(mSettings->value("cpu/otherColour",     defaultColours["cpuOther"]    .name()).toString());
    colours["cpuFrequency"] = QColor(mSettings->value("cpu/frequencyColour", defaultColours["cpuFrequency"].name()).toString());

    colours["memApps"]    = QColor(mSettings->value("mem/appsColour",    defaultColours["memApps"]   .name()).toString());
    colours["memBuffers"] = QColor(mSettings->value("mem/buffersColour", defaultColours["memBuffers"].name()).toString());
    colours["memCached"]  = QColor(mSettings->value("mem/cachedColour",  defaultColours["memCached"] .name()).toString());
    colours["memSwap"]    = QColor(mSettings->value("mem/swapColour",    defaultColours["memSwap"]   .name()).toString());

    colours["netReceived"]    = QColor(mSettings->value("net/receivedColour",    defaultColours["netReceived"]   .name()).toString());
    colours["netTransmitted"] = QColor(mSettings->value("net/transmittedColour", defaultColours["netTransmitted"].name()).toString());

    mColoursDialog->setColours(colours);

    mColoursDialog->exec();
}
<commit_msg>plugin-sysstat: fix for source strings translation<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXDE-Qt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Kuzma Shapran <kuzma.shapran@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "lxqtsysstatconfiguration.h"
#include "ui_lxqtsysstatconfiguration.h"
#include "lxqtsysstatutils.h"
#include "lxqtsysstatcolours.h"

#include <SysStat/CpuStat>
#include <SysStat/MemStat>
#include <SysStat/NetStat>

//Note: strings can't actually be translated here (in static initialization time)
//      the QT_TR_NOOP here is just for qt translate tools to get the strings for translation
const QStringList LxQtSysStatConfiguration::msStatTypes = {
    QStringLiteral(QT_TR_NOOP("CPU"))
    , QStringLiteral(QT_TR_NOOP("Memory"))
    , QStringLiteral(QT_TR_NOOP("Network"))
};

namespace
{
    //Note: workaround for making source strings translatable
    //  (no need to ever call this function)
    void localizationWorkaround();
    auto t = localizationWorkaround;//avoid unused function warning
    void localizationWorkaround()
    {
        const char * loc;
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu1");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu2");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu3");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu4");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu5");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu6");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu7");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu8");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu9");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu11");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu12");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu13");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu14");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu15");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu16");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu17");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu18");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu19");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu20");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu21");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu22");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu23");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "cpu24");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "memory");
        loc = QT_TRANSLATE_NOOP("LxQtSysStatConfiguration", "swap");
        static_cast<void>(t);//avoid unused variable warning
    }
}

LxQtSysStatConfiguration::LxQtSysStatConfiguration(QSettings *settings, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::LxQtSysStatConfiguration),
    mSettings(settings),
    oldSettings(settings),
    mStat(NULL),
    mColoursDialog(NULL)
{
    setAttribute(Qt::WA_DeleteOnClose);
    setObjectName("SysStatConfigurationWindow");
    ui->setupUi(this);

    //Note: translation is needed here in runtime (translator is attached already)
    for (auto const & type : msStatTypes)
        ui->typeCOB->addItem(tr(type.toStdString().c_str()), type);

    loadSettings();

    connect(ui->typeCOB, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->intervalSB, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->sizeSB, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->linesSB, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->titleLE, &QLineEdit::editingFinished, this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->useFrequencyCB, &QCheckBox::toggled, this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->logarithmicCB, &QCheckBox::toggled, this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->sourceCOB, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &LxQtSysStatConfiguration::saveSettings);
    connect(ui->useThemeColoursRB, &QRadioButton::toggled, this, &LxQtSysStatConfiguration::saveSettings);
}

LxQtSysStatConfiguration::~LxQtSysStatConfiguration()
{
    delete ui;
}

void LxQtSysStatConfiguration::loadSettings()
{
    ui->intervalSB->setValue(mSettings->value("graph/updateInterval", 1.0).toDouble());
    ui->sizeSB->setValue(mSettings->value("graph/minimalSize", 30).toInt());

    ui->linesSB->setValue(mSettings->value("grid/lines", 1).toInt());

    ui->titleLE->setText(mSettings->value("title/label", QString()).toString());

    int typeIndex = ui->typeCOB->findData(mSettings->value("data/type", msStatTypes[0]));
    ui->typeCOB->setCurrentIndex((typeIndex >= 0) ? typeIndex : 0);
    on_typeCOB_currentIndexChanged(ui->typeCOB->currentIndex());

    int sourceIndex = ui->sourceCOB->findData(mSettings->value("data/source", QString()));
    ui->sourceCOB->setCurrentIndex((sourceIndex >= 0) ? sourceIndex : 0);

    ui->useFrequencyCB->setChecked(mSettings->value("cpu/useFrequency", true).toBool());
    ui->maximumHS->setValue(PluginSysStat::netSpeedFromString(mSettings->value("net/maximumSpeed", "1 MB/s").toString()));
    on_maximumHS_valueChanged(ui->maximumHS->value());
    ui->logarithmicCB->setChecked(mSettings->value("net/logarithmicScale", true).toBool());
    ui->logScaleSB->setValue(mSettings->value("net/logarithmicScaleSteps", 4).toInt());

    bool useThemeColours = mSettings->value("graph/useThemeColours", true).toBool();
    ui->useThemeColoursRB->setChecked(useThemeColours);
    ui->useCustomColoursRB->setChecked(!useThemeColours);
    ui->customColoursB->setEnabled(!useThemeColours);
}

void LxQtSysStatConfiguration::saveSettings()
{
    mSettings->setValue("graph/useThemeColours", ui->useThemeColoursRB->isChecked());
    mSettings->setValue("graph/updateInterval", ui->intervalSB->value());
    mSettings->setValue("graph/minimalSize", ui->sizeSB->value());

    mSettings->setValue("grid/lines", ui->linesSB->value());

    mSettings->setValue("title/label", ui->titleLE->text());

    //Note:
    // need to make a realy deep copy of the msStatTypes[x] because of SEGFAULTs
    // occuring in static finalization time (don't know the real reason...maybe ordering of static finalizers/destructors)
    QString type = ui->typeCOB->itemData(ui->typeCOB->currentIndex(), Qt::UserRole).toString().toStdString().c_str();
    mSettings->setValue("data/type", type);
    mSettings->setValue("data/source", ui->sourceCOB->itemData(ui->sourceCOB->currentIndex(), Qt::UserRole));

    mSettings->setValue("cpu/useFrequency", ui->useFrequencyCB->isChecked());

    mSettings->setValue("net/maximumSpeed", PluginSysStat::netSpeedToString(ui->maximumHS->value()));
    mSettings->setValue("net/logarithmicScale", ui->logarithmicCB->isChecked());
    mSettings->setValue("net/logarithmicScaleSteps", ui->logScaleSB->value());
}

void LxQtSysStatConfiguration::on_buttons_clicked(QAbstractButton *btn)
{
    if (ui->buttons->buttonRole(btn) == QDialogButtonBox::ResetRole)
    {
        oldSettings.loadToSettings();
        loadSettings();
    }
    else
        close();
}

void LxQtSysStatConfiguration::on_typeCOB_currentIndexChanged(int index)
{
    if (mStat)
        mStat->deleteLater();
    switch (index)
    {
    case 0:
        mStat = new SysStat::CpuStat(this);
        break;

    case 1:
        mStat = new SysStat::MemStat(this);
        break;

    case 2:
        mStat = new SysStat::NetStat(this);
        break;
    }

    ui->sourceCOB->blockSignals(true);
    ui->sourceCOB->clear();
    for (auto const & s : mStat->sources())
        ui->sourceCOB->addItem(tr(s.toStdString().c_str()), s);
    ui->sourceCOB->blockSignals(false);
    ui->sourceCOB->setCurrentIndex(0);
}

void LxQtSysStatConfiguration::on_maximumHS_valueChanged(int value)
{
    ui->maximumValueL->setText(PluginSysStat::netSpeedToString(value));
}

void LxQtSysStatConfiguration::coloursChanged()
{
    const LxQtSysStatColours::Colours &colours = mColoursDialog->colours();

    mSettings->setValue("grid/colour",  colours["grid"].name());
    mSettings->setValue("title/colour", colours["title"].name());

    mSettings->setValue("cpu/systemColour",    colours["cpuSystem"].name());
    mSettings->setValue("cpu/userColour",      colours["cpuUser"].name());
    mSettings->setValue("cpu/niceColour",      colours["cpuNice"].name());
    mSettings->setValue("cpu/otherColour",     colours["cpuOther"].name());
    mSettings->setValue("cpu/frequencyColour", colours["cpuFrequency"].name());

    mSettings->setValue("mem/appsColour",    colours["memApps"].name());
    mSettings->setValue("mem/buffersColour", colours["memBuffers"].name());
    mSettings->setValue("mem/cachedColour",  colours["memCached"].name());
    mSettings->setValue("mem/swapColour",    colours["memSwap"].name());

    mSettings->setValue("net/receivedColour",    colours["netReceived"].name());
    mSettings->setValue("net/transmittedColour", colours["netTransmitted"].name());
}

void LxQtSysStatConfiguration::on_customColoursB_clicked()
{
    if (!mColoursDialog)
    {
        mColoursDialog = new LxQtSysStatColours(this);
        connect(mColoursDialog, SIGNAL(coloursChanged()), SLOT(coloursChanged()));
    }

    LxQtSysStatColours::Colours colours;

    const LxQtSysStatColours::Colours &defaultColours = mColoursDialog->defaultColours();

    colours["grid"]  = QColor(mSettings->value("grid/colour",  defaultColours["grid"] .name()).toString());
    colours["title"] = QColor(mSettings->value("title/colour", defaultColours["title"].name()).toString());

    colours["cpuSystem"]    = QColor(mSettings->value("cpu/systemColour",    defaultColours["cpuSystem"]   .name()).toString());
    colours["cpuUser"]      = QColor(mSettings->value("cpu/userColour",      defaultColours["cpuUser"]     .name()).toString());
    colours["cpuNice"]      = QColor(mSettings->value("cpu/niceColour",      defaultColours["cpuNice"]     .name()).toString());
    colours["cpuOther"]     = QColor(mSettings->value("cpu/otherColour",     defaultColours["cpuOther"]    .name()).toString());
    colours["cpuFrequency"] = QColor(mSettings->value("cpu/frequencyColour", defaultColours["cpuFrequency"].name()).toString());

    colours["memApps"]    = QColor(mSettings->value("mem/appsColour",    defaultColours["memApps"]   .name()).toString());
    colours["memBuffers"] = QColor(mSettings->value("mem/buffersColour", defaultColours["memBuffers"].name()).toString());
    colours["memCached"]  = QColor(mSettings->value("mem/cachedColour",  defaultColours["memCached"] .name()).toString());
    colours["memSwap"]    = QColor(mSettings->value("mem/swapColour",    defaultColours["memSwap"]   .name()).toString());

    colours["netReceived"]    = QColor(mSettings->value("net/receivedColour",    defaultColours["netReceived"]   .name()).toString());
    colours["netTransmitted"] = QColor(mSettings->value("net/transmittedColour", defaultColours["netTransmitted"].name()).toString());

    mColoursDialog->setColours(colours);

    mColoursDialog->exec();
}
<|endoftext|>


<commit_before>// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "VkFramebuffer.hpp"

#include "VkImageView.hpp"
#include "VkRenderPass.hpp"
#include "VkStringify.hpp"

#include <memory.h>
#include <algorithm>

namespace vk {

Framebuffer::Framebuffer(const VkFramebufferCreateInfo *pCreateInfo, void *mem)
    : attachments(reinterpret_cast<ImageView **>(mem))
    , extent{ pCreateInfo->width, pCreateInfo->height, pCreateInfo->layers }
{
	const VkBaseInStructure *curInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
	const VkFramebufferAttachmentsCreateInfo *attachmentsCreateInfo = nullptr;
	while(curInfo)
	{
		switch(curInfo->sType)
		{
		case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO:
			attachmentsCreateInfo = reinterpret_cast<const VkFramebufferAttachmentsCreateInfo *>(curInfo);
			break;
		default:
			LOG_TRAP("pFramebufferCreateInfo->pNext->sType = %s", vk::Stringify(curInfo->sType).c_str());
			break;
		}
		curInfo = curInfo->pNext;
	}

	if(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT)
	{
		// If flags includes VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, the pNext chain **must**
		// include a VkFramebufferAttachmentsCreateInfo.
		ASSERT(attachmentsCreateInfo != nullptr);
		attachmentCount = attachmentsCreateInfo->attachmentImageInfoCount;
		for(uint32_t i = 0; i < attachmentCount; i++)
		{
			attachments[i] = nullptr;
		}
	}
	else
	{
		attachmentCount = pCreateInfo->attachmentCount;
		for(uint32_t i = 0; i < attachmentCount; i++)
		{
			attachments[i] = vk::Cast(pCreateInfo->pAttachments[i]);
		}
	}
}

void Framebuffer::destroy(const VkAllocationCallbacks *pAllocator)
{
	vk::deallocate(attachments, pAllocator);
}

void Framebuffer::executeLoadOp(const RenderPass *renderPass, uint32_t clearValueCount, const VkClearValue *pClearValues, const VkRect2D &renderArea)
{
	// This gets called at the start of a renderpass. Logically the `loadOp` gets executed at the
	// subpass where an attachment is first used, but since we don't discard contents between subpasses,
	// we can execute it sooner. Only clear operations have an effect.

	ASSERT(attachmentCount == renderPass->getAttachmentCount());

	const uint32_t count = std::min(clearValueCount, attachmentCount);
	for(uint32_t i = 0; i < count; i++)
	{
		const VkAttachmentDescription attachment = renderPass->getAttachment(i);
		VkImageAspectFlags aspectMask = Format(attachment.format).getAspects();

		switch(attachment.loadOp)
		{
		case VK_ATTACHMENT_LOAD_OP_CLEAR:
			// Keep the color aspect for clearing.
			break;
		case VK_ATTACHMENT_LOAD_OP_LOAD:
		case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
			// Don't clear the attachment's color aspect.
			aspectMask &= VK_IMAGE_ASPECT_STENCIL_BIT;
			break;
		default:
			UNSUPPORTED("attachment.loadOp %d", attachment.loadOp);
		}

		switch(attachment.stencilLoadOp)
		{
		case VK_ATTACHMENT_LOAD_OP_CLEAR:
			// Keep the stencil aspect for clearing.
			break;
		case VK_ATTACHMENT_LOAD_OP_LOAD:
		case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
			// Don't clear the attachment's stencil aspect.
			aspectMask &= ~VK_IMAGE_ASPECT_STENCIL_BIT;
			break;
		default:
			UNSUPPORTED("attachment.stencilLoadOp %d", attachment.stencilLoadOp);
		}

		if(!aspectMask || !renderPass->isAttachmentUsed(i))
		{
			continue;
		}

		if(renderPass->isMultiView())
		{
			attachments[i]->clearWithLayerMask(pClearValues[i], aspectMask, renderArea,
			                                   renderPass->getAttachmentViewMask(i));
		}
		else
		{
			attachments[i]->clear(pClearValues[i], aspectMask, renderArea);
		}
	}
}

void Framebuffer::clearAttachment(const RenderPass *renderPass, uint32_t subpassIndex, const VkClearAttachment &attachment, const VkClearRect &rect)
{
	VkSubpassDescription subpass = renderPass->getSubpass(subpassIndex);

	if(attachment.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
	{
		ASSERT(attachment.colorAttachment < subpass.colorAttachmentCount);
		uint32_t attachmentIndex = subpass.pColorAttachments[attachment.colorAttachment].attachment;

		if(attachmentIndex != VK_ATTACHMENT_UNUSED)
		{
			ASSERT(attachmentIndex < attachmentCount);
			ImageView *imageView = attachments[attachmentIndex];

			if(renderPass->isMultiView())
			{
				imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect,
				                              renderPass->getViewMask(subpassIndex));
			}
			else
			{
				imageView->clear(attachment.clearValue, attachment.aspectMask, rect);
			}
		}
	}
	else if(attachment.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
	{
		uint32_t attachmentIndex = subpass.pDepthStencilAttachment->attachment;

		if(attachmentIndex != VK_ATTACHMENT_UNUSED)
		{
			ASSERT(attachmentIndex < attachmentCount);
			ImageView *imageView = attachments[attachmentIndex];

			if(renderPass->isMultiView())
			{
				imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect,
				                              renderPass->getViewMask(subpassIndex));
			}
			else
			{
				imageView->clear(attachment.clearValue, attachment.aspectMask, rect);
			}
		}
	}
}

void Framebuffer::setAttachment(ImageView *imageView, uint32_t index)
{
	ASSERT(index < attachmentCount);
	ASSERT(attachments[index] == nullptr);
	attachments[index] = imageView;
}

ImageView *Framebuffer::getAttachment(uint32_t index) const
{
	return attachments[index];
}

void Framebuffer::resolve(const RenderPass *renderPass, uint32_t subpassIndex)
{
	auto const &subpass = renderPass->getSubpass(subpassIndex);
	if(subpass.pResolveAttachments)
	{
		for(uint32_t i = 0; i < subpass.colorAttachmentCount; i++)
		{
			uint32_t resolveAttachment = subpass.pResolveAttachments[i].attachment;
			if(resolveAttachment != VK_ATTACHMENT_UNUSED)
			{
				ImageView *imageView = attachments[subpass.pColorAttachments[i].attachment];
				if(renderPass->isMultiView())
				{
					imageView->resolveWithLayerMask(attachments[resolveAttachment],
					                                renderPass->getViewMask(subpassIndex));
				}
				else
				{
					imageView->resolve(attachments[resolveAttachment]);
				}
			}
		}
	}

	if(renderPass->hasDepthStencilResolve() && subpass.pDepthStencilAttachment != nullptr)
	{
		VkSubpassDescriptionDepthStencilResolve dsResolve = renderPass->getSubpassDepthStencilResolve(subpassIndex);
		uint32_t depthStencilAttachment = subpass.pDepthStencilAttachment->attachment;
		if(depthStencilAttachment != VK_ATTACHMENT_UNUSED)
		{
			ImageView *imageView = attachments[depthStencilAttachment];
			imageView->resolveDepthStencil(attachments[dsResolve.pDepthStencilResolveAttachment->attachment], dsResolve);
		}
	}
}

size_t Framebuffer::ComputeRequiredAllocationSize(const VkFramebufferCreateInfo *pCreateInfo)
{
	const VkBaseInStructure *curInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
	const VkFramebufferAttachmentsCreateInfo *attachmentsInfo = nullptr;
	while(curInfo)
	{
		switch(curInfo->sType)
		{
		case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO:
			attachmentsInfo = reinterpret_cast<const VkFramebufferAttachmentsCreateInfo *>(curInfo);
			break;
		default:
			LOG_TRAP("pFramebufferCreateInfo->pNext->sType = %s", vk::Stringify(curInfo->sType).c_str());
			break;
		}

		curInfo = curInfo->pNext;
	}

	if(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT)
	{
		ASSERT(attachmentsInfo != nullptr);
		return attachmentsInfo->attachmentImageInfoCount * sizeof(void *);
	}
	else
	{
		return pCreateInfo->attachmentCount * sizeof(void *);
	}
}

}  // namespace vk
<commit_msg>Refactor determining the aspects to clear<commit_after>// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "VkFramebuffer.hpp"

#include "VkImageView.hpp"
#include "VkRenderPass.hpp"
#include "VkStringify.hpp"

#include <memory.h>
#include <algorithm>

namespace vk {

Framebuffer::Framebuffer(const VkFramebufferCreateInfo *pCreateInfo, void *mem)
    : attachments(reinterpret_cast<ImageView **>(mem))
    , extent{ pCreateInfo->width, pCreateInfo->height, pCreateInfo->layers }
{
	const VkBaseInStructure *curInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
	const VkFramebufferAttachmentsCreateInfo *attachmentsCreateInfo = nullptr;
	while(curInfo)
	{
		switch(curInfo->sType)
		{
		case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO:
			attachmentsCreateInfo = reinterpret_cast<const VkFramebufferAttachmentsCreateInfo *>(curInfo);
			break;
		default:
			LOG_TRAP("pFramebufferCreateInfo->pNext->sType = %s", vk::Stringify(curInfo->sType).c_str());
			break;
		}
		curInfo = curInfo->pNext;
	}

	if(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT)
	{
		// If flags includes VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, the pNext chain **must**
		// include a VkFramebufferAttachmentsCreateInfo.
		ASSERT(attachmentsCreateInfo != nullptr);
		attachmentCount = attachmentsCreateInfo->attachmentImageInfoCount;
		for(uint32_t i = 0; i < attachmentCount; i++)
		{
			attachments[i] = nullptr;
		}
	}
	else
	{
		attachmentCount = pCreateInfo->attachmentCount;
		for(uint32_t i = 0; i < attachmentCount; i++)
		{
			attachments[i] = vk::Cast(pCreateInfo->pAttachments[i]);
		}
	}
}

void Framebuffer::destroy(const VkAllocationCallbacks *pAllocator)
{
	vk::deallocate(attachments, pAllocator);
}

void Framebuffer::executeLoadOp(const RenderPass *renderPass, uint32_t clearValueCount, const VkClearValue *pClearValues, const VkRect2D &renderArea)
{
	// This gets called at the start of a renderpass. Logically the `loadOp` gets executed at the
	// subpass where an attachment is first used, but since we don't discard contents between subpasses,
	// we can execute it sooner. Only clear operations have an effect.

	ASSERT(attachmentCount == renderPass->getAttachmentCount());

	const uint32_t count = std::min(clearValueCount, attachmentCount);
	for(uint32_t i = 0; i < count; i++)
	{
		const VkAttachmentDescription attachment = renderPass->getAttachment(i);
		VkImageAspectFlags clearMask = 0;

		switch(attachment.loadOp)
		{
		case VK_ATTACHMENT_LOAD_OP_CLEAR:
			clearMask |= VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
			break;
		case VK_ATTACHMENT_LOAD_OP_LOAD:
		case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
			// Don't clear the attachment's color or depth aspect.
			break;
		default:
			UNSUPPORTED("attachment.loadOp %d", attachment.loadOp);
		}

		switch(attachment.stencilLoadOp)
		{
		case VK_ATTACHMENT_LOAD_OP_CLEAR:
			clearMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
			break;
		case VK_ATTACHMENT_LOAD_OP_LOAD:
		case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
			// Don't clear the attachment's stencil aspect.
			break;
		default:
			UNSUPPORTED("attachment.stencilLoadOp %d", attachment.stencilLoadOp);
		}

		// Image::clear() demands that we only specify existing aspects.
		clearMask &= Format(attachment.format).getAspects();

		if(!clearMask || !renderPass->isAttachmentUsed(i))
		{
			continue;
		}

		if(renderPass->isMultiView())
		{
			attachments[i]->clearWithLayerMask(pClearValues[i], clearMask, renderArea,
			                                   renderPass->getAttachmentViewMask(i));
		}
		else
		{
			attachments[i]->clear(pClearValues[i], clearMask, renderArea);
		}
	}
}

void Framebuffer::clearAttachment(const RenderPass *renderPass, uint32_t subpassIndex, const VkClearAttachment &attachment, const VkClearRect &rect)
{
	VkSubpassDescription subpass = renderPass->getSubpass(subpassIndex);

	if(attachment.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
	{
		ASSERT(attachment.colorAttachment < subpass.colorAttachmentCount);
		uint32_t attachmentIndex = subpass.pColorAttachments[attachment.colorAttachment].attachment;

		if(attachmentIndex != VK_ATTACHMENT_UNUSED)
		{
			ASSERT(attachmentIndex < attachmentCount);
			ImageView *imageView = attachments[attachmentIndex];

			if(renderPass->isMultiView())
			{
				imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect,
				                              renderPass->getViewMask(subpassIndex));
			}
			else
			{
				imageView->clear(attachment.clearValue, attachment.aspectMask, rect);
			}
		}
	}
	else if(attachment.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
	{
		uint32_t attachmentIndex = subpass.pDepthStencilAttachment->attachment;

		if(attachmentIndex != VK_ATTACHMENT_UNUSED)
		{
			ASSERT(attachmentIndex < attachmentCount);
			ImageView *imageView = attachments[attachmentIndex];

			if(renderPass->isMultiView())
			{
				imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect,
				                              renderPass->getViewMask(subpassIndex));
			}
			else
			{
				imageView->clear(attachment.clearValue, attachment.aspectMask, rect);
			}
		}
	}
	else
		UNSUPPORTED("attachment.aspectMask %X", attachment.aspectMask);
}

void Framebuffer::setAttachment(ImageView *imageView, uint32_t index)
{
	ASSERT(index < attachmentCount);
	ASSERT(attachments[index] == nullptr);
	attachments[index] = imageView;
}

ImageView *Framebuffer::getAttachment(uint32_t index) const
{
	return attachments[index];
}

void Framebuffer::resolve(const RenderPass *renderPass, uint32_t subpassIndex)
{
	auto const &subpass = renderPass->getSubpass(subpassIndex);
	if(subpass.pResolveAttachments)
	{
		for(uint32_t i = 0; i < subpass.colorAttachmentCount; i++)
		{
			uint32_t resolveAttachment = subpass.pResolveAttachments[i].attachment;
			if(resolveAttachment != VK_ATTACHMENT_UNUSED)
			{
				ImageView *imageView = attachments[subpass.pColorAttachments[i].attachment];
				if(renderPass->isMultiView())
				{
					imageView->resolveWithLayerMask(attachments[resolveAttachment],
					                                renderPass->getViewMask(subpassIndex));
				}
				else
				{
					imageView->resolve(attachments[resolveAttachment]);
				}
			}
		}
	}

	if(renderPass->hasDepthStencilResolve() && subpass.pDepthStencilAttachment != nullptr)
	{
		VkSubpassDescriptionDepthStencilResolve dsResolve = renderPass->getSubpassDepthStencilResolve(subpassIndex);
		uint32_t depthStencilAttachment = subpass.pDepthStencilAttachment->attachment;
		if(depthStencilAttachment != VK_ATTACHMENT_UNUSED)
		{
			ImageView *imageView = attachments[depthStencilAttachment];
			imageView->resolveDepthStencil(attachments[dsResolve.pDepthStencilResolveAttachment->attachment], dsResolve);
		}
	}
}

size_t Framebuffer::ComputeRequiredAllocationSize(const VkFramebufferCreateInfo *pCreateInfo)
{
	const VkBaseInStructure *curInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
	const VkFramebufferAttachmentsCreateInfo *attachmentsInfo = nullptr;
	while(curInfo)
	{
		switch(curInfo->sType)
		{
		case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO:
			attachmentsInfo = reinterpret_cast<const VkFramebufferAttachmentsCreateInfo *>(curInfo);
			break;
		default:
			LOG_TRAP("pFramebufferCreateInfo->pNext->sType = %s", vk::Stringify(curInfo->sType).c_str());
			break;
		}

		curInfo = curInfo->pNext;
	}

	if(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT)
	{
		ASSERT(attachmentsInfo != nullptr);
		return attachmentsInfo->attachmentImageInfoCount * sizeof(void *);
	}
	else
	{
		return pCreateInfo->attachmentCount * sizeof(void *);
	}
}

}  // namespace vk
<|endoftext|>