<commit_before>/*
Copyright (C) 2001-2015 by Serge Lamikhov-Center

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef ELFIO_SECTION_HPP
#define ELFIO_SECTION_HPP

#include <string>
#include <iostream>

namespace ELFIO {

class section
{
    friend class elfio;
  public:
    virtual ~section() {};

    ELFIO_GET_ACCESS_DECL    ( Elf_Half,    index              );
    ELFIO_GET_SET_ACCESS_DECL( std::string, name               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    type               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   flags              );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    info               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    link               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   addr_align         );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   entry_size         );
    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr,  address            );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   size               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    name_string_offset );

    virtual const char* get_data() const                                = 0;
    virtual void        set_data( const char* pData, Elf_Word size )    = 0;
    virtual void        set_data( const std::string& data )             = 0;
    virtual void        append_data( const char* pData, Elf_Word size ) = 0;
    virtual void        append_data( const std::string& data )          = 0;

  protected:
    ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, offset );
    ELFIO_SET_ACCESS_DECL( Elf_Half,  index  );

    virtual void load( std::istream&  f,
                       std::streampos header_offset ) = 0;
    virtual void save( std::ostream&  f,
                       std::streampos header_offset,
                       std::streampos data_offset )   = 0;
    virtual bool is_address_initialized() const       = 0;
};

template< class T >
class section_impl : public section
{
  public:
//------------------------------------------------------------------------------
    section_impl( const endianess_convertor* convertor_ ) : convertor( convertor_ )
    {
        std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
        is_address_set = false;
        data           = 0;
        data_size      = 0;
    }

//------------------------------------------------------------------------------
    ~section_impl()
    {
        delete [] data;
    }

//------------------------------------------------------------------------------
    // Section info functions
    ELFIO_GET_SET_ACCESS( Elf_Word,   type,               header.sh_type      );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  flags,              header.sh_flags     );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  size,               header.sh_size      );
    ELFIO_GET_SET_ACCESS( Elf_Word,   link,               header.sh_link      );
    ELFIO_GET_SET_ACCESS( Elf_Word,   info,               header.sh_info      );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  addr_align,         header.sh_addralign );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  entry_size,         header.sh_entsize   );
    ELFIO_GET_SET_ACCESS( Elf_Word,   name_string_offset, header.sh_name      );
    ELFIO_GET_ACCESS    ( Elf64_Addr, address,            header.sh_addr      );

//------------------------------------------------------------------------------
    Elf_Half
    get_index() const
    {
        return index;
    }

//------------------------------------------------------------------------------
    std::string
    get_name() const
    {
        return name;
    }

//------------------------------------------------------------------------------
    void
    set_name( std::string name_ )
    {
        name = name_;
    }

//------------------------------------------------------------------------------
    void
    set_address( Elf64_Addr value )
    {
        header.sh_addr = value;
        header.sh_addr = (*convertor)( header.sh_addr );
        is_address_set = true;
    }

//------------------------------------------------------------------------------
    bool
    is_address_initialized() const
    {
        return is_address_set;
    }

//------------------------------------------------------------------------------
    const char*
    get_data() const
    {
        return data;
    }

//------------------------------------------------------------------------------
    void
    set_data( const char* raw_data, Elf_Word size )
    {
        if ( get_type() != SHT_NOBITS ) {
            delete [] data;
            data = new char[size];
            if ( 0 != data && 0 != raw_data ) {
                data_size = size;
                std::copy( raw_data, raw_data + size, data );
            }
        }

        set_size( size );
    }

//------------------------------------------------------------------------------
    void
    set_data( const std::string& str_data )
    {
        return set_data( str_data.c_str(), (Elf_Word)str_data.size() );
    }

//------------------------------------------------------------------------------
    void
    append_data( const char* raw_data, Elf_Word size )
    {
        if ( get_type() != SHT_NOBITS ) {
            if ( get_size() + size < data_size ) {
                std::copy( raw_data, raw_data + size, data + get_size() );
            }
            else {
                data_size = 2*( data_size + size);
                char* new_data = new char[data_size];
                if ( 0 != new_data ) {
                    std::copy( data, data + get_size(), new_data );
                    std::copy( raw_data, raw_data + size, new_data + get_size() );
                    delete [] data;
                    data = new_data;
                }
            }
            set_size( get_size() + size );
        }
    }

//------------------------------------------------------------------------------
    void
    append_data( const std::string& str_data )
    {
        return append_data( str_data.c_str(), (Elf_Word)str_data.size() );
    }

//------------------------------------------------------------------------------
  protected:
//------------------------------------------------------------------------------
    ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset );

//------------------------------------------------------------------------------
    void
    set_index( Elf_Half value )
    {
        index = value;
    }

//------------------------------------------------------------------------------
    void
    load( std::istream&  stream,
          std::streampos header_offset )
    {
        std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
        stream.seekg( header_offset );
        stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );

        Elf_Xword size = get_size();
        if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() ) {
            data = new char[size];
            if ( 0 != size ) {
                stream.seekg( (*convertor)( header.sh_offset ) );
                stream.read( data, size );
                data_size = size;
            }
        }
    }

//------------------------------------------------------------------------------
    void
    save( std::ostream&  f,
          std::streampos header_offset,
          std::streampos data_offset )
    {
        if ( 0 != get_index() ) {
            header.sh_offset = data_offset;
            header.sh_offset = (*convertor)( header.sh_offset );
        }

        save_header( f, header_offset );
        if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL &&
             get_size() != 0 && data != 0 ) {
            save_data( f, data_offset );
        }
    }

//------------------------------------------------------------------------------
  private:
//------------------------------------------------------------------------------
    void
    save_header( std::ostream&  f,
                 std::streampos header_offset ) const
    {
        f.seekp( header_offset );
        f.write( reinterpret_cast<const char*>( &header ), sizeof( header ) );
    }

//------------------------------------------------------------------------------
    void
    save_data( std::ostream&  f,
               std::streampos data_offset ) const
    {
        f.seekp( data_offset );
        f.write( get_data(), get_size() );
    }

//------------------------------------------------------------------------------
  private:
    T                          header;
    Elf_Half                   index;
    std::string                name;
    char*                      data;
    Elf_Word                   data_size;
    const endianess_convertor* convertor;
    bool                       is_address_set;
};

} // namespace ELFIO

#endif // ELFIO_SECTION_HPP
<commit_msg>Implement setData at certain offset<commit_after>/*
Copyright (C) 2001-2015 by Serge Lamikhov-Center

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef ELFIO_SECTION_HPP
#define ELFIO_SECTION_HPP

#include <string>
#include <iostream>

namespace ELFIO {

class section
{
    friend class elfio;
  public:
    virtual ~section() {};

    ELFIO_GET_ACCESS_DECL    ( Elf_Half,    index              );
    ELFIO_GET_SET_ACCESS_DECL( std::string, name               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    type               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   flags              );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    info               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    link               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   addr_align         );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   entry_size         );
    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr,  address            );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   size               );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    name_string_offset );

    virtual const char* get_data() const                                = 0;
    virtual void        set_data( const char* pData, Elf_Word size )    = 0;
    virtual void        set_data( const std::string& data )             = 0;
    virtual void        set_data( const char* raw_data, Elf_Word dataSize, Elf64_Addr updateAddress ) = 0;
    virtual void        append_data( const char* pData, Elf_Word size ) = 0;
    virtual void        append_data( const std::string& data )          = 0;

  protected:
    ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, offset );
    ELFIO_SET_ACCESS_DECL( Elf_Half,  index  );

    virtual void load( std::istream&  f,
                       std::streampos header_offset ) = 0;
    virtual void save( std::ostream&  f,
                       std::streampos header_offset,
                       std::streampos data_offset )   = 0;
    virtual bool is_address_initialized() const       = 0;
};

template< class T >
class section_impl : public section
{
  public:
//------------------------------------------------------------------------------
    section_impl( const endianess_convertor* convertor_ ) : convertor( convertor_ )
    {
        std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
        is_address_set = false;
        data           = 0;
        data_size      = 0;
    }

//------------------------------------------------------------------------------
    ~section_impl()
    {
        delete [] data;
    }

//------------------------------------------------------------------------------
    // Section info functions
    ELFIO_GET_SET_ACCESS( Elf_Word,   type,               header.sh_type      );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  flags,              header.sh_flags     );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  size,               header.sh_size      );
    ELFIO_GET_SET_ACCESS( Elf_Word,   link,               header.sh_link      );
    ELFIO_GET_SET_ACCESS( Elf_Word,   info,               header.sh_info      );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  addr_align,         header.sh_addralign );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  entry_size,         header.sh_entsize   );
    ELFIO_GET_SET_ACCESS( Elf_Word,   name_string_offset, header.sh_name      );
    ELFIO_GET_ACCESS    ( Elf64_Addr, address,            header.sh_addr      );

//------------------------------------------------------------------------------
    Elf_Half
    get_index() const
    {
        return index;
    }

//------------------------------------------------------------------------------
    std::string
    get_name() const
    {
        return name;
    }

//------------------------------------------------------------------------------
    void
    set_name( std::string name_ )
    {
        name = name_;
    }

//------------------------------------------------------------------------------
    void
    set_address( Elf64_Addr value )
    {
        header.sh_addr = value;
        header.sh_addr = (*convertor)( header.sh_addr );
        is_address_set = true;
    }

//------------------------------------------------------------------------------
    bool
    is_address_initialized() const
    {
        return is_address_set;
    }

//------------------------------------------------------------------------------
    const char*
    get_data() const
    {
        return data;
    }

//------------------------------------------------------------------------------
    void
    set_data( const char* raw_data, Elf_Word size )
    {
        if ( get_type() != SHT_NOBITS ) {
            delete [] data;
            data = new char[size];
            if ( 0 != data && 0 != raw_data ) {
                data_size = size;
                std::copy( raw_data, raw_data + size, data );
            }
        }

        set_size( size );
    }

//------------------------------------------------------------------------------
    void
    set_data( const std::string& str_data )
    {
        return set_data( str_data.c_str(), (Elf_Word)str_data.size() );
    }

    void
    set_data( const char* raw_data, Elf_Word dataSize, Elf64_Addr updateAddress)
    {
        if (dataSize <= (get_address() + get_size() - updateAddress))
        {
            std::copy(raw_data, raw_data + dataSize, data + (updateAddress - get_address()));
        }
    }

//------------------------------------------------------------------------------
    void
    append_data( const char* raw_data, Elf_Word size )
    {
        if ( get_type() != SHT_NOBITS ) {
            if ( get_size() + size < data_size ) {
                std::copy( raw_data, raw_data + size, data + get_size() );
            }
            else {
                data_size = 2*( data_size + size);
                char* new_data = new char[data_size];
                if ( 0 != new_data ) {
                    std::copy( data, data + get_size(), new_data );
                    std::copy( raw_data, raw_data + size, new_data + get_size() );
                    delete [] data;
                    data = new_data;
                }
            }
            set_size( get_size() + size );
        }
    }

//------------------------------------------------------------------------------
    void
    append_data( const std::string& str_data )
    {
        return append_data( str_data.c_str(), (Elf_Word)str_data.size() );
    }

//------------------------------------------------------------------------------
  protected:
//------------------------------------------------------------------------------
    ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset );

//------------------------------------------------------------------------------
    void
    set_index( Elf_Half value )
    {
        index = value;
    }

//------------------------------------------------------------------------------
    void
    load( std::istream&  stream,
          std::streampos header_offset )
    {
        std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
        stream.seekg( header_offset );
        stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );

        Elf_Xword size = get_size();
        if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() ) {
            data = new char[size];
            if ( 0 != size ) {
                stream.seekg( (*convertor)( header.sh_offset ) );
                stream.read( data, size );
                data_size = size;
            }
        }
    }

//------------------------------------------------------------------------------
    void
    save( std::ostream&  f,
          std::streampos header_offset,
          std::streampos data_offset )
    {
        if ( 0 != get_index() ) {
            header.sh_offset = data_offset;
            header.sh_offset = (*convertor)( header.sh_offset );
        }

        save_header( f, header_offset );
        if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL &&
             get_size() != 0 && data != 0 ) {
            save_data( f, data_offset );
        }
    }

//------------------------------------------------------------------------------
  private:
//------------------------------------------------------------------------------
    void
    save_header( std::ostream&  f,
                 std::streampos header_offset ) const
    {
        f.seekp( header_offset );
        f.write( reinterpret_cast<const char*>( &header ), sizeof( header ) );
    }

//------------------------------------------------------------------------------
    void
    save_data( std::ostream&  f,
               std::streampos data_offset ) const
    {
        f.seekp( data_offset );
        f.write( get_data(), get_size() );
    }

//------------------------------------------------------------------------------
  private:
    T                          header;
    Elf_Half                   index;
    std::string                name;
    char*                      data;
    Elf_Word                   data_size;
    const endianess_convertor* convertor;
    bool                       is_address_set;
};

} // namespace ELFIO

#endif // ELFIO_SECTION_HPP
<|endoftext|>


<commit_before>#include "band.h"

namespace sirius {

template <>
void Band::diag_h_o<double_complex>(K_point* kp__,
                                    int N__,
                                    int num_bands__,
                                    matrix<double_complex>& hmlt__,
                                    matrix<double_complex>& ovlp__,
                                    matrix<double_complex>& evec__,
                                    dmatrix<double_complex>& hmlt_dist__,
                                    dmatrix<double_complex>& ovlp_dist__,
                                    dmatrix<double_complex>& evec_dist__,
                                    std::vector<double>& eval__)
{
    PROFILE_WITH_TIMER("sirius::Band::diag_h_o");

    runtime::Timer t1("sirius::Band::diag_h_o|load");
    if (kp__->comm().size() > 1 && gen_evp_solver()->parallel())
    {
        for (int jloc = 0; jloc < hmlt_dist__.num_cols_local(); jloc++)
        {
            int j = hmlt_dist__.icol(jloc);
            for (int iloc = 0; iloc < hmlt_dist__.num_rows_local(); iloc++)
            {
                int i = hmlt_dist__.irow(iloc);
                hmlt_dist__(iloc, jloc) = (i > j) ? std::conj(hmlt__(j, i)) : hmlt__(i, j);
                ovlp_dist__(iloc, jloc) = (i > j) ? std::conj(ovlp__(j, i)) : ovlp__(i, j);
            }
        }
    }
    t1.stop();

    runtime::Timer t2("sirius::Band::diag_h_o|diag");
    int result = gen_evp_solver()->solve(N__,  num_bands__, hmlt_dist__.at<CPU>(), hmlt_dist__.ld(),
                                         ovlp_dist__.at<CPU>(), ovlp_dist__.ld(), &eval__[0], evec_dist__.at<CPU>(),
                                         evec_dist__.ld(), hmlt_dist__.num_rows_local(), hmlt_dist__.num_cols_local());
    if (result) TERMINATE("error in diagonalziation");
    t2.stop();

    runtime::Timer t3("sirius::Band::diag_h_o|gather");
    if (kp__->comm().size() > 1 && gen_evp_solver()->parallel())
    {
        evec__.zero();
        for (int i = 0; i < evec_dist__.num_cols_local(); i++)
        {
            for (int j = 0; j < evec_dist__.num_rows_local(); j++)
            {
                evec__(evec_dist__.irow(j), evec_dist__.icol(i)) = evec_dist__(j, i);
            }
        }
        kp__->comm().allreduce(evec__.at<CPU>(), evec__.ld() * num_bands__);
    }
    t3.stop();

    /* copy eigen-vectors to GPU */
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU)
        acc::copyin(evec__.at<GPU>(), evec__.ld(), evec__.at<CPU>(), evec__.ld(), N__, num_bands__);
    #endif
}

