<commit_before>///
/// @file  nth_prime.cpp
/// @brief Find the nth prime
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount.hpp>
#include <primecount-internal.hpp>
#include <primesieve.hpp>
#include <pmath.hpp>

#include <stdint.h>

namespace primecount {

/// Find the nth prime using a combination of the Deleglise-Rivat
/// prime counting algorithm and the segmented sieve of Eratosthenes.
/// Run time: O(x^(2/3) / (log x)^2), space: O(x^(1/2)).
///
int64_t nth_prime(int64_t n, int threads)
{
  if (n < 1)
    n = 1;

  int64_t prime = 0;
  int64_t prime_approx = 0;
  int64_t count_approx = 0;

  primesieve::set_num_threads(threads);

  if (n < 100000)
    prime = primesieve::parallel_nth_prime(n, 0);
  else
  {
    // Formula due to Dana Jacobsen:
    // Nth prime ~ Li^-1(n) + Li^-1(sqrt(n)) / 4
    prime_approx = Li_inverse(n) + Li_inverse(isqrt(n)) / 4;
    count_approx = pi(prime_approx, threads);

    if (count_approx <= n)
      prime = primesieve::parallel_nth_prime(n - count_approx, prime_approx);
    else /* count_approx > n */
      prime = primesieve::parallel_nth_prime(n - count_approx - 1, prime_approx + 1);
  }

  return prime;
}

} // namespace primecount
<commit_msg>Approximately symbol<commit_after>///
/// @file  nth_prime.cpp
/// @brief Find the nth prime
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount.hpp>
#include <primecount-internal.hpp>
#include <primesieve.hpp>
#include <pmath.hpp>

#include <stdint.h>

namespace primecount {

/// Find the nth prime using a combination of the Deleglise-Rivat
/// prime counting algorithm and the segmented sieve of Eratosthenes.
/// Run time: O(x^(2/3) / (log x)^2), space: O(x^(1/2)).
///
int64_t nth_prime(int64_t n, int threads)
{
  if (n < 1)
    n = 1;

  int64_t prime = 0;
  int64_t prime_approx = 0;
  int64_t count_approx = 0;

  primesieve::set_num_threads(threads);

  if (n < 100000)
    prime = primesieve::parallel_nth_prime(n, 0);
  else
  {
    // Formula due to Dana Jacobsen:
    // Nth prime ≈ Li^-1(n) + Li^-1(sqrt(n)) / 4
    prime_approx = Li_inverse(n) + Li_inverse(isqrt(n)) / 4;
    count_approx = pi(prime_approx, threads);

    if (count_approx <= n)
      prime = primesieve::parallel_nth_prime(n - count_approx, prime_approx);
    else /* count_approx > n */
      prime = primesieve::parallel_nth_prime(n - count_approx - 1, prime_approx + 1);
  }

  return prime;
}

} // namespace primecount
<|endoftext|>


<commit_before>#include <osg/GL>
#include <osg/GLU>

#include <osg/Image>
#include <osg/Notify>

#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/StateSet>
#include <osg/Texture>

using namespace osg;

Image::Image()
{
    _fileName        = "";
    _s = _t = _r     = 0;
    _internalFormat  = 0;
    _pixelFormat     = (unsigned int)0;
    _dataType        = (unsigned int)0;
    _packing         = 4;

    _data = (unsigned char *)0L;
}

Image::~Image()
{
    if (_data) ::free(_data);
}

void Image::setFileName(const std::string& fileName)
{
    _fileName = fileName;
}

void Image::setImage(const int s,const int t,const int r,
                     const int internalFormat,
                     const unsigned int pixelFormat,
                     const unsigned int dataType,
                     unsigned char *data,
                     const int packing)
{
    if (_data) ::free(_data);

    _s = s;
    _t = t;
    _r = r;

    _internalFormat = internalFormat;
    _pixelFormat    = pixelFormat;
    _dataType       = dataType;

    _data = data;

    if (packing<0)
    {
        if (_s%4==0)
            _packing = 4;
        else
            _packing = 1;
    }
    else
        _packing = packing;

    // test scaling...
    //    scaleImageTo(16,16,_r);

}

void Image::scaleImage(const int s,const int t,const int /*r*/)
{
    if (_data==NULL) return;

    unsigned char* newData = (unsigned char *)malloc(2 * (s+1)*(t+1)*4);

    glPixelStorei(GL_PACK_ALIGNMENT,_packing);
    glPixelStorei(GL_UNPACK_ALIGNMENT,_packing);

    GLint status = gluScaleImage((GLenum)_pixelFormat,
        _s,
        _t,
        (GLenum)_dataType,
        _data,
        s,
        t,
        (GLenum)_dataType,
        newData);

    if (status==0)
    {

        // free old image.
        ::free(_data);

        _s = s;
        _t = t;
        _data = newData;
    }
    else
    {
        ::free(newData);

        notify(WARN) << "Error Image::scaleImage() do not succeed : errorString = "<<gluErrorString((GLenum)status)<<endl;
    }
}

void Image::ensureDimensionsArePowerOfTwo()
{
    float sp2 = logf((float)_s)/logf(2.0f);
    float rounded_sp2 = floorf(sp2+0.5f);
    int new_s = (int)(powf(2.0f,rounded_sp2));

    float tp2 = logf((float)_t)/logf(2.0f);
    float rounded_tp2 = floorf(tp2+0.5f);
    int new_t = (int)(powf(2.0f,rounded_tp2));

    if (new_s!=_s && new_t!=_t)
    {
        if (!_fileName.empty()) notify(NOTICE) << "Scaling image '"<<_fileName<<"' from ("<<_s<<","<<_t<<") to ("<<new_s<<","<<new_t<<")"<<endl;
        else notify(NOTICE) << "Scaling image from ("<<_s<<","<<_t<<") to ("<<new_s<<","<<new_t<<")"<<endl;

        scaleImage(new_s,new_t,_r);
    }
}

Geode* osg::createGeodeForImage(osg::Image* image)
{
    return createGeodeForImage(image,image->s(),image->t());
}

Geode* osg::createGeodeForImage(osg::Image* image,const float s,const float t)
{
    if (image)
    {
        if (s>0 && t>0)
        {

            float y = 1.0;
            float x = y*(s/t);

            // set up the texture.
            osg::Texture* texture = new osg::Texture;
            texture->setImage(image);

            // set up the drawstate.
            osg::StateSet* dstate = new osg::StateSet;
            dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
            dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
            dstate->setAttributeAndModes(texture,osg::StateAttribute::ON);

            // set up the geoset.
            osg::GeoSet* gset = new osg::GeoSet;
            gset->setStateSet(dstate);

            osg::Vec3* coords = new Vec3 [4];
            coords[0].set(-x,0.0f,y);
            coords[1].set(-x,0.0f,-y);
            coords[2].set(x,0.0f,-y);
            coords[3].set(x,0.0f,y);
            gset->setCoords(coords);

            osg::Vec2* tcoords = new Vec2 [4];
            tcoords[0].set(0.0f,1.0f);
            tcoords[1].set(0.0f,0.0f);
            tcoords[2].set(1.0f,0.0f);
            tcoords[3].set(1.0f,1.0f);
            gset->setTextureCoords(tcoords);
            gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);

            osg::Vec4* colours = new Vec4;
            colours->set(1.0f,1.0f,1.0,1.0f);
            gset->setColors(colours);
            gset->setColorBinding(osg::GeoSet::BIND_OVERALL);

            gset->setNumPrims(1);
            gset->setPrimType(osg::GeoSet::QUADS);

            // set up the geode.
            osg::Geode* geode = new osg::Geode;
            geode->addDrawable(gset);

            return geode;

        }
        else
        {
            return NULL;
        }
    }
    else
    {
        return NULL;
    }
}
<commit_msg>Fixed a bug in osg::Image::ensureDimensionsArePowerOfTwo() which only scaled dimensions if *both* axis wern't a power of two, have fixed it to rescale if either of the axis arn't a power to two.<commit_after>#include <osg/GL>
#include <osg/GLU>

#include <osg/Image>
#include <osg/Notify>

#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/StateSet>
#include <osg/Texture>

using namespace osg;

Image::Image()
{
    _fileName        = "";
    _s = _t = _r     = 0;
    _internalFormat  = 0;
    _pixelFormat     = (unsigned int)0;
    _dataType        = (unsigned int)0;
    _packing         = 4;

    _data = (unsigned char *)0L;
}

Image::~Image()
{
    if (_data) ::free(_data);
}

void Image::setFileName(const std::string& fileName)
{
    _fileName = fileName;
}

void Image::setImage(const int s,const int t,const int r,
                     const int internalFormat,
                     const unsigned int pixelFormat,
                     const unsigned int dataType,
                     unsigned char *data,
                     const int packing)
{
    if (_data) ::free(_data);

    _s = s;
    _t = t;
    _r = r;

    _internalFormat = internalFormat;
    _pixelFormat    = pixelFormat;
    _dataType       = dataType;

    _data = data;

    if (packing<0)
    {
        if (_s%4==0)
            _packing = 4;
        else
            _packing = 1;
    }
    else
        _packing = packing;

    // test scaling...
    //    scaleImageTo(16,16,_r);

}

void Image::scaleImage(const int s,const int t,const int /*r*/)
{
    if (_data==NULL) return;

    unsigned char* newData = (unsigned char *)malloc(2 * (s+1)*(t+1)*4);

    glPixelStorei(GL_PACK_ALIGNMENT,_packing);
    glPixelStorei(GL_UNPACK_ALIGNMENT,_packing);

    GLint status = gluScaleImage((GLenum)_pixelFormat,
        _s,
        _t,
        (GLenum)_dataType,
        _data,
        s,
        t,
        (GLenum)_dataType,
        newData);

    if (status==0)
    {

        // free old image.
        ::free(_data);

        _s = s;
        _t = t;
        _data = newData;
    }
    else
    {
        ::free(newData);

        notify(WARN) << "Error Image::scaleImage() do not succeed : errorString = "<<gluErrorString((GLenum)status)<<endl;
    }
}

void Image::ensureDimensionsArePowerOfTwo()
{
    float sp2 = logf((float)_s)/logf(2.0f);
    float rounded_sp2 = floorf(sp2+0.5f);
    int new_s = (int)(powf(2.0f,rounded_sp2));

    float tp2 = logf((float)_t)/logf(2.0f);
    float rounded_tp2 = floorf(tp2+0.5f);
    int new_t = (int)(powf(2.0f,rounded_tp2));

    if (new_s!=_s || new_t!=_t)
    {
        if (!_fileName.empty()) notify(NOTICE) << "Scaling image '"<<_fileName<<"' from ("<<_s<<","<<_t<<") to ("<<new_s<<","<<new_t<<")"<<endl;
        else notify(NOTICE) << "Scaling image from ("<<_s<<","<<_t<<") to ("<<new_s<<","<<new_t<<")"<<endl;

        scaleImage(new_s,new_t,_r);
    }
}

Geode* osg::createGeodeForImage(osg::Image* image)
{
    return createGeodeForImage(image,image->s(),image->t());
}

