<commit_before>#include <boost/filesystem.hpp>
#include <magic.h>

#include "reporter.h"
#include "scanner_mp3.h"
#include "scanner_ogg_vorbis.h"
#include "scanner_flac.h"
#include "scanner_mp4.h"

namespace fs = boost::filesystem;

Reporter::Reporter(string* dir, string* r_type) {
  directory = dir;
  report_type = r_type;
  report = report_map_type();
}

void Reporter::run() {
  iterate_directory();
  generate();
}

void Reporter::generate() {
  if (*report_type == "plain") {
    generate_plain();
  } else if (*report_type == "csv") {
    generate_csv();
  } else if (*report_type == "html_list") {
    generate_html_list();
  } else if (*report_type == "html_collapsible") {
    generate_html_collapsible();
  }
}

void Reporter::generate_plain() {
  for (report_map_type::iterator artist=report.begin();
      artist!=report.end(); ++artist) {
    cout << "Artist: " << artist->first << endl;
    albums_type albums(artist->second);

    for (albums_type::iterator album=albums.begin();
        album!=albums.end(); ++album) {
      cout << "  Albums: " << album->first << endl;
      directories_type directories(album->second);

      for (directories_type::iterator directory=directories.begin();
          directory!=directories.end(); ++directory) {
        cout << "    Directory '" << directory->first << "': " << endl;
        errors_type errors(directory->second);

        for (errors_type::iterator error=errors.begin();
            error!=errors.end(); ++error) {
          cout << "      * " << *error << endl;
        }
      }
    }
  }
}

void Reporter::generate_csv() {
  cout << "Report type '" << *report_type << "' is not supported yet." << endl;
}

void Reporter::generate_html_list() {
  cout << "Report type '" << *report_type << "' is not supported yet." << endl;
}

void Reporter::generate_html_collapsible() {
  cout << "Report type '" << *report_type << "' is not supported yet." << endl;
}

const string Reporter::get_file_type(const string file) {
  const char *contentType;
  string type;

  magic_t magic = magic_open(MAGIC_MIME_TYPE|MAGIC_ERROR);
  if (magic == NULL) {
    cerr << file << ": Error initializing libmagic" << endl;
    return "unknown";
  }
  if (magic_load(magic, NULL) != 0) {
    cerr << file << ": Error loading libmagic database" << endl;
    magic_close(magic);
    return "unknown";
  }
  contentType = magic_file(magic, file.c_str());
  if (contentType == NULL) {
    cerr << file << ": Unknown content type" << endl;
    magic_close(magic);
    return "unknown";
  }
  type = string(contentType);
  magic_close(magic);
  return type;
}

void Reporter::iterate_directory() {
  for (fs::recursive_directory_iterator end, file(*directory);
      file != end; ++file) {
    if (is_directory(file->status())) {
      continue;
    }
    string file_type = get_file_type(file->path().string());
    // Only consider audio files
    if (file_type == "audio/mpeg") {
      MP3Scanner mp3_scanner(file->path().string(),&report);
      mp3_scanner.scan();
    } else if (file_type == "application/ogg") {
      OggVorbisScanner ogg_vorbis_scanner(file->path().string(),&report);
      ogg_vorbis_scanner.scan();
    } else if (file_type == "audio/x-flac") {
      FLACScanner flac_scanner(file->path().string(),&report);
      flac_scanner.scan();
    } else if (file_type == "audio/mp4") {
      MP4Scanner mp4_scanner(file->path().string(),&report);
      mp4_scanner.scan();
    }
  }
}
<commit_msg>add csv report format.<commit_after>#include <sstream>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/join.hpp>
#include <magic.h>

#include "reporter.h"
#include "scanner_mp3.h"
#include "scanner_ogg_vorbis.h"
#include "scanner_flac.h"
#include "scanner_mp4.h"

namespace fs = boost::filesystem;

Reporter::Reporter(string* dir, string* r_type) {
  directory = dir;
  report_type = r_type;
  report = report_map_type();
}

void Reporter::run() {
  iterate_directory();
  generate();
}

void Reporter::generate() {
  if (*report_type == "plain") {
    generate_plain();
  } else if (*report_type == "csv") {
    generate_csv();
  } else if (*report_type == "html_list") {
    generate_html_list();
  } else if (*report_type == "html_collapsible") {
    generate_html_collapsible();
  }
}

void Reporter::generate_plain() {
  for (report_map_type::iterator artist=report.begin();
      artist!=report.end(); ++artist) {
    cout << "Artist: " << artist->first << endl;
    albums_type albums(artist->second);

    for (albums_type::iterator album=albums.begin();
        album!=albums.end(); ++album) {
      cout << "  Albums: " << album->first << endl;
      directories_type directories(album->second);

      for (directories_type::iterator directory=directories.begin();
          directory!=directories.end(); ++directory) {
        cout << "    Directory '" << directory->first << "': " << endl;
        errors_type errors(directory->second);

        for (errors_type::iterator error=errors.begin();
            error!=errors.end(); ++error) {
          cout << "      * " << *error << endl;
        }
      }
    }
  }
}

void Reporter::generate_csv() {
  std::ostringstream ss;
  ss << "Artist,Album,Directory,Error(s)" << endl;
  for (report_map_type::iterator artist=report.begin();
      artist!=report.end(); ++artist) {
    albums_type albums(artist->second);
    for (albums_type::iterator album=albums.begin();
        album!=albums.end(); ++album) {
      directories_type directories(album->second);
      for (directories_type::iterator directory=directories.begin();
          directory!=directories.end(); ++directory) {
        ss << "\"" << artist->first << "\",";
        ss << "\"" << album->first << "\",";
        ss << "\"" << directory->first << "\",";
        errors_type errors(directory->second);
        ss << boost::algorithm::join(errors, "|");
        ss << endl;
      }
    }
  }
  std::cout << ss.str() << endl;
}

void Reporter::generate_html_list() {
  cout << "Report type '" << *report_type << "' is not supported yet." << endl;
}

void Reporter::generate_html_collapsible() {
  cout << "Report type '" << *report_type << "' is not supported yet." << endl;
}

const string Reporter::get_file_type(const string file) {
  const char *contentType;
  string type;

  magic_t magic = magic_open(MAGIC_MIME_TYPE|MAGIC_ERROR);
  if (magic == NULL) {
    cerr << file << ": Error initializing libmagic" << endl;
    return "unknown";
  }
  if (magic_load(magic, NULL) != 0) {
    cerr << file << ": Error loading libmagic database" << endl;
    magic_close(magic);
    return "unknown";
  }
  contentType = magic_file(magic, file.c_str());
  if (contentType == NULL) {
    cerr << file << ": Unknown content type" << endl;
    magic_close(magic);
    return "unknown";
  }
  type = string(contentType);
  magic_close(magic);
  return type;
}

void Reporter::iterate_directory() {
  for (fs::recursive_directory_iterator end, file(*directory);
      file != end; ++file) {
    if (is_directory(file->status())) {
      continue;
    }
    string file_type = get_file_type(file->path().string());
    // Only consider audio files
    if (file_type == "audio/mpeg") {
      MP3Scanner mp3_scanner(file->path().string(),&report);
      mp3_scanner.scan();
    } else if (file_type == "application/ogg") {
      OggVorbisScanner ogg_vorbis_scanner(file->path().string(),&report);
      ogg_vorbis_scanner.scan();
    } else if (file_type == "audio/x-flac") {
      FLACScanner flac_scanner(file->path().string(),&report);
      flac_scanner.scan();
    } else if (file_type == "audio/mp4") {
      MP4Scanner mp4_scanner(file->path().string(),&report);
      mp4_scanner.scan();
    }
  }
}
<|endoftext|>


<commit_before>#ifndef SPIRIT_USE_CUDA
#include "FFT.hpp"
#include <iostream>
#include <vector>

namespace Engine
{
    namespace FFT
    {
        //=== Functions for FFTW backend ===
        #ifdef SPIRIT_USE_FFTW

        //Dont need the single transforms because FFTW can do real batch transforms
        void Four_3D(const FFT_cfg & cfg, FFT_real_type * in, FFT_cpx_type * out)
        {
            std::cerr << "NOT IMPLEMENTED FOR FFTW!" << std::endl;
        }
        void iFour_3D(const FFT_cfg & cfg, FFT_cpx_type * in, FFT_real_type * out)
        {
            std::cerr << "NOT IMPLEMENTED FOR FFTW!" << std::endl;
        }

        void batch_Four_3D(FFT_Plan & plan)
        {
            FFTW_EXECUTE(plan.cfg);
            // fftw_execute(plan.cfg);
        }

        void batch_iFour_3D(FFT_Plan & plan)
        {
            FFTW_EXECUTE(plan.cfg);
            // fftw_execute(plan.cfg);
        }

        void FFT_Plan::Create_Configuration()
        {
            int rank = this->dims.size();
            int *n = this->dims.data();
            int howmany = this->howmany;
            int istride = howmany, ostride = howmany;
            int *inembed = n, *onembed = n;

            int size = 1;
            for(auto k : dims)
                size *= k;

            int idist = 1, odist = 1;

            if(this->inverse == false)
                // this->cfg = fftw_plan_many_dft_r2c(rank, n, howmany, this->real_ptr.data(), inembed, istride, idist, reinterpret_cast<fftw_complex*>(this->cpx_ptr.data()), onembed, ostride, odist, FFTW_MEASURE);
                this->cfg = FFTW_PLAN_MANY_DFT_R2C(rank, n, howmany, this->real_ptr.data(), inembed, istride, idist, reinterpret_cast<FFTW_COMPLEX*>(this->cpx_ptr.data()), onembed, ostride, odist, FFTW_MEASURE);
            else
                this->cfg = FFTW_PLAN_MANY_DFT_C2R(rank, n, howmany, reinterpret_cast<FFTW_COMPLEX*>(this->cpx_ptr.data()), inembed, istride, idist, this->real_ptr.data(), onembed, ostride, odist, FFTW_MEASURE);
            this->freeable = true;
        }

        void FFT_Plan::Free_Configuration()
        {
            if(freeable)
            {
                // fftw_destroy_plan(this->cfg);
                FFTW_DESTROY_PLAN(this->cfg);
                this->freeable = false;
            }
        }

        void FFT_Plan::Clean()
        {
            this->cpx_ptr = field<FFT_cpx_type>();
            this->real_ptr = field<FFT_real_type>();
            Free_Configuration();
        }

        // FFT_Plan::FFT_Plan(std::string name) : name(name) {

        //     std::cerr << "Calling constructor " << name << std::endl;
        // }

        FFT_Plan::~FFT_Plan()
        {
            // std::cerr << "Calling Destructor " << name << std::endl;
        }

        #endif

        //=== Functions for kissFFT backend ===
        #ifdef SPIRIT_USE_KISSFFT
        void Four_3D(const FFT_cfg & cfg, FFT_real_type * in, FFT_cpx_type * out)
        {
            kiss_fftndr(cfg, in, out);
        }

        void iFour_3D(const FFT_cfg & cfg, FFT_cpx_type * in, FFT_real_type * out)
        {
            kiss_fftndri(cfg, in, out);
        }

        void batch_Four_3D(FFT_Plan & plan)
        {
            // std::cerr << "Calling batch Four" << std::endl;
            int number = plan.howmany;
            int size = 1;
            for(auto k : plan.dims)
                size *= k;
            const auto& in = plan.real_ptr.data();
            const auto& out = plan.cpx_ptr.data();

            //just for testing
            // const auto& in = plan.real_ptr;
            // const auto& out = plan.cpx_ptr;

            for(int dir = 0; dir < number; ++dir)
                Engine::FFT::Four_3D(plan.cfg, in + dir * size, out + dir * size);

        }