template <>
void Band::diag_h_o<double>(K_point* kp__,
                            int N__,
                            int num_bands__,
                            matrix<double>& hmlt__,
                            matrix<double>& ovlp__,
                            matrix<double>& evec__,
                            dmatrix<double>& hmlt_dist__,
                            dmatrix<double>& ovlp_dist__,
                            dmatrix<double>& evec_dist__,
                            std::vector<double>& eval__)
{
    PROFILE_WITH_TIMER("sirius::Band::diag_h_o");

    runtime::Timer t1("sirius::Band::diag_h_o|load");
    if (kp__->comm().size() > 1 && gen_evp_solver()->parallel())
    {
        for (int jloc = 0; jloc < hmlt_dist__.num_cols_local(); jloc++)
        {
            int j = hmlt_dist__.icol(jloc);
            for (int iloc = 0; iloc < hmlt_dist__.num_rows_local(); iloc++)
            {
                int i = hmlt_dist__.irow(iloc);
                hmlt_dist__(iloc, jloc) = (i > j) ? hmlt__(j, i) : hmlt__(i, j);
                ovlp_dist__(iloc, jloc) = (i > j) ? ovlp__(j, i) : ovlp__(i, j);
            }
        }
    }
    t1.stop();

    runtime::Timer t2("sirius::Band::diag_h_o|diag");
    int result = gen_evp_solver()->solve(N__,  num_bands__, hmlt_dist__.at<CPU>(), hmlt_dist__.ld(),
                                         ovlp_dist__.at<CPU>(), ovlp_dist__.ld(), &eval__[0], evec_dist__.at<CPU>(),
                                         evec_dist__.ld(), hmlt_dist__.num_rows_local(), hmlt_dist__.num_cols_local());
    if (result) TERMINATE("error in diagonalziation");
    t2.stop();

    runtime::Timer t3("sirius::Band::diag_h_o|gather");
    if (kp__->comm().size() > 1 && gen_evp_solver()->parallel())
    {
        evec__.zero();
        for (int i = 0; i < evec_dist__.num_cols_local(); i++)
        {
            for (int j = 0; j < evec_dist__.num_rows_local(); j++)
            {
                evec__(evec_dist__.irow(j), evec_dist__.icol(i)) = evec_dist__(j, i);
            }
        }
        kp__->comm().allreduce(evec__.at<CPU>(), evec__.ld() * num_bands__);
    }
    t3.stop();

    /* copy eigen-vectors to GPU */
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU)
        acc::copyin(evec__.at<GPU>(), evec__.ld(), evec__.at<CPU>(), evec__.ld(), N__, num_bands__);
    #endif
}

};
<commit_msg>this was stupid<commit_after>#include "band.h"