Geode* osg::createGeodeForImage(osg::Image* image,const float s,const float t)
{
    if (image)
    {
        if (s>0 && t>0)
        {

            float y = 1.0;
            float x = y*(s/t);

            // set up the texture.
            osg::Texture* texture = new osg::Texture;
            texture->setImage(image);

            // set up the drawstate.
            osg::StateSet* dstate = new osg::StateSet;
            dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
            dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
            dstate->setAttributeAndModes(texture,osg::StateAttribute::ON);

            // set up the geoset.
            osg::GeoSet* gset = new osg::GeoSet;
            gset->setStateSet(dstate);

            osg::Vec3* coords = new Vec3 [4];
            coords[0].set(-x,0.0f,y);
            coords[1].set(-x,0.0f,-y);
            coords[2].set(x,0.0f,-y);
            coords[3].set(x,0.0f,y);
            gset->setCoords(coords);

            osg::Vec2* tcoords = new Vec2 [4];
            tcoords[0].set(0.0f,1.0f);
            tcoords[1].set(0.0f,0.0f);
            tcoords[2].set(1.0f,0.0f);
            tcoords[3].set(1.0f,1.0f);
            gset->setTextureCoords(tcoords);
            gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);

            osg::Vec4* colours = new Vec4;
            colours->set(1.0f,1.0f,1.0,1.0f);
            gset->setColors(colours);
            gset->setColorBinding(osg::GeoSet::BIND_OVERALL);

            gset->setNumPrims(1);
            gset->setPrimType(osg::GeoSet::QUADS);

            // set up the geode.
            osg::Geode* geode = new osg::Geode;
            geode->addDrawable(gset);

            return geode;

        }
        else
        {
            return NULL;
        }
    }
    else
    {
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <wallet/test/wallet_test_fixture.h>

#include <rpc/server.h>
#include <wallet/db.h>
#include <wallet/wallet.h>

CWallet *pwalletMain;

WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
    TestingSetup(chainName)
{
    bitdb.MakeMock();

    bool fFirstRun;
    std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat"));
    pwalletMain = new CWallet(std::move(dbw));
    pwalletMain->LoadWallet(fFirstRun);
    RegisterValidationInterface(pwalletMain);

    RegisterWalletRPCCommands(tableRPC);
}

WalletTestingSetup::~WalletTestingSetup()
{
    UnregisterValidationInterface(pwalletMain);
    delete pwalletMain;
    pwalletMain = nullptr;

    bitdb.Flush(true);
    bitdb.Reset();
}
<commit_msg>Use unique_ptr for pwalletMain (CWallet)<commit_after>// Copyright (c) 2016-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <wallet/test/wallet_test_fixture.h>

#include <rpc/server.h>
#include <wallet/db.h>
#include <wallet/wallet.h>

std::unique_ptr<CWallet> pwalletMain;

WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
    TestingSetup(chainName)
{
    bitdb.MakeMock();

    bool fFirstRun;
    std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat"));
    pwalletMain = std::unique_ptr<CWallet>(new CWallet(std::move(dbw)));
    pwalletMain->LoadWallet(fFirstRun);
    RegisterValidationInterface(pwalletMain.get());

    RegisterWalletRPCCommands(tableRPC);
}

WalletTestingSetup::~WalletTestingSetup()
{
    UnregisterValidationInterface(pwalletMain.get());
    pwalletMain.reset();

    bitdb.Flush(true);
    bitdb.Reset();
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 * $Id$
 */

#include "DOMLSInputImpl.hpp"

#include <xercesc/util/XMLString.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMLSInputImpl::DOMLSInputImpl(MemoryManager* const manager /*= XMLPlatformUtils::fgMemoryManager*/)
:fStringData(0)
,fByteStream(0)
,fEncoding(0)
,fPublicId(0)
,fSystemId(0)
,fBaseURI(0)
,fIssueFatalErrorIfNotFound(true)
,fMemoryManager(manager)
{
}

DOMLSInputImpl::~DOMLSInputImpl()
{
    fMemoryManager->deallocate(fEncoding);
    fMemoryManager->deallocate(fPublicId);
    fMemoryManager->deallocate(fSystemId);
    fMemoryManager->deallocate(fBaseURI);
}

void DOMLSInputImpl::setStringData(const XMLCh* data)
{
    fStringData=data;
}

void DOMLSInputImpl::setByteStream(InputSource* stream)
{
    fByteStream=stream;
}

void DOMLSInputImpl::setEncoding(const XMLCh* const encodingStr)
{
    fMemoryManager->deallocate(fEncoding);
    fEncoding = XMLString::replicate(encodingStr, fMemoryManager);
}

void DOMLSInputImpl::setPublicId(const XMLCh* const publicId)
{
    fMemoryManager->deallocate(fPublicId);
    fPublicId = XMLString::replicate(publicId, fMemoryManager);
}

void DOMLSInputImpl::setSystemId(const XMLCh* const systemId)
{
    fMemoryManager->deallocate(fSystemId);
    fSystemId = XMLString::replicate(systemId, fMemoryManager);
}

void DOMLSInputImpl::setBaseURI(const XMLCh* const baseURI)
{
    fMemoryManager->deallocate(fBaseURI);
    fBaseURI = XMLString::replicate(baseURI, fMemoryManager);
}

void DOMLSInputImpl::setIssueFatalErrorIfNotFound(bool flag)
{
    fIssueFatalErrorIfNotFound=flag;
}

void DOMLSInputImpl::release()
{
    delete this;
}

XERCES_CPP_NAMESPACE_END

<commit_msg>When the DOMLSInput contains a stringData buffer, the encoding of the source is XMLCH<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 * $Id$
 */

#include "DOMLSInputImpl.hpp"

#include <xercesc/util/XMLString.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMLSInputImpl::DOMLSInputImpl(MemoryManager* const manager /*= XMLPlatformUtils::fgMemoryManager*/)
:fStringData(0)
,fByteStream(0)
,fEncoding(0)
,fPublicId(0)
,fSystemId(0)
,fBaseURI(0)
,fIssueFatalErrorIfNotFound(true)
,fMemoryManager(manager)
{
}

DOMLSInputImpl::~DOMLSInputImpl()
{
    fMemoryManager->deallocate(fEncoding);
    fMemoryManager->deallocate(fPublicId);
    fMemoryManager->deallocate(fSystemId);
    fMemoryManager->deallocate(fBaseURI);
}

void DOMLSInputImpl::setStringData(const XMLCh* data)
{
    fStringData=data;
    setEncoding(XMLUni::fgXMLChEncodingString);
}

void DOMLSInputImpl::setByteStream(InputSource* stream)
{
    fByteStream=stream;
}

void DOMLSInputImpl::setEncoding(const XMLCh* const encodingStr)
{
    fMemoryManager->deallocate(fEncoding);
    fEncoding = XMLString::replicate(encodingStr, fMemoryManager);
}

void DOMLSInputImpl::setPublicId(const XMLCh* const publicId)
{
    fMemoryManager->deallocate(fPublicId);
    fPublicId = XMLString::replicate(publicId, fMemoryManager);
}

void DOMLSInputImpl::setSystemId(const XMLCh* const systemId)
{
    fMemoryManager->deallocate(fSystemId);
    fSystemId = XMLString::replicate(systemId, fMemoryManager);
}

void DOMLSInputImpl::setBaseURI(const XMLCh* const baseURI)
{
    fMemoryManager->deallocate(fBaseURI);
    fBaseURI = XMLString::replicate(baseURI, fMemoryManager);
}

void DOMLSInputImpl::setIssueFatalErrorIfNotFound(bool flag)
{
    fIssueFatalErrorIfNotFound=flag;
}

void DOMLSInputImpl::release()
{
    delete this;
}

XERCES_CPP_NAMESPACE_END

<|endoftext|>


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <iostream>
#include <string>
#include <vector>
#include <exception>
#include <fstream>
#include <iomanip>
#include <limits>
#include <ctime>

#include <ArgumentList.hpp>
#include <Observation.hpp>
#include <utils.hpp>
#include <SNR.hpp>

int main(int argc, char *argv[]) {
  bool dSNR = false;
  std::string typeName;
	AstroData::Observation observation;
  PulsarSearch::snrDedispersedConf dConf;
  PulsarSearch::snrFoldedConf fConf;

	try {
    isa::utils::ArgumentList args(argc, argv);
    dSNR = args.getSwitch("-dedispersed");
    bool fSNR = args.getSwitch("-folded");
    if ( (dSNR && fSNR) || (!dSNR && ! fSNR) ) {
      throw std::exception();
    }
    typeName = args.getSwitchArgument< std::string >("-type");
    observation.setPadding(args.getSwitchArgument< unsigned int >("-padding"));
    if ( fSNR ) {
      fConf.setNrDMsPerBlock(args.getSwitchArgument< unsigned int >("-db"));
      fConf.setNrDMsPerThread(args.getSwitchArgument< unsigned int >("-dt"));
      fConf.setNrPeriodsPerBlock(args.getSwitchArgument< unsigned int >("-pb"));
      fConf.setNrPeriodsPerThread(args.getSwitchArgument< unsigned int >("-pt"));
    } else {
      dConf.setNrDMsPerBlock(args.getSwitchArgument< unsigned int >("-db"));
      dConf.setNrDMsPerThread(args.getSwitchArgument< unsigned int >("-dt"));
      observation.setNrSamplesPerSecond(args.getSwitchArgument< unsigned int >("-samples"));
    }
		observation.setDMRange(args.getSwitchArgument< unsigned int >("-dms"), 0.0, 0.0);
    if ( fSNR ) {
      observation.setPeriodRange(args.getSwitchArgument< unsigned int >("-periods"), 0, 0);
      observation.setNrBins(args.getSwitchArgument< unsigned int >("-bins"));
    }
	} catch  ( isa::utils::SwitchNotFound &err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  } catch ( std::exception &err ) {
    std::cerr << "Usage: " << argv[0] << " [-dedispersed | -folded] -type ... -padding ... -db ... -dt ... -dms ..." << std::endl;
    std::cerr << "\t -dedispersed -samples ..." << std::endl;
    std::cerr << "\t -folded -pb ... -pt ... -periods .... -bins ..." << std::endl;
		return 1;
	}

  // Generate kernel
  std::string * code;
  if ( dSNR ) {
    code = PulsarSearch::getSNRDedispersedOpenCL(dConf, typeName, observation);
  } else {
    code = PulsarSearch::getSNRFoldedOpenCL(fConf, typeName, observation);
  }
  std::cout << *code << std::endl;

	return 0;
}

<commit_msg>Updated the print code utility.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <iostream>
#include <string>
#include <vector>
#include <exception>
#include <fstream>
#include <iomanip>
#include <limits>
#include <ctime>

#include <ArgumentList.hpp>
#include <Observation.hpp>
#include <utils.hpp>
#include <SNR.hpp>

int main(int argc, char *argv[]) {
  std::string typeName;
	AstroData::Observation observation;
  PulsarSearch::snrDedispersedConf dConf;

	try {
    isa::utils::ArgumentList args(argc, argv);
    typeName = args.getSwitchArgument< std::string >("-type");
    observation.setPadding(args.getSwitchArgument< unsigned int >("-padding"));
    dConf.setNrDMsPerBlock(args.getSwitchArgument< unsigned int >("-db"));
    observation.setNrSamplesPerSecond(args.getSwitchArgument< unsigned int >("-samples"));
		observation.setDMRange(args.getSwitchArgument< unsigned int >("-dms"), 0.0, 0.0);
	} catch  ( isa::utils::SwitchNotFound &err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  } catch ( std::exception &err ) {
    std::cerr << "Usage: " << argv[0] << " -type ... -padding ... -db ... -dms ... -samples ..." << std::endl;
		return 1;
	}

  // Generate kernel
  std::string * code;
  code = PulsarSearch::getSNRDedispersedOpenCL(dConf, typeName, observation);
  std::cout << *code << std::endl;

	return 0;
}

<|endoftext|>


<commit_before>#include "repository.h"
#include "commit.h"
#include "tree.h"
#include "odb.h"
#include "index.h"

using namespace std;

static void StubWeakCallback(Persistent<Value> val, void *data) {
	// TODO: should we actually be doing anything here? node's ObjectWrap deletes the object, but as far as I can tell, the dtor
	// for my weak ref'd stuff is getting called, which means memory is being freed... Unless I'm completely retarded?
}

Persistent<FunctionTemplate> Repository::constructor_template;

void Repository::Init(Handle<Object> target) {
	HandleScope scope;

	Local<FunctionTemplate> t = FunctionTemplate::New(New);
	constructor_template = Persistent<FunctionTemplate>::New(t);
	constructor_template->SetClassName(String::New("Repository"));
	t->InstanceTemplate()->SetInternalFieldCount(1);

	NODE_SET_PROTOTYPE_METHOD(t, "getObjectDatabase", GetODB);
	NODE_SET_PROTOTYPE_METHOD(t, "getCommit", GetCommit);
	NODE_SET_PROTOTYPE_METHOD(t, "getTree", GetTree);

	t->InstanceTemplate()->SetAccessor(String::New("index"), IndexGetter);

	target->Set(String::New("Repository"), t->GetFunction());
}

Handle<Value> Repository::New(const Arguments& args) {
	HandleScope scope;

	REQ_ARGS(1);
	REQ_STR_ARG(0, path);

	Repository *repo = new Repository();

	if(int result = git_repository_open(&repo->repo_, *path) != GIT_SUCCESS) {
		Handle<Value> ex = Exception::Error(String::New("Git error."));
		return ThrowException(ex);
	}

	repo->path_ = *path;

	repo->Wrap(args.This());
	repo->MakeWeak();

	return args.This();
}

Handle<Value> Repository::GetODB(const Arguments& args) {
	HandleScope scope;

	Repository *repo = ObjectWrap::Unwrap<Repository>(args.This());
	git_odb *odb = git_repository_database(repo->repo_);

	Local<Value> arg = External::New(odb);
	Persistent<Object> result(ObjectDatabase::constructor_template->GetFunction()->NewInstance(1, &arg));
	return scope.Close(result);
}

Handle<Value> Repository::GetCommit(const Arguments& args) {
	HandleScope scope;

	REQ_ARGS(1);
	REQ_OID_ARG(0, commitOid);

	Repository *repo = ObjectWrap::Unwrap<Repository>(args.This());
	const char* oidStr = git_oid_allocfmt(&commitOid);

	git_commit* commit;
	if(git_commit_lookup(&commit, repo->repo_, &commitOid) != GIT_SUCCESS) {
		// TODO: error code handling.
		return scope.Close(Null());
	}

	Commit *commitObject = repo->wrapCommit(commit);
	return scope.Close(commitObject->handle_);
}

Handle<Value> Repository::GetTree(const Arguments& args) {
	HandleScope scope;

	REQ_ARGS(1);
	REQ_OID_ARG(0, commitOid);

	Repository *repo = ObjectWrap::Unwrap<Repository>(args.This());

	git_tree *tree;
	if(git_tree_lookup(&tree, repo->repo_, &commitOid) != GIT_SUCCESS) {
		return scope.Close(Null());
	}

	Tree *treeObject = repo->wrapTree(tree);
	return scope.Close(treeObject->handle_);
}

Handle<Value> Repository::IndexGetter(Local<String>, const AccessorInfo& info) {
	HandleScope scope;

	Repository *repo = ObjectWrap::Unwrap<Repository>(info.This());
	if(repo->index_ == NULL) {
		git_index *index;
		int result = git_repository_index(&index, repo->repo_);
		if(result == GIT_EBAREINDEX) {
			git_index_open_bare(&index, repo->path_);
		}

		Handle<Value> arg = External::New(index);
		Handle<Object> instance = Index::constructor_template->GetFunction()->NewInstance(1, &arg);
		repo->index_ = ObjectWrap::Unwrap<Index>(instance);
	}

	return repo->index_->handle_;
}

Repository::~Repository() {
	close();
}

void Repository::close() {
	if(repo_) {
		git_repository_free(repo_);
		repo_ = NULL;
	}
}

Commit *Repository::wrapCommit(git_commit *commit) {
	Commit *commitObject;
	if(commitStore_.getObjectFor(commit, &commitObject)) {
		// Commit needs to know who it's daddy is.
		commitObject->repository_ = this;
	}

	return commitObject;
}

Tree *Repository::wrapTree(git_tree *tree) {
	Tree *treeObject;
	if(treeStore_.getObjectFor(tree, &treeObject)) {
		treeObject->repository_ = this;
	}

	return treeObject;
}
<commit_msg>Repo adds immutable path prop to JS object.<commit_after>#include "repository.h"
#include "commit.h"
#include "tree.h"
#include "odb.h"
#include "index.h"

using namespace std;

static void StubWeakCallback(Persistent<Value> val, void *data) {
	// TODO: should we actually be doing anything here? node's ObjectWrap deletes the object, but as far as I can tell, the dtor
	// for my weak ref'd stuff is getting called, which means memory is being freed... Unless I'm completely retarded?
}

Persistent<FunctionTemplate> Repository::constructor_template;

void Repository::Init(Handle<Object> target) {
	HandleScope scope;

	Local<FunctionTemplate> t = FunctionTemplate::New(New);
	constructor_template = Persistent<FunctionTemplate>::New(t);
	constructor_template->SetClassName(String::New("Repository"));
	t->InstanceTemplate()->SetInternalFieldCount(1);

	NODE_SET_PROTOTYPE_METHOD(t, "getObjectDatabase", GetODB);
	NODE_SET_PROTOTYPE_METHOD(t, "getCommit", GetCommit);
	NODE_SET_PROTOTYPE_METHOD(t, "getTree", GetTree);

	t->InstanceTemplate()->SetAccessor(String::New("index"), IndexGetter);

	target->Set(String::New("Repository"), t->GetFunction());
}

Handle<Value> Repository::New(const Arguments& args) {
	HandleScope scope;

	REQ_ARGS(1);
	REQ_STR_ARG(0, path);

	Repository *repo = new Repository();

	if(int result = git_repository_open(&repo->repo_, *path) != GIT_SUCCESS) {
		Handle<Value> ex = Exception::Error(String::New("Git error."));
		return ThrowException(ex);
	}

	repo->path_ = *path;

	args.This()->Set(String::New("path"), String::New(repo->path_), ReadOnly);

	repo->Wrap(args.This());
	repo->MakeWeak();

	return args.This();
}

Handle<Value> Repository::GetODB(const Arguments& args) {
	HandleScope scope;

	Repository *repo = ObjectWrap::Unwrap<Repository>(args.This());
	git_odb *odb = git_repository_database(repo->repo_);

	Local<Value> arg = External::New(odb);
	Persistent<Object> result(ObjectDatabase::constructor_template->GetFunction()->NewInstance(1, &arg));
	return scope.Close(result);
}

Handle<Value> Repository::GetCommit(const Arguments& args) {
	HandleScope scope;

	REQ_ARGS(1);
	REQ_OID_ARG(0, commitOid);

	Repository *repo = ObjectWrap::Unwrap<Repository>(args.This());
	const char* oidStr = git_oid_allocfmt(&commitOid);

	git_commit* commit;
	if(git_commit_lookup(&commit, repo->repo_, &commitOid) != GIT_SUCCESS) {
		// TODO: error code handling.
		return scope.Close(Null());
	}

	Commit *commitObject = repo->wrapCommit(commit);
	return scope.Close(commitObject->handle_);
}

Handle<Value> Repository::GetTree(const Arguments& args) {
	HandleScope scope;

	REQ_ARGS(1);
	REQ_OID_ARG(0, commitOid);

	Repository *repo = ObjectWrap::Unwrap<Repository>(args.This());

	git_tree *tree;
	if(git_tree_lookup(&tree, repo->repo_, &commitOid) != GIT_SUCCESS) {
		return scope.Close(Null());
	}

	Tree *treeObject = repo->wrapTree(tree);
	return scope.Close(treeObject->handle_);
}

Handle<Value> Repository::IndexGetter(Local<String>, const AccessorInfo& info) {
	HandleScope scope;

	Repository *repo = ObjectWrap::Unwrap<Repository>(info.This());
	if(repo->index_ == NULL) {
		git_index *index;
		int result = git_repository_index(&index, repo->repo_);
		if(result == GIT_EBAREINDEX) {
			git_index_open_bare(&index, repo->path_);
		}

		Handle<Value> arg = External::New(index);
		Handle<Object> instance = Index::constructor_template->GetFunction()->NewInstance(1, &arg);
		repo->index_ = ObjectWrap::Unwrap<Index>(instance);
	}

	return repo->index_->handle_;
}

Repository::~Repository() {
	close();
}

void Repository::close() {
	if(repo_) {
		git_repository_free(repo_);
		repo_ = NULL;
	}
}

Commit *Repository::wrapCommit(git_commit *commit) {
	Commit *commitObject;
	if(commitStore_.getObjectFor(commit, &commitObject)) {
		// Commit needs to know who it's daddy is.
		commitObject->repository_ = this;
	}

	return commitObject;
}

Tree *Repository::wrapTree(git_tree *tree) {
	Tree *treeObject;
	if(treeStore_.getObjectFor(tree, &treeObject)) {
		treeObject->repository_ = this;
	}

	return treeObject;
}
<|endoftext|>


<commit_before>//===- unittest/ADT/MapVectorTest.cpp - MapVector unit tests ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"
#include "llvm/ADT/MapVector.h"
#include <utility>

using namespace llvm;

TEST(MapVectorTest, insert_pop) {
  MapVector<int, int> MV;
  std::pair<MapVector<int, int>::iterator, bool> R;

  R = MV.insert(std::make_pair(1, 2));
  ASSERT_EQ(R.first, MV.begin());
  EXPECT_EQ(R.first->first, 1);
  EXPECT_EQ(R.first->second, 2);
  EXPECT_TRUE(R.second);

  R = MV.insert(std::make_pair(1, 3));
  ASSERT_EQ(R.first, MV.begin());
  EXPECT_EQ(R.first->first, 1);
  EXPECT_EQ(R.first->second, 2);
  EXPECT_FALSE(R.second);

  R = MV.insert(std::make_pair(4, 5));
  ASSERT_NE(R.first, MV.end());
  EXPECT_EQ(R.first->first, 4);
  EXPECT_EQ(R.first->second, 5);
  EXPECT_TRUE(R.second);

  EXPECT_EQ(MV.size(), 2u);
  EXPECT_EQ(MV[1], 2);
  EXPECT_EQ(MV[4], 5);

  MV.pop_back();
  EXPECT_EQ(MV.size(), 1u);
  EXPECT_EQ(MV[1], 2);

  R = MV.insert(std::make_pair(4, 7));
  ASSERT_NE(R.first, MV.end());
  EXPECT_EQ(R.first->first, 4);
  EXPECT_EQ(R.first->second, 7);
  EXPECT_TRUE(R.second);

  EXPECT_EQ(MV.size(), 2u);
  EXPECT_EQ(MV[1], 2);
  EXPECT_EQ(MV[4], 7);
}

TEST(MapVectorTest, erase) {
  MapVector<int, int> MV;

  MV.insert(std::make_pair(1, 2));
  MV.insert(std::make_pair(3, 4));
  MV.insert(std::make_pair(5, 6));
  ASSERT_EQ(MV.size(), 3u);

  MV.erase(MV.find(1));
  ASSERT_EQ(MV.size(), 2u);
  ASSERT_EQ(MV.find(1), MV.end());
  ASSERT_EQ(MV[3], 4);
  ASSERT_EQ(MV[5], 6);

  MV.erase(3);
  ASSERT_EQ(MV.size(), 1u);
  ASSERT_EQ(MV.find(3), MV.end());
  ASSERT_EQ(MV[5], 6);
}

TEST(MapVectorTest, remove_if) {
  MapVector<int, int> MV;

  MV.insert(std::make_pair(1, 11));
  MV.insert(std::make_pair(2, 12));
  MV.insert(std::make_pair(3, 13));
  MV.insert(std::make_pair(4, 14));
  MV.insert(std::make_pair(5, 15));
  MV.insert(std::make_pair(6, 16));
  ASSERT_EQ(MV.size(), 6u);

  MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
  ASSERT_EQ(MV.size(), 3u);
  ASSERT_EQ(MV.find(1), MV.end());
  ASSERT_EQ(MV.find(3), MV.end());
  ASSERT_EQ(MV.find(5), MV.end());
  ASSERT_EQ(MV[2], 12);
  ASSERT_EQ(MV[4], 14);
  ASSERT_EQ(MV[6], 16);
}
<commit_msg>Add return value and negative checks to MapVector::erase from r219240.<commit_after>//===- unittest/ADT/MapVectorTest.cpp - MapVector unit tests ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"
#include "llvm/ADT/MapVector.h"
#include <utility>

using namespace llvm;

TEST(MapVectorTest, insert_pop) {
  MapVector<int, int> MV;
  std::pair<MapVector<int, int>::iterator, bool> R;

  R = MV.insert(std::make_pair(1, 2));
  ASSERT_EQ(R.first, MV.begin());
  EXPECT_EQ(R.first->first, 1);
  EXPECT_EQ(R.first->second, 2);
  EXPECT_TRUE(R.second);

  R = MV.insert(std::make_pair(1, 3));
  ASSERT_EQ(R.first, MV.begin());
  EXPECT_EQ(R.first->first, 1);
  EXPECT_EQ(R.first->second, 2);
  EXPECT_FALSE(R.second);

  R = MV.insert(std::make_pair(4, 5));
  ASSERT_NE(R.first, MV.end());
  EXPECT_EQ(R.first->first, 4);
  EXPECT_EQ(R.first->second, 5);
  EXPECT_TRUE(R.second);

  EXPECT_EQ(MV.size(), 2u);
  EXPECT_EQ(MV[1], 2);
  EXPECT_EQ(MV[4], 5);

  MV.pop_back();
  EXPECT_EQ(MV.size(), 1u);
  EXPECT_EQ(MV[1], 2);

  R = MV.insert(std::make_pair(4, 7));
  ASSERT_NE(R.first, MV.end());
  EXPECT_EQ(R.first->first, 4);
  EXPECT_EQ(R.first->second, 7);
  EXPECT_TRUE(R.second);

  EXPECT_EQ(MV.size(), 2u);
  EXPECT_EQ(MV[1], 2);
  EXPECT_EQ(MV[4], 7);
}

TEST(MapVectorTest, erase) {
  MapVector<int, int> MV;

  MV.insert(std::make_pair(1, 2));
  MV.insert(std::make_pair(3, 4));
  MV.insert(std::make_pair(5, 6));
  ASSERT_EQ(MV.size(), 3u);

  MV.erase(MV.find(1));
  ASSERT_EQ(MV.size(), 2u);
  ASSERT_EQ(MV.find(1), MV.end());
  ASSERT_EQ(MV[3], 4);
  ASSERT_EQ(MV[5], 6);

  ASSERT_EQ(MV.erase(3), 1u);
  ASSERT_EQ(MV.size(), 1u);
  ASSERT_EQ(MV.find(3), MV.end());
  ASSERT_EQ(MV[5], 6);

  ASSERT_EQ(MV.erase(79), 0u);
  ASSERT_EQ(MV.size(), 1u);
}

TEST(MapVectorTest, remove_if) {
  MapVector<int, int> MV;

  MV.insert(std::make_pair(1, 11));
  MV.insert(std::make_pair(2, 12));
  MV.insert(std::make_pair(3, 13));
  MV.insert(std::make_pair(4, 14));
  MV.insert(std::make_pair(5, 15));
  MV.insert(std::make_pair(6, 16));
  ASSERT_EQ(MV.size(), 6u);

  MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
  ASSERT_EQ(MV.size(), 3u);
  ASSERT_EQ(MV.find(1), MV.end());
  ASSERT_EQ(MV.find(3), MV.end());
  ASSERT_EQ(MV.find(5), MV.end());
  ASSERT_EQ(MV[2], 12);
  ASSERT_EQ(MV[4], 14);
  ASSERT_EQ(MV[6], 16);
}
<|endoftext|>


<commit_before>//===- llvm/unittest/ADT/StringMapMap.cpp - StringMap unit tests ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/DataTypes.h"
using namespace llvm;

namespace {

// Test fixture
class StringMapTest : public testing::Test {
protected:
  StringMap<uint32_t> testMap;

  static const char testKey[];
  static const uint32_t testValue;
  static const char* testKeyFirst;
  static size_t testKeyLength;
  static const std::string testKeyStr;

  void assertEmptyMap() {
    // Size tests
    EXPECT_EQ(0u, testMap.size());
    EXPECT_TRUE(testMap.empty());

    // Iterator tests
    EXPECT_TRUE(testMap.begin() == testMap.end());

    // Lookup tests
    EXPECT_EQ(0u, testMap.count(testKey));
    EXPECT_EQ(0u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
    EXPECT_EQ(0u, testMap.count(testKeyStr));
    EXPECT_TRUE(testMap.find(testKey) == testMap.end());
    EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
                testMap.end());
    EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end());
  }

  void assertSingleItemMap() {
    // Size tests
    EXPECT_EQ(1u, testMap.size());
    EXPECT_FALSE(testMap.begin() == testMap.end());
    EXPECT_FALSE(testMap.empty());

    // Iterator tests
    StringMap<uint32_t>::iterator it = testMap.begin();
    EXPECT_STREQ(testKey, it->first().data());
    EXPECT_EQ(testValue, it->second);
    ++it;
    EXPECT_TRUE(it == testMap.end());

    // Lookup tests
    EXPECT_EQ(1u, testMap.count(testKey));
    EXPECT_EQ(1u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
    EXPECT_EQ(1u, testMap.count(testKeyStr));
    EXPECT_TRUE(testMap.find(testKey) == testMap.begin());
    EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
                testMap.begin());
    EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin());
  }
};

const char StringMapTest::testKey[] = "key";
const uint32_t StringMapTest::testValue = 1u;
const char* StringMapTest::testKeyFirst = testKey;
size_t StringMapTest::testKeyLength = sizeof(testKey) - 1;
const std::string StringMapTest::testKeyStr(testKey);

// Empty map tests.
TEST_F(StringMapTest, EmptyMapTest) {
  assertEmptyMap();
}

// Constant map tests.
TEST_F(StringMapTest, ConstEmptyMapTest) {
  const StringMap<uint32_t>& constTestMap = testMap;

  // Size tests
  EXPECT_EQ(0u, constTestMap.size());
  EXPECT_TRUE(constTestMap.empty());

  // Iterator tests
  EXPECT_TRUE(constTestMap.begin() == constTestMap.end());

  // Lookup tests
  EXPECT_EQ(0u, constTestMap.count(testKey));
  EXPECT_EQ(0u, constTestMap.count(StringRef(testKeyFirst, testKeyLength)));
  EXPECT_EQ(0u, constTestMap.count(testKeyStr));
  EXPECT_TRUE(constTestMap.find(testKey) == constTestMap.end());
  EXPECT_TRUE(constTestMap.find(StringRef(testKeyFirst, testKeyLength)) ==
              constTestMap.end());
  EXPECT_TRUE(constTestMap.find(testKeyStr) == constTestMap.end());
}

// A map with a single entry.
TEST_F(StringMapTest, SingleEntryMapTest) {
  testMap[testKey] = testValue;
  assertSingleItemMap();
}

// Test clear() method.
TEST_F(StringMapTest, ClearTest) {
  testMap[testKey] = testValue;
  testMap.clear();
  assertEmptyMap();
}

// Test erase(iterator) method.
TEST_F(StringMapTest, EraseIteratorTest) {
  testMap[testKey] = testValue;
  testMap.erase(testMap.begin());
  assertEmptyMap();
}

// Test erase(value) method.
TEST_F(StringMapTest, EraseValueTest) {
  testMap[testKey] = testValue;
  testMap.erase(testKey);
  assertEmptyMap();
}

// Test inserting two values and erasing one.
TEST_F(StringMapTest, InsertAndEraseTest) {
  testMap[testKey] = testValue;
  testMap["otherKey"] = 2;
  testMap.erase("otherKey");
  assertSingleItemMap();
}

TEST_F(StringMapTest, SmallFullMapTest) {
  // StringMap has a tricky corner case when the map is small (<8 buckets) and
  // it fills up through a balanced pattern of inserts and erases. This can
  // lead to inf-loops in some cases (PR13148) so we test it explicitly here.
  llvm::StringMap<int> Map(2);

  Map["eins"] = 1;
  Map["zwei"] = 2;
  Map["drei"] = 3;
  Map.erase("drei");
  Map.erase("eins");
  Map["veir"] = 4;
  Map["funf"] = 5;

  EXPECT_EQ(3u, Map.size());
  EXPECT_EQ(0, Map.lookup("eins"));
  EXPECT_EQ(2, Map.lookup("zwei"));
  EXPECT_EQ(0, Map.lookup("drei"));
  EXPECT_EQ(4, Map.lookup("veir"));
  EXPECT_EQ(5, Map.lookup("funf"));
}

// A more complex iteration test.
TEST_F(StringMapTest, IterationTest) {
  bool visited[100];

  // Insert 100 numbers into the map
  for (int i = 0; i < 100; ++i) {
    std::stringstream ss;
    ss << "key_" << i;
    testMap[ss.str()] = i;
    visited[i] = false;
  }

  // Iterate over all numbers and mark each one found.
  for (StringMap<uint32_t>::iterator it = testMap.begin();
      it != testMap.end(); ++it) {
    std::stringstream ss;
    ss << "key_" << it->second;
    ASSERT_STREQ(ss.str().c_str(), it->first().data());
    visited[it->second] = true;
  }

  // Ensure every number was visited.
  for (int i = 0; i < 100; ++i) {
    ASSERT_TRUE(visited[i]) << "Entry #" << i << " was never visited";
  }
}

// Test StringMapEntry::Create() method.
TEST_F(StringMapTest, StringMapEntryTest) {
  StringMap<uint32_t>::value_type* entry =
      StringMap<uint32_t>::value_type::Create(
          testKeyFirst, testKeyFirst + testKeyLength, 1u);
  EXPECT_STREQ(testKey, entry->first().data());
  EXPECT_EQ(1u, entry->second);
  free(entry);
}

// Test insert() method.
TEST_F(StringMapTest, InsertTest) {
  SCOPED_TRACE("InsertTest");
  testMap.insert(
      StringMap<uint32_t>::value_type::Create(
          testKeyFirst, testKeyFirst + testKeyLength,
          testMap.getAllocator(), 1u));
  assertSingleItemMap();
}

// Create a non-default constructable value
TEST_F(StringMapTest, NonDefaultConstructable) {
  struct StringMapTestStruct {
    StringMapTestStruct(int i) : i(i) {}
    StringMapTestStruct() LLVM_DELETED_FUNCTION;
    int i;
  };

  StringMap<StringMapTestStruct> t;
  t.GetOrCreateValue("Test", StringMapTestStruct(123));
  StringMap<StringMapTestStruct>::iterator iter = t.find("Test");
  ASSERT_NE(iter, t.end());
  ASSERT_EQ(iter->second.i, 123);
}

} // end anonymous namespace
<commit_msg>Fix break introduced in r198377 due to using a local type as a template parameter.<commit_after>//===- llvm/unittest/ADT/StringMapMap.cpp - StringMap unit tests ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/DataTypes.h"
using namespace llvm;