        //same as above but iFFT
        void batch_iFour_3D(FFT_Plan & plan)
        {
            int number = plan.howmany;
            int size = 1;
            for(auto k : plan.dims)
                size *= k;

            const auto& in = plan.cpx_ptr.data();
            const auto& out = plan.real_ptr.data();

            for(int dir = 0; dir < number; ++dir)
                Engine::FFT::iFour_3D(plan.cfg, in + dir * size, out + dir * size);
        }

        void FFT_Plan::Create_Configuration()
        {
            this->cfg = kiss_fftndr_alloc(this->dims.data(), this->dims.size(), this->inverse, NULL, NULL);
            this->freeable = true;
        }

        void FFT_Plan::Free_Configuration()
        {
            if(freeable)
            {
                free(this->cfg);
                this->freeable = false;
            }
        }

        void FFT_Plan::Clean()
        {
            this->cpx_ptr = field<FFT_cpx_type>();
            this->real_ptr = field<FFT_real_type>();
            Free_Configuration();
        }

        FFT_Plan::~FFT_Plan()
        {
            std::cerr << "Calling Destructor " << name << std::endl;
        }
        #endif
    }
}
#endif<commit_msg>Core: removed unnecessary debug print in FFT.<commit_after>#ifndef SPIRIT_USE_CUDA
#include "FFT.hpp"
#include <iostream>
#include <vector>

namespace Engine
{
    namespace FFT
    {
        //=== Functions for FFTW backend ===
        #ifdef SPIRIT_USE_FFTW

        //Dont need the single transforms because FFTW can do real batch transforms
        void Four_3D(const FFT_cfg & cfg, FFT_real_type * in, FFT_cpx_type * out)
        {
            std::cerr << "NOT IMPLEMENTED FOR FFTW!" << std::endl;
        }
        void iFour_3D(const FFT_cfg & cfg, FFT_cpx_type * in, FFT_real_type * out)
        {
            std::cerr << "NOT IMPLEMENTED FOR FFTW!" << std::endl;
        }

        void batch_Four_3D(FFT_Plan & plan)
        {
            FFTW_EXECUTE(plan.cfg);
            // fftw_execute(plan.cfg);
        }

        void batch_iFour_3D(FFT_Plan & plan)
        {
            FFTW_EXECUTE(plan.cfg);
            // fftw_execute(plan.cfg);
        }

        void FFT_Plan::Create_Configuration()
        {
            int rank = this->dims.size();
            int *n = this->dims.data();
            int howmany = this->howmany;
            int istride = howmany, ostride = howmany;
            int *inembed = n, *onembed = n;

            int size = 1;
            for(auto k : dims)
                size *= k;

            int idist = 1, odist = 1;

            if(this->inverse == false)
                // this->cfg = fftw_plan_many_dft_r2c(rank, n, howmany, this->real_ptr.data(), inembed, istride, idist, reinterpret_cast<fftw_complex*>(this->cpx_ptr.data()), onembed, ostride, odist, FFTW_MEASURE);
                this->cfg = FFTW_PLAN_MANY_DFT_R2C(rank, n, howmany, this->real_ptr.data(), inembed, istride, idist, reinterpret_cast<FFTW_COMPLEX*>(this->cpx_ptr.data()), onembed, ostride, odist, FFTW_MEASURE);
            else
                this->cfg = FFTW_PLAN_MANY_DFT_C2R(rank, n, howmany, reinterpret_cast<FFTW_COMPLEX*>(this->cpx_ptr.data()), inembed, istride, idist, this->real_ptr.data(), onembed, ostride, odist, FFTW_MEASURE);
            this->freeable = true;
        }

        void FFT_Plan::Free_Configuration()
        {
            if(freeable)
            {
                // fftw_destroy_plan(this->cfg);
                FFTW_DESTROY_PLAN(this->cfg);
                this->freeable = false;
            }
        }

        void FFT_Plan::Clean()
        {
            this->cpx_ptr = field<FFT_cpx_type>();
            this->real_ptr = field<FFT_real_type>();
            Free_Configuration();
        }

        // FFT_Plan::FFT_Plan(std::string name) : name(name) {

        //     std::cerr << "Calling constructor " << name << std::endl;
        // }

        FFT_Plan::~FFT_Plan()
        {
            // std::cerr << "Calling Destructor " << name << std::endl;
        }

        #endif

        //=== Functions for kissFFT backend ===
        #ifdef SPIRIT_USE_KISSFFT
        void Four_3D(const FFT_cfg & cfg, FFT_real_type * in, FFT_cpx_type * out)
        {
            kiss_fftndr(cfg, in, out);
        }

        void iFour_3D(const FFT_cfg & cfg, FFT_cpx_type * in, FFT_real_type * out)
        {
            kiss_fftndri(cfg, in, out);
        }

        void batch_Four_3D(FFT_Plan & plan)
        {
            // std::cerr << "Calling batch Four" << std::endl;
            int number = plan.howmany;
            int size = 1;
            for(auto k : plan.dims)
                size *= k;
            const auto& in = plan.real_ptr.data();
            const auto& out = plan.cpx_ptr.data();

            //just for testing
            // const auto& in = plan.real_ptr;
            // const auto& out = plan.cpx_ptr;

            for(int dir = 0; dir < number; ++dir)
                Engine::FFT::Four_3D(plan.cfg, in + dir * size, out + dir * size);

        }

        //same as above but iFFT
        void batch_iFour_3D(FFT_Plan & plan)
        {
            int number = plan.howmany;
            int size = 1;
            for(auto k : plan.dims)
                size *= k;

            const auto& in = plan.cpx_ptr.data();
            const auto& out = plan.real_ptr.data();

            for(int dir = 0; dir < number; ++dir)
                Engine::FFT::iFour_3D(plan.cfg, in + dir * size, out + dir * size);
        }

        void FFT_Plan::Create_Configuration()
        {
            this->cfg = kiss_fftndr_alloc(this->dims.data(), this->dims.size(), this->inverse, NULL, NULL);
            this->freeable = true;
        }

        void FFT_Plan::Free_Configuration()
        {
            if(freeable)
            {
                free(this->cfg);
                this->freeable = false;
            }
        }

        void FFT_Plan::Clean()
        {
            this->cpx_ptr = field<FFT_cpx_type>();
            this->real_ptr = field<FFT_real_type>();
            Free_Configuration();
        }

        FFT_Plan::~FFT_Plan()
        {
            // std::cerr << "Calling Destructor " << name << std::endl;
        }
        #endif
    }
}
#endif<|endoftext|>


<commit_before>// Copyright (c) 2009-2018 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Developers
// Copyright (c) 2016-2018 Duality Blockchain Solutions Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "utilmoneystr.h"

#include "tinyformat.h"
#include "primitives/transaction.h"
#include "utilstrencodings.h"

using namespace std;

string FormatMoney(const CAmount& n, bool fPlus)
{
    // Note: not using straight sprintf here because we do NOT want
    // localized number formatting.
    int64_t n_abs = (n > 0 ? n : -n);
    int64_t quotient = n_abs/COIN;
    int64_t remainder = n_abs%COIN;
    string str = strprintf("%d.%06d", quotient, remainder);

    // Right-trim excess zeros before the decimal point:
    int nTrim = 0;
    for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
        ++nTrim;
    if (nTrim)
        str.erase(str.size()-nTrim, nTrim);

    if (n < 0)
        str.insert((unsigned int)0, 1, '-');
    else if (fPlus && n > 0)
        str.insert((unsigned int)0, 1, '+');
    return str;
}

bool ParseMoney(const string& str, CAmount& nRet)
{
    return ParseMoney(str.c_str(), nRet);
}

bool ParseMoney(const char* pszIn, CAmount& nRet)
{
    string strWhole;
    int64_t nUnits = 0;
    const char* p = pszIn;
    while (isspace(*p))
        p++;
    for (; *p; p++)
    {
        if (*p == '.')
        {
            p++;
            int64_t nMult = CENT*1000;
            while (isdigit(*p) && (nMult > 0))
            {
                nUnits += nMult * (*p++ - '0');
                nMult /= 10;
            }
            break;
        }
        if (isspace(*p))
            break;
        if (!isdigit(*p))
            return false;
        strWhole.insert(strWhole.end(), *p);
    }
    for (; *p; p++)
        if (!isspace(*p))
            return false;
    if (strWhole.size() > 10) // guard against 63 bit overflow
        return false;
    if (nUnits < 0 || nUnits > COIN)
        return false;
    int64_t nWhole = atoi64(strWhole);
    CAmount nValue = nWhole*COIN + nUnits;

    nRet = nValue;
    return true;
}
<commit_msg>Fix decimal amount Pt.2<commit_after>// Copyright (c) 2009-2018 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Developers
// Copyright (c) 2016-2018 Duality Blockchain Solutions Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "utilmoneystr.h"

#include "tinyformat.h"
#include "primitives/transaction.h"
#include "utilstrencodings.h"

using namespace std;

string FormatMoney(const CAmount& n, bool fPlus)
{
    // Note: not using straight sprintf here because we do NOT want
    // localized number formatting.
    int64_t n_abs = (n > 0 ? n : -n);
    int64_t quotient = n_abs/COIN;
    int64_t remainder = n_abs%COIN;
    string str = strprintf("%d.%08d", quotient, remainder);

    // Right-trim excess zeros before the decimal point:
    int nTrim = 0;
    for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
        ++nTrim;
    if (nTrim)
        str.erase(str.size()-nTrim, nTrim);

    if (n < 0)
        str.insert((unsigned int)0, 1, '-');
    else if (fPlus && n > 0)
        str.insert((unsigned int)0, 1, '+');
    return str;
}

bool ParseMoney(const string& str, CAmount& nRet)
{
    return ParseMoney(str.c_str(), nRet);
}

bool ParseMoney(const char* pszIn, CAmount& nRet)
{
    string strWhole;
    int64_t nUnits = 0;
    const char* p = pszIn;
    while (isspace(*p))
        p++;
    for (; *p; p++)
    {
        if (*p == '.')
        {
            p++;
            int64_t nMult = CENT*1000;
            while (isdigit(*p) && (nMult > 0))
            {
                nUnits += nMult * (*p++ - '0');
                nMult /= 10;
            }
            break;
        }
        if (isspace(*p))
            break;
        if (!isdigit(*p))
            return false;
        strWhole.insert(strWhole.end(), *p);
    }
    for (; *p; p++)
        if (!isspace(*p))
            return false;
    if (strWhole.size() > 10) // guard against 63 bit overflow
        return false;
    if (nUnits < 0 || nUnits > COIN)
        return false;
    int64_t nWhole = atoi64(strWhole);
    CAmount nValue = nWhole*COIN + nUnits;

    nRet = nValue;
    return true;
}
<|endoftext|>


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

#include "base/crypto/cssm_init.h"

#include <Security/SecBase.h>

#include "base/logging.h"
#include "base/singleton.h"
#include "base/synchronization/lock.h"
#include "base/sys_string_conversions.h"

// When writing crypto code for Mac OS X, you may find the following
// documentation useful:
// - Common Security: CDSA and CSSM, Version 2 (with corrigenda)
//   http://www.opengroup.org/security/cdsa.htm
// - Apple Cryptographic Service Provider Functional Specification
// - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/

namespace {

class CSSMInitSingleton {
 public:
  static CSSMInitSingleton* GetInstance() {
    return Singleton<CSSMInitSingleton>::get();
  }

  CSSM_CSP_HANDLE csp_handle() const  {return csp_handle_;}