namespace sirius {

template <>
void Band::diag_h_o<double_complex>(K_point* kp__,
                                    int N__,
                                    int num_bands__,
                                    matrix<double_complex>& hmlt__,
                                    matrix<double_complex>& ovlp__,
                                    matrix<double_complex>& evec__,
                                    dmatrix<double_complex>& hmlt_dist__,
                                    dmatrix<double_complex>& ovlp_dist__,
                                    dmatrix<double_complex>& evec_dist__,
                                    std::vector<double>& eval__)
{
    PROFILE_WITH_TIMER("sirius::Band::diag_h_o");

    runtime::Timer t1("sirius::Band::diag_h_o|load");
    if (kp__->comm().size() > 1 && gen_evp_solver()->parallel())
    {
        for (int jloc = 0; jloc < hmlt_dist__.num_cols_local(); jloc++)
        {
            int j = hmlt_dist__.icol(jloc);
            for (int iloc = 0; iloc < hmlt_dist__.num_rows_local(); iloc++)
            {
                int i = hmlt_dist__.irow(iloc);
                hmlt_dist__(iloc, jloc) = (i > j) ? std::conj(hmlt__(j, i)) : hmlt__(i, j);
                ovlp_dist__(iloc, jloc) = (i > j) ? std::conj(ovlp__(j, i)) : ovlp__(i, j);
            }
        }
    }
    t1.stop();

    runtime::Timer t2("sirius::Band::diag_h_o|diag");
    int result;
    if (gen_evp_solver()->parallel())
    {
        result = gen_evp_solver()->solve(N__,  num_bands__, hmlt_dist__.at<CPU>(), hmlt_dist__.ld(),
                                         ovlp_dist__.at<CPU>(), ovlp_dist__.ld(), &eval__[0], evec_dist__.at<CPU>(),
                                         evec_dist__.ld(), hmlt_dist__.num_rows_local(), hmlt_dist__.num_cols_local());
    }
    else
    {
        result = gen_evp_solver()->solve(N__, num_bands__, hmlt__.at<CPU>(), hmlt__.ld(), ovlp__.at<CPU>(), ovlp__.ld(),
                                         &eval__[0], evec__.at<CPU>(), evec__.ld());
    }
    if (result) TERMINATE("error in diagonalziation");
    t2.stop();

    runtime::Timer t3("sirius::Band::diag_h_o|gather");
    if (kp__->comm().size() > 1 && gen_evp_solver()->parallel())
    {
        evec__.zero();
        for (int i = 0; i < evec_dist__.num_cols_local(); i++)
        {
            for (int j = 0; j < evec_dist__.num_rows_local(); j++)
            {
                evec__(evec_dist__.irow(j), evec_dist__.icol(i)) = evec_dist__(j, i);
            }
        }
        kp__->comm().allreduce(evec__.at<CPU>(), evec__.ld() * num_bands__);
    }
    t3.stop();

    /* copy eigen-vectors to GPU */
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU)
        acc::copyin(evec__.at<GPU>(), evec__.ld(), evec__.at<CPU>(), evec__.ld(), N__, num_bands__);
    #endif
}

template <>
void Band::diag_h_o<double>(K_point* kp__,
                            int N__,
                            int num_bands__,
                            matrix<double>& hmlt__,
                            matrix<double>& ovlp__,
                            matrix<double>& evec__,
                            dmatrix<double>& hmlt_dist__,
                            dmatrix<double>& ovlp_dist__,
                            dmatrix<double>& evec_dist__,
                            std::vector<double>& eval__)
{
    PROFILE_WITH_TIMER("sirius::Band::diag_h_o");

    runtime::Timer t1("sirius::Band::diag_h_o|load");
    if (kp__->comm().size() > 1 && gen_evp_solver()->parallel())
    {
        for (int jloc = 0; jloc < hmlt_dist__.num_cols_local(); jloc++)
        {
            int j = hmlt_dist__.icol(jloc);
            for (int iloc = 0; iloc < hmlt_dist__.num_rows_local(); iloc++)
            {
                int i = hmlt_dist__.irow(iloc);
                hmlt_dist__(iloc, jloc) = (i > j) ? hmlt__(j, i) : hmlt__(i, j);
                ovlp_dist__(iloc, jloc) = (i > j) ? ovlp__(j, i) : ovlp__(i, j);
            }
        }
    }
    t1.stop();

    runtime::Timer t2("sirius::Band::diag_h_o|diag");
    int result;
    if (gen_evp_solver()->parallel())
    {
        result = gen_evp_solver()->solve(N__,  num_bands__, hmlt_dist__.at<CPU>(), hmlt_dist__.ld(),
                                         ovlp_dist__.at<CPU>(), ovlp_dist__.ld(), &eval__[0], evec_dist__.at<CPU>(),
                                         evec_dist__.ld(), hmlt_dist__.num_rows_local(), hmlt_dist__.num_cols_local());
    }
    else
    {
        result = gen_evp_solver()->solve(N__, num_bands__, hmlt__.at<CPU>(), hmlt__.ld(), ovlp__.at<CPU>(), ovlp__.ld(),
                                         &eval__[0], evec__.at<CPU>(), evec__.ld());
    }
    if (result) TERMINATE("error in diagonalziation");
    t2.stop();

    runtime::Timer t3("sirius::Band::diag_h_o|gather");
    if (kp__->comm().size() > 1 && gen_evp_solver()->parallel())
    {
        evec__.zero();
        for (int i = 0; i < evec_dist__.num_cols_local(); i++)
        {
            for (int j = 0; j < evec_dist__.num_rows_local(); j++)
            {
                evec__(evec_dist__.irow(j), evec_dist__.icol(i)) = evec_dist__(j, i);
            }
        }
        kp__->comm().allreduce(evec__.at<CPU>(), evec__.ld() * num_bands__);
    }
    t3.stop();

    /* copy eigen-vectors to GPU */
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU)
        acc::copyin(evec__.at<GPU>(), evec__.ld(), evec__.at<CPU>(), evec__.ld(), N__, num_bands__);
    #endif
}

};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016, Ford Motor Company
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided with the
 * distribution.
 *
 * Neither the name of the Ford Motor Company nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
*/

#include "application_manager/application_manager_impl.h"
#include "application_manager/hmi_language_handler.h"
#include "application_manager/message_helper.h"
#include "application_manager/hmi_capabilities.h"
#include "utils/helpers.h"
#include "resumption/last_state.h"

static const std::string LanguagesKey = "Languages";
static const std::string UIKey = "UI";
static const std::string VRKey = "VR";
static const std::string TTSKey = "TTS";

namespace application_manager {

CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager")

HMILanguageHandler::HMILanguageHandler()
  : is_ui_language_received_(false),
    is_vr_language_received_(false),
    is_tts_language_received_(false) {
}

void HMILanguageHandler::set_ui_language(
      hmi_apis::Common_Language::eType language) {
  resumption::LastState::instance()->dictionary[LanguagesKey][UIKey] = language;
}

void HMILanguageHandler::set_vr_language(
      hmi_apis::Common_Language::eType language) {
  resumption::LastState::instance()->dictionary[LanguagesKey][VRKey] = language;
}

void HMILanguageHandler::set_tts_language(
      hmi_apis::Common_Language::eType language) {
  resumption::LastState::instance()->dictionary[LanguagesKey][TTSKey] = language;
}

hmi_apis::Common_Language::eType HMILanguageHandler::get_ui_language() const {
  using namespace resumption;
  using namespace hmi_apis;
  if (LastState::instance()->dictionary.isMember(LanguagesKey)) {
    if (LastState::instance()->dictionary[LanguagesKey].isMember(UIKey)) {
      Common_Language::eType ui_language =
          static_cast<Common_Language::eType>(
          LastState::instance()->dictionary[LanguagesKey][UIKey].asUInt());

      return ui_language;
    }
  }
  return Common_Language::INVALID_ENUM;
}

hmi_apis::Common_Language::eType HMILanguageHandler::get_vr_language() const {
  using namespace resumption;
  using namespace hmi_apis;
  if (LastState::instance()->dictionary.isMember(LanguagesKey)) {
    if (LastState::instance()->dictionary[LanguagesKey].isMember(VRKey)) {
      Common_Language::eType vr_language =
          static_cast<Common_Language::eType>(
          LastState::instance()->dictionary[LanguagesKey][VRKey].asUInt());

      return vr_language;
    }
  }
  return Common_Language::INVALID_ENUM;
}

hmi_apis::Common_Language::eType HMILanguageHandler::get_tts_language() const {
  using namespace resumption;
  using namespace hmi_apis;
  if (LastState::instance()->dictionary.isMember(LanguagesKey)) {
    if (LastState::instance()->dictionary[LanguagesKey].isMember(TTSKey)) {
      // Web HMI returns -1 which causes assert for debug
      Common_Language::eType tts_language = //Common_Language::EN_US;
          static_cast<Common_Language::eType>(
          LastState::instance()->dictionary[LanguagesKey][TTSKey].asUInt());

      return tts_language;
    }
  }
  return Common_Language::INVALID_ENUM;
}

void HMILanguageHandler::on_event(const event_engine::Event& event) {
  LOG4CXX_AUTO_TRACE(logger_);
  switch (event.id()) {
  case hmi_apis::FunctionID::UI_GetLanguage:
    LOG4CXX_DEBUG(logger_, "Got UI language response.");
    is_ui_language_received_ = true;
    break;
  case hmi_apis::FunctionID::VR_GetLanguage:
    LOG4CXX_DEBUG(logger_, "Got VR language response.");
    is_vr_language_received_ = true;
    break;
  case hmi_apis::FunctionID::TTS_GetLanguage:
    LOG4CXX_DEBUG(logger_, "Got TTS language response.");
    is_tts_language_received_ = true;
    break;
  default:
    return;
  }

  if (is_ui_language_received_ && is_vr_language_received_ &&
      is_tts_language_received_) {
    VerifyRegisteredApps();
  }
}

void HMILanguageHandler::set_handle_response_for(
    const event_engine::smart_objects::SmartObject& request) {
  using namespace helpers;
  if (!request.keyExists(strings::params)) {
    return;
  }

  if (!request[strings::params].keyExists(strings::function_id)) {
    return;
  }

  if (!request[strings::params].keyExists(strings::correlation_id)) {
    return;
  }

  hmi_apis::FunctionID::eType function_id =
      static_cast<hmi_apis::FunctionID::eType>(
        request[strings::params][strings::function_id].asInt());

  if (!Compare<hmi_apis::FunctionID::eType, EQ, ONE>(
        function_id,
        hmi_apis::FunctionID::UI_GetLanguage,
        hmi_apis::FunctionID::VR_GetLanguage,
        hmi_apis::FunctionID::TTS_GetLanguage)) {
    return;
  }

  uint32_t correlation_id =
      request[strings::params][strings::correlation_id].asUInt();

  subscribe_on_event(function_id, correlation_id);

  LOG4CXX_DEBUG(logger_, "Subscribed for function_id " << function_id <<
                " and correlation_id " << correlation_id);
}

void HMILanguageHandler::VerifyRegisteredApps() const {
  LOG4CXX_AUTO_TRACE(logger_);
  using namespace helpers;
  HMICapabilities& hmi_capabilities =
        ApplicationManagerImpl::instance()->hmi_capabilities();

  hmi_apis::Common_Language::eType ui_language =
          hmi_capabilities.active_ui_language();
  hmi_apis::Common_Language::eType vr_language =
          hmi_capabilities.active_vr_language();
  hmi_apis::Common_Language::eType tts_language =
          hmi_capabilities.active_tts_language();
  ApplicationManagerImpl::ApplicationListAccessor accessor;
  ApplicationSetIt it = accessor.begin();
  for (; accessor.end() != it;) {
    ApplicationSharedPtr app = *it++;
    if (app->ui_language() !=
        MessageHelper::CommonToMobileLanguage(ui_language) ||
        !Compare<mobile_apis::Language::eType, EQ, ALL>(
          app->language(),
          MessageHelper::CommonToMobileLanguage(vr_language),
          MessageHelper::CommonToMobileLanguage(tts_language))) {
      MessageHelper::SendOnLanguageChangeToMobile(app->app_id());
      MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
                  app->app_id(),
                  mobile_api::AppInterfaceUnregisteredReason::LANGUAGE_CHANGE);
      ApplicationManagerImpl::instance()->UnregisterApplication(
                  app->app_id(), mobile_apis::Result::SUCCESS, false);
    }
  }
}

} // namespace application_manager
<commit_msg>Adds more logging.<commit_after>/*
 * Copyright (c) 2016, Ford Motor Company
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided with the
 * distribution.
 *
 * Neither the name of the Ford Motor Company nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
*/

