<commit_before>//
// Copyright (C) Zbigniew Zagorski <z.zagorski@gmail.com>,
// licensed to the public under the terms of the GNU GPL (>= 2)
// see the file COPYING for details
// I.e., do what you like, but keep copyright and there's NO WARRANTY.
//

#include <iostream>
#include <stdexcept>
#include <cstdlib>

#include "tinfra/thread.h"
#include "tinfra/cmd.h"
#include <cstdlib>

#include "tstring.h"

#include <pthread.h>

#if TINFRA_TSTING_CHECKS
namespace stack_traits {
    // TODO: revise this weird stack/heap detection heuristics
    int get_stack_direction()
    {
        char a;
        char b;
        char* x = &a;
        char* y = &b; // deeper_address();
        int r = y-x;
        //std::cerr << "get_stack_direction() -> " << r << "\n";
        return y-x;
    }

    __thread void* stack_bottom = 0;

    bool is_on_heap(const void* v)
    {
        if( stack_bottom == 0 ) {
            size_t stack_size;
            current_stack_region(stack_bottom, stack_size);
        }
        bool r = (v == 0) || (v < stack_bottom);
        std::cerr << "is_on_heap(" << v << ") -> " << r << "\n";
        return r;
    }
    bool is_valid_(const void* current, const void* stamp)
    {
        static int stack_direction = 0;
        if( stack_direction == 0 )
            stack_direction = get_stack_direction();
        bool r;
        if( stack_direction < 0 )
            r = stamp   >= current;
        else
            r = current <= stamp;
        r = r || is_on_heap(stamp);
        return r;
    }

    bool is_valid(const void* current, const void* stamp)
    {
        bool r = is_valid_(current, stamp);
        //std::cerr << "is_valid(" << current << ", " << stamp << ") -> " << r << "\n";
        return r;
    }

} // end namespace stack_traits

#endif
namespace tinfra {
    namespace tstring_detail {
        bool bad_abort = false;

        void tstring_set_bad_abort(bool a)
        {
            bad_abort = a;
        }
    }

#if TINFRA_TSTING_CHECKS
    void tstring::check_stamp()
    {
        if( !stack_traits::is_valid(this, stamp_) ) {
            if( tstring_detail::bad_abort ) {
                abort();
            } else {
                throw std::logic_error("invalid tstring usage!");
            }
        }
    }
#endif

const tstring::size_type tstring::npos;

// find first of
tstring::size_type
tstring::find_first_of(char_type const* s, size_type pos, size_type n) const
{
    if( tstring::size() > 0 ) {
        for( const_iterator i = begin()+pos; i != end(); ++i ) {
            if( std::memchr(s, *i, n) != 0 ) // 'not in S' so return
                return i - begin();
        }
    }
    return npos;
}
tstring::size_type
tstring::find_first_of(char_type c, size_type pos) const
{
    if( tstring::size() > 0 ) {
        for( const_iterator i = begin()+pos; i != end(); ++i ) {
            if( *i == c ) // '== C' so return
                return i - begin();
        }
    }
    return npos;
}

// find first not of

tstring::size_type
tstring::find_first_not_of(char_type const* s, size_type pos, size_type n) const
{
    if( tstring::size() > 0 ) {
        for( const_iterator i = begin()+pos; i != end(); ++i ) {
            if( std::memchr(s, *i, n) == 0 ) // 'not in S' so return
                return i - begin();
        }
    }
    return npos;
}

tstring::size_type
tstring::find_first_not_of(char_type c, size_type pos) const
{
    if( tstring::size() > 0 ) {
        for( const_iterator i = begin()+pos; i != end(); ++i ) {
            if( *i != c )
                return i - begin();
        }
    }
    return npos;
}

// find last of

tstring::size_type
tstring::find_last_of(char_type const* s, size_type pos, size_type n) const
{
    if( tstring::size() > 0 ) {
        // TODO: pos not used!
        for( const_iterator i = rbegin(); i != rend(); --i ) {
            if( std::memchr(s, *i, n) != 0 ) // 'in S' so return
                return i - begin();
        }
    }
    return npos;
}

tstring::size_type
tstring::find_last_of(char_type c, size_type pos) const
{
    if( tstring::size() > 0 ) {
        // TODO: pos not used!
        for( const_iterator i = rbegin(); i != rend(); --i ) {
            if( *i == c ) // '== C' so return
                return i - begin();
        }
    }
    return npos;
}

// find last not of

tstring::size_type
tstring::find_last_not_of(char_type const* s, size_type pos, size_type n) const
{
    if( tstring::size() > 0 ) {
        // TODO: pos not used!
        for( const_iterator i = rbegin(); i != rend(); --i ) {
            if( std::memchr(s, *i, n) == 0 ) // 'not == S' so return
                return i - begin();
        }
    }
    return npos;
}

tstring::size_type
tstring::find_last_not_of(char_type c, size_type pos) const
{
    if( tstring::size() > 0 ) {
        // TODO: pos not used!
        for( const_iterator i = rbegin(); i != rend(); --i ) {
            if( *i != c ) // 'not = C' so return
                return i - begin();
        }
    }
    return npos;
}

std::ostream& operator<<(std::ostream& out, tstring const& s)
{
    return out.write(s.data(), s.size());
}

const char* tstring::temporary_alloc(string_pool& pool, tstring const& s)
{
    return pool.create(s);
}

const char* string_pool::create(tstring const& src)
{
    strings.push_back(0);
    size_t len = src.size();
    char* result = reinterpret_cast<char*>( std::malloc(len+1) );
    strings[len-1] = result;

    std::memcpy(result, src.data(), len);
    result[len] = 0;
    return result;
}

void string_pool::clear()
{
    for( size_t i = 0; i < strings.size(); ++i ) {
        std::free(strings[i]);
        strings[i] = 0;
    }
}
string_pool::string_pool(size_t initial_size)
{
}

string_pool::~string_pool()
{
    clear();
}

} // end namespace tinfra

// jedit: :tabSize=8:indentSize=4:noTabs=true:mode=c++:

<commit_msg>string_pool.create(): fix fatal memory corruption<commit_after>//
// Copyright (C) Zbigniew Zagorski <z.zagorski@gmail.com>,
// licensed to the public under the terms of the GNU GPL (>= 2)
// see the file COPYING for details
// I.e., do what you like, but keep copyright and there's NO WARRANTY.
//

#include <iostream>
#include <stdexcept>
#include <cstdlib>

#include "tinfra/thread.h"
#include "tinfra/cmd.h"
#include <cstdlib>

#include "tstring.h"

#include <pthread.h>

#if TINFRA_TSTING_CHECKS
namespace stack_traits {
    // TODO: revise this weird stack/heap detection heuristics
    int get_stack_direction()
    {
        char a;
        char b;
        char* x = &a;
        char* y = &b; // deeper_address();
        int r = y-x;
        //std::cerr << "get_stack_direction() -> " << r << "\n";
        return y-x;
    }

    __thread void* stack_bottom = 0;

    bool is_on_heap(const void* v)
    {
        if( stack_bottom == 0 ) {
            size_t stack_size;
            current_stack_region(stack_bottom, stack_size);
        }
        bool r = (v == 0) || (v < stack_bottom);
        std::cerr << "is_on_heap(" << v << ") -> " << r << "\n";
        return r;
    }
    bool is_valid_(const void* current, const void* stamp)
    {
        static int stack_direction = 0;
        if( stack_direction == 0 )
            stack_direction = get_stack_direction();
        bool r;
        if( stack_direction < 0 )
            r = stamp   >= current;
        else
            r = current <= stamp;
        r = r || is_on_heap(stamp);
        return r;
    }

    bool is_valid(const void* current, const void* stamp)
    {
        bool r = is_valid_(current, stamp);
        //std::cerr << "is_valid(" << current << ", " << stamp << ") -> " << r << "\n";
        return r;
    }

} // end namespace stack_traits

#endif
namespace tinfra {
    namespace tstring_detail {
        bool bad_abort = false;

        void tstring_set_bad_abort(bool a)
        {
            bad_abort = a;
        }
    }

#if TINFRA_TSTING_CHECKS
    void tstring::check_stamp()
    {
        if( !stack_traits::is_valid(this, stamp_) ) {
            if( tstring_detail::bad_abort ) {
                abort();
            } else {
                throw std::logic_error("invalid tstring usage!");
            }
        }
    }
#endif

const tstring::size_type tstring::npos;

// find first of
tstring::size_type
tstring::find_first_of(char_type const* s, size_type pos, size_type n) const
{
    if( tstring::size() > 0 ) {
        for( const_iterator i = begin()+pos; i != end(); ++i ) {
            if( std::memchr(s, *i, n) != 0 ) // 'not in S' so return
                return i - begin();
        }
    }
    return npos;
}
tstring::size_type
tstring::find_first_of(char_type c, size_type pos) const
{
    if( tstring::size() > 0 ) {
        for( const_iterator i = begin()+pos; i != end(); ++i ) {
            if( *i == c ) // '== C' so return
                return i - begin();
        }
    }
    return npos;
}

// find first not of

tstring::size_type
tstring::find_first_not_of(char_type const* s, size_type pos, size_type n) const
{
    if( tstring::size() > 0 ) {
        for( const_iterator i = begin()+pos; i != end(); ++i ) {
            if( std::memchr(s, *i, n) == 0 ) // 'not in S' so return
                return i - begin();
        }
    }
    return npos;
}

tstring::size_type
tstring::find_first_not_of(char_type c, size_type pos) const
{
    if( tstring::size() > 0 ) {
        for( const_iterator i = begin()+pos; i != end(); ++i ) {
            if( *i != c )
                return i - begin();
        }
    }
    return npos;
}

// find last of

tstring::size_type
tstring::find_last_of(char_type const* s, size_type pos, size_type n) const
{
    if( tstring::size() > 0 ) {
        // TODO: pos not used!
        for( const_iterator i = rbegin(); i != rend(); --i ) {
            if( std::memchr(s, *i, n) != 0 ) // 'in S' so return
                return i - begin();
        }
    }
    return npos;
}

tstring::size_type
tstring::find_last_of(char_type c, size_type pos) const
{
    if( tstring::size() > 0 ) {
        // TODO: pos not used!
        for( const_iterator i = rbegin(); i != rend(); --i ) {
            if( *i == c ) // '== C' so return
                return i - begin();
        }
    }
    return npos;
}

// find last not of

tstring::size_type
tstring::find_last_not_of(char_type const* s, size_type pos, size_type n) const
{
    if( tstring::size() > 0 ) {
        // TODO: pos not used!
        for( const_iterator i = rbegin(); i != rend(); --i ) {
            if( std::memchr(s, *i, n) == 0 ) // 'not == S' so return
                return i - begin();
        }
    }
    return npos;
}

tstring::size_type
tstring::find_last_not_of(char_type c, size_type pos) const
{
    if( tstring::size() > 0 ) {
        // TODO: pos not used!
        for( const_iterator i = rbegin(); i != rend(); --i ) {
            if( *i != c ) // 'not = C' so return
                return i - begin();
        }
    }
    return npos;
}

std::ostream& operator<<(std::ostream& out, tstring const& s)
{
    return out.write(s.data(), s.size());
}

const char* tstring::temporary_alloc(string_pool& pool, tstring const& s)
{
    return pool.create(s);
}

const char* string_pool::create(tstring const& src)
{
    strings.push_back(0);
    size_t len = src.size();
    char* result = reinterpret_cast<char*>( std::malloc(len+1) );
    strings[strings.size()-1] = result;

    std::memcpy(result, src.data(), len);
    result[len] = 0;
    return result;
}

void string_pool::clear()
{
    for( size_t i = 0; i < strings.size(); ++i ) {
        std::free(strings[i]);
        strings[i] = 0;
    }
    strings.clear();
}
string_pool::string_pool(size_t initial_size)
{
}

string_pool::~string_pool()
{
    clear();
}

} // end namespace tinfra