namespace {

// Test fixture
class StringMapTest : public testing::Test {
protected:
  StringMap<uint32_t> testMap;

  static const char testKey[];
  static const uint32_t testValue;
  static const char* testKeyFirst;
  static size_t testKeyLength;
  static const std::string testKeyStr;

  void assertEmptyMap() {
    // Size tests
    EXPECT_EQ(0u, testMap.size());
    EXPECT_TRUE(testMap.empty());

    // Iterator tests
    EXPECT_TRUE(testMap.begin() == testMap.end());

    // Lookup tests
    EXPECT_EQ(0u, testMap.count(testKey));
    EXPECT_EQ(0u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
    EXPECT_EQ(0u, testMap.count(testKeyStr));
    EXPECT_TRUE(testMap.find(testKey) == testMap.end());
    EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
                testMap.end());
    EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end());
  }

  void assertSingleItemMap() {
    // Size tests
    EXPECT_EQ(1u, testMap.size());
    EXPECT_FALSE(testMap.begin() == testMap.end());
    EXPECT_FALSE(testMap.empty());

    // Iterator tests
    StringMap<uint32_t>::iterator it = testMap.begin();
    EXPECT_STREQ(testKey, it->first().data());
    EXPECT_EQ(testValue, it->second);
    ++it;
    EXPECT_TRUE(it == testMap.end());

    // Lookup tests
    EXPECT_EQ(1u, testMap.count(testKey));
    EXPECT_EQ(1u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
    EXPECT_EQ(1u, testMap.count(testKeyStr));
    EXPECT_TRUE(testMap.find(testKey) == testMap.begin());
    EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
                testMap.begin());
    EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin());
  }
};