#include "application_manager/application_manager_impl.h"
#include "application_manager/hmi_language_handler.h"
#include "application_manager/message_helper.h"
#include "application_manager/hmi_capabilities.h"
#include "utils/helpers.h"
#include "resumption/last_state.h"

static const std::string LanguagesKey = "Languages";
static const std::string UIKey = "UI";
static const std::string VRKey = "VR";
static const std::string TTSKey = "TTS";

namespace application_manager {

CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager")

HMILanguageHandler::HMILanguageHandler()
  : is_ui_language_received_(false),
    is_vr_language_received_(false),
    is_tts_language_received_(false) {
}

void HMILanguageHandler::set_ui_language(
      hmi_apis::Common_Language::eType language) {
  LOG4CXX_AUTO_TRACE(logger_);
  resumption::LastState::instance()->dictionary[LanguagesKey][UIKey] = language;
}

void HMILanguageHandler::set_vr_language(
      hmi_apis::Common_Language::eType language) {
  LOG4CXX_AUTO_TRACE(logger_);
  resumption::LastState::instance()->dictionary[LanguagesKey][VRKey] = language;
}

void HMILanguageHandler::set_tts_language(
      hmi_apis::Common_Language::eType language) {
  LOG4CXX_AUTO_TRACE(logger_);
  resumption::LastState::instance()->dictionary[LanguagesKey][TTSKey] = language;
}

hmi_apis::Common_Language::eType HMILanguageHandler::get_ui_language() const {
  LOG4CXX_AUTO_TRACE(logger_);
  using namespace resumption;
  using namespace hmi_apis;
  if (LastState::instance()->dictionary.isMember(LanguagesKey)) {
    if (LastState::instance()->dictionary[LanguagesKey].isMember(UIKey)) {
      Common_Language::eType ui_language =
          static_cast<Common_Language::eType>(
          LastState::instance()->dictionary[LanguagesKey][UIKey].asUInt());

      return ui_language;
    }
  }
  return Common_Language::INVALID_ENUM;
}

hmi_apis::Common_Language::eType HMILanguageHandler::get_vr_language() const {
  LOG4CXX_AUTO_TRACE(logger_);
  using namespace resumption;
  using namespace hmi_apis;
  if (LastState::instance()->dictionary.isMember(LanguagesKey)) {
    if (LastState::instance()->dictionary[LanguagesKey].isMember(VRKey)) {
      Common_Language::eType vr_language =
          static_cast<Common_Language::eType>(
          LastState::instance()->dictionary[LanguagesKey][VRKey].asUInt());

      return vr_language;
    }
  }
  return Common_Language::INVALID_ENUM;
}

hmi_apis::Common_Language::eType HMILanguageHandler::get_tts_language() const {
  LOG4CXX_AUTO_TRACE(logger_);
  using namespace resumption;
  using namespace hmi_apis;
  if (LastState::instance()->dictionary.isMember(LanguagesKey)) {
    if (LastState::instance()->dictionary[LanguagesKey].isMember(TTSKey)) {
      // Web HMI returns -1 which causes assert for debug
      Common_Language::eType tts_language = //Common_Language::EN_US;
          static_cast<Common_Language::eType>(
          LastState::instance()->dictionary[LanguagesKey][TTSKey].asUInt());

      return tts_language;
    }
  }
  return Common_Language::INVALID_ENUM;
}

void HMILanguageHandler::on_event(const event_engine::Event& event) {
  LOG4CXX_AUTO_TRACE(logger_);
  switch (event.id()) {
  case hmi_apis::FunctionID::UI_GetLanguage:
    LOG4CXX_DEBUG(logger_, "Got UI language response.");
    is_ui_language_received_ = true;
    break;
  case hmi_apis::FunctionID::VR_GetLanguage:
    LOG4CXX_DEBUG(logger_, "Got VR language response.");
    is_vr_language_received_ = true;
    break;
  case hmi_apis::FunctionID::TTS_GetLanguage:
    LOG4CXX_DEBUG(logger_, "Got TTS language response.");
    is_tts_language_received_ = true;
    break;
  default:
    return;
  }

  if (is_ui_language_received_ && is_vr_language_received_ &&
      is_tts_language_received_) {
    VerifyRegisteredApps();
  }
}

void HMILanguageHandler::set_handle_response_for(
    const event_engine::smart_objects::SmartObject& request) {
  LOG4CXX_AUTO_TRACE(logger_);
  using namespace helpers;
  if (!request.keyExists(strings::params)) {
    LOG4CXX_ERROR(logger_, "Object does not have " << strings::params
                  << " key.");
    return;
  }

  if (!request[strings::params].keyExists(strings::function_id)) {
    LOG4CXX_ERROR(logger_, "Object does not have " << strings::function_id
                  << " key.");
    return;
  }

  if (!request[strings::params].keyExists(strings::correlation_id)) {
    LOG4CXX_ERROR(logger_, "Object does not have " << strings::correlation_id
                  << " key.");
    return;
  }

  hmi_apis::FunctionID::eType function_id =
      static_cast<hmi_apis::FunctionID::eType>(
        request[strings::params][strings::function_id].asInt());

  if (!Compare<hmi_apis::FunctionID::eType, EQ, ONE>(
        function_id,
        hmi_apis::FunctionID::UI_GetLanguage,
        hmi_apis::FunctionID::VR_GetLanguage,
        hmi_apis::FunctionID::TTS_GetLanguage)) {
    LOG4CXX_ERROR(logger_,
                  "Only *GetLanguage request are allowed to be subscribed.");
    return;
  }

  uint32_t correlation_id =
      request[strings::params][strings::correlation_id].asUInt();

  subscribe_on_event(function_id, correlation_id);

  LOG4CXX_DEBUG(logger_, "Subscribed for function_id " << function_id <<
                " and correlation_id " << correlation_id);
}

void HMILanguageHandler::VerifyRegisteredApps() const {
  LOG4CXX_AUTO_TRACE(logger_);
  using namespace helpers;
  HMICapabilities& hmi_capabilities =
        ApplicationManagerImpl::instance()->hmi_capabilities();

  hmi_apis::Common_Language::eType ui_language =
          hmi_capabilities.active_ui_language();
  hmi_apis::Common_Language::eType vr_language =
          hmi_capabilities.active_vr_language();
  hmi_apis::Common_Language::eType tts_language =
          hmi_capabilities.active_tts_language();
  ApplicationManagerImpl::ApplicationListAccessor accessor;
  ApplicationSetIt it = accessor.begin();
  for (; accessor.end() != it;) {
    ApplicationSharedPtr app = *it++;
    if (app->ui_language() !=
        MessageHelper::CommonToMobileLanguage(ui_language) ||
        !Compare<mobile_apis::Language::eType, EQ, ALL>(
          app->language(),
          MessageHelper::CommonToMobileLanguage(vr_language),
          MessageHelper::CommonToMobileLanguage(tts_language))) {
      LOG4CXX_INFO(logger_, "Application with app_id " << app->app_id()
                   << " will be unregistered because of "
                      "HMI language(s) mismatch.");
      MessageHelper::SendOnLanguageChangeToMobile(app->app_id());
      MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
                  app->app_id(),
                  mobile_api::AppInterfaceUnregisteredReason::LANGUAGE_CHANGE);
      ApplicationManagerImpl::instance()->UnregisterApplication(
                  app->app_id(), mobile_apis::Result::SUCCESS, false);
    }
  }
}

} // namespace application_manager
<|endoftext|>


<commit_before><commit_msg>correct geam ldc bug<commit_after><|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */

/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#pragma once

#include "sstring.hh"
#include "future.hh"

// iostream.hh
template <class CharType> class input_stream;
template <class CharType> class output_stream;

// reactor.hh
class server_socket;
class connected_socket;
class socket_address;
class listen_options;

// file.hh
class file;
enum class open_flags;

// Networking API
server_socket listen(socket_address sa);
server_socket listen(socket_address sa, listen_options opts);
future<connected_socket> connect(socket_address sa);

// File API
future<file> open_file_dma(sstring name, open_flags flags);
future<file> open_directory(sstring name);
future<> make_directory(sstring name);
future<> remove_file(sstring pathname);