// jedit: :tabSize=8:indentSize=4:noTabs=true:mode=c++:

<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright 2011-2013 The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/visualization/software-license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "MetropolisHastingsSampler.h"

#include <cassert> // assert
#include <cmath> // std::exp
#include <algorithm> // std::count

namespace madai {

MetropolisHastingsSampler
::MetropolisHastingsSampler() :
  Sampler(),
  m_StepSize( 1.0e-2 )
{
}

MetropolisHastingsSampler
::~MetropolisHastingsSampler()
{
}

void
MetropolisHastingsSampler
::Initialize( const Model * model )
{
  assert(model != NULL);
  m_Model = model;

  Sampler::Initialize( model );

  const std::vector< Parameter > & params = m_Model->GetParameters();
  m_StepScales.resize( model->GetNumberOfParameters() );
  for ( unsigned int i = 0; i < model->GetNumberOfParameters(); i++ ) {
    const Distribution * priorDist = params[i].GetPriorDistribution();
    m_CurrentParameters[i] = priorDist->GetSample(m_Random);
    // Random initial starting point
    m_StepScales[i]
      = priorDist->GetPercentile(0.75) - priorDist->GetPercentile(0.25);
    // set step scales
  }
  Model * m = const_cast< Model * >(m_Model);
  m_CurrentOutputs.resize( model->GetNumberOfScalarOutputs() );
  Model::ErrorType error = m->GetScalarOutputsAndLogLikelihood(
    m_CurrentParameters, m_CurrentOutputs, m_CurrentLogLikelihood);
  // initial starting point LogLikelihood.
  #ifdef NDEBUG
  (void)error;
  #else
  assert (error == Model::NO_ERROR);
  #endif
}

void MetropolisHastingsSampler
::SetStepSize( double stepSize )
{
  m_StepSize = stepSize;
}

Sample
MetropolisHastingsSampler
::NextSample()
{
  // xc is x_candidate
  Model * m = const_cast< Model * >(m_Model);

  std::vector< double > xc( m_Model->GetNumberOfParameters(), 0.0 );
  std::vector< double > yc( m_Model->GetNumberOfScalarOutputs(), 0.0 );
  std::vector< double > dl_dsigmay( m_Model->GetNumberOfScalarOutputs(), 0.0 );

  assert( static_cast<unsigned int>(
              std::count( m_ActiveParameterIndices.begin(),
                          m_ActiveParameterIndices.end(), true ))
          == ( this->GetNumberOfActiveParameters() ) );

  for ( unsigned int i = 0; i < m_Model->GetNumberOfParameters(); i++ ) {
    if ( m_ActiveParameterIndices[i] ) {
      double step
        = (m_StepSize   // scale each step by this variable
           * m_Random.Gaussian() // random direction, length
           * m_StepScales[i]); // scaled by parameter domain size
      xc[i] = m_CurrentParameters[i] + step;
    } else {
      xc[i] = m_CurrentParameters[i];
    }
  }
  double ll; // ll is new_log_likelihood
  m->GetScalarOutputsAndLogLikelihoodAndLikelihoodErrorGradient(xc,yc,ll,dl_dsigmay);

  // Check for NaN
  assert( ll == ll );

  double delta_logLikelihood = ll - m_CurrentLogLikelihood;

  if ((delta_logLikelihood > 0) ||
      (std::exp(delta_logLikelihood) > m_Random.Uniform())) {
    m_CurrentLogLikelihood = ll;
    m_CurrentParameters = xc;
    m_CurrentOutputs = yc;
    m_CurrentLogLikelihoodGradient = dl_dsigmay;
    return Sample( xc, yc, ll, dl_dsigmay);
  }

  // Stay at this point in parameter space
  return Sample( m_CurrentParameters,
                 m_CurrentOutputs,
                 m_CurrentLogLikelihood,
                 m_CurrentLogLikelihoodGradient);

}

} // end namespace madai
<commit_msg>Updated to work with value and error gradients.<commit_after>/*=========================================================================
 *
 *  Copyright 2011-2013 The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/visualization/software-license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "MetropolisHastingsSampler.h"

#include <cassert> // assert
#include <cmath> // std::exp
#include <algorithm> // std::count

namespace madai {

MetropolisHastingsSampler
::MetropolisHastingsSampler() :
  Sampler(),
  m_StepSize( 1.0e-2 )
{
}

MetropolisHastingsSampler
::~MetropolisHastingsSampler()
{
}

void
MetropolisHastingsSampler
::Initialize( const Model * model )
{
  assert(model != NULL);
  m_Model = model;

  Sampler::Initialize( model );

  const std::vector< Parameter > & params = m_Model->GetParameters();
  m_StepScales.resize( model->GetNumberOfParameters() );
  for ( unsigned int i = 0; i < model->GetNumberOfParameters(); i++ ) {
    const Distribution * priorDist = params[i].GetPriorDistribution();
    m_CurrentParameters[i] = priorDist->GetSample(m_Random);
    // Random initial starting point
    m_StepScales[i]
      = priorDist->GetPercentile(0.75) - priorDist->GetPercentile(0.25);
    // set step scales
  }
  Model * m = const_cast< Model * >(m_Model);
  m_CurrentOutputs.resize( model->GetNumberOfScalarOutputs() );
  Model::ErrorType error = m->GetScalarOutputsAndLogLikelihood(
    m_CurrentParameters, m_CurrentOutputs, m_CurrentLogLikelihood);
  // initial starting point LogLikelihood.
  #ifdef NDEBUG
  (void)error;
  #else
  assert (error == Model::NO_ERROR);
  #endif
}

void MetropolisHastingsSampler
::SetStepSize( double stepSize )
{
  m_StepSize = stepSize;
}

Sample
MetropolisHastingsSampler
::NextSample()
{
  // xc is x_candidate
  Model * m = const_cast< Model * >(m_Model);

  std::vector< double > xc( m_Model->GetNumberOfParameters(), 0.0 );
  std::vector< double > yc( m_Model->GetNumberOfScalarOutputs(), 0.0 );
  std::vector< double > dl_dy( m_Model->GetNumberOfScalarOutputs(), 0.0 );
  std::vector< double > ydl_dsigmay( m_Model->GetNumberOfScalarOutputs(), 0.0 );

  assert( static_cast<unsigned int>(
              std::count( m_ActiveParameterIndices.begin(),
                          m_ActiveParameterIndices.end(), true ))
          == ( this->GetNumberOfActiveParameters() ) );

  for ( unsigned int i = 0; i < m_Model->GetNumberOfParameters(); i++ ) {
    if ( m_ActiveParameterIndices[i] ) {
      double step
        = (m_StepSize   // scale each step by this variable
           * m_Random.Gaussian() // random direction, length
           * m_StepScales[i]); // scaled by parameter domain size
      xc[i] = m_CurrentParameters[i] + step;
    } else {
      xc[i] = m_CurrentParameters[i];
    }
  }
  double ll; // ll is new_log_likelihood
  m->GetScalarOutputsAndLogLikelihoodAndLikelihoodErrorGradient(xc,yc,ll,dl_dy,ydl_dsigmay);

  // Check for NaN
  assert( ll == ll );

  double delta_logLikelihood = ll - m_CurrentLogLikelihood;

  if ((delta_logLikelihood > 0) ||
      (std::exp(delta_logLikelihood) > m_Random.Uniform())) {
    m_CurrentLogLikelihood = ll;
    m_CurrentParameters = xc;
    m_CurrentOutputs = yc;
    m_CurrentLogLikelihoodValueGradient = dl_dy;
    m_CurrentLogLikelihoodErrorGradient = ydl_dsigmay;
    return Sample( xc, yc, ll, dl_dy, ydl_dsigmay);
  }

  // Stay at this point in parameter space
  return Sample( m_CurrentParameters,
                 m_CurrentOutputs,
                 m_CurrentLogLikelihood,
                 m_CurrentLogLikelihoodValueGradient,
                 m_CurrentLogLikelihoodErrorGradient);

}

} // end namespace madai
<|endoftext|>


<commit_before>#include "system/Platform.h"

#include "system/Logger.h"

#include <cstring>
#include <iostream>

namespace Sketch3D
{
#if COMPILER == COMPILER_MSVC
#   include <excpt.h>
#   if _MSC_VER >= 1400
#       include <intrin.h>
#   endif
#elif COMPILER == COMPILER_GNUC
#   include <signal.h>
#   include <setjmp.h>
#endif

#if CPU == CPU_X86
    struct CpuidResult
    {
        unsigned int _eax;
        unsigned int _ebx;
        unsigned int _edx;
        unsigned int _ecx;
    };

#if COMPILER == COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable: 4035) // no return value
#endif

    static int SupportCpuid()
    {
#if COMPILER == COMPILER_MSVC
#   if _MSC_VER >= 1400 && defined(_M_X64)
        return true;
#   else
        __asm
        {
            // Read Eflag
            pushfd
            pop     eax
            mov     ecx, eax

            // Modify bit 21
            xor     eax, 0x200000
            push    eax
            popfd

            // Read back Eflag
            pushfd
            pop     eax

            // Restore Eflag
            push    ecx
            popfd

            // Check but 21 modifiable
            xor     eax, ecx
            neg     eax
            sbb     eax, eax
        }
#   endif
#elif COMPILER == COMPILER_GNUC
#   if ARCH_TYPE == ARCHITECTURE_64
        return true;
#   else
        unsigned oldFlags, newFlags;
        __asm__
        (
            "pushfl         \n\t"
            "pop    %0      \n\t"
            "mov    %0, %1  \n\t"
            "xor    %2, %0  \n\t"
            "push   %0      \n\t"
            "popfl          \n\t"
            "pushfl         \n\t"
            "pop    %0      \n\t"
            "push   %1      \n\t"
            "popfl          \n\t"
            : "=r" (oldFlags), "=r" (newFlags)
            : "n" (0x200000)
        );

        return oldFlags != newFlags;
#   endif
#else
        return false;
#endif
    }

    static unsigned int PerformCpuid(int query, CpuidResult& result)
    {
#if COMPILER == COMPILER_MSVC
#   if _MSC_VER >= 1400
        int CPUInfo[4];
        __cpuid(CPUInfo, query);
        result._eax = CPUInfo[0];
        result._ebx = CPUInfo[1];
        result._ecx = CPUInfo[2];
        result._edx = CPUInfo[3];
        return result._eax;

#   else
        __asm
        {
            mov     edi, result
            mov     eax, query
            cpuid
            mov     [edi]._eax, eax
            mov     [edi]._ebx, ebx
            mov     [edi]._edx, edx
            mov     [edi]._ecx, ecx
        }
#   endif
#elif COMPILER == COMPILER_GNUC
#   if ARCH_TYPE == ARCHITECTURE_64
        __asm__
        (
            "cpuid" : "=a" (result._eax), "=b" (result._ebx), "=c" (result._ecx), "=d" (result._edx) : "a" (query)
        );
#   else
        __asm__
        (
            "pushl  %%ebx       \n\t"
            "cpuid              \n\t"
            "movl   %%ebx, %%edi\n\t"
            "popl   %%ebx       \n\t"
            : "=a" (result._eax), "=D" (result._ebx), "=c" (result._ecx), "=d" (result._edx)
            : "a" (query)
        );
#   endif
        return result._eax;
#endif
        return 0;
    }

#if COMPILER == COMPILER_MSVC
#pragma warning(pop)
#endif

// Detect SIMD
#if COMPILER == COMPILER_GNUC
#   if ARCH_TYPE == ARCHITECTURE_32
    static jmp_buf sIllegalJmpBuf;
    static void IllegalHandler(int x)
    {
        (void)(x);
        longjmp(sIllegalJmpBuf, 1);
    }
#   endif
#endif

    static bool CheckOperatingSystemSupportSSE()
    {
#if COMPILER == COMPILER_MSVC
#   if _MSC_VER >= 1400 && defined(_M_X64)
        return true;
#   else
        __try
        {
            __asm orps xmm0, xmm0
            return true;
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            return false;
        }
#   endif
#elif COMPILER == COMPILER_GNUC
#   if ARCH_TYPE == ARCHITECTURE_64
        return true;
#   else
        void (*oldHandler)(int);
        oldHandler = signal(SIGILL, IllegalHandler);

        if (setjmp(sIllegalJpmpBuf)) {
            signal(SIGILL, oldHandler);
            return false;
        } else {
            __asm__ __volatile__ ("orps %xmm0, %xmm0");
            signal(SIGILL, oldHandler);
            return true;
        }
#   endif
#else
        return true;
#endif
    }

    static unsigned int QueryCpuFeatures()
    {
#define CPUID_STD_MMX       (1 << 23)
#define CPUID_STD_SSE       (1 << 25)
#define CPUID_STD_SSE2      (1 << 26)

        unsigned int features = 0;
        if (SupportCpuid()) {
            CpuidResult result;

            if (PerformCpuid(0, result)) {
				bool continueFeatures = false;
                if (memcmp(&result._ebx, "GenuineIntel", 12) == 0) {
					continueFeatures = true;
					Logger::GetInstance()->Info("CPU manufacturer: GenuineIntel");

                } else if (memcmp(&result._ebx, "AuthenticAMD", 12) == 0) {
					continueFeatures = true;
					Logger::GetInstance()->Info("CPU manufacturer: AuthenticAMD");

                } else {
					Logger::GetInstance()->Warning("CPU manufacturer: Unknown");
				}

				if (continueFeatures) {
					Logger::GetInstance()->Info("CPU features:");
                    PerformCpuid(1, result);

                    if (result._edx & CPUID_STD_MMX) {
                        features |= PlatformInformation::MMX;
						Logger::GetInstance()->Info("MMX supported");
                    }

                    if (result._edx & CPUID_STD_SSE) {
                        features |= PlatformInformation::SSE;
						Logger::GetInstance()->Info("SSE supported");
                    }

                    if (result._edx & CPUID_STD_SSE2) {
                        features |= PlatformInformation::SSE2;
						Logger::GetInstance()->Info("SSE2 supported");
                    }
				}
            }
        } else {
			Logger::GetInstance()->Warning("Couldn't perform CPUID operation");
		}

        return features;
    }

    static unsigned int DetectCpuFeatures()
    {
		Logger::GetInstance()->Info("Querying CPU info...");

        unsigned int features = QueryCpuFeatures();
        const unsigned int sse_features = PlatformInformation::SSE |
            PlatformInformation::SSE2;
        if ((features & sse_features) && !CheckOperatingSystemSupportSSE()) {
            features &= ~sse_features;
        }

        return features;
    }

    static string DetectCpuIdentifier()
    {
        string cpuId;

        return cpuId;
    }

    const string& PlatformInformation::GetCpuIdentifier()
    {
        static const string identifier = DetectCpuIdentifier();
        return identifier;
    }

    unsigned int PlatformInformation::GetCpuFeatures()
    {
        static const unsigned int features = DetectCpuFeatures();
        return features;
    }

    bool PlatformInformation::HasCpuFeature(CpuFeatures feature)
    {
        //return (GetCpuFeatures() & feature) != 0;
		return false;
    }

#endif
}
<commit_msg>Fixed SIMD math on Win32, have still to code the linux version<commit_after>#include "system/Platform.h"

#include "system/Logger.h"

#include <cstring>
#include <iostream>

namespace Sketch3D
{
#if COMPILER == COMPILER_MSVC
#   include <excpt.h>
#   if _MSC_VER >= 1400
#       include <intrin.h>
#   endif
#elif COMPILER == COMPILER_GNUC
#   include <signal.h>
#   include <setjmp.h>
#endif

#if CPU == CPU_X86
    struct CpuidResult
    {
        unsigned int _eax;
        unsigned int _ebx;
        unsigned int _edx;
        unsigned int _ecx;
    };

#if COMPILER == COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable: 4035) // no return value
#endif

    static int SupportCpuid()
    {
#if COMPILER == COMPILER_MSVC
#   if _MSC_VER >= 1400 && defined(_M_X64)
        return true;
#   else
        __asm
        {
            // Read Eflag
            pushfd
            pop     eax
            mov     ecx, eax

            // Modify bit 21
            xor     eax, 0x200000
            push    eax
            popfd

            // Read back Eflag
            pushfd
            pop     eax

            // Restore Eflag
            push    ecx
            popfd

            // Check but 21 modifiable
            xor     eax, ecx
            neg     eax
            sbb     eax, eax
        }
#   endif
#elif COMPILER == COMPILER_GNUC
#   if ARCH_TYPE == ARCHITECTURE_64
        return true;
#   else
        unsigned oldFlags, newFlags;
        __asm__
        (
            "pushfl         \n\t"
            "pop    %0      \n\t"
            "mov    %0, %1  \n\t"
            "xor    %2, %0  \n\t"
            "push   %0      \n\t"
            "popfl          \n\t"
            "pushfl         \n\t"
            "pop    %0      \n\t"
            "push   %1      \n\t"
            "popfl          \n\t"
            : "=r" (oldFlags), "=r" (newFlags)
            : "n" (0x200000)
        );

        return oldFlags != newFlags;
#   endif
#else
        return false;
#endif
    }

    static unsigned int PerformCpuid(int query, CpuidResult& result)
    {
#if COMPILER == COMPILER_MSVC
#   if _MSC_VER >= 1400
        int CPUInfo[4];
        __cpuid(CPUInfo, query);
        result._eax = CPUInfo[0];
        result._ebx = CPUInfo[1];
        result._ecx = CPUInfo[2];
        result._edx = CPUInfo[3];
        return result._eax;

#   else
        __asm
        {
            mov     edi, result
            mov     eax, query
            cpuid
            mov     [edi]._eax, eax
            mov     [edi]._ebx, ebx
            mov     [edi]._edx, edx
            mov     [edi]._ecx, ecx
        }
#   endif
#elif COMPILER == COMPILER_GNUC
#   if ARCH_TYPE == ARCHITECTURE_64
        __asm__
        (
            "cpuid" : "=a" (result._eax), "=b" (result._ebx), "=c" (result._ecx), "=d" (result._edx) : "a" (query)
        );
#   else
        __asm__
        (
            "pushl  %%ebx       \n\t"
            "cpuid              \n\t"
            "movl   %%ebx, %%edi\n\t"
            "popl   %%ebx       \n\t"
            : "=a" (result._eax), "=D" (result._ebx), "=c" (result._ecx), "=d" (result._edx)
            : "a" (query)
        );
#   endif
        return result._eax;
#endif
        return 0;
    }

#if COMPILER == COMPILER_MSVC
#pragma warning(pop)
#endif

// Detect SIMD
#if COMPILER == COMPILER_GNUC
#   if ARCH_TYPE == ARCHITECTURE_32
    static jmp_buf sIllegalJmpBuf;
    static void IllegalHandler(int x)
    {
        (void)(x);
        longjmp(sIllegalJmpBuf, 1);
    }
#   endif
#endif

    static bool CheckOperatingSystemSupportSSE()
    {
#if COMPILER == COMPILER_MSVC
#   if _MSC_VER >= 1400 && defined(_M_X64)
        return true;
#   else
        __try
        {
            __asm orps xmm0, xmm0
            return true;
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            return false;
        }
#   endif
#elif COMPILER == COMPILER_GNUC
#   if ARCH_TYPE == ARCHITECTURE_64
        return true;
#   else
        void (*oldHandler)(int);
        oldHandler = signal(SIGILL, IllegalHandler);

        if (setjmp(sIllegalJpmpBuf)) {
            signal(SIGILL, oldHandler);
            return false;
        } else {
            __asm__ __volatile__ ("orps %xmm0, %xmm0");
            signal(SIGILL, oldHandler);
            return true;
        }
#   endif
#else
        return true;
#endif
    }

    static unsigned int QueryCpuFeatures()
    {
#define CPUID_STD_MMX       (1 << 23)
#define CPUID_STD_SSE       (1 << 25)
#define CPUID_STD_SSE2      (1 << 26)

        unsigned int features = 0;
        if (SupportCpuid()) {
            CpuidResult result;

            if (PerformCpuid(0, result)) {
				bool continueFeatures = false;
                if (memcmp(&result._ebx, "GenuineIntel", 12) == 0) {
					continueFeatures = true;
					Logger::GetInstance()->Info("CPU manufacturer: GenuineIntel");

                } else if (memcmp(&result._ebx, "AuthenticAMD", 12) == 0) {
					continueFeatures = true;
					Logger::GetInstance()->Info("CPU manufacturer: AuthenticAMD");

                } else {
					Logger::GetInstance()->Warning("CPU manufacturer: Unknown");
				}

				if (continueFeatures) {
					Logger::GetInstance()->Info("CPU features:");
                    PerformCpuid(1, result);

                    if (result._edx & CPUID_STD_MMX) {
                        features |= PlatformInformation::MMX;
						Logger::GetInstance()->Info("MMX supported");
                    }

                    if (result._edx & CPUID_STD_SSE) {
                        features |= PlatformInformation::SSE;
						Logger::GetInstance()->Info("SSE supported");
                    }

                    if (result._edx & CPUID_STD_SSE2) {
                        features |= PlatformInformation::SSE2;
						Logger::GetInstance()->Info("SSE2 supported");
                    }
				}
            }
        } else {
			Logger::GetInstance()->Warning("Couldn't perform CPUID operation");
		}

        return features;
    }

    static unsigned int DetectCpuFeatures()
    {
		Logger::GetInstance()->Info("Querying CPU info...");

        unsigned int features = QueryCpuFeatures();
        const unsigned int sse_features = PlatformInformation::SSE |
            PlatformInformation::SSE2;
        if ((features & sse_features) && !CheckOperatingSystemSupportSSE()) {
            features &= ~sse_features;
        }

        return features;
    }

    static string DetectCpuIdentifier()
    {
        string cpuId;

        return cpuId;
    }

    const string& PlatformInformation::GetCpuIdentifier()
    {
        static const string identifier = DetectCpuIdentifier();
        return identifier;
    }

    unsigned int PlatformInformation::GetCpuFeatures()
    {
        static const unsigned int features = DetectCpuFeatures();
        return features;
    }

    bool PlatformInformation::HasCpuFeature(CpuFeatures feature)
    {
        return (GetCpuFeatures() & feature) != 0;
		//return false;
    }

#endif
}
<|endoftext|>


<commit_before>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "cAuthenticator.h"
#include "cBlockingTCPLink.h"
#include "cRoot.h"
#include "cServer.h"

#include "../iniFile/iniFile.h"

#include <sstream>

#define DEFAULT_AUTH_SERVER "session.minecraft.net"
#define DEFAULT_AUTH_ADDRESS "/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%"
#define MAX_REDIRECTS 10

cAuthenticator::cAuthenticator(void) :
	super("cAuthenticator"),
	m_Server(DEFAULT_AUTH_SERVER),
	m_Address(DEFAULT_AUTH_ADDRESS),
	m_ShouldAuthenticate(true)
{
	ReadINI();
}

cAuthenticator::~cAuthenticator()
{
	Stop();
}

/// Read custom values from INI
void cAuthenticator::ReadINI(void)
{
	cIniFile IniFile("settings.ini");
	if (!IniFile.ReadFile())
	{
		return;
	}

	m_Server  = IniFile.GetValue("Authentication", "Server");
	m_Address = IniFile.GetValue("Authentication", "Address");
	m_ShouldAuthenticate = IniFile.GetValueB("Authentication", "Authenticate", true);
	bool bSave = false;

	if (m_Server.length() == 0)
	{
		m_Server = DEFAULT_AUTH_SERVER;
		IniFile.SetValue("Authentication", "Server", m_Server);
		bSave = true;
	}
	if (m_Address.length() == 0)
	{
		m_Address = DEFAULT_AUTH_ADDRESS;
		IniFile.SetValue("Authentication", "Address", m_Address);
		bSave = true;
	}

	if (bSave)
	{
		IniFile.SetValueB("Authentication", "Authenticate", m_ShouldAuthenticate);
		IniFile.WriteFile();
	}
}

/// Queues a request for authenticating a user. If the auth fails, the user is kicked
void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash)
{
	if (!m_ShouldAuthenticate)
	{
		cRoot::Get()->AuthenticateUser(a_ClientID);
		return;
	}

	cCSLock Lock(m_CS);
	m_Queue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash));
	m_QueueNonempty.Set();
}

void cAuthenticator::Stop(void)
{
	m_ShouldTerminate = true;
	m_QueueNonempty.Set();
	Wait();
}

void cAuthenticator::Execute(void)
{
	for (;;)
	{
		cCSLock Lock(m_CS);
		while (!m_ShouldTerminate && (m_Queue.size() == 0))
		{
			cCSUnlock Unlock(Lock);
			m_QueueNonempty.Wait();
		}
		if (m_ShouldTerminate)
		{
			return;
		}
		ASSERT(!m_Queue.empty());

		int ClientID = m_Queue.front().mClientID;
		AString UserName = m_Queue.front().mName;
		AString ActualAddress = m_Address;
		ReplaceString(ActualAddress, "%USERNAME%", UserName);
		ReplaceString(ActualAddress, "%SERVERID%", cRoot::Get()->GetServer()->GetServerID());
		m_Queue.pop_front();
		Lock.Unlock();

		if (!AuthFromAddress(m_Server, ActualAddress, UserName))
		{
			cRoot::Get()->KickUser(ClientID, "Failed to authenticate account!");
		}
		else
		{
			cRoot::Get()->AuthenticateUser(ClientID);
		}
	}  // for (-ever)
}

bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level /* = 1 */)
{
	// Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep)

	cBlockingTCPLink Link;
	if (!Link.Connect(a_Server.c_str(), 80))
	{
		LOGERROR("cAuthenticator: cannot connect to auth server \"%s\", kicking user \"%s\"", a_Server.c_str(), a_Server.c_str());
		return false;
	}

	Link.SendMessage( AString( "GET " + a_Address + " HTTP/1.0\r\n\r\n" ).c_str());
	AString DataRecvd;
	Link.ReceiveData(DataRecvd);
	Link.CloseSocket();

	std::stringstream ss(DataRecvd);

	// Parse the data received:
	std::string temp;
	ss >> temp;
	bool bRedirect = false;
	bool bOK = false;
	if ((temp.compare("HTTP/1.1") == 0) || (temp.compare("HTTP/1.0") == 0))
	{
		int code;
		ss >> code;
		if (code == 302)
		{
			// redirect blabla
			LOGINFO("Need to redirect!");
			if (a_Level > MAX_REDIRECTS)
			{
				LOGERROR("cAuthenticator: received too many levels of redirection from auth server \"%s\" for user \"%s\", bailing out and kicking the user", a_Server.c_str(), a_UserName.c_str());
				return false;
			}
			bRedirect = true;
		}
		else if (code == 200)
		{
			LOGINFO("Got 200 OK :D");
			bOK = true;
		}
	}
	else
	{
		LOGERROR("cAuthenticator: cannot parse auth reply from server \"%s\" for user \"%s\", kicking the user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	if( bRedirect )
	{
		AString Location;
		// Search for "Location:"
		bool bFoundLocation = false;
		while( !bFoundLocation && ss.good() )
		{
			char c = 0;
			while( c != '\n' )
			{
				ss.get( c );
			}
			AString Name;
			ss >> Name;
			if (Name.compare("Location:") == 0)
			{
				bFoundLocation = true;
				ss >> Location;
			}
		}
		if (!bFoundLocation)
		{
			LOGERROR("cAuthenticator: received invalid redirection from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
			return false;
		}

		Location = Location.substr(strlen("http://"), std::string::npos); // Strip http://
		std::string Server = Location.substr( 0, Location.find( "/" ) ); // Only leave server address
		Location = Location.substr( Server.length(), std::string::npos);
		return AuthFromAddress(Server, Location, a_UserName, a_Level + 1);
	}

	if (!bOK)
	{
		LOGERROR("cAuthenticator: received an error from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	// Header says OK, so receive the rest.
	// Go past header, double \n means end of headers
	char c = 0;
	while (ss.good())
	{
		while (c != '\n')
		{
			ss.get(c);
		}
		ss.get(c);
		if( c == '\n' || c == '\r' || ss.peek() == '\r' || ss.peek() == '\n' )
			break;
	}
	if (!ss.good())
	{
		LOGERROR("cAuthenticator: error while parsing response body from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	std::string Result;
	ss >> Result;
	LOGINFO("Got result: %s", Result.c_str());
	if (Result.compare("YES") == 0)
	{
		LOGINFO("Result was \"YES\", so player is authenticated!");
		return true;
	}
	LOGINFO("Result was \"%s\", so player is NOT authenticated!", Result.c_str());
	return false;
}

<commit_msg>Quick fix to support authentication.<commit_after>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "cAuthenticator.h"
#include "cBlockingTCPLink.h"
#include "cRoot.h"
#include "cServer.h"

#include "../iniFile/iniFile.h"

#include <sstream>

#define DEFAULT_AUTH_SERVER "session.minecraft.net"
#define DEFAULT_AUTH_ADDRESS "/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%"
#define MAX_REDIRECTS 10

cAuthenticator::cAuthenticator(void) :
	super("cAuthenticator"),
	m_Server(DEFAULT_AUTH_SERVER),
	m_Address(DEFAULT_AUTH_ADDRESS),
	m_ShouldAuthenticate(true)
{
	ReadINI();
}

cAuthenticator::~cAuthenticator()
{
	Stop();
}

/// Read custom values from INI
void cAuthenticator::ReadINI(void)
{
	cIniFile IniFile("settings.ini");
	if (!IniFile.ReadFile())
	{
		return;
	}

	m_Server  = IniFile.GetValue("Authentication", "Server");
	m_Address = IniFile.GetValue("Authentication", "Address");
	m_ShouldAuthenticate = IniFile.GetValueB("Authentication", "Authenticate", true);
	bool bSave = false;

	if (m_Server.length() == 0)
	{
		m_Server = DEFAULT_AUTH_SERVER;
		IniFile.SetValue("Authentication", "Server", m_Server);
		bSave = true;
	}
	if (m_Address.length() == 0)
	{
		m_Address = DEFAULT_AUTH_ADDRESS;
		IniFile.SetValue("Authentication", "Address", m_Address);
		bSave = true;
	}

	if (bSave)
	{
		IniFile.SetValueB("Authentication", "Authenticate", m_ShouldAuthenticate);
		IniFile.WriteFile();
	}
}

/// Queues a request for authenticating a user. If the auth fails, the user is kicked
void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash)
{
	if (!m_ShouldAuthenticate)
	{
		cRoot::Get()->AuthenticateUser(a_ClientID);
		return;
	}

	cCSLock Lock(m_CS);
	m_Queue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash));
	m_QueueNonempty.Set();
}

void cAuthenticator::Stop(void)
{
	m_ShouldTerminate = true;
	m_QueueNonempty.Set();
	Wait();
}

void cAuthenticator::Execute(void)
{
	for (;;)
	{
		cCSLock Lock(m_CS);
		while (!m_ShouldTerminate && (m_Queue.size() == 0))
		{
			cCSUnlock Unlock(Lock);
			m_QueueNonempty.Wait();
		}
		if (m_ShouldTerminate)
		{
			return;
		}
		ASSERT(!m_Queue.empty());

		int ClientID = m_Queue.front().mClientID;
		AString UserName = m_Queue.front().mName;
		AString ActualAddress = m_Address;
		ReplaceString(ActualAddress, "%USERNAME%", UserName);
		ReplaceString(ActualAddress, "%SERVERID%", cRoot::Get()->GetServer()->GetServerID());
		m_Queue.pop_front();
		Lock.Unlock();

		if (!AuthFromAddress(m_Server, ActualAddress, UserName))
		{
			cRoot::Get()->KickUser(ClientID, "Failed to authenticate account!");
		}
		else
		{
			cRoot::Get()->AuthenticateUser(ClientID);
		}
	}  // for (-ever)
}

bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level /* = 1 */)
{
	// Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep)

	cBlockingTCPLink Link;
	if (!Link.Connect(a_Server.c_str(), 80))
	{
		LOGERROR("cAuthenticator: cannot connect to auth server \"%s\", kicking user \"%s\"", a_Server.c_str(), a_Server.c_str());
		return false;
	}

	Link.SendMessage( AString( "GET " + a_Address + " HTTP/1.1\r\n" ).c_str());
	Link.SendMessage( AString( "User-Agent: MCServer\r\n" ).c_str());
	// FIXME: AString( "Host: %s\r\n", a_Server.c_str() ).c_str() doesn't work. Causes segfault.
	Link.SendMessage( AString( "Host: session.minecraft.net\r\n" ).c_str());
	Link.SendMessage( AString( "Accept: */*\r\n" ).c_str());
	Link.SendMessage( AString( "Connection: keep-alive\r\n" ).c_str());
	Link.SendMessage( AString( "\r\n" ).c_str());
	AString DataRecvd;
	Link.ReceiveData(DataRecvd);
	Link.CloseSocket();

	std::stringstream ss(DataRecvd);

	// Parse the data received:
	std::string temp;
	ss >> temp;
	bool bRedirect = false;
	bool bOK = false;
	if ((temp.compare("HTTP/1.1") == 0) || (temp.compare("HTTP/1.0") == 0))
	{
		int code;
		ss >> code;
		if (code == 302)
		{
			// redirect blabla
			LOGINFO("Need to redirect!");
			if (a_Level > MAX_REDIRECTS)
			{
				LOGERROR("cAuthenticator: received too many levels of redirection from auth server \"%s\" for user \"%s\", bailing out and kicking the user", a_Server.c_str(), a_UserName.c_str());
				return false;
			}
			bRedirect = true;
		}
		else if (code == 200)
		{
			LOGINFO("Got 200 OK :D");
			bOK = true;
		}
	}
	else
	{
		LOGERROR("cAuthenticator: cannot parse auth reply from server \"%s\" for user \"%s\", kicking the user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	if( bRedirect )
	{
		AString Location;
		// Search for "Location:"
		bool bFoundLocation = false;
		while( !bFoundLocation && ss.good() )
		{
			char c = 0;
			while( c != '\n' )
			{
				ss.get( c );
			}
			AString Name;
			ss >> Name;
			if (Name.compare("Location:") == 0)
			{
				bFoundLocation = true;
				ss >> Location;
			}
		}
		if (!bFoundLocation)
		{
			LOGERROR("cAuthenticator: received invalid redirection from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
			return false;
		}

		Location = Location.substr(strlen("http://"), std::string::npos); // Strip http://
		std::string Server = Location.substr( 0, Location.find( "/" ) ); // Only leave server address
		Location = Location.substr( Server.length(), std::string::npos);
		return AuthFromAddress(Server, Location, a_UserName, a_Level + 1);
	}

	if (!bOK)
	{
		LOGERROR("cAuthenticator: received an error from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	// Header says OK, so receive the rest.
	// Go past header, double \n means end of headers
	char c = 0;
	while (ss.good())
	{
		while (c != '\n')
		{
			ss.get(c);
		}
		ss.get(c);
		if( c == '\n' || c == '\r' || ss.peek() == '\r' || ss.peek() == '\n' )
			break;
	}
	if (!ss.good())
	{
		LOGERROR("cAuthenticator: error while parsing response body from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	std::string Result;
	ss >> Result;
	LOGINFO("Got result: %s", Result.c_str());
	// if (Result.compare("YES") == 0)
	// TODO: I'm assuming the only response containing 3 letters is "YES", but proper reading of the return code
	//       would be preferred.
	if (Result.compare("3") == 0) // FIXME: Quick and dirty hack to support auth
	{
		LOGINFO("Result was \"YES\", so player is authenticated!");
		return true;
	}
	LOGINFO("Result was \"%s\", so player is NOT authenticated!", Result.c_str());
	return false;
}

<|endoftext|>


<commit_before>#include "tiling_render_policy_st.hpp"

#include "../platform/platform.hpp"

#include "../graphics/opengl/opengl.hpp"
#include "../graphics/render_context.hpp"

#include "window_handle.hpp"
#include "queued_renderer.hpp"
#include "tile_renderer.hpp"
#include "coverage_generator.hpp"

TilingRenderPolicyST::TilingRenderPolicyST(Params const & p)
  : BasicTilingRenderPolicy(p,
                            true)
{
  int cpuCores = GetPlatform().CpuCores();

  graphics::ResourceManager::Params rmp = p.m_rmParams;

  rmp.checkDeviceCaps();

  graphics::ResourceManager::TexturePoolParams tpp;
  graphics::ResourceManager::StoragePoolParams spp;

  tpp = graphics::ResourceManager::TexturePoolParams(512,
                                                     256,
                                                     1,
                                                     rmp.m_texFormat,
                                                     graphics::ELargeTexture,
                                                     true);

  rmp.m_textureParams[tpp.m_textureType] = tpp;

  tpp = graphics::ResourceManager::TexturePoolParams(256,
                                                     256,
                                                     10,
                                                     rmp.m_texFormat,
                                                     graphics::EMediumTexture,
                                                     true);

  rmp.m_textureParams[tpp.m_textureType] = tpp;

  tpp = graphics::ResourceManager::TexturePoolParams(TileSize(),
                                                     TileSize(),
                                                     1,
                                                     rmp.m_texRtFormat,
                                                     graphics::ERenderTargetTexture,
                                                     true);

  rmp.m_textureParams[tpp.m_textureType] = tpp;

  tpp = graphics::ResourceManager::TexturePoolParams(256,
                                                     128,
                                                     2,
                                                     rmp.m_texFormat,
                                                     graphics::ESmallTexture,
                                                     true);

  rmp.m_textureParams[tpp.m_textureType] = tpp;

  spp = graphics::ResourceManager::StoragePoolParams(6000 * sizeof(graphics::gl::Vertex),
                                                     sizeof(graphics::gl::Vertex),
                                                     9000 * sizeof(unsigned short),
                                                     sizeof(unsigned short),
                                                     10,
                                                     graphics::ELargeStorage,
                                                     true);

  rmp.m_storageParams[spp.m_storageType] = spp;

  spp = graphics::ResourceManager::StoragePoolParams(6000 * sizeof(graphics::gl::Vertex),
                                                     sizeof(graphics::gl::Vertex),
                                                     9000 * sizeof(unsigned short),
                                                     sizeof(unsigned short),
                                                     1,
                                                     graphics::EMediumStorage,
                                                     true);

  rmp.m_storageParams[spp.m_storageType] = spp;

  spp = graphics::ResourceManager::StoragePoolParams(2000 * sizeof(graphics::gl::Vertex),
                                                     sizeof(graphics::gl::Vertex),
                                                     4000 * sizeof(unsigned short),
                                                     sizeof(unsigned short),
                                                     5,
                                                     graphics::ESmallStorage,
                                                     true);

  rmp.m_storageParams[spp.m_storageType] = spp;

  rmp.m_glyphCacheParams = graphics::ResourceManager::GlyphCacheParams("unicode_blocks.txt",
                                                                       "fonts_whitelist.txt",
                                                                       "fonts_blacklist.txt",
                                                                       2 * 1024 * 1024);

  rmp.m_threadSlotsCount = cpuCores + 2;
  rmp.m_renderThreadsCount = cpuCores;

  rmp.m_useSingleThreadedOGL = true;

  m_resourceManager.reset(new graphics::ResourceManager(rmp));

  m_primaryRC->setResourceManager(m_resourceManager);
  m_primaryRC->startThreadDrawing(m_resourceManager->guiThreadSlot());

  m_QueuedRenderer->SetSinglePipelineProcessing(m_resourceManager->useReadPixelsToSynchronize());

  Platform::FilesList fonts;
  GetPlatform().GetFontNames(fonts);
  m_resourceManager->addFonts(fonts);

  Drawer::Params dp;

  dp.m_frameBuffer = make_shared_ptr(new graphics::gl::FrameBuffer(p.m_useDefaultFB));
  dp.m_resourceManager = m_resourceManager;
  dp.m_threadSlot = m_resourceManager->guiThreadSlot();
  dp.m_skinName = SkinName();
  dp.m_visualScale = VisualScale();
  dp.m_storageType = graphics::ESmallStorage;
  dp.m_textureType = graphics::ESmallTexture;
  dp.m_isSynchronized = false;
  dp.m_fastSolidPath = true;
  dp.m_renderContext = p.m_primaryRC;

//  p.m_isDebugging = true;

  m_drawer.reset(new Drawer(dp));

  InitCacheScreen();

  m_windowHandle.reset(new WindowHandle());

  m_windowHandle->setUpdatesEnabled(false);
  m_windowHandle->setRenderPolicy(this);
  m_windowHandle->setVideoTimer(p.m_videoTimer);
  m_windowHandle->setRenderContext(p.m_primaryRC);
}

TilingRenderPolicyST::~TilingRenderPolicyST()
{
  LOG(LINFO, ("cancelling ResourceManager"));
  m_resourceManager->cancel();

  int cpuCores = GetPlatform().CpuCores();

  LOG(LINFO, ("deleting TilingRenderPolicyST"));

  m_QueuedRenderer->PrepareQueueCancellation(cpuCores);

  /// now we should process all commands to collect them into queues
  m_CoverageGenerator->SetSequenceID(numeric_limits<int>::max());
  m_CoverageGenerator->WaitForEmptyAndFinished();

  m_QueuedRenderer->CancelQueuedCommands(cpuCores);

  LOG(LINFO, ("reseting coverageGenerator"));
  m_CoverageGenerator.reset();

  /// firstly stop all rendering commands in progress and collect all commands into queues

  for (unsigned i = 0; i < cpuCores; ++i)
    m_QueuedRenderer->PrepareQueueCancellation(i);

  m_TileRenderer->ClearCommands();
  m_TileRenderer->SetSequenceID(numeric_limits<int>::max());
  m_TileRenderer->CancelCommands();
  m_TileRenderer->WaitForEmptyAndFinished();

  /// now we should cancel all collected commands

  for (unsigned i = 0; i < cpuCores; ++i)
    m_QueuedRenderer->CancelQueuedCommands(i);

  LOG(LINFO, ("reseting tileRenderer"));
  m_TileRenderer.reset();
  LOG(LINFO, ("done reseting tileRenderer"));
}

void TilingRenderPolicyST::SetRenderFn(TRenderFn renderFn)
{
  int cpuCores = GetPlatform().CpuCores();
  string skinName = SkinName();

  graphics::PacketsQueue ** queues = new graphics::PacketsQueue*[cpuCores];

  for (unsigned i = 0; i < cpuCores; ++i)
    queues[i] = m_QueuedRenderer->GetPacketsQueue(i);

  m_TileRenderer.reset(new TileRenderer(TileSize(),
                                        skinName,
                                        cpuCores,
                                        m_bgColor,
                                        renderFn,
                                        m_primaryRC,
                                        m_resourceManager,
                                        VisualScale(),
                                        queues));

  delete [] queues;

  /// CoverageGenerator rendering queue could execute commands partially
  /// as there are no render-to-texture calls.
//  m_QueuedRenderer->SetPartialExecution(cpuCores, true);
  m_CoverageGenerator.reset(new CoverageGenerator(skinName,
                                                  m_TileRenderer.get(),
                                                  m_windowHandle,
                                                  m_primaryRC,
                                                  m_resourceManager,
                                                  m_QueuedRenderer->GetPacketsQueue(cpuCores),
                                                  m_countryIndexFn));
}
<commit_msg>fixed TilingRenderPolicyST resources sizes for HiDpi screens.<commit_after>#include "tiling_render_policy_st.hpp"

#include "../platform/platform.hpp"

#include "../graphics/opengl/opengl.hpp"
#include "../graphics/render_context.hpp"

#include "window_handle.hpp"
#include "queued_renderer.hpp"
#include "tile_renderer.hpp"
#include "coverage_generator.hpp"

TilingRenderPolicyST::TilingRenderPolicyST(Params const & p)
  : BasicTilingRenderPolicy(p,
                            true)
{
  int cpuCores = GetPlatform().CpuCores();

  graphics::ResourceManager::Params rmp = p.m_rmParams;

  rmp.checkDeviceCaps();

  graphics::ResourceManager::TexturePoolParams tpp;
  graphics::ResourceManager::StoragePoolParams spp;

  int k = int(ceil(VisualScale()));

  tpp = graphics::ResourceManager::TexturePoolParams(512,
                                                     512,
                                                     1,
                                                     rmp.m_texFormat,
                                                     graphics::ELargeTexture,
                                                     true);

  rmp.m_textureParams[tpp.m_textureType] = tpp;

  tpp = graphics::ResourceManager::TexturePoolParams(256 * k,
                                                     256 * k,
                                                     10,
                                                     rmp.m_texFormat,
                                                     graphics::EMediumTexture,
                                                     true);

  rmp.m_textureParams[tpp.m_textureType] = tpp;

  tpp = graphics::ResourceManager::TexturePoolParams(TileSize(),
                                                     TileSize(),
                                                     1,
                                                     rmp.m_texRtFormat,
                                                     graphics::ERenderTargetTexture,
                                                     true);

  rmp.m_textureParams[tpp.m_textureType] = tpp;

  tpp = graphics::ResourceManager::TexturePoolParams(128 * k,
                                                     128 * k,
                                                     2,
                                                     rmp.m_texFormat,
                                                     graphics::ESmallTexture,
                                                     true);

  rmp.m_textureParams[tpp.m_textureType] = tpp;

  spp = graphics::ResourceManager::StoragePoolParams(6000 * sizeof(graphics::gl::Vertex),
                                                     sizeof(graphics::gl::Vertex),
                                                     9000 * sizeof(unsigned short),
                                                     sizeof(unsigned short),
                                                     10,
                                                     graphics::ELargeStorage,
                                                     true);

  rmp.m_storageParams[spp.m_storageType] = spp;

  spp = graphics::ResourceManager::StoragePoolParams(6000 * sizeof(graphics::gl::Vertex),
                                                     sizeof(graphics::gl::Vertex),
                                                     9000 * sizeof(unsigned short),
                                                     sizeof(unsigned short),
                                                     1,
                                                     graphics::EMediumStorage,
                                                     true);

  rmp.m_storageParams[spp.m_storageType] = spp;

  spp = graphics::ResourceManager::StoragePoolParams(2000 * sizeof(graphics::gl::Vertex),
                                                     sizeof(graphics::gl::Vertex),
                                                     4000 * sizeof(unsigned short),
                                                     sizeof(unsigned short),
                                                     5,
                                                     graphics::ESmallStorage,
                                                     true);

  rmp.m_storageParams[spp.m_storageType] = spp;

  rmp.m_glyphCacheParams = graphics::ResourceManager::GlyphCacheParams("unicode_blocks.txt",
                                                                       "fonts_whitelist.txt",
                                                                       "fonts_blacklist.txt",
                                                                       2 * 1024 * 1024);

  rmp.m_threadSlotsCount = cpuCores + 2;
  rmp.m_renderThreadsCount = cpuCores;

  rmp.m_useSingleThreadedOGL = true;

  m_resourceManager.reset(new graphics::ResourceManager(rmp));

  m_primaryRC->setResourceManager(m_resourceManager);
  m_primaryRC->startThreadDrawing(m_resourceManager->guiThreadSlot());

  m_QueuedRenderer->SetSinglePipelineProcessing(m_resourceManager->useReadPixelsToSynchronize());

  Platform::FilesList fonts;
  GetPlatform().GetFontNames(fonts);
  m_resourceManager->addFonts(fonts);

  Drawer::Params dp;

  dp.m_frameBuffer = make_shared_ptr(new graphics::gl::FrameBuffer(p.m_useDefaultFB));
  dp.m_resourceManager = m_resourceManager;
  dp.m_threadSlot = m_resourceManager->guiThreadSlot();
  dp.m_skinName = SkinName();
  dp.m_visualScale = VisualScale();
  dp.m_storageType = graphics::ESmallStorage;
  dp.m_textureType = graphics::ESmallTexture;
  dp.m_isSynchronized = false;
  dp.m_fastSolidPath = true;
  dp.m_renderContext = p.m_primaryRC;

//  p.m_isDebugging = true;

  m_drawer.reset(new Drawer(dp));

  InitCacheScreen();

  m_windowHandle.reset(new WindowHandle());

  m_windowHandle->setUpdatesEnabled(false);
  m_windowHandle->setRenderPolicy(this);
  m_windowHandle->setVideoTimer(p.m_videoTimer);
  m_windowHandle->setRenderContext(p.m_primaryRC);
}

TilingRenderPolicyST::~TilingRenderPolicyST()
{
  LOG(LINFO, ("cancelling ResourceManager"));
  m_resourceManager->cancel();

  int cpuCores = GetPlatform().CpuCores();

  LOG(LINFO, ("deleting TilingRenderPolicyST"));

  m_QueuedRenderer->PrepareQueueCancellation(cpuCores);

  /// now we should process all commands to collect them into queues
  m_CoverageGenerator->SetSequenceID(numeric_limits<int>::max());
  m_CoverageGenerator->WaitForEmptyAndFinished();

  m_QueuedRenderer->CancelQueuedCommands(cpuCores);

  LOG(LINFO, ("reseting coverageGenerator"));
  m_CoverageGenerator.reset();

  /// firstly stop all rendering commands in progress and collect all commands into queues

  for (unsigned i = 0; i < cpuCores; ++i)
    m_QueuedRenderer->PrepareQueueCancellation(i);

  m_TileRenderer->ClearCommands();
  m_TileRenderer->SetSequenceID(numeric_limits<int>::max());
  m_TileRenderer->CancelCommands();
  m_TileRenderer->WaitForEmptyAndFinished();

  /// now we should cancel all collected commands

  for (unsigned i = 0; i < cpuCores; ++i)
    m_QueuedRenderer->CancelQueuedCommands(i);

  LOG(LINFO, ("reseting tileRenderer"));
  m_TileRenderer.reset();
  LOG(LINFO, ("done reseting tileRenderer"));
}

void TilingRenderPolicyST::SetRenderFn(TRenderFn renderFn)
{
  int cpuCores = GetPlatform().CpuCores();
  string skinName = SkinName();

  graphics::PacketsQueue ** queues = new graphics::PacketsQueue*[cpuCores];

  for (unsigned i = 0; i < cpuCores; ++i)
    queues[i] = m_QueuedRenderer->GetPacketsQueue(i);

  m_TileRenderer.reset(new TileRenderer(TileSize(),
                                        skinName,
                                        cpuCores,
                                        m_bgColor,
                                        renderFn,
                                        m_primaryRC,
                                        m_resourceManager,
                                        VisualScale(),
                                        queues));

  delete [] queues;

  /// CoverageGenerator rendering queue could execute commands partially
  /// as there are no render-to-texture calls.
//  m_QueuedRenderer->SetPartialExecution(cpuCores, true);
  m_CoverageGenerator.reset(new CoverageGenerator(skinName,
                                                  m_TileRenderer.get(),
                                                  m_windowHandle,
                                                  m_primaryRC,
                                                  m_resourceManager,
                                                  m_QueuedRenderer->GetPacketsQueue(cpuCores),
                                                  m_countryIndexFn));
}
<|endoftext|>


<commit_before>//std::copy wird nur durch zeiger aufgerufen, deswegen muss die Warnung deaktiviert werden
#define _SCL_SECURE_NO_WARNINGS

#include <algorithm>

class Primitive_Matrix
{
private:
	//hche und breite, beginnen bei 1!
	unsigned int height = 0;
	unsigned int width = 0;
	//Matrix als dynamische Array
	float **matrix;

public:
	//Konstr. Hhe und Breite
	Primitive_Matrix(unsigned int h, unsigned int w);

	//Kontrs. 2D dyn. Array
	Primitive_Matrix(float **arr, unsigned int h, unsigned int w);

	//Destruktor
	~Primitive_Matrix();

};

Primitive_Matrix::Primitive_Matrix(unsigned int h, unsigned int w)
{
	//hhe und breite zuweisen
	height = h;
	width = w;
	//dyn. array aufspannen
	matrix = new float*[height];
	for (unsigned int i = 0; i < height; i++)
	{
		matrix[i] = new float[width];
	}
}

Primitive_Matrix::Primitive_Matrix(float **arr ,unsigned int h, unsigned int w)
{
	//hhe und breite zuweisen
	height = h;
	width = w;
	//dyn. array aufspannen
	matrix = new float*[height];
	for (unsigned int i = 0; i < height; i++)
	{
		matrix[i] = new float[width];
		//Gleichzeitiges Kopieren der Arrayzeilen - TESTEN!
		std::copy(matrix[i], matrix[i] + width, arr[i]);
	}
}

Primitive_Matrix::~Primitive_Matrix()
{
	for (unsigned int i = 0; i < height; i++)
	{
		//dyn Array auf jeder Zeile wird gelscht
		delete[] matrix[i];
	}
}
<commit_msg>vor änderungen wegen realloc<commit_after>//std::copy wird nur durch zeiger aufgerufen, deswegen muss die Warnung deaktiviert werden
#define _SCL_SECURE_NO_WARNINGS

#include <algorithm>
#include <cstdlib>

class Primitive_Matrix
{
private:
	//hche und breite, beginnen bei 1!
	unsigned int height = 0;
	unsigned int width = 0;
	//Matrix als dynamische Array
	float **matrix;

public:
	//Konstr. Hhe und Breite
	Primitive_Matrix(unsigned int h, unsigned int w);

	//Kontrs. 2D dyn. Array
	Primitive_Matrix(float **arr, unsigned int h, unsigned int w);

	//Destruktor
	~Primitive_Matrix();

	//ndert Hhe
	void ChangeHeight(unsigned int newHeight);

	//ndert Breite
	void ChangeWidth(unsigned int newWidth);

};

Primitive_Matrix::Primitive_Matrix(unsigned int h, unsigned int w)
{
	//hhe und breite zuweisen
	height = h;
	width = w;
	//dyn. array aufspannen
	matrix = new float*[height];
	for (unsigned int i = 0; i < height; i++)
	{
		matrix[i] = new float[width];
	}
}

Primitive_Matrix::Primitive_Matrix(float **arr ,unsigned int h, unsigned int w)
{
	//hhe und breite zuweisen
	height = h;
	width = w;
	//dyn. array aufspannen
	matrix = new float*[height];
	for (unsigned int i = 0; i < height; i++)
	{
		matrix[i] = new float[width];
		//Gleichzeitiges Kopieren der Arrayzeilen - TESTEN!
		std::copy(matrix[i], matrix[i] + width, arr[i]);
	}
}

Primitive_Matrix::~Primitive_Matrix()
{
	for (unsigned int i = 0; i < height; i++)
	{
		//dyn Array auf jeder Zeile wird gelscht
		delete[] matrix[i];
	}
}

void Primitive_Matrix::ChangeHeight(unsigned int newHeight)
{
	//neue hhe kleiner als alte: zeilen lschen, bis newHeight -1
	if (newHeight < height)
	{
		for (unsigned int i = height - 1; i >= newHeight; i--)
		{
			//dyn Array auf betroffenen Zeile wird gelscht
			delete[] matrix[i];
		}
		height = newHeight;
	}
	//neue hhe grer als alte: zeilen hinzufgen
	else if (newHeight > height)
	{
		for (unsigned int i = height - 1; i < newHeight; i++)
		{
			//dyn Array auf betroffenen Zeile wird hinzugefgt
			matrix[i] = new float[width];
		}
		height = newHeight;
	}
}

void Primitive_Matrix::ChangeWidth(unsigned int newWidth)
{
	//neue breite kleiner als alte: spalten lschen, bis newWidth -1
	if (newWidth < width)
	{
		for (unsigned int i = 0; i < height; i++)
		{

		}
	}
}
<|endoftext|>


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

#include "config.h"

#include <tr1/memory>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <vector>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif

#include <time.h>

#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif

#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif

#include "except.h"
#include "video.h"
#include "opts.h"
#include "macros.h"
#include "util.h"
#include "exec.h"
#include "log.h"
#include "progressbar.h"

#ifdef SIGWINCH
static volatile sig_atomic_t recv_sigwinch;

RETSIGTYPE
handle_sigwinch(int sig) {
    recv_sigwinch = 1;
    signal(SIGWINCH, handle_sigwinch);
}

static int
getTermWidth() {
    int fd = fileno(stderr);
    winsize wsz;

    if (ioctl(fd, TIOCGWINSZ, &wsz) < 0)
        return 0;

    return wsz.ws_col;
}
#endif

ProgressBar::ProgressBar()
    : props(VideoProperties()), lastUpdate(0),
      started(0),               initial(0),
      total(0),                 count(0),
      done(false),              width(0),
      termWidth(0),             streamFlag(false),
      streamPid(-1)
{
}

void
ProgressBar::init(const VideoProperties& props) {
    this->props = props;

    initial = props.getInitial(); // bytes dl previously
    total   = props.getLength();  // expected bytes

    if (initial > total)
        total = initial;

#ifdef SIGWINCH
    if (!termWidth || recv_sigwinch) {
        termWidth = getTermWidth();
        if (!termWidth)
            termWidth = DEFAULT_TERM_WIDTH;
    }
#else
    termWidth = DEFAULT_TERM_WIDTH;
#endif
    width = termWidth-1; // do not use the last column
    time(&started);
}

typedef unsigned int _uint;

void
ProgressBar::update(double now) {
    static const double REFRESH_INTERVAL = 0.2;
    bool force_update = false;
#ifdef SIGWINCH
    if (recv_sigwinch) {
        const int old_width = termWidth;
        termWidth = getTermWidth();
        if (!termWidth)
            termWidth = DEFAULT_TERM_WIDTH;
        if (termWidth != old_width) {
            width = termWidth - 1;
            force_update = true;
        }
        recv_sigwinch = 0;
    }
#endif
    time_t tnow;
    time(&tnow);

    const time_t elapsed = tnow - started;

    if (!done) {
        if ((elapsed - lastUpdate) < REFRESH_INTERVAL
            && !force_update)
        {
            return;
        }
    }
    else
        now = total;

    lastUpdate        = elapsed;
    const double size = initial+now;

    std::stringstream b;
    b.setf(std::ios::fixed);

    register _uint l = 32;
    if (width > DEFAULT_TERM_WIDTH)
        l += width - DEFAULT_TERM_WIDTH;
    b << props.getFilename().substr(0,l);

    if (total > 0) {
        const double _size = !done ? size:now;
        const int percent  = static_cast<int>(100.0*size/total);
        if (percent < 100)
            b << "  " << std::setw(2) << percent << "% ";
        else
            b << "  100%";
        b << "  "
          << std::setw(4)
          << std::setprecision(1)
          << _TOMB(_size)
          << "M / "
          << std::setw(4)
          << std::setprecision(1)
          << _TOMB(total)
          << "M";

#if defined(HAVE_FORK) && defined(HAVE_WORKING_FORK)
        const Options opts = optsmgr.getOptions();
        if (opts.stream_given
            && opts.stream_exec_given
            && !streamFlag)
        {
            if (percent >= opts.stream_arg)
                forkStreamer();
        }
#endif
    }

    std::stringstream tmp;
    tmp.setf(std::ios::fixed);

    double rate = elapsed ? (now/elapsed):0;

    if (rate > 0) {
        std::string eta;

        if (!done) {
            double left = (total - (now+initial)) / rate;
            eta = timeToStr(static_cast<int>(left+0.5));
        }
        else {
            rate = (total - initial) / elapsed;
            eta  = timeToStr(elapsed);
        }

        std::string unit = getUnit(rate);

        tmp << "  "
            << std::setw(4)
            << std::setprecision(1)
            << rate
            << unit
            << "  "
            << std::setw(6)
            << eta;
    }
    else
        tmp << "  --.-K/s  --:--";

    l = width - tmp.str().length(); // pad to term width
    for (register _uint i=b.str().length(); i<l; ++i)
        b << " ";

    b << tmp.str();

    logmgr.cout() << "\r" << b.str() << std::flush;
    count = now;
}

void
ProgressBar::finish() {
    if (total > 0
        && count + initial > total)
    {
        total = initial + count;
    }
    done = true;
    update(-1);

#ifdef HAVE_SYS_WAIT_H
    if (streamFlag) {
        if (waitpid(streamPid, 0, 0) != streamPid)
            perror("waitpid");
        streamFlag = false;
    }
#endif
}

const std::string
ProgressBar::timeToStr(const int& secs) const {
    std::stringstream s;

    if (secs < 100)
        s << secs << "s";
    else if (secs < 100 * 60)
        s << zeropad(2,secs/60) << "m" << zeropad(2,secs%60) << "s";
    else if (secs < 48 * 3600)
        s << zeropad(2,secs/3600) << "h" << zeropad(2,(secs/60)%60) << "m";
    else if (secs < 100 * 86400)
        s << secs/86400 << "d" << zeropad(2,(secs/3600)%60) << "h";
    else
        s << secs/86400 << "d";

    return s.str();
}

const std::string
ProgressBar::getUnit(double& rate) const {
    static const char *units[] = {"K/s", "M/s", "G/s"};
    int i = 0;
    if (rate < 1024*1024) {
        rate /= 1024;
    }
    else if (rate < 1024*1024) {
        rate /= 1024*1024;
        i = 1;
    }
    else if (rate < 1024*1024*1024) {
        rate /= 1024*1024*1024;
        i = 2;
    }
    return units[i];
}

void
ProgressBar::forkStreamer() {
#if defined(HAVE_FORK) && defined(HAVE_WORKING_FORK)
    streamFlag = true;
    if ((streamPid = fork()) < 0)
        perror("fork");
    else if (streamPid == 0) {
        execmgr.playStream(props);
        exit(0);
    }
#endif
}
<commit_msg>progressbar: tweak timetostr.<commit_after>/*
 * Copyright (C) 2009 Toni Gundogdu.
 *
 * This file is part of cclive.
 *
 * cclive is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * cclive is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <tr1/memory>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <vector>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif

#include <time.h>

#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif

#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif

#include "except.h"
#include "video.h"
#include "opts.h"
#include "macros.h"
#include "util.h"
#include "exec.h"
#include "log.h"
#include "progressbar.h"

#ifdef SIGWINCH
static volatile sig_atomic_t recv_sigwinch;

RETSIGTYPE
handle_sigwinch(int sig) {
    recv_sigwinch = 1;
    signal(SIGWINCH, handle_sigwinch);
}

static int
getTermWidth() {
    int fd = fileno(stderr);
    winsize wsz;

    if (ioctl(fd, TIOCGWINSZ, &wsz) < 0)
        return 0;

    return wsz.ws_col;
}
#endif

ProgressBar::ProgressBar()
    : props(VideoProperties()), lastUpdate(0),
      started(0),               initial(0),
      total(0),                 count(0),
      done(false),              width(0),
      termWidth(0),             streamFlag(false),
      streamPid(-1)
{
}

void
ProgressBar::init(const VideoProperties& props) {
    this->props = props;

    initial = props.getInitial(); // bytes dl previously
    total   = props.getLength();  // expected bytes

    if (initial > total)
        total = initial;

#ifdef SIGWINCH
    if (!termWidth || recv_sigwinch) {
        termWidth = getTermWidth();
        if (!termWidth)
            termWidth = DEFAULT_TERM_WIDTH;
    }
#else
    termWidth = DEFAULT_TERM_WIDTH;
#endif
    width = termWidth-1; // do not use the last column
    time(&started);
}

typedef unsigned int _uint;

void
ProgressBar::update(double now) {
    static const double REFRESH_INTERVAL = 0.2;
    bool force_update = false;
#ifdef SIGWINCH
    if (recv_sigwinch) {
        const int old_width = termWidth;
        termWidth = getTermWidth();
        if (!termWidth)
            termWidth = DEFAULT_TERM_WIDTH;
        if (termWidth != old_width) {
            width = termWidth - 1;
            force_update = true;
        }
        recv_sigwinch = 0;
    }
#endif
    time_t tnow;
    time(&tnow);

    const time_t elapsed = tnow - started;

    if (!done) {
        if ((elapsed - lastUpdate) < REFRESH_INTERVAL
            && !force_update)
        {
            return;
        }
    }
    else
        now = total;

    lastUpdate        = elapsed;
    const double size = initial+now;

    std::stringstream b;
    b.setf(std::ios::fixed);

    register _uint l = 32;
    if (width > DEFAULT_TERM_WIDTH)
        l += width - DEFAULT_TERM_WIDTH;
    b << props.getFilename().substr(0,l);

    if (total > 0) {
        const double _size = !done ? size:now;
        const int percent  = static_cast<int>(100.0*size/total);
        if (percent < 100)
            b << "  " << std::setw(2) << percent << "% ";
        else
            b << "  100%";
        b << "  "
          << std::setw(4)
          << std::setprecision(1)
          << _TOMB(_size)
          << "M / "
          << std::setw(4)
          << std::setprecision(1)
          << _TOMB(total)
          << "M";

#if defined(HAVE_FORK) && defined(HAVE_WORKING_FORK)
        const Options opts = optsmgr.getOptions();
        if (opts.stream_given
            && opts.stream_exec_given
            && !streamFlag)
        {
            if (percent >= opts.stream_arg)
                forkStreamer();
        }
#endif
    }

    std::stringstream tmp;
    tmp.setf(std::ios::fixed);

    double rate = elapsed ? (now/elapsed):0;

    if (rate > 0) {
        std::string eta;

        if (!done) {
            double left = (total - (now+initial)) / rate;
            eta = timeToStr(static_cast<int>(left+0.5));
        }
        else {
            rate = (total - initial) / elapsed;
            eta  = timeToStr(elapsed);
        }

        std::string unit = getUnit(rate);

        tmp << "  "
            << std::setw(4)
            << std::setprecision(1)
            << rate
            << unit
            << "  "
            << std::setw(6)
            << eta;
    }
    else
        tmp << "  --.-K/s  --:--";

    l = width - tmp.str().length(); // pad to term width
    for (register _uint i=b.str().length(); i<l; ++i)
        b << " ";

    b << tmp.str();

    logmgr.cout() << "\r" << b.str() << std::flush;
    count = now;
}

void
ProgressBar::finish() {
    if (total > 0
        && count + initial > total)
    {
        total = initial + count;
    }
    done = true;
    update(-1);

#ifdef HAVE_SYS_WAIT_H
    if (streamFlag) {
        if (waitpid(streamPid, 0, 0) != streamPid)
            perror("waitpid");
        streamFlag = false;
    }
#endif
}

const std::string
ProgressBar::timeToStr(const int& secs) const {
    std::stringstream s;

    if (secs < 60)
        s << secs << "s";
    else if (secs < 60 * 60)
        s << zeropad(2,secs/60) << "m" << zeropad(2,secs%60) << "s";
    else if (secs < 48 * 3600)
        s << zeropad(2,secs/3600) << "h" << zeropad(2,(secs/60)%60) << "m";
    else if (secs < 100 * 86400)
        s << secs/86400 << "d" << zeropad(2,(secs/3600)%60) << "h";
    else
        s << secs/86400 << "d";

    return s.str();
}

const std::string
ProgressBar::getUnit(double& rate) const {
    static const char *units[] = {"K/s", "M/s", "G/s"};
    int i = 0;
    if (rate < 1024*1024) {
        rate /= 1024;
    }
    else if (rate < 1024*1024) {
        rate /= 1024*1024;
        i = 1;
    }
    else if (rate < 1024*1024*1024) {
        rate /= 1024*1024*1024;
        i = 2;
    }
    return units[i];
}

void
ProgressBar::forkStreamer() {
#if defined(HAVE_FORK) && defined(HAVE_WORKING_FORK)
    streamFlag = true;
    if ((streamPid = fork()) < 0)
        perror("fork");
    else if (streamPid == 0) {
        execmgr.playStream(props);
        exit(0);
    }
#endif
}
<|endoftext|>


<commit_before>/*
 * TTBlue Cycling Ramp Generator
 * Copyright © 2003, Timothy Place
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "TTPhasor.h"

TTPhasor::TTPhasor(TTUInt8 newMaxNumChannels)
	: TTAudioObject("audio.phasor", newMaxNumChannels),
	attrPhase(0.0), step(0.0), linearGain(1.0)
{
	registerAttribute(TT("frequency"),	kTypeFloat64,	&attrFrequency,	(TTSetterMethod)&TTPhasor::setFrequency);
	registerAttribute(TT("gain"),		kTypeFloat64,	&attrGain,		(TTGetterMethod)&TTPhasor::getGain, (TTSetterMethod)&TTPhasor::setGain);
	registerAttribute(TT("phase"),		kTypeFloat64,	&attrPhase);
	// TODO: More Attributes left to add...
	//	linearGain
	//	period in ms
	//	period in samples

	registerMessage(TT("updateSr"),	(TTMethod)&TTPhasor::updateSr);

	setAttributeValue(TT("frequency"), 1.0);
	setAttributeValue(TT("gain"), 0.0);
}

TTPhasor::~TTPhasor()
{
	;
}

TTErr TTPhasor::updateSr()
{
	TTValue	v(attrFrequency);
	return setFrequency(TTATTR, v);
}

TTErr TTPhasor::setFrequency(const TTAttribute&, const TTValue& newValue)
{
	attrFrequency = newValue;
	if(attrFrequency == 0){
		rampSamples = 0xFFFFFFFF;
		rampMilliseconds = 0;
	}
	else{
		rampSamples = (1.0 / attrFrequency) * sr;
		rampMilliseconds = 1000.0 * (rampSamples / TTFloat64(sr));
	}
	setStep();
	return kTTErrNone;
}

void TTPhasor::setStep()
{
	step = antiDenormal(1.0 / TTFloat64(rampSamples));	// 1.0 is the destination
}

TTErr TTPhasor::setGain(const TTAttribute&, const TTValue& newValue)
{
	attrGain = newValue;
	linearGain = dbToLinear(attrGain);
	return kTTErrNone;
}

TTErr TTPhasor::getGain(const TTAttribute&, TTValue& value)
{
	value = linearToDb(linearGain);
	return kTTErrNone;
}

// TODO: add flags so that TTAudioObject can call a process method with a different number audio signals?

TTErr TTPhasor::processAudio(TTAudioSignal& in, TTAudioSignal& out)
{
	TTSampleValue	*outSample;
	TTUInt8			numchannels = out.getNumChannels();
	TTUInt8			channel;
	TTUInt16		vs;

	for(channel=0; channel<numchannels; channel++){
		outSample = out.sampleVectors[channel];
		vs = out.getVectorSize();

		while(vs--){
			attrPhase += step;
			if(attrPhase >= 1.0)
				attrPhase -= 1.0;
			else if(attrPhase < 0.0)
				attrPhase += 1.0;
			*outSample++ = attrPhase * linearGain;
		}
	}
	return kTTErrNone;
}
<commit_msg>fix for missing setProcess() call<commit_after>/*
 * TTBlue Cycling Ramp Generator
 * Copyright © 2003, Timothy Place
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "TTPhasor.h"

TTPhasor::TTPhasor(TTUInt8 newMaxNumChannels)
	: TTAudioObject("audio.phasor", newMaxNumChannels),
	attrPhase(0.0), step(0.0), linearGain(1.0)
{
	registerAttribute(TT("frequency"),	kTypeFloat64,	&attrFrequency,	(TTSetterMethod)&TTPhasor::setFrequency);
	registerAttribute(TT("gain"),		kTypeFloat64,	&attrGain,		(TTGetterMethod)&TTPhasor::getGain, (TTSetterMethod)&TTPhasor::setGain);
	registerAttribute(TT("phase"),		kTypeFloat64,	&attrPhase);
	// TODO: More Attributes left to add...
	//	linearGain
	//	period in ms
	//	period in samples

	registerMessage(TT("updateSr"),	(TTMethod)&TTPhasor::updateSr);

	setAttributeValue(TT("frequency"), 1.0);
	setAttributeValue(TT("gain"), 0.0);
	setProcess((TTProcessMethod)&TTPhasor::processAudio);
}

TTPhasor::~TTPhasor()
{
	;
}

TTErr TTPhasor::updateSr()
{
	TTValue	v(attrFrequency);
	return setFrequency(TTATTR, v);
}

TTErr TTPhasor::setFrequency(const TTAttribute&, const TTValue& newValue)
{
	attrFrequency = newValue;
	if(attrFrequency == 0){
		rampSamples = 0xFFFFFFFF;
		rampMilliseconds = 0;
	}
	else{
		rampSamples = (1.0 / attrFrequency) * sr;
		rampMilliseconds = 1000.0 * (rampSamples / TTFloat64(sr));
	}
	setStep();
	return kTTErrNone;
}

void TTPhasor::setStep()
{
	step = antiDenormal(1.0 / TTFloat64(rampSamples));	// 1.0 is the destination
}

TTErr TTPhasor::setGain(const TTAttribute&, const TTValue& newValue)
{
	attrGain = newValue;
	linearGain = dbToLinear(attrGain);
	return kTTErrNone;
}

TTErr TTPhasor::getGain(const TTAttribute&, TTValue& value)
{
	value = linearToDb(linearGain);
	return kTTErrNone;
}

// TODO: add flags so that TTAudioObject can call a process method with a different number audio signals?

TTErr TTPhasor::processAudio(TTAudioSignal& in, TTAudioSignal& out)
{
	TTSampleValue	*outSample;
	TTUInt8			numchannels = out.getNumChannels();
	TTUInt8			channel;
	TTUInt16		vs;

	for(channel=0; channel<numchannels; channel++){
		outSample = out.sampleVectors[channel];
		vs = out.getVectorSize();

		while(vs--){
			attrPhase += step;
			if(attrPhase >= 1.0)
				attrPhase -= 1.0;
			else if(attrPhase < 0.0)
				attrPhase += 1.0;
			*outSample++ = attrPhase * linearGain;
		}
	}
	return kTTErrNone;
}
<|endoftext|>