 private:
  CSSMInitSingleton() : inited_(false), loaded_(false), csp_handle_(NULL) {
    static CSSM_VERSION version = {2, 0};
    // TODO(wtc): what should our caller GUID be?
    static const CSSM_GUID test_guid = {
      0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 }
    };
    CSSM_RETURN crtn;
    CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE;
    crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid,
                     CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL);
    if (crtn) {
      NOTREACHED();
      return;
    }
    inited_ = true;

    crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL);
    if (crtn) {
      NOTREACHED();
      return;
    }
    loaded_ = true;

    crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version,
                             &base::kCssmMemoryFunctions, 0,
                             CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE,
                             NULL, 0, NULL, &csp_handle_);
    DCHECK(crtn == CSSM_OK);
  }

  ~CSSMInitSingleton() {
    CSSM_RETURN crtn;
    if (csp_handle_) {
      CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_);
      DCHECK(crtn == CSSM_OK);
    }
    if (loaded_) {
      crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL);
      DCHECK(crtn == CSSM_OK);
    }
    if (inited_) {
      crtn = CSSM_Terminate();
      DCHECK(crtn == CSSM_OK);
    }
  }

  bool inited_;  // True if CSSM_Init has been called successfully.
  bool loaded_;  // True if CSSM_ModuleLoad has been called successfully.
  CSSM_CSP_HANDLE csp_handle_;

  friend struct DefaultSingletonTraits<CSSMInitSingleton>;
};

// This singleton is separate as it pertains to Apple's wrappers over
// their own CSSM handles, as opposed to our own CSSM_CSP_HANDLE.
class SecurityServicesSingleton {
 public:
  static SecurityServicesSingleton* GetInstance() {
    return Singleton<SecurityServicesSingleton>::get();
  }

  ~SecurityServicesSingleton() {}

  base::Lock& lock() { return lock_; }

 private:
  friend class Singleton<SecurityServicesSingleton>;
  friend struct DefaultSingletonTraits<SecurityServicesSingleton>;

  SecurityServicesSingleton() {}

  base::Lock lock_;

  DISALLOW_COPY_AND_ASSIGN(SecurityServicesSingleton);
};

}  // namespace

namespace base {

void EnsureCSSMInit() {
  CSSMInitSingleton::GetInstance();
}

CSSM_CSP_HANDLE GetSharedCSPHandle() {
  return CSSMInitSingleton::GetInstance()->csp_handle();
}

void* CSSMMalloc(CSSM_SIZE size, void *alloc_ref) {
  return malloc(size);
}

void CSSMFree(void* mem_ptr, void* alloc_ref) {
  free(mem_ptr);
}

void* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) {
  return realloc(ptr, size);
}

void* CSSMCalloc(uint32 num, CSSM_SIZE size, void* alloc_ref) {
  return calloc(num, size);
}

const CSSM_API_MEMORY_FUNCS kCssmMemoryFunctions = {
  CSSMMalloc,
  CSSMFree,
  CSSMRealloc,
  CSSMCalloc,
  NULL
};

void LogCSSMError(const char *fn_name, CSSM_RETURN err) {
  if (!err)
    return;
  CFStringRef cfstr = SecCopyErrorMessageString(err, NULL);
  if (cfstr) {
    std::string err_name = SysCFStringRefToUTF8(cfstr);
    CFRelease(cfstr);
    LOG(ERROR) << fn_name << " returned " << err << " (" << err_name << ")";
  } else {
    LOG(ERROR) << fn_name << " returned " << err;
  }
}

base::Lock& GetMacSecurityServicesLock() {
  return SecurityServicesSingleton::GetInstance()->lock();
}

}  // namespace base
<commit_msg>Allow CDSA/CSSM to be used on worker threads in debug builds by making both the CSSM init singleton and the Mac Security Services lock singleton leaky.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/crypto/cssm_init.h"

#include <Security/SecBase.h>

#include "base/logging.h"
#include "base/singleton.h"
#include "base/synchronization/lock.h"
#include "base/sys_string_conversions.h"

// When writing crypto code for Mac OS X, you may find the following
// documentation useful:
// - Common Security: CDSA and CSSM, Version 2 (with corrigenda)
//   http://www.opengroup.org/security/cdsa.htm
// - Apple Cryptographic Service Provider Functional Specification
// - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/

namespace {

class CSSMInitSingleton {
 public:
  static CSSMInitSingleton* GetInstance() {
    return Singleton<CSSMInitSingleton,
                     LeakySingletonTraits<CSSMInitSingleton> >::get();
  }

  CSSM_CSP_HANDLE csp_handle() const  { return csp_handle_; }

 private:
  CSSMInitSingleton() : inited_(false), loaded_(false), csp_handle_(NULL) {
    static CSSM_VERSION version = {2, 0};
    // TODO(wtc): what should our caller GUID be?
    static const CSSM_GUID test_guid = {
      0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 }
    };
    CSSM_RETURN crtn;
    CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE;
    crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid,
                     CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL);
    if (crtn) {
      NOTREACHED();
      return;
    }
    inited_ = true;

    crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL);
    if (crtn) {
      NOTREACHED();
      return;
    }
    loaded_ = true;

    crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version,
                             &base::kCssmMemoryFunctions, 0,
                             CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE,
                             NULL, 0, NULL, &csp_handle_);
    DCHECK(crtn == CSSM_OK);
  }

  ~CSSMInitSingleton() {
    CSSM_RETURN crtn;
    if (csp_handle_) {
      CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_);
      DCHECK(crtn == CSSM_OK);
    }
    if (loaded_) {
      crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL);
      DCHECK(crtn == CSSM_OK);
    }
    if (inited_) {
      crtn = CSSM_Terminate();
      DCHECK(crtn == CSSM_OK);
    }
  }

  bool inited_;  // True if CSSM_Init has been called successfully.
  bool loaded_;  // True if CSSM_ModuleLoad has been called successfully.
  CSSM_CSP_HANDLE csp_handle_;

  friend struct DefaultSingletonTraits<CSSMInitSingleton>;
};

// This singleton is separate as it pertains to Apple's wrappers over
// their own CSSM handles, as opposed to our own CSSM_CSP_HANDLE.
class SecurityServicesSingleton {
 public:
  static SecurityServicesSingleton* GetInstance() {
    return Singleton<SecurityServicesSingleton,
                     LeakySingletonTraits<SecurityServicesSingleton> >::get();
  }

  base::Lock& lock() { return lock_; }

 private:
  friend struct DefaultSingletonTraits<SecurityServicesSingleton>;

  SecurityServicesSingleton() {}
  ~SecurityServicesSingleton() {}

  base::Lock lock_;

  DISALLOW_COPY_AND_ASSIGN(SecurityServicesSingleton);
};

}  // namespace

namespace base {

void EnsureCSSMInit() {
  CSSMInitSingleton::GetInstance();
}

CSSM_CSP_HANDLE GetSharedCSPHandle() {
  return CSSMInitSingleton::GetInstance()->csp_handle();
}

void* CSSMMalloc(CSSM_SIZE size, void *alloc_ref) {
  return malloc(size);
}

void CSSMFree(void* mem_ptr, void* alloc_ref) {
  free(mem_ptr);
}

void* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) {
  return realloc(ptr, size);
}

void* CSSMCalloc(uint32 num, CSSM_SIZE size, void* alloc_ref) {
  return calloc(num, size);
}

const CSSM_API_MEMORY_FUNCS kCssmMemoryFunctions = {
  CSSMMalloc,
  CSSMFree,
  CSSMRealloc,
  CSSMCalloc,
  NULL
};

void LogCSSMError(const char *fn_name, CSSM_RETURN err) {
  if (!err)
    return;
  CFStringRef cfstr = SecCopyErrorMessageString(err, NULL);
  if (cfstr) {
    std::string err_name = SysCFStringRefToUTF8(cfstr);
    CFRelease(cfstr);
    LOG(ERROR) << fn_name << " returned " << err << " (" << err_name << ")";
  } else {
    LOG(ERROR) << fn_name << " returned " << err;
  }
}

base::Lock& GetMacSecurityServicesLock() {
  return SecurityServicesSingleton::GetInstance()->lock();
}

}  // namespace base
<|endoftext|>


<commit_before>#include "Buffer.hpp"
#include "conversions.h"
#include "PVLog.hpp"

#include <cstring>
#include <cmath>

namespace PV {

   Buffer::Buffer(int width, int height, int features) {
      resize(width, height, features);
   }

   Buffer::Buffer() {
      resize(1,1,1);
   }

   Buffer::Buffer(const std::vector<float> &data, int width, int height, int features) {
      set(data, width, height, features);
   }

   float Buffer::at(int x, int y, int feature) {
      return mData.at(index(x, y, feature));
   }

   void Buffer::set(int x, int y, int feature, float value) {
      mData.at(index(x, y, feature)) = value;
   }

   void Buffer::set(const std::vector<float> &vector, int width, int height, int features) {
      pvErrorIf(vector.size() != width * height * features,
         "Invalid vector size: Expected %d elements, vector contained %d elements.\n",
         width * height * features, vector.size());
      mData = vector;
      mWidth = width;
      mHeight = height;
      mFeatures = features;
   }

   // Resizing a Buffer will clear its contents. Use rescale, crop, or grow to preserve values.
   void Buffer::resize(int width, int height, int features) {
      mData.clear();
      mData.resize(height * width * features, 0.0f);
      mWidth = width;
      mHeight = height;
      mFeatures = features;
   }

      // Grows a buffer
   void Buffer::grow(int newWidth, int newHeight, enum Anchor anchor) {
      if(newWidth < getWidth() && newHeight < getHeight()) {
         return;
      }
      int offsetX = getAnchorX(anchor, getWidth(),  newWidth);
      int offsetY = getAnchorY(anchor, getHeight(), newHeight);
      Buffer bigger(newWidth, newHeight, getFeatures());

      for(int y = 0; y < getHeight(); ++y) {
         for(int x = 0; x < getWidth(); ++x) {
            for(int f = 0; f < getFeatures(); ++f) {
               int destX = x + offsetX;
               int destY = y + offsetY;
               if(destX < 0 || destX >= newWidth)  continue;
               if(destY < 0 || destY >= newHeight) continue;
               bigger.set(destX, destY, f, at(x, y, f));
            }
         }
      }
      set(bigger.asVector(), newWidth, newHeight, getFeatures());
   }

   // Crops a buffer down to the specified size
   void Buffer::crop(int newWidth, int newHeight, enum Anchor anchor) {
      if(newWidth >= getWidth() && newHeight >= getHeight()) {
         return;
      }
      int offsetX = getAnchorX(anchor, newWidth,  getWidth());
      int offsetY = getAnchorY(anchor, newHeight, getHeight());
      Buffer cropped(newWidth, newHeight, getFeatures());

      for(int destY = 0; destY < newHeight; ++destY) {
         for(int destX = 0; destX < newWidth; ++destX) {
            for(int f = 0; f < getFeatures(); ++f) {
               int sourceX = destX + offsetX;
               int sourceY = destY + offsetY;
               if(sourceX < 0 || sourceX >= getWidth())  continue;
               if(sourceY < 0 || sourceX >= getHeight()) continue;
               cropped.set(destX, destY, f, at(sourceX, sourceY, f));
            }
         }
      }
      set(cropped.asVector(), newWidth, newHeight, getFeatures());
   }

   // Rescale a buffer, preserving aspect ratio
   void Buffer::rescale(int newWidth, int newHeight,
         enum RescaleMethod rescaleMethod,
         enum InterpolationMethod interpMethod,
         enum Anchor anchor) {
      float xRatio = static_cast<float>(newWidth)  / getWidth();
      float yRatio = static_cast<float>(newHeight) / getHeight();
      int resizedWidth = newWidth;
      int resizedHeight = newHeight;
      float resizeFactor = 1.0f;