const char StringMapTest::testKey[] = "key";
const uint32_t StringMapTest::testValue = 1u;
const char* StringMapTest::testKeyFirst = testKey;
size_t StringMapTest::testKeyLength = sizeof(testKey) - 1;
const std::string StringMapTest::testKeyStr(testKey);

// Empty map tests.
TEST_F(StringMapTest, EmptyMapTest) {
  assertEmptyMap();
}

// Constant map tests.
TEST_F(StringMapTest, ConstEmptyMapTest) {
  const StringMap<uint32_t>& constTestMap = testMap;

  // Size tests
  EXPECT_EQ(0u, constTestMap.size());
  EXPECT_TRUE(constTestMap.empty());

  // Iterator tests
  EXPECT_TRUE(constTestMap.begin() == constTestMap.end());

  // Lookup tests
  EXPECT_EQ(0u, constTestMap.count(testKey));
  EXPECT_EQ(0u, constTestMap.count(StringRef(testKeyFirst, testKeyLength)));
  EXPECT_EQ(0u, constTestMap.count(testKeyStr));
  EXPECT_TRUE(constTestMap.find(testKey) == constTestMap.end());
  EXPECT_TRUE(constTestMap.find(StringRef(testKeyFirst, testKeyLength)) ==
              constTestMap.end());
  EXPECT_TRUE(constTestMap.find(testKeyStr) == constTestMap.end());
}