<commit_msg>doc: add main doxygen page<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */

/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#pragma once

/// \mainpage
///
/// Seastar is a high performance C++ application framework for high
/// concurrency server applications.
///
/// Please see:
///   - \ref future Documentation on futures and promises, which are
///          the seastar building blocks.

#include "sstring.hh"
#include "future.hh"

// iostream.hh
template <class CharType> class input_stream;
template <class CharType> class output_stream;

// reactor.hh
class server_socket;
class connected_socket;
class socket_address;
class listen_options;

// file.hh
class file;
enum class open_flags;

// Networking API
server_socket listen(socket_address sa);
server_socket listen(socket_address sa, listen_options opts);
future<connected_socket> connect(socket_address sa);

// File API
future<file> open_file_dma(sstring name, open_flags flags);
future<file> open_directory(sstring name);
future<> make_directory(sstring name);
future<> remove_file(sstring pathname);

<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/perv/p9_sbe_chiplet_reset.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//------------------------------------------------------------------------------
/// @file  p9_sbe_chiplet_reset.H
///
/// @brief Steps:-
///     1) Identify Partical good chiplet and configure Multicasting register
///     2) Similar way, Configure hang pulse counter for Nest/MC/OBus/XBus/PCIe
///     3) Similar way,  set fence for Nest and MC chiplet
///     4) Similar way,  Reset sys.config and OPCG setting for Nest and MC chiplet in sync mode
///
/// Done
//------------------------------------------------------------------------------
// *HWP HW Owner        : Abhishek Agarwal <abagarw8@in.ibm.com>
// *HWP HW Backup Owner : Srinivas V. Naga <srinivan@in.ibm.com>
// *HWP FW Owner        : Brian Silver <bsilver@us.ibm.com>
// *HWP Team            : Perv
// *HWP Level           : 3
// *HWP Consumed by     : SBE
//------------------------------------------------------------------------------

#ifndef _P9_SBE_CHIPLET_RESET_H_
#define _P9_SBE_CHIPLET_RESET_H_

#include <fapi2.H>

namespace p9SbeChipletReset
{
enum P9_SBE_CHIPLET_RESET_Public_Constants
{
    MCGR_CNFG_SETTING_EMPTY  = 0xFC00000000000000ull,
    MCGR_CNFG_SETTING_GROUP0 = 0xE0001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP1 = 0xE4001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP2 = 0xE8001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP3 = 0xEC001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP4 = 0xF0001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP5 = 0xF4001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP6 = 0xF8001C0000000000ull,
    NET_CNTL0_HW_INIT_VALUE = 0x7C06222000000000ull,
    NET_CNTL0_HW_INIT_VALUE_FOR_DD1 = 0x7C16222000000000ull,
    HANG_PULSE_0X10 = 0x10,
    HANG_PULSE_0X0F = 0x0F,
    HANG_PULSE_0X06 = 0x06,
    HANG_PULSE_0X17 = 0x17,
    HANG_PULSE_0X18 = 0x18,
    HANG_PULSE_0X22 = 0x22,
    HANG_PULSE_0X13 = 0x13,
    HANG_PULSE_0X03 = 0x03,
    OPCG_ALIGN_SETTING = 0x5000000000003020ull,
    INOP_ALIGN_SETTING_0X5 = 0x5,
    OPCG_WAIT_CYCLE_0X020 = 0x020,
    SCAN_RATIO_0X3 = 0x3,
    SYNC_PULSE_DELAY_0X0 = 0X00,
    SYNC_CONFIG_DEFAULT = 0X0000000000000000,
    HANG_PULSE_0X00 = 0x00,
    HANG_PULSE_0X01 = 0x01,
    HANG_PULSE_0X04 = 0x04,
    HANG_PULSE_0X1A = 0x1A,
    NET_CNTL1_HW_INIT_VALUE = 0x7200000000000000ull,
    REGIONS_EXCEPT_VITAL = 0x7FF,
    SCAN_TYPES_EXCEPT_TIME_GPTR_REPR = 0xDCF,
    SCAN_TYPES_TIME_GPTR_REPR = 0x230,
    SCAN_RATIO_0X0 = 0x0,
    SYNC_CONFIG_4TO1 = 0X0800000000000000,
    HW_NS_DELAY = 200000, // unit is nano seconds
    SIM_CYCLE_DELAY = 10000, // unit is cycles
    HANG_PULSE_0X12 = 0x12,
    HANG_PULSE_0X1C = 0x1C,
    HANG_PULSE_0X08 = 0x08,
    MC_CPLT_CONF1_FASTX2_RATIO_MASK = 0x0000C00000000000ULL
};
}

typedef fapi2::ReturnCode (*p9_sbe_chiplet_reset_FP_t)(const
        fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);

/// @brief Identify all good chiplets excluding EQ/EC
///  -- All chiplets will be reset and PLLs started
///  -- Partial bad - All nest Chiplets must be good, MC, IO can be partial bad
/// Setup multicast groups for all chiplets
///  -- Can't use the multicast for all non-nest chiplets
///  -- This is intended to be the eventual product setting
///  -- This includes the core/cache chiplets
/// For all good chiplets excluding EQ/EC
/// -- Setup Chiplet GP3 regs
///  -- Reset to default state
///  -- Set chiplet enable on all all good chiplets excluding EQ/EC
/// For all enabled chiplets excluding EQ/EC/Buses
///  -- Start vital clocks and release endpoint reset
///  -- PCB Slave error register Reset
///
///
/// @param[in]     i_target_chip   Reference to TARGET_TYPE_PROC_CHIP target
/// @return  FAPI2_RC_SUCCESS if success, else error code.
extern "C"
{
    fapi2::ReturnCode p9_sbe_chiplet_reset(const
                                           fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip);
}

#endif
<commit_msg>p9_sbe_chiplet_reset: Set VITL_AL flag for MC chiplets<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/perv/p9_sbe_chiplet_reset.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//------------------------------------------------------------------------------
/// @file  p9_sbe_chiplet_reset.H
///
/// @brief Steps:-
///     1) Identify Partical good chiplet and configure Multicasting register
///     2) Similar way, Configure hang pulse counter for Nest/MC/OBus/XBus/PCIe
///     3) Similar way,  set fence for Nest and MC chiplet
///     4) Similar way,  Reset sys.config and OPCG setting for Nest and MC chiplet in sync mode
///
/// Done
//------------------------------------------------------------------------------
// *HWP HW Owner        : Abhishek Agarwal <abagarw8@in.ibm.com>
// *HWP HW Backup Owner : Srinivas V. Naga <srinivan@in.ibm.com>
// *HWP FW Owner        : Brian Silver <bsilver@us.ibm.com>
// *HWP Team            : Perv
// *HWP Level           : 3
// *HWP Consumed by     : SBE
//------------------------------------------------------------------------------

#ifndef _P9_SBE_CHIPLET_RESET_H_
#define _P9_SBE_CHIPLET_RESET_H_

#include <fapi2.H>

namespace p9SbeChipletReset
{
enum P9_SBE_CHIPLET_RESET_Public_Constants
{
    MCGR_CNFG_SETTING_EMPTY  = 0xFC00000000000000ull,
    MCGR_CNFG_SETTING_GROUP0 = 0xE0001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP1 = 0xE4001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP2 = 0xE8001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP3 = 0xEC001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP4 = 0xF0001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP5 = 0xF4001C0000000000ull,
    MCGR_CNFG_SETTING_GROUP6 = 0xF8001C0000000000ull,
    NET_CNTL0_HW_INIT_VALUE = 0x7C06222000000000ull,
    NET_CNTL0_HW_INIT_VALUE_FOR_DD1 = 0x7C16222000000000ull,
    NET_CNTL0_SET_VITL_AL = 0x0020000000000000ull,
    HANG_PULSE_0X10 = 0x10,
    HANG_PULSE_0X0F = 0x0F,
    HANG_PULSE_0X06 = 0x06,
    HANG_PULSE_0X17 = 0x17,
    HANG_PULSE_0X18 = 0x18,
    HANG_PULSE_0X22 = 0x22,
    HANG_PULSE_0X13 = 0x13,
    HANG_PULSE_0X03 = 0x03,
    OPCG_ALIGN_SETTING = 0x5000000000003020ull,
    INOP_ALIGN_SETTING_0X5 = 0x5,
    OPCG_WAIT_CYCLE_0X020 = 0x020,
    SCAN_RATIO_0X3 = 0x3,
    SYNC_PULSE_DELAY_0X0 = 0X00,
    SYNC_CONFIG_DEFAULT = 0X0000000000000000,
    HANG_PULSE_0X00 = 0x00,
    HANG_PULSE_0X01 = 0x01,
    HANG_PULSE_0X04 = 0x04,
    HANG_PULSE_0X1A = 0x1A,
    NET_CNTL1_HW_INIT_VALUE = 0x7200000000000000ull,
    REGIONS_EXCEPT_VITAL = 0x7FF,
    SCAN_TYPES_EXCEPT_TIME_GPTR_REPR = 0xDCF,
    SCAN_TYPES_TIME_GPTR_REPR = 0x230,
    SCAN_RATIO_0X0 = 0x0,
    SYNC_CONFIG_4TO1 = 0X0800000000000000,
    HW_NS_DELAY = 200000, // unit is nano seconds
    SIM_CYCLE_DELAY = 10000, // unit is cycles
    HANG_PULSE_0X12 = 0x12,
    HANG_PULSE_0X1C = 0x1C,
    HANG_PULSE_0X08 = 0x08,
    MC_CPLT_CONF1_FASTX2_RATIO_MASK = 0x0000C00000000000ULL
};
}

typedef fapi2::ReturnCode (*p9_sbe_chiplet_reset_FP_t)(const
        fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);