      switch(rescaleMethod) {
         case CROP:
            resizeFactor = xRatio < yRatio ? yRatio : xRatio;
            break;
         case PAD:
            resizeFactor = xRatio < yRatio ? xRatio : yRatio;
            break;
      }

      resizedWidth   = static_cast<int>(nearbyintf(resizeFactor * getWidth()));
      resizedHeight  = static_cast<int>(nearbyintf(resizeFactor * getHeight()));

      std::vector<float> rawInput = asVector();
      std::vector<float> scaledInput(resizedWidth * resizedHeight * getFeatures());
      switch(interpMethod) {
         case BICUBIC:
            bicubicInterp(rawInput.data(),                        // Input data
                  getWidth(),    getHeight(), getFeatures(),      // Input dimensions
                  getFeatures(), getFeatures() * getWidth(), 1,   // Strides
                  scaledInput.data(),                             // Output data
                  resizedWidth,  resizedHeight);                  // Target dimensions
            break;
         case NEAREST:
            nearestNeighborInterp(rawInput.data(),                // Input data
                  getWidth(),    getHeight(), getFeatures(),      // Input dimensions
                  getFeatures(), getFeatures() * getWidth(), 1,   // Strides
                  scaledInput.data(),                             // Output data
                  resizedWidth,  resizedHeight);                  // Target dimensions
            break;
      }
      set(scaledInput, resizedWidth, resizedHeight, getFeatures());

      // This final call resizes the buffer to our specified
      // newWidth and newHeight. If our rescaleMethod was PAD,
      // this actually grows the buffer to include the padded region.
      switch(rescaleMethod) {
         case CROP:
            crop(newWidth, newHeight, anchor);
            break;
         case PAD:
            grow(newWidth, newHeight, anchor);
            break;
      }
   }

   // Shift a buffer, clipping any values that land out of bounds
   void Buffer::translate(int xShift, int yShift) {
      Buffer result(getWidth(), getHeight(), getFeatures());
      for(int y = 0; y < getHeight(); ++y) {
         for(int x = 0; x < getWidth(); ++x) {
            for(int f = 0; f < getFeatures(); ++f) {
               int destX = x + xShift;
               int destY = y + yShift;
               if(destX < 0 || destX >= getWidth())  continue;
               if(destY < 0 || destY >= getHeight()) continue;
               result.set(destX, destY, f, at(x, y, f));
            }
         }
      }
      set(result.asVector(), getWidth(), getHeight(), getFeatures());
   }

   int Buffer::getAnchorX(enum Anchor anchor, int smallerWidth, int biggerWidth) {
      switch(anchor) {
         case NORTHWEST:
         case WEST:
         case SOUTHWEST:
            return 0;
         case NORTH:
         case CENTER:
         case SOUTH:
            return biggerWidth/2 - smallerWidth/2;
         case NORTHEAST:
         case EAST:
         case SOUTHEAST:
            return biggerWidth - smallerWidth;
      }
   }

   int Buffer::getAnchorY(enum Anchor anchor, int smallerHeight, int biggerHeight) {
      switch(anchor) {
         case NORTHWEST:
         case NORTH:
         case NORTHEAST:
            return 0;
         case WEST:
         case CENTER:
         case EAST:
            return biggerHeight/2 - smallerHeight/2;
         case SOUTHWEST:
         case SOUTH:
         case SOUTHEAST:
            return biggerHeight - smallerHeight;
      }
   }

   void Buffer::nearestNeighborInterp(float const * bufferIn,
         int widthIn,   int heightIn,  int numBands,
         int xStrideIn, int yStrideIn, int bandStrideIn,
         float * bufferOut,
         int widthOut,  int heightOut) {

      /* Interpolation using nearest neighbor interpolation */
      int xinteger[widthOut];
      float dx = (float) (widthIn-1)/(float) (widthOut-1);

      for (int kx=0; kx<widthOut; kx++) {
         float x = dx * (float) kx;
         xinteger[kx] = (int) nearbyintf(x);
      }

      int yinteger[heightOut];
      float dy = (float) (heightIn-1)/(float) (heightOut-1);

      for (int ky=0; ky<heightOut; ky++) {
         float y = dy * (float) ky;
         yinteger[ky] = (int) nearbyintf(y);
      }

      for (int ky=0; ky<heightOut; ky++) {
         float yfetch = yinteger[ky];
         for (int kx=0; kx<widthOut; kx++) {
            int xfetch = xinteger[kx];
            for (int f=0; f<numBands; f++) {
               int fetchIdx = yfetch * yStrideIn + xfetch * xStrideIn + f * bandStrideIn;
               int outputIdx = kIndex(kx, ky, f, widthOut, heightOut, numBands);
               bufferOut[outputIdx] = bufferIn[fetchIdx];
            }
         }
      }
   }

   void Buffer::bicubicInterp(float const * bufferIn,
         int widthIn,   int heightIn,  int numBands,
         int xStrideIn, int yStrideIn, int bandStrideIn,
         float * bufferOut,
         int widthOut,  int heightOut) {

      /* Interpolation using bicubic convolution with a=-1 (following Octave image toolbox's imremap function -- change this?). */
      float xinterp[widthOut];
      int xinteger[widthOut];
      float xfrac[widthOut];
      float dx = (float) (widthIn-1)/(float) (widthOut-1);

      for (int kx=0; kx<widthOut; kx++) {
         float x = dx * (float) kx;
         xinterp[kx] = x;
         float xfloor = floorf(x);
         xinteger[kx] = (int) xfloor;
         xfrac[kx] = x-xfloor;
      }

      float yinterp[heightOut];
      int yinteger[heightOut];
      float yfrac[heightOut];
      float dy = (float) (heightIn-1)/(float) (heightOut-1);

      for (int ky=0; ky<heightOut; ky++) {
         float y = dy * (float) ky;
         yinterp[ky] = y;
         float yfloor = floorf(y);
         yinteger[ky] = (int) yfloor;
         yfrac[ky] = y-yfloor;
      }

      memset(bufferOut, 0, sizeof(*bufferOut)*size_t(widthOut*heightOut*numBands));

      for (int xOff = 2; xOff > -2; xOff--) {
         for (int yOff = 2; yOff > -2; yOff--) {
            for (int ky=0; ky<heightOut; ky++) {
               float ycoeff = bicubic(yfrac[ky]-(float) yOff);
               int yfetch = yinteger[ky]+yOff;

               if (yfetch < 0) yfetch = -yfetch;
               if (yfetch >= heightIn) yfetch = heightIn - (yfetch - heightIn) - 1;

               for (int kx=0; kx<widthOut; kx++) {
                  float xcoeff = bicubic(xfrac[kx]-(float) xOff);
                  int xfetch = xinteger[kx]+xOff;

                  if (xfetch < 0) xfetch = -xfetch;
                  if (xfetch >= widthIn) xfetch = widthIn - (xfetch - widthIn) - 1;

                  assert(xfetch >= 0 && xfetch < widthIn && yfetch >= 0 && yfetch < heightIn);

                  for (int f=0; f<numBands; f++) {
                     int fetchIdx = yfetch * yStrideIn + xfetch * xStrideIn + f * bandStrideIn;
                     float p = bufferIn[fetchIdx];
                     int outputIdx = kIndex(kx, ky, f, widthOut, heightOut, numBands);
                     bufferOut[outputIdx] += xcoeff * ycoeff * p;
                  }
               }
            }
         }
      }
   }
}
<commit_msg>Hotfix: Fixed typo in Buffer.cpp<commit_after>#include "Buffer.hpp"
#include "conversions.h"
#include "PVLog.hpp"

#include <cstring>
#include <cmath>

namespace PV {

   Buffer::Buffer(int width, int height, int features) {
      resize(width, height, features);
   }

   Buffer::Buffer() {
      resize(1,1,1);
   }

   Buffer::Buffer(const std::vector<float> &data, int width, int height, int features) {
      set(data, width, height, features);
   }

   float Buffer::at(int x, int y, int feature) {
      return mData.at(index(x, y, feature));
   }

   void Buffer::set(int x, int y, int feature, float value) {
      mData.at(index(x, y, feature)) = value;
   }

   void Buffer::set(const std::vector<float> &vector, int width, int height, int features) {
      pvErrorIf(vector.size() != width * height * features,
         "Invalid vector size: Expected %d elements, vector contained %d elements.\n",
         width * height * features, vector.size());
      mData = vector;
      mWidth = width;
      mHeight = height;
      mFeatures = features;
   }

   // Resizing a Buffer will clear its contents. Use rescale, crop, or grow to preserve values.
   void Buffer::resize(int width, int height, int features) {
      mData.clear();
      mData.resize(height * width * features, 0.0f);
      mWidth = width;
      mHeight = height;
      mFeatures = features;
   }

      // Grows a buffer
   void Buffer::grow(int newWidth, int newHeight, enum Anchor anchor) {
      if(newWidth < getWidth() && newHeight < getHeight()) {
         return;
      }
      int offsetX = getAnchorX(anchor, getWidth(),  newWidth);
      int offsetY = getAnchorY(anchor, getHeight(), newHeight);
      Buffer bigger(newWidth, newHeight, getFeatures());

      for(int y = 0; y < getHeight(); ++y) {
         for(int x = 0; x < getWidth(); ++x) {
            for(int f = 0; f < getFeatures(); ++f) {
               int destX = x + offsetX;
               int destY = y + offsetY;
               if(destX < 0 || destX >= newWidth)  continue;
               if(destY < 0 || destY >= newHeight) continue;
               bigger.set(destX, destY, f, at(x, y, f));
            }
         }
      }
      set(bigger.asVector(), newWidth, newHeight, getFeatures());
   }

   // Crops a buffer down to the specified size
   void Buffer::crop(int newWidth, int newHeight, enum Anchor anchor) {
      if(newWidth >= getWidth() && newHeight >= getHeight()) {
         return;
      }
      int offsetX = getAnchorX(anchor, newWidth,  getWidth());
      int offsetY = getAnchorY(anchor, newHeight, getHeight());
      Buffer cropped(newWidth, newHeight, getFeatures());

      for(int destY = 0; destY < newHeight; ++destY) {
         for(int destX = 0; destX < newWidth; ++destX) {
            for(int f = 0; f < getFeatures(); ++f) {
               int sourceX = destX + offsetX;
               int sourceY = destY + offsetY;
               if(sourceX < 0 || sourceX >= getWidth())  continue;
               if(sourceY < 0 || sourceY >= getHeight()) continue;
               cropped.set(destX, destY, f, at(sourceX, sourceY, f));
            }
         }
      }
      set(cropped.asVector(), newWidth, newHeight, getFeatures());
   }

   // Rescale a buffer, preserving aspect ratio
   void Buffer::rescale(int newWidth, int newHeight,
         enum RescaleMethod rescaleMethod,
         enum InterpolationMethod interpMethod,
         enum Anchor anchor) {
      float xRatio = static_cast<float>(newWidth)  / getWidth();
      float yRatio = static_cast<float>(newHeight) / getHeight();
      int resizedWidth = newWidth;
      int resizedHeight = newHeight;
      float resizeFactor = 1.0f;

      switch(rescaleMethod) {
         case CROP:
            resizeFactor = xRatio < yRatio ? yRatio : xRatio;
            break;
         case PAD:
            resizeFactor = xRatio < yRatio ? xRatio : yRatio;
            break;
      }