// A map with a single entry.
TEST_F(StringMapTest, SingleEntryMapTest) {
  testMap[testKey] = testValue;
  assertSingleItemMap();
}

// Test clear() method.
TEST_F(StringMapTest, ClearTest) {
  testMap[testKey] = testValue;
  testMap.clear();
  assertEmptyMap();
}

// Test erase(iterator) method.
TEST_F(StringMapTest, EraseIteratorTest) {
  testMap[testKey] = testValue;
  testMap.erase(testMap.begin());
  assertEmptyMap();
}

// Test erase(value) method.
TEST_F(StringMapTest, EraseValueTest) {
  testMap[testKey] = testValue;
  testMap.erase(testKey);
  assertEmptyMap();
}

// Test inserting two values and erasing one.
TEST_F(StringMapTest, InsertAndEraseTest) {
  testMap[testKey] = testValue;
  testMap["otherKey"] = 2;
  testMap.erase("otherKey");
  assertSingleItemMap();
}

TEST_F(StringMapTest, SmallFullMapTest) {
  // StringMap has a tricky corner case when the map is small (<8 buckets) and
  // it fills up through a balanced pattern of inserts and erases. This can
  // lead to inf-loops in some cases (PR13148) so we test it explicitly here.
  llvm::StringMap<int> Map(2);

  Map["eins"] = 1;
  Map["zwei"] = 2;
  Map["drei"] = 3;
  Map.erase("drei");
  Map.erase("eins");
  Map["veir"] = 4;
  Map["funf"] = 5;

  EXPECT_EQ(3u, Map.size());
  EXPECT_EQ(0, Map.lookup("eins"));
  EXPECT_EQ(2, Map.lookup("zwei"));
  EXPECT_EQ(0, Map.lookup("drei"));
  EXPECT_EQ(4, Map.lookup("veir"));
  EXPECT_EQ(5, Map.lookup("funf"));
}

// A more complex iteration test.
TEST_F(StringMapTest, IterationTest) {
  bool visited[100];

  // Insert 100 numbers into the map
  for (int i = 0; i < 100; ++i) {
    std::stringstream ss;
    ss << "key_" << i;
    testMap[ss.str()] = i;
    visited[i] = false;
  }

  // Iterate over all numbers and mark each one found.
  for (StringMap<uint32_t>::iterator it = testMap.begin();
      it != testMap.end(); ++it) {
    std::stringstream ss;
    ss << "key_" << it->second;
    ASSERT_STREQ(ss.str().c_str(), it->first().data());
    visited[it->second] = true;
  }

  // Ensure every number was visited.
  for (int i = 0; i < 100; ++i) {
    ASSERT_TRUE(visited[i]) << "Entry #" << i << " was never visited";
  }
}

// Test StringMapEntry::Create() method.
TEST_F(StringMapTest, StringMapEntryTest) {
  StringMap<uint32_t>::value_type* entry =
      StringMap<uint32_t>::value_type::Create(
          testKeyFirst, testKeyFirst + testKeyLength, 1u);
  EXPECT_STREQ(testKey, entry->first().data());
  EXPECT_EQ(1u, entry->second);
  free(entry);
}

// Test insert() method.
TEST_F(StringMapTest, InsertTest) {
  SCOPED_TRACE("InsertTest");
  testMap.insert(
      StringMap<uint32_t>::value_type::Create(
          testKeyFirst, testKeyFirst + testKeyLength,
          testMap.getAllocator(), 1u));
  assertSingleItemMap();
}

// Create a non-default constructable value
struct StringMapTestStruct {
  StringMapTestStruct(int i) : i(i) {}
  StringMapTestStruct() LLVM_DELETED_FUNCTION;
  int i;
};

TEST_F(StringMapTest, NonDefaultConstructable) {
  StringMap<StringMapTestStruct> t;
  t.GetOrCreateValue("Test", StringMapTestStruct(123));
  StringMap<StringMapTestStruct>::iterator iter = t.find("Test");
  ASSERT_NE(iter, t.end());
  ASSERT_EQ(iter->second.i, 123);
}

} // end anonymous namespace
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Andrew Kelley
 *
 * This file is part of zig, which is MIT licensed.
 * See http://opensource.org/licenses/MIT
 */

// TODO in this file we cast between __float128 and long double
// and lose precision. for now this is going to be a bug in
// the compiler because I don't want to add a dependency on libquadmath.
// when we self host we can use zig's f128 and the problem is fixed.

#include "bigfloat.hpp"
#include "bigint.hpp"
#include "buffer.hpp"
#include <math.h>
#include <errno.h>

void bigfloat_init_float(BigFloat *dest, __float128 x) {
    dest->value = x;
}

void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x) {
    dest->value = x->value;
}

void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {
    dest->value = 0.0;
    if (op->digit_count == 0)
        return;

    __float128 base = (__float128)UINT64_MAX;
    const uint64_t *digits = bigint_ptr(op);

    for (size_t i = op->digit_count - 1;;) {
        uint64_t digit = digits[i];
        dest->value *= base;
        dest->value += (__float128)digit;

        if (i == 0) {
            if (op->is_negative) {
                dest->value = -dest->value;
            }
            return;
        }
        i -= 1;
    }
}

int bigfloat_init_buf_base10(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len) {
    char *str_begin = (char *)buf_ptr;
    char *str_end;
    errno = 0;
    dest->value = (__float128)strtold(str_begin, &str_end);
    if (errno) {
        return ErrorOverflow;
    }
    assert(str_end <= ((char*)buf_ptr) + buf_len);
    return 0;
}

void bigfloat_add(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value + op2->value;
}

void bigfloat_negate(BigFloat *dest, const BigFloat *op) {
    dest->value = -op->value;
}

void bigfloat_sub(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value - op2->value;
}

void bigfloat_mul(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value * op2->value;
}

void bigfloat_div(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value / op2->value;
}

void bigfloat_div_trunc(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value / op2->value;
    if (dest->value >= 0.0) {
        dest->value = (__float128)floorl((long double)dest->value);
    } else {
        dest->value = (__float128)ceill((long double)dest->value);
    }
}

void bigfloat_div_floor(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = (__float128)floorl((long double)(op1->value / op2->value));
}

void bigfloat_rem(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = (__float128)fmodl((long double)op1->value, (long double)op2->value);
}

void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = (__float128)fmodl(fmodl((long double)op1->value, (long double)op2->value) + (long double)op2->value, (long double)op2->value);
}

void bigfloat_write_buf(Buf *buf, const BigFloat *op) {
    buf_appendf(buf, "%Lf", (long double)op->value);
}

Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {
    if (op1->value > op2->value) {
        return CmpGT;
    } else if (op1->value < op2->value) {
        return CmpLT;
    } else {
        return CmpEQ;
    }
}

// TODO this is wrong when compiler running on big endian systems. caught by tests
void bigfloat_write_ieee597(const BigFloat *op, uint8_t *buf, size_t bit_count, bool is_big_endian) {
    if (bit_count == 32) {
        float f32 = op->value;
        memcpy(buf, &f32, 4);
    } else if (bit_count == 64) {
        double f64 = op->value;
        memcpy(buf, &f64, 8);
    } else if (bit_count == 128) {
        __float128 f128 = op->value;
        memcpy(buf, &f128, 16);
    } else {
        zig_unreachable();
    }
}

// TODO this is wrong when compiler running on big endian systems. caught by tests
void bigfloat_read_ieee597(BigFloat *dest, const uint8_t *buf, size_t bit_count, bool is_big_endian) {
    if (bit_count == 32) {
        float f32;
        memcpy(&f32, buf, 4);
        dest->value = f32;
    } else if (bit_count == 64) {
        double f64;
        memcpy(&f64, buf, 8);
        dest->value = f64;
    } else if (bit_count == 128) {
        __float128 f128;
        memcpy(&f128, buf, 16);
        dest->value = f128;
    } else {
        zig_unreachable();
    }
}