/// @brief Identify all good chiplets excluding EQ/EC
///  -- All chiplets will be reset and PLLs started
///  -- Partial bad - All nest Chiplets must be good, MC, IO can be partial bad
/// Setup multicast groups for all chiplets
///  -- Can't use the multicast for all non-nest chiplets
///  -- This is intended to be the eventual product setting
///  -- This includes the core/cache chiplets
/// For all good chiplets excluding EQ/EC
/// -- Setup Chiplet GP3 regs
///  -- Reset to default state
///  -- Set chiplet enable on all all good chiplets excluding EQ/EC
/// For all enabled chiplets excluding EQ/EC/Buses
///  -- Start vital clocks and release endpoint reset
///  -- PCB Slave error register Reset
///
///
/// @param[in]     i_target_chip   Reference to TARGET_TYPE_PROC_CHIP target
/// @return  FAPI2_RC_SUCCESS if success, else error code.
extern "C"
{
    fapi2::ReturnCode p9_sbe_chiplet_reset(const
                                           fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip);
}

#endif
<|endoftext|>


<commit_before>#include "session.h"

#include "util.h"

Session::Session() {
    curl_ = {cpr::util::newHolder(), &cpr::util::freeHolder};
    auto curl = curl_->handle;
    if (curl) {
        // Set up some sensible defaults
        auto version_info = curl_version_info(CURLVERSION_NOW);
        auto version = std::string{"curl/"} + std::string{version_info->version};
        curl_easy_setopt(curl, CURLOPT_USERAGENT, version.data());
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
#if LIBCURL_VERSION_MAJOR >= 7
#if LIBCURL_VERSION_MINOR >= 25
#if LIBCURL_VERSION_PATCH >= 0
        curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
#endif
#endif
#endif
    }
}

void Session::SetUrl(Url url) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.data());
    }
}

void Session::SetUrl(Url url, Parameters parameters) {
    auto curl = curl_->handle;
    if (curl) {
        Url new_url{url + "?"};
        for(auto parameter = parameters.cbegin(); parameter != parameters.cend(); ++parameter) {
            new_url += parameter->first + "=" + parameter->second;
        }
        curl_easy_setopt(curl, CURLOPT_URL, new_url.data());
    }
}

void Session::SetHeader(Header header) {
    auto curl = curl_->handle;
    if (curl) {
        struct curl_slist* chunk = NULL;
        for (auto item = header.cbegin(); item != header.cend(); ++item) {
            auto header_string = std::string{item->first};
            if (item->second.empty()) {
                header_string += ";";
            } else {
                header_string += ": " + item->second;
            }
            chunk = curl_slist_append(chunk, header_string.data());
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
            curl_->chunk = chunk;
        }
    }
}

void Session::SetTimeout(long timeout) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, timeout);
    }
}

void Session::SetAuth(Authentication auth) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_USERPWD, auth.GetAuthString());
    }
}

void Session::SetPayload(Payload payload) {
    auto curl = curl_->handle;
    if (curl) {
        struct curl_slist* chunk = NULL;
        auto payload_string = std::string{};
        for (auto item = payload.cbegin(); item != payload.cend(); ++item) {
            if (!payload_string.empty()) {
                payload_string += "&";
            }
            payload_string += item->first + "=" + item->second;
        }
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload_string.data());
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload_string.length());
    }
}

void Session::SetRedirect(bool redirect) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, long(redirect));
    }
}

Response Session::Get() {
    auto curl = curl_->handle;
    CURLcode res;

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
        curl_easy_setopt(curl, CURLOPT_POST, 0L);
        std::string response_string;
        std::string header_string;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cpr::util::writeFunction);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header_string);

        res = curl_easy_perform(curl);

        if (res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));
        }

        char* raw_url;
        long response_code;
        double elapsed;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
        curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed);
        curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &raw_url);
        auto header = cpr::util::parseHeader(header_string);
        Response response{response_code, response_string, header, raw_url, elapsed};
        return response;
    }

    return Response{0, "Curl could not start", Header{}, Url{}, 0.0};
}

Response Session::Post() {
    auto curl = curl_->handle;
    CURLcode res;

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 0L);
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        std::string response_string;
        std::string header_string;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cpr::util::writeFunction);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header_string);

        res = curl_easy_perform(curl);

        if (res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));
        }

        char* raw_url;
        long response_code;
        double elapsed;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
        curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed);
        curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &raw_url);
        auto header = cpr::util::parseHeader(header_string);
        Response response{response_code, response_string, header, raw_url, elapsed};
        return response;
    }

    return Response{0, "Curl could not start", Header{}, Url{}, 0.0};
}
<commit_msg>Remove verbosity<commit_after>#include "session.h"

#include "util.h"

Session::Session() {
    curl_ = {cpr::util::newHolder(), &cpr::util::freeHolder};
    auto curl = curl_->handle;
    if (curl) {
        // Set up some sensible defaults
        auto version_info = curl_version_info(CURLVERSION_NOW);
        auto version = std::string{"curl/"} + std::string{version_info->version};
        curl_easy_setopt(curl, CURLOPT_USERAGENT, version.data());
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
#if LIBCURL_VERSION_MAJOR >= 7
#if LIBCURL_VERSION_MINOR >= 25
#if LIBCURL_VERSION_PATCH >= 0
        curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
#endif
#endif
#endif
    }
}

void Session::SetUrl(Url url) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.data());
    }
}

void Session::SetUrl(Url url, Parameters parameters) {
    auto curl = curl_->handle;
    if (curl) {
        Url new_url{url + "?"};
        for(auto parameter = parameters.cbegin(); parameter != parameters.cend(); ++parameter) {
            new_url += parameter->first + "=" + parameter->second;
        }
        curl_easy_setopt(curl, CURLOPT_URL, new_url.data());
    }
}

void Session::SetHeader(Header header) {
    auto curl = curl_->handle;
    if (curl) {
        struct curl_slist* chunk = NULL;
        for (auto item = header.cbegin(); item != header.cend(); ++item) {
            auto header_string = std::string{item->first};
            if (item->second.empty()) {
                header_string += ";";
            } else {
                header_string += ": " + item->second;
            }
            chunk = curl_slist_append(chunk, header_string.data());
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
            curl_->chunk = chunk;
        }
    }
}

void Session::SetTimeout(long timeout) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, timeout);
    }
}

void Session::SetAuth(Authentication auth) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_USERPWD, auth.GetAuthString());
    }
}

void Session::SetPayload(Payload payload) {
    auto curl = curl_->handle;
    if (curl) {
        struct curl_slist* chunk = NULL;
        auto payload_string = std::string{};
        for (auto item = payload.cbegin(); item != payload.cend(); ++item) {
            if (!payload_string.empty()) {
                payload_string += "&";
            }
            payload_string += item->first + "=" + item->second;
        }
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload_string.data());
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload_string.length());
    }
}

void Session::SetRedirect(bool redirect) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, long(redirect));
    }
}

Response Session::Get() {
    auto curl = curl_->handle;
    CURLcode res;

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
        curl_easy_setopt(curl, CURLOPT_POST, 0L);
        std::string response_string;
        std::string header_string;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cpr::util::writeFunction);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header_string);

        res = curl_easy_perform(curl);

        if (res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));
        }

        char* raw_url;
        long response_code;
        double elapsed;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
        curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed);
        curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &raw_url);
        auto header = cpr::util::parseHeader(header_string);
        Response response{response_code, response_string, header, raw_url, elapsed};
        return response;
    }

    return Response{0, "Curl could not start", Header{}, Url{}, 0.0};
}

Response Session::Post() {
    auto curl = curl_->handle;
    CURLcode res;

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 0L);
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        std::string response_string;
        std::string header_string;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cpr::util::writeFunction);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header_string);

        res = curl_easy_perform(curl);

        if (res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));
        }

        char* raw_url;
        long response_code;
        double elapsed;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
        curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed);
        curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &raw_url);
        auto header = cpr::util::parseHeader(header_string);
        Response response{response_code, response_string, header, raw_url, elapsed};
        return response;
    }

    return Response{0, "Curl could not start", Header{}, Url{}, 0.0};
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
 *
 * This 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

// boost
#include <boost/python/suite/indexing/indexing_suite.hpp>
#include <boost/python/iterator.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python.hpp>
#include <boost/scoped_array.hpp>
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/wkb.hpp>

mapnik::geometry_type & (mapnik::Feature::*get_geom1)(unsigned) = &mapnik::Feature::get_geometry;

namespace {

using mapnik::Feature;
using mapnik::geometry_utils;

void feature_add_wkb_geometry(Feature &feature, std::string wkb)
{
    geometry_utils::from_wkb(feature, wkb.c_str(), wkb.size(), true);
}

void add_geometry(Feature & feature, std::auto_ptr<mapnik::geometry_type> geom)
{
    feature.add_geometry(geom.get());
    geom.release();
}

} // end anonymous namespace

namespace boost { namespace python {
    struct value_converter : public boost::static_visitor<PyObject*>
    {
        PyObject * operator() (int val) const
        {
#if PY_VERSION_HEX >= 0x03000000
            return ::PyLong_FromLong(val);
#else
            return ::PyInt_FromLong(val);
#endif
        }

        PyObject * operator() (double val) const
        {
            return ::PyFloat_FromDouble(val);
        }

        PyObject * operator() (UnicodeString const& s) const
        {
            std::string buffer;
            mapnik::to_utf8(s,buffer);
            PyObject *obj = Py_None;
            obj = ::PyUnicode_DecodeUTF8(buffer.c_str(),implicit_cast<ssize_t>(buffer.length()),0);
            return obj;
        }

        PyObject * operator() (mapnik::value_null const& s) const
        {
            return NULL;
        }
    };