      resizedWidth   = static_cast<int>(nearbyintf(resizeFactor * getWidth()));
      resizedHeight  = static_cast<int>(nearbyintf(resizeFactor * getHeight()));

      std::vector<float> rawInput = asVector();
      std::vector<float> scaledInput(resizedWidth * resizedHeight * getFeatures());
      switch(interpMethod) {
         case BICUBIC:
            bicubicInterp(rawInput.data(),                        // Input data
                  getWidth(),    getHeight(), getFeatures(),      // Input dimensions
                  getFeatures(), getFeatures() * getWidth(), 1,   // Strides
                  scaledInput.data(),                             // Output data
                  resizedWidth,  resizedHeight);                  // Target dimensions
            break;
         case NEAREST:
            nearestNeighborInterp(rawInput.data(),                // Input data
                  getWidth(),    getHeight(), getFeatures(),      // Input dimensions
                  getFeatures(), getFeatures() * getWidth(), 1,   // Strides
                  scaledInput.data(),                             // Output data
                  resizedWidth,  resizedHeight);                  // Target dimensions
            break;
      }
      set(scaledInput, resizedWidth, resizedHeight, getFeatures());

      // This final call resizes the buffer to our specified
      // newWidth and newHeight. If our rescaleMethod was PAD,
      // this actually grows the buffer to include the padded region.
      switch(rescaleMethod) {
         case CROP:
            crop(newWidth, newHeight, anchor);
            break;
         case PAD:
            grow(newWidth, newHeight, anchor);
            break;
      }
   }

   // Shift a buffer, clipping any values that land out of bounds
   void Buffer::translate(int xShift, int yShift) {
      Buffer result(getWidth(), getHeight(), getFeatures());
      for(int y = 0; y < getHeight(); ++y) {
         for(int x = 0; x < getWidth(); ++x) {
            for(int f = 0; f < getFeatures(); ++f) {
               int destX = x + xShift;
               int destY = y + yShift;
               if(destX < 0 || destX >= getWidth())  continue;
               if(destY < 0 || destY >= getHeight()) continue;
               result.set(destX, destY, f, at(x, y, f));
            }
         }
      }
      set(result.asVector(), getWidth(), getHeight(), getFeatures());
   }

   int Buffer::getAnchorX(enum Anchor anchor, int smallerWidth, int biggerWidth) {
      switch(anchor) {
         case NORTHWEST:
         case WEST:
         case SOUTHWEST:
            return 0;
         case NORTH:
         case CENTER:
         case SOUTH:
            return biggerWidth/2 - smallerWidth/2;
         case NORTHEAST:
         case EAST:
         case SOUTHEAST:
            return biggerWidth - smallerWidth;
      }
   }

   int Buffer::getAnchorY(enum Anchor anchor, int smallerHeight, int biggerHeight) {
      switch(anchor) {
         case NORTHWEST:
         case NORTH:
         case NORTHEAST:
            return 0;
         case WEST:
         case CENTER:
         case EAST:
            return biggerHeight/2 - smallerHeight/2;
         case SOUTHWEST:
         case SOUTH:
         case SOUTHEAST:
            return biggerHeight - smallerHeight;
      }
   }

   void Buffer::nearestNeighborInterp(float const * bufferIn,
         int widthIn,   int heightIn,  int numBands,
         int xStrideIn, int yStrideIn, int bandStrideIn,
         float * bufferOut,
         int widthOut,  int heightOut) {

      /* Interpolation using nearest neighbor interpolation */
      int xinteger[widthOut];
      float dx = (float) (widthIn-1)/(float) (widthOut-1);

      for (int kx=0; kx<widthOut; kx++) {
         float x = dx * (float) kx;
         xinteger[kx] = (int) nearbyintf(x);
      }

      int yinteger[heightOut];
      float dy = (float) (heightIn-1)/(float) (heightOut-1);

      for (int ky=0; ky<heightOut; ky++) {
         float y = dy * (float) ky;
         yinteger[ky] = (int) nearbyintf(y);
      }

      for (int ky=0; ky<heightOut; ky++) {
         float yfetch = yinteger[ky];
         for (int kx=0; kx<widthOut; kx++) {
            int xfetch = xinteger[kx];
            for (int f=0; f<numBands; f++) {
               int fetchIdx = yfetch * yStrideIn + xfetch * xStrideIn + f * bandStrideIn;
               int outputIdx = kIndex(kx, ky, f, widthOut, heightOut, numBands);
               bufferOut[outputIdx] = bufferIn[fetchIdx];
            }
         }
      }
   }

   void Buffer::bicubicInterp(float const * bufferIn,
         int widthIn,   int heightIn,  int numBands,
         int xStrideIn, int yStrideIn, int bandStrideIn,
         float * bufferOut,
         int widthOut,  int heightOut) {

      /* Interpolation using bicubic convolution with a=-1 (following Octave image toolbox's imremap function -- change this?). */
      float xinterp[widthOut];
      int xinteger[widthOut];
      float xfrac[widthOut];
      float dx = (float) (widthIn-1)/(float) (widthOut-1);

      for (int kx=0; kx<widthOut; kx++) {
         float x = dx * (float) kx;
         xinterp[kx] = x;
         float xfloor = floorf(x);
         xinteger[kx] = (int) xfloor;
         xfrac[kx] = x-xfloor;
      }

      float yinterp[heightOut];
      int yinteger[heightOut];
      float yfrac[heightOut];
      float dy = (float) (heightIn-1)/(float) (heightOut-1);

      for (int ky=0; ky<heightOut; ky++) {
         float y = dy * (float) ky;
         yinterp[ky] = y;
         float yfloor = floorf(y);
         yinteger[ky] = (int) yfloor;
         yfrac[ky] = y-yfloor;
      }

      memset(bufferOut, 0, sizeof(*bufferOut)*size_t(widthOut*heightOut*numBands));

      for (int xOff = 2; xOff > -2; xOff--) {
         for (int yOff = 2; yOff > -2; yOff--) {
            for (int ky=0; ky<heightOut; ky++) {
               float ycoeff = bicubic(yfrac[ky]-(float) yOff);
               int yfetch = yinteger[ky]+yOff;

               if (yfetch < 0) yfetch = -yfetch;
               if (yfetch >= heightIn) yfetch = heightIn - (yfetch - heightIn) - 1;

               for (int kx=0; kx<widthOut; kx++) {
                  float xcoeff = bicubic(xfrac[kx]-(float) xOff);
                  int xfetch = xinteger[kx]+xOff;

                  if (xfetch < 0) xfetch = -xfetch;
                  if (xfetch >= widthIn) xfetch = widthIn - (xfetch - widthIn) - 1;

                  assert(xfetch >= 0 && xfetch < widthIn && yfetch >= 0 && yfetch < heightIn);

                  for (int f=0; f<numBands; f++) {
                     int fetchIdx = yfetch * yStrideIn + xfetch * xStrideIn + f * bandStrideIn;
                     float p = bufferIn[fetchIdx];
                     int outputIdx = kIndex(kx, ky, f, widthOut, heightOut, numBands);
                     bufferOut[outputIdx] += xcoeff * ycoeff * p;
                  }
               }
            }
         }
      }
   }
}
<|endoftext|>


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

#include "RequestSystem.h"
#include "Fass.h"

void SystemVersion::request_execute(xmlrpc_c::paramList const& paramList,
                                 RequestAttributes& att)
{
    /** Request_execute will not be executed if the session string
     * is not authenticated in Request::execute.
     * TODO: should we make the version call accessible even
     * if no user is provided? */

    success_response(Fass::instance().version(), att);

    return;
}

<commit_msg>Update RequestSystem.cc<commit_after>/**
 * Copyright © 2017 INFN Torino - INDIGO-DataCloud
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "RequestSystem.h"
#include "Fass.h"

void SystemVersion::request_execute(xmlrpc_c::paramList const& paramList,
                                 RequestAttributes& att){

    /** Request_execute will not be executed if the session string
     * is not authenticated in Request::execute.
     * TODO: should we make the version call accessible even
     * if no user is provided? */

    success_response(Fass::instance().version(), att);

    return;
}

<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** rtspaudiocapturer.cpp
**
** -------------------------------------------------------------------------*/

#ifdef HAVE_LIVE555

#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#endif

#include "rtc_base/logging.h"
#include "rtc_base/ref_counted_object.h"

#include "rtspaudiocapturer.h"

RTSPAudioSource::RTSPAudioSource(rtc::scoped_refptr<webrtc::AudioDecoderFactory> audioDecoderFactory, const std::string & uri, const std::map<std::string,std::string> & opts)
				: m_connection(m_env, this, uri.c_str()
					, RTSPConnection::decodeTimeoutOption(opts)
					, RTSPConnection::decodeRTPTransport(opts)
					, rtc::LogMessage::GetLogToDebug()<=2)
				, m_factory(audioDecoderFactory), m_freq(8000), m_channel(1) {
//	SetName("RTSPAudioSource", NULL);
	m_capturethread = std::thread(&RTSPAudioSource::CaptureThread, this);
}

RTSPAudioSource::~RTSPAudioSource()  {
	m_env.stop();
	m_capturethread.join();
}

// overide RTSPConnection::Callback
bool RTSPAudioSource::onNewSession(const char* id, const char* media, const char* codec, const char* sdp) {

	bool success = false;
	if (strcmp(media, "audio") == 0) {
		RTC_LOG(INFO) << "RTSPAudioSource::onNewSession " << media << "/" << codec << " " << sdp;

		// parse sdp to extract freq and channel
		std::string fmt(sdp);
		size_t pos = fmt.find(codec);
		if (pos != std::string::npos) {
			fmt.erase(0, pos+strlen(codec));
			fmt.erase(fmt.find_first_of(" \r\n"));
			std::istringstream is (fmt);
			std::string dummy;
			std::getline(is, dummy, '/');
			std::string freq;
			std::getline(is, freq, '/');
			if (!freq.empty()) {
				m_freq = std::stoi(freq);
			}
			std::string channel;
			std::getline(is, channel, '/');
			if (!channel.empty()) {
				m_channel = std::stoi(channel);
			}
		}
		RTC_LOG(INFO) << "RTSPAudioSource::onNewSession freq:" << m_freq << " channel:" << m_channel;

		if (strcmp(codec, "PCMU") == 0)
		{
			m_decoder = m_factory->MakeAudioDecoder(webrtc::SdpAudioFormat(codec, m_freq, m_channel),absl::optional<webrtc::AudioCodecPairId>());
			success = true;
		}
		else if (strcmp(codec, "OPUS") == 0)
		{
			m_decoder = m_factory->MakeAudioDecoder(webrtc::SdpAudioFormat(codec, m_freq, m_channel),absl::optional<webrtc::AudioCodecPairId>());
			success = true;
		}
		else if (strcmp(codec, "L16") == 0)
		{
			m_decoder = m_factory->MakeAudioDecoder(webrtc::SdpAudioFormat(codec, m_freq, m_channel),absl::optional<webrtc::AudioCodecPairId>());
			success = true;
		}
	}
	return success;
}