double bigfloat_to_double(const BigFloat *bigfloat) {
    return bigfloat->value;
}

Cmp bigfloat_cmp_zero(const BigFloat *bigfloat) {
    if (bigfloat->value < 0.0) {
        return CmpLT;
    } else if (bigfloat->value > 0.0) {
        return CmpGT;
    } else {
        return CmpEQ;
    }
}

bool bigfloat_has_fraction(const BigFloat *bigfloat) {
    return ((__float128)floorl((long double)bigfloat->value)) != bigfloat->value;
}
<commit_msg>cast between __float128 and double to fix build in some places<commit_after>/*
 * Copyright (c) 2017 Andrew Kelley
 *
 * This file is part of zig, which is MIT licensed.
 * See http://opensource.org/licenses/MIT
 */

// TODO in this file we cast between __float128 and double
// and lose precision. for now this is going to be a bug in
// the compiler because I don't want to add a dependency on libquadmath.
// when we self host we can use zig's f128 and the problem is fixed.

#include "bigfloat.hpp"
#include "bigint.hpp"
#include "buffer.hpp"
#include <math.h>
#include <errno.h>

void bigfloat_init_float(BigFloat *dest, __float128 x) {
    dest->value = x;
}

void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x) {
    dest->value = x->value;
}

void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {
    dest->value = 0.0;
    if (op->digit_count == 0)
        return;

    __float128 base = (__float128)UINT64_MAX;
    const uint64_t *digits = bigint_ptr(op);

    for (size_t i = op->digit_count - 1;;) {
        uint64_t digit = digits[i];
        dest->value *= base;
        dest->value += (__float128)digit;

        if (i == 0) {
            if (op->is_negative) {
                dest->value = -dest->value;
            }
            return;
        }
        i -= 1;
    }
}

int bigfloat_init_buf_base10(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len) {
    char *str_begin = (char *)buf_ptr;
    char *str_end;
    errno = 0;
    dest->value = (__float128)strtod(str_begin, &str_end);
    if (errno) {
        return ErrorOverflow;
    }
    assert(str_end <= ((char*)buf_ptr) + buf_len);
    return 0;
}

void bigfloat_add(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value + op2->value;
}

void bigfloat_negate(BigFloat *dest, const BigFloat *op) {
    dest->value = -op->value;
}

void bigfloat_sub(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value - op2->value;
}

void bigfloat_mul(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value * op2->value;
}

void bigfloat_div(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value / op2->value;
}

void bigfloat_div_trunc(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = op1->value / op2->value;
    if (dest->value >= 0.0) {
        dest->value = (__float128)floor((double)dest->value);
    } else {
        dest->value = (__float128)ceil((double)dest->value);
    }
}

void bigfloat_div_floor(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = (__float128)floor((double)(op1->value / op2->value));
}

void bigfloat_rem(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = (__float128)fmod((double)op1->value, (double)op2->value);
}

void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
    dest->value = (__float128)fmod(fmod((double)op1->value, (double)op2->value) + (double)op2->value, (double)op2->value);
}

void bigfloat_write_buf(Buf *buf, const BigFloat *op) {
    buf_appendf(buf, "%f", (double)op->value);
}

Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {
    if (op1->value > op2->value) {
        return CmpGT;
    } else if (op1->value < op2->value) {
        return CmpLT;
    } else {
        return CmpEQ;
    }
}

// TODO this is wrong when compiler running on big endian systems. caught by tests
void bigfloat_write_ieee597(const BigFloat *op, uint8_t *buf, size_t bit_count, bool is_big_endian) {
    if (bit_count == 32) {
        float f32 = op->value;
        memcpy(buf, &f32, 4);
    } else if (bit_count == 64) {
        double f64 = op->value;
        memcpy(buf, &f64, 8);
    } else if (bit_count == 128) {
        __float128 f128 = op->value;
        memcpy(buf, &f128, 16);
    } else {
        zig_unreachable();
    }
}

// TODO this is wrong when compiler running on big endian systems. caught by tests
void bigfloat_read_ieee597(BigFloat *dest, const uint8_t *buf, size_t bit_count, bool is_big_endian) {
    if (bit_count == 32) {
        float f32;
        memcpy(&f32, buf, 4);
        dest->value = f32;
    } else if (bit_count == 64) {
        double f64;
        memcpy(&f64, buf, 8);
        dest->value = f64;
    } else if (bit_count == 128) {
        __float128 f128;
        memcpy(&f128, buf, 16);
        dest->value = f128;
    } else {
        zig_unreachable();
    }
}

double bigfloat_to_double(const BigFloat *bigfloat) {
    return bigfloat->value;
}

Cmp bigfloat_cmp_zero(const BigFloat *bigfloat) {
    if (bigfloat->value < 0.0) {
        return CmpLT;
    } else if (bigfloat->value > 0.0) {
        return CmpGT;
    } else {
        return CmpEQ;
    }
}

bool bigfloat_has_fraction(const BigFloat *bigfloat) {
    return ((__float128)floor((double)bigfloat->value)) != bigfloat->value;
}
<|endoftext|>


<commit_before>
#include "gmock/gmock.h"
#include "FileSystem.h"
#include "ListDirEndPoint.h"

TEST (ListDirEndPointTester, NotFound) {

    HTTP::Request request (HTTP::Method::GET, "/some/api/path");;
    HTTP::Response response;

    API::ListDirEndPoint endPoint ("/some/api/path", "I/do/not/exist");
    endPoint.Route (request, response);

    EXPECT_EQ (response.mCode, HTTP::Code::INTERNAL_SERVER_ERROR);
}

TEST (ListDirEndPointTester, ListFiles) {

    HTTP::Request request (HTTP::Method::GET, "/some/api/path");
    HTTP::Response response;

    std::string path (std::string ("../Test/FileEndPointTester"));
    API::ListDirEndPoint endPoint ("/some/api/path", path);

    endPoint.Route (request, response);

    EXPECT_EQ (response.mCode, HTTP::Code::OK);
    EXPECT_EQ (std::string ("[\"file.css\",\"file.csv\",\"file.html\",\"file.js\",\"file.json\",\"file.txt\"]"), response.GetBody ());
}

TEST (ListDirEndPointTester, ListFilesWithoutExtensions) {

    HTTP::Request request (HTTP::Method::GET, "/some/api/path");
    HTTP::Response response;

    std::string path (std::string ("../Test/FileEndPointTester"));
    API::ListDirEndPoint endPoint ("/some/api/path", path, false);

    endPoint.Route (request, response);

    EXPECT_EQ (response.mCode, HTTP::Code::OK);
    EXPECT_EQ (std::string ("[\"file\",\"file\",\"file\",\"file\",\"file\",\"file\"]"), response.GetBody ());
}<commit_msg>Fixed unit test<commit_after>
#include <json.hpp>
using json = nlohmann::json;

#include "gmock/gmock.h"
#include "FileSystem.h"
#include "ListDirEndPoint.h"

TEST (ListDirEndPointTester, NotFound) {

    HTTP::Request request (HTTP::Method::GET, "/some/api/path");;
    HTTP::Response response;

    API::ListDirEndPoint endPoint ("/some/api/path", "I/do/not/exist");
    endPoint.Route (request, response);

    EXPECT_EQ (response.mCode, HTTP::Code::INTERNAL_SERVER_ERROR);
}

TEST (ListDirEndPointTester, ListFiles) {

    HTTP::Request request (HTTP::Method::GET, "/some/api/path");
    HTTP::Response response;

    std::string path (std::string ("../Test/FileEndPointTester"));
    API::ListDirEndPoint endPoint ("/some/api/path", path);

    endPoint.Route (request, response);

    EXPECT_EQ (response.mCode, HTTP::Code::OK);

    json body;
    try {
        body = json::parse (response.GetBody ());
    }
    catch (...) {
        ASSERT_TRUE (false);
    }

    ASSERT_NE (std::find (std::begin (body), std::end (body), std::string ("file.css")), std::end (body));
    ASSERT_NE (std::find (std::begin (body), std::end (body), std::string ("file.csv")), std::end (body));
    ASSERT_NE (std::find (std::begin (body), std::end (body), std::string ("file.html")), std::end (body));
    ASSERT_NE (std::find (std::begin (body), std::end (body), std::string ("file.txt")), std::end (body));
    ASSERT_NE (std::find (std::begin (body), std::end (body), std::string ("file.css")), std::end (body));

}

TEST (ListDirEndPointTester, ListFilesWithoutExtensions) {

    HTTP::Request request (HTTP::Method::GET, "/some/api/path");
    HTTP::Response response;

    std::string path (std::string ("../Test/FileEndPointTester"));
    API::ListDirEndPoint endPoint ("/some/api/path", path, false);

    endPoint.Route (request, response);

    EXPECT_EQ (response.mCode, HTTP::Code::OK);
    EXPECT_EQ (std::string ("[\"file\",\"file\",\"file\",\"file\",\"file\",\"file\"]"), response.GetBody ());
}
<|endoftext|>


<commit_before>#include "ChunkPatcher.h"
#include "../stringtools.h"

ChunkPatcher::ChunkPatcher(void)
	: cb(NULL), require_unchanged(true)
{
}

void ChunkPatcher::setCallback(IChunkPatcherCallback *pCb)
{
	cb=pCb;
}

bool ChunkPatcher::ApplyPatch(IFile *file, IFile *patch)
{
	patch->Seek(0);
	file->Seek(0);
	_i64 patchf_pos=0;

	const unsigned int buffer_size=32768;
	char buf[buffer_size];

	if(patch->Read((char*)&filesize, sizeof(_i64))!=sizeof(_i64))
	{
		return false;
	}

	filesize = little_endian(filesize);

	patchf_pos+=sizeof(_i64);

	SPatchHeader next_header;
	next_header.patch_off=-1;
	bool has_header=true;
	for(_i64 file_pos=0,size=file->Size(); (file_pos<size && file_pos<filesize) || has_header;)
	{
		if(has_header && next_header.patch_off==-1)
		{
			has_header=readNextValidPatch(patch, patchf_pos, &next_header);
		}

		unsigned int tr=buffer_size;
		if(next_header.patch_off!=-1)
		{
			_i64 hoff=next_header.patch_off-file_pos;
			if(hoff>=0 && hoff<tr)
				tr=(unsigned int)hoff;
		}

		if(file_pos>=size || file_pos>=filesize || tr==0)
		{
			file_pos+=next_header.patch_size;

			while(next_header.patch_size>0)
			{
				_u32 r=patch->Read((char*)buf, (std::min)((unsigned int)buffer_size, next_header.patch_size));
				patchf_pos+=r;
				cb->next_chunk_patcher_bytes(buf, r, true);
				next_header.patch_size-=r;
			}
			file->Seek(file_pos);
			next_header.patch_off=-1;
		}
		else if(file_pos<size && file_pos<filesize)
		{
			while(tr>0 && file_pos<size && file_pos<filesize)
			{
				if(require_unchanged)
				{
					if(file_pos+tr>filesize)
					{
						tr=static_cast<unsigned int>(filesize-file_pos);
					}
					_u32 r=file->Read((char*)buf, tr);
					file_pos+=r;
					cb->next_chunk_patcher_bytes(buf, r, false);
					tr-=r;
				}
				else
				{
					if(file_pos+tr>filesize)
					{
						tr=static_cast<unsigned int>(filesize-file_pos);
					}
					file_pos+=tr;
					tr=0;
				}
			}
		}
	}
	return true;
}