    struct mapnik_value_to_python
    {
        static PyObject* convert(mapnik::value const& v)
        {
            return boost::apply_visitor(value_converter(),v.base());
        }
    };

// Forward declaration
    template <class Container, bool NoProxy, class DerivedPolicies>
    class map_indexing_suite2;

    namespace detail
    {
    template <class Container, bool NoProxy>
    class final_map_derived_policies
        : public map_indexing_suite2<Container,
                                     NoProxy, final_map_derived_policies<Container, NoProxy> > {};
    }

    template <class Container,bool NoProxy = false,
              class DerivedPolicies = detail::final_map_derived_policies<Container, NoProxy> >
    class map_indexing_suite2
        : public indexing_suite<
    Container
    , DerivedPolicies
    , NoProxy
    , true
    , typename Container::value_type::second_type
    , typename Container::key_type
    , typename Container::key_type
    >
    {
    public:

        typedef typename Container::value_type value_type;
        typedef typename Container::value_type::second_type data_type;
        typedef typename Container::key_type key_type;
        typedef typename Container::key_type index_type;
        typedef typename Container::size_type size_type;
        typedef typename Container::difference_type difference_type;

        template <class Class>
        static void
        extension_def(Class& cl)
        {

        }

        static data_type&
        get_item(Container& container, index_type i_)
        {
            typename Container::iterator i = container.props().find(i_);
            if (i == container.end())
            {
                PyErr_SetString(PyExc_KeyError, "Invalid key");
                throw_error_already_set();
            }
            return i->second;
        }

        static void
        set_item(Container& container, index_type i, data_type const& v)
        {
            container[i] = v;
        }

        static void
        delete_item(Container& container, index_type i)
        {
            container.props().erase(i);
        }

        static size_t
        size(Container& container)
        {
            return container.props().size();
        }

        static bool
        contains(Container& container, key_type const& key)
        {
            return container.props().find(key) != container.end();
        }

        static bool
        compare_index(Container& container, index_type a, index_type b)
        {
            return container.props().key_comp()(a, b);
        }

        static index_type
        convert_index(Container& /*container*/, PyObject* i_)
        {
            extract<key_type const&> i(i_);
            if (i.check())
            {
                return i();
            }
            else
            {
                extract<key_type> i(i_);
                if (i.check())
                    return i();
            }

            PyErr_SetString(PyExc_TypeError, "Invalid index type");
            throw_error_already_set();
            return index_type();
        }
    };

    template <typename T1, typename T2>
    struct std_pair_to_tuple
    {
        static PyObject* convert(std::pair<T1, T2> const& p)
        {
            return boost::python::incref(
                boost::python::make_tuple(p.first, p.second).ptr());
        }
    };

    template <typename T1, typename T2>
    struct std_pair_to_python_converter
    {
        std_pair_to_python_converter()
        {
            boost::python::to_python_converter<
                std::pair<T1, T2>,
                std_pair_to_tuple<T1, T2> >();
        }
    };

    }}

struct UnicodeString_from_python_str
{
    UnicodeString_from_python_str()
    {
        boost::python::converter::registry::push_back(
            &convertible,
            &construct,
            boost::python::type_id<UnicodeString>());
    }

    static void* convertible(PyObject* obj_ptr)
    {
        if (!(
#if PY_VERSION_HEX >= 0x03000000
                PyBytes_Check(obj_ptr)
#else
                PyString_Check(obj_ptr)
#endif
                || PyUnicode_Check(obj_ptr)))
            return 0;
        return obj_ptr;
    }

    static void construct(
        PyObject* obj_ptr,
        boost::python::converter::rvalue_from_python_stage1_data* data)
    {
        char * value=0;
        if (PyUnicode_Check(obj_ptr)) {
            PyObject *encoded = PyUnicode_AsEncodedString(obj_ptr, "utf8", "replace");
            if (encoded) {
#if PY_VERSION_HEX >= 0x03000000
                value = PyBytes_AsString(encoded);
#else
                value = PyString_AsString(encoded);
#endif
                Py_DecRef(encoded);
            }
        } else {
#if PY_VERSION_HEX >= 0x03000000
            value = PyBytes_AsString(obj_ptr);
#else
            value = PyString_AsString(obj_ptr);
#endif
        }
        if (value == 0) boost::python::throw_error_already_set();
        void* storage = (
            (boost::python::converter::rvalue_from_python_storage<UnicodeString>*)
            data)->storage.bytes;
        new (storage) UnicodeString(value);
        data->convertible = storage;
    }
};

void export_feature()
{
    using namespace boost::python;
    using mapnik::Feature;

    implicitly_convertible<int,mapnik::value>();
    implicitly_convertible<double,mapnik::value>();
    implicitly_convertible<UnicodeString,mapnik::value>();
    implicitly_convertible<bool,mapnik::value>();

    std_pair_to_python_converter<std::string const,mapnik::value>();
    to_python_converter<mapnik::value,mapnik_value_to_python>();
    UnicodeString_from_python_str();

    class_<Feature,boost::shared_ptr<Feature>,
        boost::noncopyable>("Feature",init<int>("Default ctor."))
        .def("id",&Feature::id)
        .def("__str__",&Feature::to_string)
//        .def("add_geometry", &feature_add_wkb_geometry)
        .def("add_geometry", add_geometry)
        .def("num_geometries",&Feature::num_geometries)
        .def("get_geometry", make_function(get_geom1,return_value_policy<reference_existing_object>()))
        .def("envelope", &Feature::envelope)
        .def(map_indexing_suite2<Feature, true >())
        .def("iteritems",iterator<Feature> ())
        // TODO define more mapnik::Feature methods
        ;
}
<commit_msg>comment unused function<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
 *
 * This 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

// boost
#include <boost/python/suite/indexing/indexing_suite.hpp>
#include <boost/python/iterator.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python.hpp>
#include <boost/scoped_array.hpp>
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/wkb.hpp>

mapnik::geometry_type & (mapnik::Feature::*get_geom1)(unsigned) = &mapnik::Feature::get_geometry;

namespace {

using mapnik::Feature;
using mapnik::geometry_utils;

/*
void feature_add_wkb_geometry(Feature &feature, std::string wkb)
{
    geometry_utils::from_wkb(feature, wkb.c_str(), wkb.size(), true);
}
*/

void add_geometry(Feature & feature, std::auto_ptr<mapnik::geometry_type> geom)
{
    feature.add_geometry(geom.get());
    geom.release();
}

} // end anonymous namespace

namespace boost { namespace python {
    struct value_converter : public boost::static_visitor<PyObject*>
    {
        PyObject * operator() (int val) const
        {
#if PY_VERSION_HEX >= 0x03000000
            return ::PyLong_FromLong(val);
#else
            return ::PyInt_FromLong(val);
#endif
        }

        PyObject * operator() (double val) const
        {
            return ::PyFloat_FromDouble(val);
        }

        PyObject * operator() (UnicodeString const& s) const
        {
            std::string buffer;
            mapnik::to_utf8(s,buffer);
            PyObject *obj = Py_None;
            obj = ::PyUnicode_DecodeUTF8(buffer.c_str(),implicit_cast<ssize_t>(buffer.length()),0);
            return obj;
        }

        PyObject * operator() (mapnik::value_null const& s) const
        {
            return NULL;
        }
    };

    struct mapnik_value_to_python
    {
        static PyObject* convert(mapnik::value const& v)
        {
            return boost::apply_visitor(value_converter(),v.base());
        }
    };

// Forward declaration
    template <class Container, bool NoProxy, class DerivedPolicies>
    class map_indexing_suite2;

    namespace detail
    {
    template <class Container, bool NoProxy>
    class final_map_derived_policies
        : public map_indexing_suite2<Container,
                                     NoProxy, final_map_derived_policies<Container, NoProxy> > {};
    }

    template <class Container,bool NoProxy = false,
              class DerivedPolicies = detail::final_map_derived_policies<Container, NoProxy> >
    class map_indexing_suite2
        : public indexing_suite<
    Container
    , DerivedPolicies
    , NoProxy
    , true
    , typename Container::value_type::second_type
    , typename Container::key_type
    , typename Container::key_type
    >
    {
    public:

        typedef typename Container::value_type value_type;
        typedef typename Container::value_type::second_type data_type;
        typedef typename Container::key_type key_type;
        typedef typename Container::key_type index_type;
        typedef typename Container::size_type size_type;
        typedef typename Container::difference_type difference_type;

        template <class Class>
        static void
        extension_def(Class& cl)
        {

        }

        static data_type&
        get_item(Container& container, index_type i_)
        {
            typename Container::iterator i = container.props().find(i_);
            if (i == container.end())
            {
                PyErr_SetString(PyExc_KeyError, "Invalid key");
                throw_error_already_set();
            }
            return i->second;
        }

        static void
        set_item(Container& container, index_type i, data_type const& v)
        {
            container[i] = v;
        }

        static void
        delete_item(Container& container, index_type i)
        {
            container.props().erase(i);
        }

        static size_t
        size(Container& container)
        {
            return container.props().size();
        }

        static bool
        contains(Container& container, key_type const& key)
        {
            return container.props().find(key) != container.end();
        }

        static bool
        compare_index(Container& container, index_type a, index_type b)
        {
            return container.props().key_comp()(a, b);
        }

        static index_type
        convert_index(Container& /*container*/, PyObject* i_)
        {
            extract<key_type const&> i(i_);
            if (i.check())
            {
                return i();
            }
            else
            {
                extract<key_type> i(i_);
                if (i.check())
                    return i();
            }

            PyErr_SetString(PyExc_TypeError, "Invalid index type");
            throw_error_already_set();
            return index_type();
        }
    };

    template <typename T1, typename T2>
    struct std_pair_to_tuple
    {
        static PyObject* convert(std::pair<T1, T2> const& p)
        {
            return boost::python::incref(
                boost::python::make_tuple(p.first, p.second).ptr());
        }
    };