bool RTSPAudioSource::onData(const char* id, unsigned char* buffer, ssize_t size, struct timeval presentationTime) {
	bool success = false;
	int segmentLength = m_freq/100;
	if (m_decoder.get() != NULL) {
		int16_t* decoded = new int16_t[size];
		webrtc::AudioDecoder::SpeechType speech_type;
		int res = m_decoder->Decode(buffer, size, m_freq, size*sizeof(int16_t), decoded, &speech_type);
		RTC_LOG(LS_VERBOSE) << "RTSPAudioSource::onData size:" << size << " decoded:" << res;
		if (res > 0) {
			for (int i = 0 ; i < res*m_channel; ++i) {
				m_buffer.push(decoded[i]);
			}
		} else {
			RTC_LOG(LS_ERROR) << "RTSPAudioSource::onData error:Decode Audio failed";
		}
		delete [] decoded;
		while (m_buffer.size() > segmentLength*m_channel) {
			int16_t* outbuffer = new int16_t[segmentLength*m_channel];
			for (int i=0; i<segmentLength*m_channel; ++i) {
				uint16_t value = m_buffer.front();
				outbuffer[i] = value;
				m_buffer.pop();
			}
			std::lock_guard<std::mutex> lock(m_sink_lock);
			for (auto* sink : m_sinks) {
				sink->OnData(outbuffer, 16, m_freq, m_channel, segmentLength);
			}
			delete [] outbuffer;
		}
		success = true;
	} else {
		RTC_LOG(LS_ERROR) << "RTSPAudioSource::onData error:No Audio decoder";
	}
	return success;
}

#endif
<commit_msg>fix OPUS audio decode error<commit_after>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** rtspaudiocapturer.cpp
**
** -------------------------------------------------------------------------*/

#ifdef HAVE_LIVE555

#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#endif

#include "rtc_base/logging.h"
#include "rtc_base/ref_counted_object.h"

#include "rtspaudiocapturer.h"

RTSPAudioSource::RTSPAudioSource(rtc::scoped_refptr<webrtc::AudioDecoderFactory> audioDecoderFactory, const std::string & uri, const std::map<std::string,std::string> & opts)
				: m_connection(m_env, this, uri.c_str()
					, RTSPConnection::decodeTimeoutOption(opts)
					, RTSPConnection::decodeRTPTransport(opts)
					, rtc::LogMessage::GetLogToDebug()<=2)
				, m_factory(audioDecoderFactory), m_freq(8000), m_channel(1) {
//	SetName("RTSPAudioSource", NULL);
	m_capturethread = std::thread(&RTSPAudioSource::CaptureThread, this);
}

RTSPAudioSource::~RTSPAudioSource()  {
	m_env.stop();
	m_capturethread.join();
}

// overide RTSPConnection::Callback
bool RTSPAudioSource::onNewSession(const char* id, const char* media, const char* codec, const char* sdp) {

	bool success = false;
	if (strcmp(media, "audio") == 0) {
		RTC_LOG(INFO) << "RTSPAudioSource::onNewSession " << media << "/" << codec << " " << sdp;

		std::string sdp_codec(codec);
		if (strcmp(codec, "PCMU") == 0 || strcmp(codec, "L16") == 0)
		{
			success = true;
		}
		else if (strcmp(codec, "OPUS") == 0)
		{
			sdp_codec = "opus";
			success = true;
		}
		else
		{
			RTC_LOG(LS_ERROR) << "RTSPAudioSource::onNewSession not support codec" << sdp;
			return success;
		}
		// parse sdp to extract freq and channel
		std::string fmt(sdp);
		size_t pos = fmt.find(sdp_codec);
		if (pos != std::string::npos) {
			fmt.erase(0, pos+strlen(codec));
			fmt.erase(fmt.find_first_of(" \r\n"));
			std::istringstream is (fmt);
			std::string dummy;
			std::getline(is, dummy, '/');
			std::string freq;
			std::getline(is, freq, '/');
			if (!freq.empty()) {
				m_freq = std::stoi(freq);
			}
			std::string channel;
			std::getline(is, channel, '/');
			if (!channel.empty()) {
				m_channel = std::stoi(channel);
			}
		}
		RTC_LOG(INFO) << "RTSPAudioSource::onNewSession freq:" << m_freq << " channel:" << m_channel;

		m_decoder = m_factory->MakeAudioDecoder(webrtc::SdpAudioFormat(codec, m_freq, m_channel),absl::optional<webrtc::AudioCodecPairId>());
		if(m_decoder.get() == NULL)
		{
			RTC_LOG(LS_ERROR) << "RTSPAudioSource::onNewSession No Audio decoder " << sdp;
			success = false;
		}

	}
	return success;
}

bool RTSPAudioSource::onData(const char* id, unsigned char* buffer, ssize_t size, struct timeval presentationTime) {
	bool success = false;
	int segmentLength = m_freq/100;
	if (m_decoder.get() != NULL) {
		int16_t* decoded = new int16_t[size];
		webrtc::AudioDecoder::SpeechType speech_type;
		int res = m_decoder->Decode(buffer, size, m_freq, size*sizeof(int16_t), decoded, &speech_type);
		RTC_LOG(LS_VERBOSE) << "RTSPAudioSource::onData size:" << size << " decoded:" << res;
		if (res > 0) {
			for (int i = 0 ; i < res*m_channel; ++i) {
				m_buffer.push(decoded[i]);
			}
		} else {
			RTC_LOG(LS_ERROR) << "RTSPAudioSource::onData error:Decode Audio failed";
		}
		delete [] decoded;
		while (m_buffer.size() > segmentLength*m_channel) {
			int16_t* outbuffer = new int16_t[segmentLength*m_channel];
			for (int i=0; i<segmentLength*m_channel; ++i) {
				uint16_t value = m_buffer.front();
				outbuffer[i] = value;
				m_buffer.pop();
			}
			std::lock_guard<std::mutex> lock(m_sink_lock);
			for (auto* sink : m_sinks) {
				sink->OnData(outbuffer, 16, m_freq, m_channel, segmentLength);
			}
			delete [] outbuffer;
		}
		success = true;
	} else {
		RTC_LOG(LS_ERROR) << "RTSPAudioSource::onData error:No Audio decoder";
	}
	return success;
}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/**
 ** \file runner/interpreter.cc
 ** \brief Implementation of runner::Interpreter.
 */

// #define ENABLE_DEBUG_TRACES

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

#include <libport/config.h>
#include <libport/echo.hh>
#include <libport/finally.hh>
#include <libport/foreach.hh>
#include <libport/format.hh>
#include <libport/lexical-cast.hh>
#include <libport/symbol.hh>

#include <ast/call.hh>
#include <ast/exp.hh>

#include <kernel/uconnection.hh>

#include <object/symbols.hh>
#include <object/urbi-exception.hh>
#include <object/system.hh>

#include <parser/uparser.hh>

#include <runner/interpreter.hh>
#include <urbi/runner/raise.hh>

#include <sched/exception.hh>

#include <urbi/object/cxx-conversions.hh>
#include <urbi/object/global.hh>
#include <urbi/object/lobby.hh>
#include <urbi/object/location.hh>
#include <urbi/object/job.hh>

// If not in speed mode, compile visit methods here.
#ifndef LIBPORT_COMPILATION_MODE_SPEED
# include <runner/interpreter-visit.hxx>
#else
GD_ADD_CATEGORY(Urbi);
#endif

namespace runner
{
  using libport::Finally;

  // This function takes an expression and attempts to decompose it
  // into a list of identifiers. The resulting chain is stored in
  // reverse order, that is the most specific tag first.
  typedef std::vector<libport::Symbol> tag_chain_type;
  static
  tag_chain_type
  decompose_tag_chain (ast::rConstExp e)
  {
    tag_chain_type res;
    while (!e->implicit())
    {
      ast::rConstCall c = e.unsafe_cast<const ast::Call>();
      if (!c || c->arguments_get())
	runner::raise_urbi(SYMBOL(ImplicitTagComponent));
      res.push_back (c->name_get());
      e = c->target_get();
    }
    return res;
  }

  /*--------------.
  | Interpreter.  |
  `--------------*/

  Interpreter::Interpreter(rLobby lobby,
                           sched::Scheduler& sched,
                           ast::rConstAst ast,
                           libport::Symbol name)
    : Runner(lobby, sched, name)
    , ast_(ast)
    , code_(0)
    , result_(0)
    , stacks_(lobby)
  {
    init();
    apply_tag(lobby->tag_get());
  }

  Interpreter::Interpreter(rLobby lobby,
                           sched::Scheduler& sched,
                           rObject code,
                           libport::Symbol name,
                           rObject self,
                           const objects_type& args)
    : Runner(lobby, sched, name)
    , ast_(0)
    , code_(code)
    , this_(self)
    , args_(args)
    , result_(0)
    , stacks_(lobby)
  {
    init();
    apply_tag(lobby->tag_get());
  }

  Interpreter::Interpreter(const Interpreter& model, rObject code,
			   libport::Symbol name,
                           const objects_type& args)
    : Runner(model, name)
    , ast_(0)
    , code_(code)
    , args_(args)
    , result_(0)
    , call_stack_(model.call_stack_)
    , stacks_(model.lobby_)
  {
    tag_stack_set(model.tag_stack_get_all());
    init();
  }

  Interpreter::Interpreter(const Interpreter& model,
			   ast::rConstAst ast,
			   libport::Symbol name)
    : Runner(model, name)
    , ast_(ast)
    , code_(0)
    , result_(0)
    , call_stack_(model.call_stack_)
    , stacks_(model.lobby_)
  {
    tag_stack_set(model.tag_stack_get_all());
    init();
  }

  Interpreter::Interpreter(rLobby lobby,
                           sched::Scheduler& sched,
                           boost::function0<void> job,
                           rObject self,
                           libport::Symbol name)
    : Runner(lobby, sched, name)
    , ast_(0)
    , code_(0)
    , job_(job)
    , result_(0)
    , stacks_(self)
  {
    GD_CATEGORY(Urbi);
    GD_FINFO_TRACE("Spawn new interpreter \"%s\".", name);
    init();
    apply_tag(lobby->tag_get());
  }

  Interpreter::~Interpreter()
  {
  }

  void
  Interpreter::init()
  {
    // Push a dummy scope tag, in case we do have an "at" at the
    // toplevel.
    create_scope_tag();
  }

  void
  Interpreter::show_exception(object::UrbiException& ue)
  {
    CAPTURE_GLOBAL(Exception);

    // FIXME: should bounce in all case to Exception.'$show'.
    if (is_a(ue.value_get(), Exception))
      ue.value_get()->call(SYMBOL(DOLLAR_show));
    else
    {
      send_message("error",
                   libport::format("!!! %s",
                                   (ue.value_get()
                                    ->call(SYMBOL(asString))
                                    ->as<object::String>()
                                    ->value_get())));
      show_backtrace(ue.backtrace_get(), "error");
    }
  }

  void
  Interpreter::work()
  {
    try
    {
      aver(ast_ || code_ || job_);
      check_for_pending_exception();
      if (ast_)
	result_ = operator()(ast_.get());
      else if (code_)
      {
        libport::push_front(args_, this_ ? this_ : rObject(lobby_));
	result_ = apply(code_, libport::Symbol::make_empty(), args_);
      }
      else
        job_();
    }
    catch (object::UrbiException& exn)
    {
      // If this runner has a parent, let the exception go through
      // so that it will be handled by Job::run().
      if (child_job())
	throw;
      else
      // This is a detached runner, show the error.
      {
        // Yielding inside a catch is forbidden.
        Finally finally(boost::bind(&Runner::non_interruptible_set,
                                    this, non_interruptible_get()));
        non_interruptible_set(true);
        show_exception(exn);
      }
    }
  }