bool ChunkPatcher::readNextValidPatch(IFile *patchf, _i64 &patchf_pos, SPatchHeader *patch_header)
{
	const unsigned int to_read=sizeof(_i64)+sizeof(unsigned int);
	do
	{
		_u32 r=patchf->Read((char*)&patch_header->patch_off, to_read);
		patchf_pos+=r;
		if(r!=to_read)
		{
			patch_header->patch_off=-1;
			patch_header->patch_size=0;
			return false;
		}
		else
		{
			patch_header->patch_off = little_endian(patch_header->patch_off);
			patch_header->patch_size = little_endian(patch_header->patch_size);
		}

		if(patch_header->patch_off==-1)
		{
			patchf_pos+=patch_header->patch_size;
			patchf->Seek(patchf_pos);
		}
	}
	while(patch_header->patch_off==-1);

	return true;
}

_i64 ChunkPatcher::getFilesize(void)
{
	return filesize;
}

void ChunkPatcher::setRequireUnchanged( bool b )
{
	require_unchanged=b;
}
<commit_msg>Call callback for correct seeking<commit_after>#include "ChunkPatcher.h"
#include "../stringtools.h"

ChunkPatcher::ChunkPatcher(void)
	: cb(NULL), require_unchanged(true)
{
}

void ChunkPatcher::setCallback(IChunkPatcherCallback *pCb)
{
	cb=pCb;
}

bool ChunkPatcher::ApplyPatch(IFile *file, IFile *patch)
{
	patch->Seek(0);
	file->Seek(0);
	_i64 patchf_pos=0;

	const unsigned int buffer_size=32768;
	char buf[buffer_size];

	if(patch->Read((char*)&filesize, sizeof(_i64))!=sizeof(_i64))
	{
		return false;
	}

	filesize = little_endian(filesize);

	patchf_pos+=sizeof(_i64);

	SPatchHeader next_header;
	next_header.patch_off=-1;
	bool has_header=true;
	for(_i64 file_pos=0,size=file->Size(); (file_pos<size && file_pos<filesize) || has_header;)
	{
		if(has_header && next_header.patch_off==-1)
		{
			has_header=readNextValidPatch(patch, patchf_pos, &next_header);
		}

		unsigned int tr=buffer_size;
		if(next_header.patch_off!=-1)
		{
			_i64 hoff=next_header.patch_off-file_pos;
			if(hoff>=0 && hoff<tr)
				tr=(unsigned int)hoff;
		}

		if(file_pos>=size || file_pos>=filesize || tr==0)
		{
			file_pos+=next_header.patch_size;

			while(next_header.patch_size>0)
			{
				_u32 r=patch->Read((char*)buf, (std::min)((unsigned int)buffer_size, next_header.patch_size));
				patchf_pos+=r;
				cb->next_chunk_patcher_bytes(buf, r, true);
				next_header.patch_size-=r;
			}
			file->Seek(file_pos);
			next_header.patch_off=-1;
		}
		else if(file_pos<size && file_pos<filesize)
		{
			while(tr>0 && file_pos<size && file_pos<filesize)
			{
				if(file_pos+tr>filesize)
				{
					tr=static_cast<unsigned int>(filesize-file_pos);
				}

				if(require_unchanged)
				{
					_u32 r=file->Read((char*)buf, tr);
					file_pos+=r;
					cb->next_chunk_patcher_bytes(buf, r, false);
					tr-=r;
				}
				else
				{
					file_pos+=tr;
					cb->next_chunk_patcher_bytes(NULL, tr, false);
					tr=0;
				}
			}
		}
	}
	return true;
}

bool ChunkPatcher::readNextValidPatch(IFile *patchf, _i64 &patchf_pos, SPatchHeader *patch_header)
{
	const unsigned int to_read=sizeof(_i64)+sizeof(unsigned int);
	do
	{
		_u32 r=patchf->Read((char*)&patch_header->patch_off, to_read);
		patchf_pos+=r;
		if(r!=to_read)
		{
			patch_header->patch_off=-1;
			patch_header->patch_size=0;
			return false;
		}
		else
		{
			patch_header->patch_off = little_endian(patch_header->patch_off);
			patch_header->patch_size = little_endian(patch_header->patch_size);
		}

		if(patch_header->patch_off==-1)
		{
			patchf_pos+=patch_header->patch_size;
			patchf->Seek(patchf_pos);
		}
	}
	while(patch_header->patch_off==-1);

	return true;
}

_i64 ChunkPatcher::getFilesize(void)
{
	return filesize;
}

void ChunkPatcher::setRequireUnchanged( bool b )
{
	require_unchanged=b;
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	DS3231 RTC ドライバー
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include "common/iica_io.hpp"
#include "common/time.h"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  DS3231 RTC テンプレートクラス
		@param[in]	I2C_IO	i2c I/O クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class I2C_IO>
	class DS3231 {

		// R/W ビットを含まない７ビット値
		static const uint8_t DS3231_ADR_ = 0x68;

		I2C_IO& i2c_io_;

		struct reg_t {
			uint8_t	reg[7];
			bool operator != (const reg_t& t) {
				for(uint8_t i = 0; i < 7; ++i) {
					if(reg[i] != t.reg[i]) return true;
				}
				return false;
			}
		};

		bool get_time_(reg_t& t) const {
			uint8_t reg[1];
			reg[0] = 0x00;	// set address
			if(!i2c_io_.send(DS3231_ADR_, reg, 1)) {
				return false;
			}
			if(!i2c_io_.recv(DS3231_ADR_, &t.reg[0], 7)) {
				return false;
			}
			return true;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	i2c	iica_io クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		DS3231(I2C_IO& i2c) : i2c_io_(i2c) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	開始
			@return エラーなら「false」を返す
		 */
		//-----------------------------------------------------------------//
		bool start() {
			uint8_t reg[2];
			reg[0] = 0x0e;	/// internal register address
			reg[1] = 0x00;
			return i2c_io_.send(DS3231_ADR_, reg, 2);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	DS3231 時間設定
			@param[in]	t	時間
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool set_time(time_t t) const {
			const tm* tp = gmtime(&t);
			uint8_t reg[7];
			reg[0] = ((tp->tm_sec  / 10) << 4) | (tp->tm_sec  % 10);  // 0 to 59
			reg[1] = ((tp->tm_min  / 10) << 4) | (tp->tm_min  % 10);  // 0 to 59
			reg[2] = ((tp->tm_hour / 10) << 4) | (tp->tm_hour % 10);  // 0 to 23
			reg[3] = tp->tm_wday + 1;  // 1 to 7
			reg[4] = ((tp->tm_mday / 10) << 4) | (tp->tm_mday % 10);  // 1 to 31
			uint8_t mon = tp->tm_mon + 1;
			reg[5] = ((mon / 10) << 4) | (mon % 10);  // 1 to 12
			uint16_t y = tp->tm_year % 100;
			reg[6] = ((y / 10) << 4) | (y % 10);  // 0 to 99
			return i2c_io_.send(DS3231_ADR_, 0x00, reg, 7);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	DS3231 時間呼び出し
			@param[in]	tp	取得時間
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool get_time(time_t& tp) const {
			// 二度読んで、同じだったら正しい時間とする
			reg_t t;
			{
				reg_t tmp;
				uint8_t n = 5; // ５回ループして正常に読めなかったら、エラーとする
				do {
					tmp = t;
					if(!get_time_(t)) return false;
					--n;
					if(n == 0) {
						return false;
					}
				} while(t != tmp) ;
			}
			tm ts;
			ts.tm_sec  = ((t.reg[0] >> 4) * 10) + (t.reg[0] & 0xf);
			ts.tm_min  = ((t.reg[1] >> 4) * 10) + (t.reg[1] & 0xf);
			ts.tm_hour = ((t.reg[2] >> 4) * 10) + (t.reg[2] & 0xf);
			ts.tm_mday = ((t.reg[4] >> 4) * 10) + (t.reg[4] & 0xf);
			ts.tm_mon  = ((((t.reg[5] & 0x10) >> 4) * 10) + (t.reg[5] & 0xf)) - 1;
			ts.tm_year = ((t.reg[6] >> 4) * 10) + (t.reg[6] & 0xf);
			ts.tm_year += 100;
			tp = mktime(&ts);
			return true;
		}
	};
}
<commit_msg>fix stack overflow<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	DS3231 RTC ドライバー
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include "common/iica_io.hpp"
#include "common/time.h"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  DS3231 RTC テンプレートクラス
		@param[in]	I2C_IO	i2c I/O クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class I2C_IO>
	class DS3231 {

		// R/W ビットを含まない７ビット値
		static const uint8_t DS3231_ADR_ = 0x68;

		I2C_IO& i2c_io_;

		struct reg_t {
			uint8_t	reg[7];
			bool operator != (const reg_t& t) {
				for(uint8_t i = 0; i < 7; ++i) {
					if(reg[i] != t.reg[i]) return true;
				}
				return false;
			}
		};

		bool get_time_(reg_t& t) const {
			uint8_t reg[1];
			reg[0] = 0x00;	// set address
			if(!i2c_io_.send(DS3231_ADR_, reg, 1)) {
				return false;
			}
			if(!i2c_io_.recv(DS3231_ADR_, &t.reg[0], 7)) {
				return false;
			}
			return true;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	i2c	iica_io クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		DS3231(I2C_IO& i2c) : i2c_io_(i2c) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	開始
			@return エラーなら「false」を返す
		 */
		//-----------------------------------------------------------------//
		bool start() {
			uint8_t reg[2];
			reg[0] = 0x0e;	/// internal register address
			reg[1] = 0x00;
			return i2c_io_.send(DS3231_ADR_, reg, 2);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	DS3231 時間設定
			@param[in]	t	時間
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool set_time(time_t t) const {
			const tm* tp = gmtime(&t);
			uint8_t reg[7];
			reg[0] = ((tp->tm_sec  / 10) << 4) | (tp->tm_sec  % 10);  // 0 to 59
			reg[1] = ((tp->tm_min  / 10) << 4) | (tp->tm_min  % 10);  // 0 to 59
			reg[2] = ((tp->tm_hour / 10) << 4) | (tp->tm_hour % 10);  // 0 to 23
			reg[3] = tp->tm_wday + 1;  // 1 to 7
			reg[4] = ((tp->tm_mday / 10) << 4) | (tp->tm_mday % 10);  // 1 to 31
			uint8_t mon = tp->tm_mon + 1;
			reg[5] = ((mon / 10) << 4) | (mon % 10);  // 1 to 12
			uint16_t y = tp->tm_year % 100;
			reg[6] = ((y / 10) << 4) | (y % 10);  // 0 to 99
			return i2c_io_.send(DS3231_ADR_, 0x00, reg, 7);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	DS3231 時間呼び出し
			@param[in]	tp	取得時間
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool get_time(time_t& tp) const {
			reg_t t;
			reg_t tmp;
			tm ts;
			// 二度読んで、同じだったら正しい時間とする
			uint8_t n = 5; // ５回ループして正常に読めなかったら、エラーとする
			do {
				tmp = t;
				if(!get_time_(t)) return false;
				--n;
				if(n == 0) {
					return false;
				}
			} while(t != tmp) ;

			ts.tm_sec  = ((t.reg[0] >> 4) * 10) + (t.reg[0] & 0xf);
			ts.tm_min  = ((t.reg[1] >> 4) * 10) + (t.reg[1] & 0xf);
			ts.tm_hour = ((t.reg[2] >> 4) * 10) + (t.reg[2] & 0xf);
			ts.tm_mday = ((t.reg[4] >> 4) * 10) + (t.reg[4] & 0xf);
			ts.tm_mon  = ((((t.reg[5] & 0x10) >> 4) * 10) + (t.reg[5] & 0xf)) - 1;
			ts.tm_year = ((t.reg[6] >> 4) * 10) + (t.reg[6] & 0xf);
			ts.tm_year += 100;
			tp = mktime(&ts);
			return true;
		}
	};
}
<|endoftext|>


<commit_before>/*************************************************************************/
/*  gd_mono_internals.cpp                                                */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "gd_mono_internals.h"

#include "../csharp_script.h"
#include "../mono_gc_handle.h"
#include "../utils/macros.h"
#include "gd_mono_class.h"
#include "gd_mono_marshal.h"
#include "gd_mono_utils.h"

#include "core/debugger/engine_debugger.h"
#include "core/debugger/script_debugger.h"

#include <mono/metadata/exception.h>

namespace GDMonoInternals {
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
	// This method should not fail

	CRASH_COND(!unmanaged);

	// All mono objects created from the managed world (e.g.: 'new Player()')
	// need to have a CSharpScript in order for their methods to be callable from the unmanaged side

	Reference *ref = Object::cast_to<Reference>(unmanaged);

	GDMonoClass *klass = GDMonoUtils::get_object_class(managed);

	CRASH_COND(!klass);

	GDMonoClass *native = GDMonoUtils::get_class_native_base(klass);

	CRASH_COND(native == nullptr);

	if (native == klass) {
		// If it's just a wrapper Godot class and not a custom inheriting class, then attach a
		// script binding instead. One of the advantages of this is that if a script is attached
		// later and it's not a C# script, then the managed object won't have to be disposed.
		// Another reason for doing this is that this instance could outlive CSharpLanguage, which would
		// be problematic when using a script. See: https://github.com/godotengine/godot/issues/25621

		CSharpScriptBinding script_binding;

		script_binding.inited = true;
		script_binding.type_name = NATIVE_GDMONOCLASS_NAME(klass);
		script_binding.wrapper_class = klass;
		script_binding.gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed);
		script_binding.owner = unmanaged;

		if (ref) {
			// Unsafe refcount increment. The managed instance also counts as a reference.
			// This way if the unmanaged world has no references to our owner
			// but the managed instance is alive, the refcount will be 1 instead of 0.
			// See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr)

			// May not me referenced yet, so we must use init_ref() instead of reference()
			if (ref->init_ref()) {
				CSharpLanguage::get_singleton()->post_unsafe_reference(ref);
			}
		}

		// The object was just created, no script instance binding should have been attached
		CRASH_COND(unmanaged->has_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index()));

		void *data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding);

		// Should be thread safe because the object was just created and nothing else should be referencing it
		unmanaged->set_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index(), data);

		return;
	}

	MonoGCHandleData gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed);

	Ref<CSharpScript> script = CSharpScript::create_for_managed_type(klass, native);

	CRASH_COND(script.is_null());

	CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);

	unmanaged->set_script_and_instance(script, csharp_instance);
}