    template <typename T1, typename T2>
    struct std_pair_to_python_converter
    {
        std_pair_to_python_converter()
        {
            boost::python::to_python_converter<
                std::pair<T1, T2>,
                std_pair_to_tuple<T1, T2> >();
        }
    };

    }}

struct UnicodeString_from_python_str
{
    UnicodeString_from_python_str()
    {
        boost::python::converter::registry::push_back(
            &convertible,
            &construct,
            boost::python::type_id<UnicodeString>());
    }

    static void* convertible(PyObject* obj_ptr)
    {
        if (!(
#if PY_VERSION_HEX >= 0x03000000
                PyBytes_Check(obj_ptr)
#else
                PyString_Check(obj_ptr)
#endif
                || PyUnicode_Check(obj_ptr)))
            return 0;
        return obj_ptr;
    }

    static void construct(
        PyObject* obj_ptr,
        boost::python::converter::rvalue_from_python_stage1_data* data)
    {
        char * value=0;
        if (PyUnicode_Check(obj_ptr)) {
            PyObject *encoded = PyUnicode_AsEncodedString(obj_ptr, "utf8", "replace");
            if (encoded) {
#if PY_VERSION_HEX >= 0x03000000
                value = PyBytes_AsString(encoded);
#else
                value = PyString_AsString(encoded);
#endif
                Py_DecRef(encoded);
            }
        } else {
#if PY_VERSION_HEX >= 0x03000000
            value = PyBytes_AsString(obj_ptr);
#else
            value = PyString_AsString(obj_ptr);
#endif
        }
        if (value == 0) boost::python::throw_error_already_set();
        void* storage = (
            (boost::python::converter::rvalue_from_python_storage<UnicodeString>*)
            data)->storage.bytes;
        new (storage) UnicodeString(value);
        data->convertible = storage;
    }
};

void export_feature()
{
    using namespace boost::python;
    using mapnik::Feature;

    implicitly_convertible<int,mapnik::value>();
    implicitly_convertible<double,mapnik::value>();
    implicitly_convertible<UnicodeString,mapnik::value>();
    implicitly_convertible<bool,mapnik::value>();

    std_pair_to_python_converter<std::string const,mapnik::value>();
    to_python_converter<mapnik::value,mapnik_value_to_python>();
    UnicodeString_from_python_str();

    class_<Feature,boost::shared_ptr<Feature>,
        boost::noncopyable>("Feature",init<int>("Default ctor."))
        .def("id",&Feature::id)
        .def("__str__",&Feature::to_string)
//        .def("add_geometry", &feature_add_wkb_geometry)
        .def("add_geometry", add_geometry)
        .def("num_geometries",&Feature::num_geometries)
        .def("get_geometry", make_function(get_geom1,return_value_policy<reference_existing_object>()))
        .def("envelope", &Feature::envelope)
        .def(map_indexing_suite2<Feature, true >())
        .def("iteritems",iterator<Feature> ())
        // TODO define more mapnik::Feature methods
        ;
}
<|endoftext|>


<commit_before>/*
  This file is part of the Ofi Labs X2 project.

  Copyright (C) 2010 Ariya Hidayat <ariya.hidayat@gmail.com>

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

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

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

#include "kineticmodel.h"

#include <QTimer>
#include <QDateTime>

static const int KineticModelDefaultUpdateInterval = 15; // ms

class KineticModelPrivate
{
public:
    QTimer ticker;

    bool released;
    int duration;
    qreal position;
    qreal velocity;
    qreal deacceleration;

    QTime timestamp;
    qreal lastPosition;

    KineticModelPrivate();
};

KineticModelPrivate::KineticModelPrivate()
    : released(false)
    , duration(1403)
    , position(0)
    , velocity(0)
    , deacceleration(0)
    , lastPosition(0)
{

}

KineticModel::KineticModel(QObject *parent)
    : QObject(parent)
    , d_ptr(new KineticModelPrivate)
{
    connect(&d_ptr->ticker, SIGNAL(timeout()), SLOT(update()));
    d_ptr->ticker.setInterval(KineticModelDefaultUpdateInterval);
}

KineticModel::~KineticModel()
{

}

int KineticModel::duration() const
{
    return d_ptr->duration;
}

void KineticModel::setDuration(int ms)
{
    d_ptr->duration = ms;
}

qreal KineticModel::position() const
{
    return d_ptr->position;
}

void KineticModel::setPosition(qreal pos)
{
    d_ptr->released = false;

    qreal oldPos = d_ptr->position;
    d_ptr->position = pos;
    if (!qFuzzyCompare(pos, oldPos))
        emit positionChanged(pos);

    update();
    if (!d_ptr->ticker.isActive())
        d_ptr->ticker.start();
}

int KineticModel::updateInterval() const
{
    return d_ptr->ticker.interval();
}

void KineticModel::setUpdateInterval(int ms)
{
    d_ptr->ticker.setInterval(ms);
}

void KineticModel::resetSpeed()
{
    Q_D(KineticModel);

    d->released = false;
    d->ticker.stop();
    d->lastPosition = d->position;
    d->timestamp.start();
    d->velocity = 0;
}

void KineticModel::release()
{
    Q_D(KineticModel);

    d->released = true;

    d->deacceleration = d->velocity * 1000 / (1 + d_ptr->duration);
    if (d->deacceleration < 0)
        d->deacceleration = -d->deacceleration;

    if (!d->ticker.isActive())
        d->ticker.start();

    update();
}

void KineticModel::update()
{
    Q_D(KineticModel);

    int elapsed = d_ptr->timestamp.elapsed();

    // too fast gives less accuracy
    if (elapsed < 5)
        return;

    qreal delta = static_cast<qreal>(elapsed) / 1000.0;

    if (d->released) {
        d->position += (d->velocity * delta);
        qreal vstep = d->deacceleration * delta;
        if (d->velocity < vstep && d->velocity >= -vstep) {
            d->velocity = 0;
            d->ticker.stop();
        } else {
            if (d->velocity > 0)
                d->velocity -= vstep;
            else
                d->velocity += vstep;
        }
        emit positionChanged(d->position);
    } else {
        qreal lastSpeed = d->velocity;
        qreal currentSpeed = (d->position - d->lastPosition) / delta;
        d->velocity = .2 * lastSpeed + .8 * currentSpeed;
        d->lastPosition = d->position;
    }

    d->timestamp.start();
}
<commit_msg>widget/kineticmodel: Deaccelerate only if necessary.<commit_after>/*
  This file is part of the Ofi Labs X2 project.

  Copyright (C) 2010 Ariya Hidayat <ariya.hidayat@gmail.com>

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

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

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

#include "kineticmodel.h"

#include <QTimer>
#include <QDateTime>

static const int KineticModelDefaultUpdateInterval = 15; // ms

class KineticModelPrivate
{
public:
    QTimer ticker;

    bool released;
    int duration;
    qreal position;
    qreal velocity;
    qreal deacceleration;

    QTime timestamp;
    qreal lastPosition;

    KineticModelPrivate();
};

KineticModelPrivate::KineticModelPrivate()
    : released(false)
    , duration(1403)
    , position(0)
    , velocity(0)
    , deacceleration(0)
    , lastPosition(0)
{

}

KineticModel::KineticModel(QObject *parent)
    : QObject(parent)
    , d_ptr(new KineticModelPrivate)
{
    connect(&d_ptr->ticker, SIGNAL(timeout()), SLOT(update()));
    d_ptr->ticker.setInterval(KineticModelDefaultUpdateInterval);
}

KineticModel::~KineticModel()
{

}

int KineticModel::duration() const
{
    return d_ptr->duration;
}

void KineticModel::setDuration(int ms)
{
    d_ptr->duration = ms;
}

qreal KineticModel::position() const
{
    return d_ptr->position;
}

void KineticModel::setPosition(qreal pos)
{
    d_ptr->released = false;

    qreal oldPos = d_ptr->position;
    d_ptr->position = pos;
    if (!qFuzzyCompare(pos, oldPos))
        emit positionChanged(pos);

    update();
    if (!d_ptr->ticker.isActive())
        d_ptr->ticker.start();
}

int KineticModel::updateInterval() const
{
    return d_ptr->ticker.interval();
}

void KineticModel::setUpdateInterval(int ms)
{
    d_ptr->ticker.setInterval(ms);
}

void KineticModel::resetSpeed()
{
    Q_D(KineticModel);

    d->released = false;
    d->ticker.stop();
    d->lastPosition = d->position;
    d->timestamp.start();
    d->velocity = 0;
}

void KineticModel::release()
{
    Q_D(KineticModel);

    d->released = true;

    d->deacceleration = d->velocity * 1000 / (1 + d_ptr->duration);
    if (d->deacceleration < 0)
        d->deacceleration = -d->deacceleration;

    if (d->deacceleration > 0.5) {
        if (!d->ticker.isActive())
            d->ticker.start();
        update();
    } else {
        d->ticker.stop();
    }
}

void KineticModel::update()
{
    Q_D(KineticModel);

    int elapsed = d_ptr->timestamp.elapsed();

    // too fast gives less accuracy
    if (elapsed < 5)
        return;

    qreal delta = static_cast<qreal>(elapsed) / 1000.0;

    if (d->released) {
        d->position += (d->velocity * delta);
        qreal vstep = d->deacceleration * delta;
        if (d->velocity < vstep && d->velocity >= -vstep) {
            d->velocity = 0;
            d->ticker.stop();
        } else {
            if (d->velocity > 0)
                d->velocity -= vstep;
            else
                d->velocity += vstep;
        }
        emit positionChanged(d->position);
    } else {
        qreal lastSpeed = d->velocity;
        qreal currentSpeed = (d->position - d->lastPosition) / delta;
        d->velocity = .2 * lastSpeed + .8 * currentSpeed;
        d->lastPosition = d->position;
    }

    d->timestamp.start();
}
<|endoftext|>