  void
  Interpreter::scheduling_error(const std::string& msg)
  {
    // We may have a situation here. If the stack space is running
    // near exhaustion, we cannot reasonably hope that we will get
    // enough stack space to build an exception, which potentially
    // requires a non-negligible amount of calls. For this reason, we
    // create another job whose job is to build the exception (in a
    // freshly allocated stack) and propagate it to us as we are its
    // parent.
    //
    // Yet, if the user asked for non-interruptible mode, we do not
    // want to fire a new Runner...

    // The user requested non-interruptible mode for a reason, honor
    // it and try to throw in this job.
    if (non_interruptible_get())
      raise_scheduling_error(msg);

    CAPTURE_GLOBAL2(Exception, Scheduling);
    object::objects_type args;
    args << object::to_urbi(msg);
    sched::rJob child =
      new Interpreter(*this,
                      Scheduling->slot_get(SYMBOL(throwNew)),
                      SYMBOL(Scheduling),
                      args);
    sched::Job::Collector collector(this);
    register_child(child, collector);
    child->start_job();

    try
    {
      yield_until_terminated(*child);
    }
    catch (const sched::ChildException& ce)
    {
      try
      {
	ce.rethrow_child_exception();
      }
      catch (const object::UrbiException& ue)
      {
	raise(ue.value_get(), false);
      }
    }
  }

  object::rObject
  Interpreter::eval_tag(ast::rConstExp e)
  {
    try
    {
      // Try to evaluate e as a normal expression.
      return operator()(e.get());
    }
    catch (object::UrbiException&)
    {
      LIBPORT_DEBUG("Implicit tag: " << *e);
      // We got a lookup error. It means that we have to automatically
      // create the tag. In this case, we only accept k1 style tags,
      // i.e. chains of identifiers, excluding function calls.
      // The reason to do that is:
      //   - we do not want to mix k1 non-declared syntax with k2
      //     clean syntax for tags
      //   - we have no way to know whether the lookup error arrived
      //     in a function call or during the direct resolution of
      //     the name.

      // `Tag.tags' represents the top level tag.
      CAPTURE_GLOBAL2(Tag, tags);
      rObject parent = tags;
      rObject where = stacks_.this_get();
      tag_chain_type chain = decompose_tag_chain(e);
      rforeach (libport::Symbol elt, chain)
      {
	// Check whether the concerned level in the chain already
	// exists.
	if (rObject owner = where->slot_locate(elt).first)
        {
          LIBPORT_DEBUG("Component " << elt << " exists.");
	  where = owner->local_slot_get(elt)->value();
	  if (object::Tag* parent_ = dynamic_cast<object::Tag*>(where.get()))
	  {
            LIBPORT_DEBUG("It is a tag, so use it as the new parent.");
	    parent = parent_;
	  }
        }
	else
	{
	  // We have to create a new tag, which will be attached
	  // to the upper level (hierarchical tags, implicitly
	  // rooted by Tags).
	  where = parent->call(SYMBOL(new), new object::String(elt));
	  parent->slot_set(elt, where);
	  parent = where;
	}
      }

      return where;
    }
  }

  void
  Interpreter::show_backtrace(const call_stack_type& bt,
                              const std::string& chan)
  {
    rforeach (const call_type& c, bt)
      send_message(chan,
                   libport::format("!!!    called from: %s", c));
  }

  void
  Interpreter::show_backtrace(const std::string& chan)
  {
    show_backtrace(call_stack_, chan);
  }

  Interpreter::backtrace_type
  Interpreter::backtrace_get() const
  {
    CAPTURE_GLOBAL(StackFrame);
    backtrace_type res;
    /* We need to create StackFrame objects while iterating, which will modify
     * the call stack, so make a copy.
     */
    call_stack_type copy = call_stack_;
    foreach (call_type c, copy)
    {
      rObject loc = object::nil_class;
      if (c.second)
        loc = new object::Location(c.second.get());
      rObject frame =
        StackFrame->call("new", new object::String(c.first.name_get()), loc);
      res << frame_type(frame);
    }
    return res;
  }

  object::call_stack_type
  Interpreter::call_stack_get() const
  {
    return call_stack_;
  }

  void
  Interpreter::raise(rObject exn, bool skip_last)
  {
    CAPTURE_GLOBAL(Exception);

    // innermost_node_ can be empty if the interpreter has not interpreted
    // any urbiscript.  E.g., slot_set can raise an exception only from the
    // C++ side.  It would be better to produce a C++ backtrace instead.
    if (is_a(exn, Exception) && innermost_node_)
    {
      boost::optional<ast::loc> l = innermost_node_->location_get();
      exn->slot_update(SYMBOL(DOLLAR_location), object::to_urbi(l));
      exn->slot_update(SYMBOL(DOLLAR_backtrace),
                       as_job()->as<object::Job>()->backtrace());
    }
    call_stack_type bt = call_stack_get();
    if (skip_last && !bt.empty())
      bt.pop_back();
    throw object::UrbiException(exn, bt);
  }

} // namespace runner
<commit_msg>Style changes.<commit_after>/*
 * Copyright (C) 2008-2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/**
 ** \file runner/interpreter.cc
 ** \brief Implementation of runner::Interpreter.
 */

// #define ENABLE_DEBUG_TRACES

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

#include <libport/config.h>
#include <libport/echo.hh>
#include <libport/finally.hh>
#include <libport/foreach.hh>
#include <libport/format.hh>
#include <libport/lexical-cast.hh>
#include <libport/symbol.hh>

#include <ast/call.hh>
#include <ast/exp.hh>

#include <kernel/uconnection.hh>

#include <object/symbols.hh>
#include <object/urbi-exception.hh>
#include <object/system.hh>

#include <parser/uparser.hh>

#include <runner/interpreter.hh>
#include <urbi/runner/raise.hh>

#include <sched/exception.hh>

#include <urbi/object/cxx-conversions.hh>
#include <urbi/object/global.hh>
#include <urbi/object/lobby.hh>
#include <urbi/object/location.hh>
#include <urbi/object/job.hh>

// If not in speed mode, compile visit methods here.
#ifndef LIBPORT_COMPILATION_MODE_SPEED
# include <runner/interpreter-visit.hxx>
#else
GD_ADD_CATEGORY(Urbi);
#endif

namespace runner
{
  using libport::Finally;

  // This function takes an expression and attempts to decompose it
  // into a list of identifiers. The resulting chain is stored in
  // reverse order, that is the most specific tag first.
  typedef std::vector<libport::Symbol> tag_chain_type;
  static
  tag_chain_type
  decompose_tag_chain(ast::rConstExp e)
  {
    tag_chain_type res;
    while (!e->implicit())
    {
      ast::rConstCall c = e.unsafe_cast<const ast::Call>();
      if (!c || c->arguments_get())
	runner::raise_urbi(SYMBOL(ImplicitTagComponent));
      res << c->name_get();
      e = c->target_get();
    }
    return res;
  }

  /*--------------.
  | Interpreter.  |
  `--------------*/

  Interpreter::Interpreter(rLobby lobby,
                           sched::Scheduler& sched,
                           ast::rConstAst ast,
                           libport::Symbol name)
    : Runner(lobby, sched, name)
    , ast_(ast)
    , code_(0)
    , result_(0)
    , stacks_(lobby)
  {
    init();
    apply_tag(lobby->tag_get());
  }

  Interpreter::Interpreter(rLobby lobby,
                           sched::Scheduler& sched,
                           rObject code,
                           libport::Symbol name,
                           rObject self,
                           const objects_type& args)
    : Runner(lobby, sched, name)
    , ast_(0)
    , code_(code)
    , this_(self)
    , args_(args)
    , result_(0)
    , stacks_(lobby)
  {
    init();
    apply_tag(lobby->tag_get());
  }

  Interpreter::Interpreter(const Interpreter& model, rObject code,
			   libport::Symbol name,
                           const objects_type& args)
    : Runner(model, name)
    , ast_(0)
    , code_(code)
    , args_(args)
    , result_(0)
    , call_stack_(model.call_stack_)
    , stacks_(model.lobby_)
  {
    tag_stack_set(model.tag_stack_get_all());
    init();
  }

  Interpreter::Interpreter(const Interpreter& model,
			   ast::rConstAst ast,
			   libport::Symbol name)
    : Runner(model, name)
    , ast_(ast)
    , code_(0)
    , result_(0)
    , call_stack_(model.call_stack_)
    , stacks_(model.lobby_)
  {
    tag_stack_set(model.tag_stack_get_all());
    init();
  }

  Interpreter::Interpreter(rLobby lobby,
                           sched::Scheduler& sched,
                           boost::function0<void> job,
                           rObject self,
                           libport::Symbol name)
    : Runner(lobby, sched, name)
    , ast_(0)
    , code_(0)
    , job_(job)
    , result_(0)
    , stacks_(self)
  {
    GD_CATEGORY(Urbi);
    GD_FINFO_TRACE("Spawn new interpreter \"%s\".", name);
    init();
    apply_tag(lobby->tag_get());
  }

  Interpreter::~Interpreter()
  {
  }

  void
  Interpreter::init()
  {
    // Push a dummy scope tag, in case we do have an "at" at the
    // toplevel.
    create_scope_tag();
  }

  void
  Interpreter::show_exception(object::UrbiException& ue)
  {
    CAPTURE_GLOBAL(Exception);

    // FIXME: should bounce in all case to Exception.'$show'.
    if (is_a(ue.value_get(), Exception))
      ue.value_get()->call(SYMBOL(DOLLAR_show));
    else
    {
      send_message("error",
                   libport::format("!!! %s",
                                   (ue.value_get()
                                    ->call(SYMBOL(asString))
                                    ->as<object::String>()
                                    ->value_get())));
      show_backtrace(ue.backtrace_get(), "error");
    }
  }

  void
  Interpreter::work()
  {
    try
    {
      aver(ast_ || code_ || job_);
      check_for_pending_exception();
      if (ast_)
	result_ = operator()(ast_.get());
      else if (code_)
      {
        libport::push_front(args_, this_ ? this_ : rObject(lobby_));
	result_ = apply(code_, libport::Symbol::make_empty(), args_);
      }
      else
        job_();
    }
    catch (object::UrbiException& exn)
    {
      // If this runner has a parent, let the exception go through
      // so that it will be handled by Job::run().
      if (child_job())
	throw;
      else
      // This is a detached runner, show the error.
      {
        // Yielding inside a catch is forbidden.
        Finally finally(boost::bind(&Runner::non_interruptible_set,
                                    this, non_interruptible_get()));
        non_interruptible_set(true);
        show_exception(exn);
      }
    }
  }

  void
  Interpreter::scheduling_error(const std::string& msg)
  {
    // We may have a situation here. If the stack space is running
    // near exhaustion, we cannot reasonably hope that we will get
    // enough stack space to build an exception, which potentially
    // requires a non-negligible amount of calls. For this reason, we
    // create another job whose job is to build the exception (in a
    // freshly allocated stack) and propagate it to us as we are its
    // parent.
    //
    // Yet, if the user asked for non-interruptible mode, we do not
    // want to fire a new Runner...

    // The user requested non-interruptible mode for a reason, honor
    // it and try to throw in this job.
    if (non_interruptible_get())
      raise_scheduling_error(msg);

    CAPTURE_GLOBAL2(Exception, Scheduling);
    object::objects_type args;
    args << object::to_urbi(msg);
    sched::rJob child =
      new Interpreter(*this,
                      Scheduling->slot_get(SYMBOL(throwNew)),
                      SYMBOL(Scheduling),
                      args);
    sched::Job::Collector collector(this);
    register_child(child, collector);
    child->start_job();

    try
    {
      yield_until_terminated(*child);
    }
    catch (const sched::ChildException& ce)
    {
      try
      {
	ce.rethrow_child_exception();
      }
      catch (const object::UrbiException& ue)
      {
	raise(ue.value_get(), false);
      }
    }
  }