void unhandled_exception(MonoException *p_exc) {
	mono_print_unhandled_exception((MonoObject *)p_exc);
	gd_unhandled_exception_event(p_exc);

	if (GDMono::get_singleton()->get_unhandled_exception_policy() == GDMono::POLICY_TERMINATE_APP) {
		// Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders
		mono_unhandled_exception((MonoObject *)p_exc);
		GDMono::unhandled_exception_hook((MonoObject *)p_exc, nullptr);
		GD_UNREACHABLE();
	} else {
#ifdef DEBUG_ENABLED
		GDMonoUtils::debug_send_unhandled_exception_error(p_exc);
		if (EngineDebugger::is_active()) {
			EngineDebugger::get_singleton()->poll_events(false);
		}
#endif
	}
}

void gd_unhandled_exception_event(MonoException *p_exc) {
	MonoImage *mono_image = GDMono::get_singleton()->get_core_api_assembly()->get_image();

	MonoClass *gd_klass = mono_class_from_name(mono_image, "Godot", "GD");
	MonoMethod *unhandled_exception_method = mono_class_get_method_from_name(gd_klass, "OnUnhandledException", -1);
	void *args[1];
	args[0] = p_exc;
	mono_runtime_invoke(unhandled_exception_method, nullptr, (void **)args, nullptr);
}
} // namespace GDMonoInternals
<commit_msg>Add mutex to protect script bindings<commit_after>/*************************************************************************/
/*  gd_mono_internals.cpp                                                */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "gd_mono_internals.h"

#include "../csharp_script.h"
#include "../mono_gc_handle.h"
#include "../utils/macros.h"
#include "gd_mono_class.h"
#include "gd_mono_marshal.h"
#include "gd_mono_utils.h"

#include "core/debugger/engine_debugger.h"
#include "core/debugger/script_debugger.h"

#include <mono/metadata/exception.h>

namespace GDMonoInternals {
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
	// This method should not fail

	CRASH_COND(!unmanaged);

	// All mono objects created from the managed world (e.g.: 'new Player()')
	// need to have a CSharpScript in order for their methods to be callable from the unmanaged side

	Reference *ref = Object::cast_to<Reference>(unmanaged);

	GDMonoClass *klass = GDMonoUtils::get_object_class(managed);

	CRASH_COND(!klass);

	GDMonoClass *native = GDMonoUtils::get_class_native_base(klass);

	CRASH_COND(native == nullptr);

	if (native == klass) {
		// If it's just a wrapper Godot class and not a custom inheriting class, then attach a
		// script binding instead. One of the advantages of this is that if a script is attached
		// later and it's not a C# script, then the managed object won't have to be disposed.
		// Another reason for doing this is that this instance could outlive CSharpLanguage, which would
		// be problematic when using a script. See: https://github.com/godotengine/godot/issues/25621

		CSharpScriptBinding script_binding;

		script_binding.inited = true;
		script_binding.type_name = NATIVE_GDMONOCLASS_NAME(klass);
		script_binding.wrapper_class = klass;
		script_binding.gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed);
		script_binding.owner = unmanaged;

		if (ref) {
			// Unsafe refcount increment. The managed instance also counts as a reference.
			// This way if the unmanaged world has no references to our owner
			// but the managed instance is alive, the refcount will be 1 instead of 0.
			// See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr)

			// May not me referenced yet, so we must use init_ref() instead of reference()
			if (ref->init_ref()) {
				CSharpLanguage::get_singleton()->post_unsafe_reference(ref);
			}
		}

		// The object was just created, no script instance binding should have been attached
		CRASH_COND(unmanaged->has_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index()));

		void *data;
		{
			MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
			data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding);
		}

		// Should be thread safe because the object was just created and nothing else should be referencing it
		unmanaged->set_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index(), data);

		return;
	}

	MonoGCHandleData gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed);

	Ref<CSharpScript> script = CSharpScript::create_for_managed_type(klass, native);

	CRASH_COND(script.is_null());

	CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);

	unmanaged->set_script_and_instance(script, csharp_instance);
}

void unhandled_exception(MonoException *p_exc) {
	mono_print_unhandled_exception((MonoObject *)p_exc);
	gd_unhandled_exception_event(p_exc);

	if (GDMono::get_singleton()->get_unhandled_exception_policy() == GDMono::POLICY_TERMINATE_APP) {
		// Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders
		mono_unhandled_exception((MonoObject *)p_exc);
		GDMono::unhandled_exception_hook((MonoObject *)p_exc, nullptr);
		GD_UNREACHABLE();
	} else {
#ifdef DEBUG_ENABLED
		GDMonoUtils::debug_send_unhandled_exception_error(p_exc);
		if (EngineDebugger::is_active()) {
			EngineDebugger::get_singleton()->poll_events(false);
		}
#endif
	}
}

void gd_unhandled_exception_event(MonoException *p_exc) {
	MonoImage *mono_image = GDMono::get_singleton()->get_core_api_assembly()->get_image();

	MonoClass *gd_klass = mono_class_from_name(mono_image, "Godot", "GD");
	MonoMethod *unhandled_exception_method = mono_class_get_method_from_name(gd_klass, "OnUnhandledException", -1);
	void *args[1];
	args[0] = p_exc;
	mono_runtime_invoke(unhandled_exception_method, nullptr, (void **)args, nullptr);
}
} // namespace GDMonoInternals
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include "CudaTypes.h"

#include <sofa/component/misc/ExtraMonitor.h>
#include <sofa/component/misc/ExtraMonitor.inl>
#include <sofa/component/misc/Monitor.inl>

#include <sofa/core/ObjectFactory.h>
#include <sofa/defaulttype/RigidTypes.h>

namespace sofa
{

namespace component
{

namespace misc
{

template class ExtraMonitor<gpu::cuda::CudaRigid3fTypes>;
#ifdef SOFA_GPU_CUDA_DOUBLE
template class ExtraMonitor<gpu::cuda::CudaRigid3dTypes>;
#endif // SOFA_GPU_CUDA_DOUBLE

}// namespace misc

}// namespace component

namespace gpu
{

namespace cuda
{

SOFA_DECL_CLASS(CudaExtraMonitor)

int ExtraMonitorCudaClass = core::RegisterObject("Supports GPU-side computation using CUDA")
        .add< component::misc::ExtraMonitor<CudaRigid3fTypes> >()
#ifdef SOFA_GPU_CUDA_DOUBLE
        .add< component::misc::ExtraMonitor<CudaRigid3dTypes> >()
#endif // SOFA_GPU_CUDA_DOUBLE
        ;

}// namespace cuda

}// namespace gpu

}// namespace sofa
<commit_msg>r10064/sofa-dev : ADD: ExtraMonitor on CudaVec6 types.<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include "CudaTypes.h"

#include <sofa/component/misc/ExtraMonitor.h>
#include <sofa/component/misc/ExtraMonitor.inl>
#include <sofa/component/misc/Monitor.inl>

#include <sofa/core/ObjectFactory.h>
#include <sofa/defaulttype/RigidTypes.h>

namespace sofa
{

namespace component
{

namespace misc
{

template class ExtraMonitor<gpu::cuda::CudaRigid3fTypes>;
template class ExtraMonitor<gpu::cuda::CudaVec6fTypes>;
#ifdef SOFA_GPU_CUDA_DOUBLE
template class ExtraMonitor<gpu::cuda::CudaRigid3dTypes>;
template class ExtraMonitor<gpu::cuda::CudaVec6dTypes>;
#endif // SOFA_GPU_CUDA_DOUBLE

}// namespace misc

}// namespace component

namespace gpu
{

namespace cuda
{

SOFA_DECL_CLASS(CudaExtraMonitor)

int ExtraMonitorCudaClass = core::RegisterObject("Supports GPU-side computation using CUDA")
        .add< component::misc::ExtraMonitor<CudaRigid3fTypes> >()
        .add< component::misc::ExtraMonitor<CudaVec6fTypes> >()
#ifdef SOFA_GPU_CUDA_DOUBLE
        .add< component::misc::ExtraMonitor<CudaRigid3dTypes> >()
        .add< component::misc::ExtraMonitor<CudaVec6dTypes> >()
#endif // SOFA_GPU_CUDA_DOUBLE
        ;

}// namespace cuda

}// namespace gpu

}// namespace sofa
<|endoftext|>