  object::rObject
  Interpreter::eval_tag(ast::rConstExp e)
  {
    try
    {
      // Try to evaluate e as a normal expression.
      return operator()(e.get());
    }
    catch (object::UrbiException&)
    {
      LIBPORT_DEBUG("Implicit tag: " << *e);
      // We got a lookup error. It means that we have to automatically
      // create the tag. In this case, we only accept k1 style tags,
      // i.e. chains of identifiers, excluding function calls.
      // The reason to do that is:
      //   - we do not want to mix k1 non-declared syntax with k2
      //     clean syntax for tags
      //   - we have no way to know whether the lookup error arrived
      //     in a function call or during the direct resolution of
      //     the name.

      // `Tag.tags' represents the top level tag.
      CAPTURE_GLOBAL2(Tag, tags);
      rObject parent = tags;
      rObject where = stacks_.this_get();
      tag_chain_type chain = decompose_tag_chain(e);
      rforeach (libport::Symbol elt, chain)
      {
	// Check whether the concerned level in the chain already
	// exists.
	if (rObject owner = where->slot_locate(elt).first)
        {
          LIBPORT_DEBUG("Component " << elt << " exists.");
	  where = owner->local_slot_get(elt)->value();
	  if (object::Tag* parent_ = dynamic_cast<object::Tag*>(where.get()))
	  {
            LIBPORT_DEBUG("It is a tag, so use it as the new parent.");
	    parent = parent_;
	  }
        }
	else
	{
	  // We have to create a new tag, which will be attached
	  // to the upper level (hierarchical tags, implicitly
	  // rooted by Tags).
	  where = parent->call(SYMBOL(new), new object::String(elt));
	  parent->slot_set(elt, where);
	  parent = where;
	}
      }

      return where;
    }
  }

  void
  Interpreter::show_backtrace(const call_stack_type& bt,
                              const std::string& chan)
  {
    rforeach (const call_type& c, bt)
      send_message(chan,
                   libport::format("!!!    called from: %s", c));
  }

  void
  Interpreter::show_backtrace(const std::string& chan)
  {
    show_backtrace(call_stack_, chan);
  }

  Interpreter::backtrace_type
  Interpreter::backtrace_get() const
  {
    CAPTURE_GLOBAL(StackFrame);
    backtrace_type res;
    /* We need to create StackFrame objects while iterating, which will modify
     * the call stack, so make a copy.
     */
    call_stack_type copy = call_stack_;
    foreach (call_type c, copy)
    {
      rObject loc = object::nil_class;
      if (c.second)
        loc = new object::Location(c.second.get());
      rObject frame =
        StackFrame->call("new", new object::String(c.first.name_get()), loc);
      res << frame_type(frame);
    }
    return res;
  }

  object::call_stack_type
  Interpreter::call_stack_get() const
  {
    return call_stack_;
  }

  void
  Interpreter::raise(rObject exn, bool skip_last)
  {
    CAPTURE_GLOBAL(Exception);

    // innermost_node_ can be empty if the interpreter has not interpreted
    // any urbiscript.  E.g., slot_set can raise an exception only from the
    // C++ side.  It would be better to produce a C++ backtrace instead.
    if (is_a(exn, Exception) && innermost_node_)
    {
      boost::optional<ast::loc> l = innermost_node_->location_get();
      exn->slot_update(SYMBOL(DOLLAR_location), object::to_urbi(l));
      exn->slot_update(SYMBOL(DOLLAR_backtrace),
                       as_job()->as<object::Job>()->backtrace());
    }
    call_stack_type bt = call_stack_get();
    if (skip_last && !bt.empty())
      bt.pop_back();
    throw object::UrbiException(exn, bt);
  }

} // namespace runner
<|endoftext|>


<commit_before>#include "runtime_internal.h"

#ifndef _STRUCT_TIMEVAL
#define _STRUCT_TIMEVAL

#ifdef BITS_64
// OSX always uses an int32 for the usec field
struct timeval {
    int64_t tv_sec;
    int32_t tv_usec;
};
#else
struct timeval {
    int32_t tv_sec;
    int32_t tv_usec;
};
#endif

#endif

#include "posix_clock.cpp"

<commit_msg>Implemented osx HR clock using mach_absolute_time<commit_after>#include "runtime_internal.h"

struct mach_timebase_info {
    uint32_t numer;
    uint32_t denom;
};

typedef struct mach_timebase_info *mach_timebase_info_t;
typedef struct mach_timebase_info  mach_timebase_info_data_t;

typedef int kern_return_t;

namespace Halide { namespace Runtime { namespace Internal {
WEAK bool halide_reference_clock_inited = false;
WEAK uint64_t halide_reference_clock = 0;
WEAK mach_timebase_info_data_t halide_timebase_info;
}}} // namespace Halide::Runtime::Internal

extern "C" {

extern uint64_t mach_absolute_time(void);
extern kern_return_t mach_timebase_info(mach_timebase_info_t info);

WEAK int halide_start_clock(void *user_context) {
    // Guard against multiple calls
    if (!halide_reference_clock_inited) {
        mach_timebase_info(&halide_timebase_info);
        halide_reference_clock = mach_absolute_time();
        halide_reference_clock_inited = true;
    }

    return 0;
}

WEAK int64_t halide_current_time_ns(void *user_context) {
    uint64_t now = mach_absolute_time();

    return (now - halide_reference_clock) * halide_timebase_info.numer / halide_timebase_info.denom;
}
}
<|endoftext|>


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

#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#if defined(_MSC_VER)
#include <io.h>
#define access _access
#define F_OK 0
#else
#include <unistd.h>
#endif

#include <string>

#include "base/file.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"

namespace operations_research {

File::File(FILE* const f_des, const std::string& name)
  : f_(f_des), name_(name) {}

bool File::Delete(char* const name) {
  return remove(name) == 0;
}

bool File::Exists(char* const name) {
  return access(name, F_OK) == 0;
}

size_t File::Size() {
  struct stat f_stat;
  stat(name_.c_str(), &f_stat);
  return f_stat.st_size;
}

bool File::Flush() {
  return fflush(f_) == 0;
}

bool File::Close() {
  if (fclose(f_) == 0) {
    f_ = NULL;
    return true;
  } else {
    return false;
  }
}

void File::ReadOrDie(void* const buf, size_t size) {
  CHECK_EQ(fread(buf, 1, size, f_), size);
}

size_t File::Read(void* const buf, size_t size) {
  return fread(buf, 1, size, f_);
}

void File::WriteOrDie(const void* const buf, size_t size) {
  CHECK_EQ(fwrite(buf, 1, size, f_), size);
}
size_t File::Write(const void* const buf, size_t size) {
  return fwrite(buf, 1, size, f_);
}

File* File::OpenOrDie(const char* const name, const char* const flag) {
  FILE* const f_des = fopen(name, flag);
  if (f_des == NULL) {
    std::cerr << "Cannot open " << name;
    exit(1);
  }
  File* const f = new File(f_des, name);
  return f;
}

File* File::Open(const char* const name, const char* const flag) {
  FILE* const f_des = fopen(name, flag);
  if (f_des == NULL) return NULL;
  File* const f = new File(f_des, name);
  return f;
}

char* File::ReadLine(char* const output, uint64 max_length) {
  char* const result = fgets(output, max_length, f_);
  if (result == NULL) {
    return NULL;
  }
  // Chop the last linefeed if there.
  int len = strlen(result);
  if (len > 0 && result[len - 1] == 10) {  // Linefeed char.
      result[--len] = '\0';
    }
  if (len > 0 && result[len - 1] == 13) {  // Carriage return.
    result[--len] = '\0';
  }
  return result;
}

int64 File::ReadToString(std::string* const output, uint64 max_length) {
  CHECK_NOTNULL(output);
  output->clear();

  if (max_length == 0) return 0;
  if (max_length < 0) return -1;

  int64 needed = max_length;
  int bufsize = (needed < (2 << 20) ? needed : (2 << 20));

  scoped_array<char> buf(new char[bufsize]);

  int64 nread = 0;
  while (needed > 0) {
    nread = Read(buf.get(), (bufsize < needed ? bufsize : needed));
    if (nread > 0) {
      output->append(buf.get(), nread);
      needed -= nread;
    } else {
      break;
    }
  }
  return (nread >= 0 ? static_cast<int64>(output->size()) : -1);
}

size_t File::WriteString(const std::string& line) {
  return Write(line.c_str(), line.size());
}

bool File::WriteLine(const std::string& line) {
  if (Write(line.c_str(), line.size()) != line.size()) return false;
  return Write("\n", 1) == 1;
}

std::string File::CreateFileName() const {
  return name_;
}

bool File::Open() const {
  return f_ != NULL;
}

void File::Init() {}
}  // namespace operations_research
<commit_msg>File::ReadLine does not chop the line anymore, this is done by the filelinereader.<commit_after>// Copyright 2011 Google
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#if defined(_MSC_VER)
#include <io.h>
#define access _access
#define F_OK 0
#else
#include <unistd.h>
#endif

#include <string>

#include "base/file.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"

namespace operations_research {

File::File(FILE* const f_des, const std::string& name)
  : f_(f_des), name_(name) {}

bool File::Delete(char* const name) {
  return remove(name) == 0;
}

bool File::Exists(char* const name) {
  return access(name, F_OK) == 0;
}

size_t File::Size() {
  struct stat f_stat;
  stat(name_.c_str(), &f_stat);
  return f_stat.st_size;
}

bool File::Flush() {
  return fflush(f_) == 0;
}

bool File::Close() {
  if (fclose(f_) == 0) {
    f_ = NULL;
    return true;
  } else {
    return false;
  }
}

void File::ReadOrDie(void* const buf, size_t size) {
  CHECK_EQ(fread(buf, 1, size, f_), size);
}

size_t File::Read(void* const buf, size_t size) {
  return fread(buf, 1, size, f_);
}

void File::WriteOrDie(const void* const buf, size_t size) {
  CHECK_EQ(fwrite(buf, 1, size, f_), size);
}
size_t File::Write(const void* const buf, size_t size) {
  return fwrite(buf, 1, size, f_);
}

File* File::OpenOrDie(const char* const name, const char* const flag) {
  FILE* const f_des = fopen(name, flag);
  if (f_des == NULL) {
    std::cerr << "Cannot open " << name;
    exit(1);
  }
  File* const f = new File(f_des, name);
  return f;
}

File* File::Open(const char* const name, const char* const flag) {
  FILE* const f_des = fopen(name, flag);
  if (f_des == NULL) return NULL;
  File* const f = new File(f_des, name);
  return f;
}

char* File::ReadLine(char* const output, uint64 max_length) {
  return fgets(output, max_length, f_);
}

int64 File::ReadToString(std::string* const output, uint64 max_length) {
  CHECK_NOTNULL(output);
  output->clear();

  if (max_length == 0) return 0;
  if (max_length < 0) return -1;

  int64 needed = max_length;
  int bufsize = (needed < (2 << 20) ? needed : (2 << 20));

  scoped_array<char> buf(new char[bufsize]);

  int64 nread = 0;
  while (needed > 0) {
    nread = Read(buf.get(), (bufsize < needed ? bufsize : needed));
    if (nread > 0) {
      output->append(buf.get(), nread);
      needed -= nread;
    } else {
      break;
    }
  }
  return (nread >= 0 ? static_cast<int64>(output->size()) : -1);
}

size_t File::WriteString(const std::string& line) {
  return Write(line.c_str(), line.size());
}

bool File::WriteLine(const std::string& line) {
  if (Write(line.c_str(), line.size()) != line.size()) return false;
  return Write("\n", 1) == 1;
}

std::string File::CreateFileName() const {
  return name_;
}

bool File::Open() const {
  return f_ != NULL;
}

void File::Init() {}
}  // namespace operations_research
<|endoftext|>