<commit_before>/*****************************************************************************
  shuffleBed.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
#include "lineFileUtilities.h"
#include "shuffleBed.h"

BedShuffle::BedShuffle(string &bedFile, string &genomeFile,
                       string &excludeFile, string &includeFile,
                       bool haveSeed, bool haveExclude,
                       bool haveInclude, bool sameChrom,
                       float overlapFraction, int seed,
                       bool chooseChrom, bool isBedpe) {

    _bedFile         = bedFile;
    _genomeFile      = genomeFile;
    _excludeFile     = excludeFile;
    _includeFile     = includeFile;
    _sameChrom       = sameChrom;
    _haveExclude     = haveExclude;
    _haveInclude     = haveInclude;
    _overlapFraction = overlapFraction;
    _haveSeed        = haveSeed;
    _chooseChrom     = chooseChrom;
    _isBedpe         = isBedpe;

    // use the supplied seed for the random
    // number generation if given.  else,
    // roll our own.
    if (_haveSeed) {
        _seed = seed;
        srand(seed);
    }
    else {
        // thanks to Rob Long for the tip.
        _seed = (unsigned)time(0)+(unsigned)getpid();
        srand(_seed);
    }

    if (_isBedpe == false)
        _bed         = new BedFile(bedFile);
    else
        _bedpe       = new BedFilePE(bedFile);

    _genome      = new GenomeFile(genomeFile);
    _chroms      = _genome->getChromList();
    _numChroms   = _genome->getNumberOfChroms();
    _genomeSize  = _genome->getGenomeSize();

    if (_haveExclude) {
        _exclude = new BedFile(excludeFile);
        _exclude->loadBedFileIntoMap();
    }

    if (_haveInclude) {
        _include = new BedFile(includeFile);
        _include->loadBedFileIntoMapNoBin();

        _numIncludeChroms = 0;
        masterBedMapNoBin::const_iterator it    = _include->bedMapNoBin.begin();
        masterBedMapNoBin::const_iterator itEnd = _include->bedMapNoBin.end();
        for(; it != itEnd; ++it) {
            _includeChroms.push_back(it->first);
            _numIncludeChroms++;
        }
    }

    if (_haveExclude == true && _haveInclude == false)
        ShuffleWithExclusions();
    else if  (_haveExclude == false && _haveInclude == true)
        ShuffleWithInclusions();
    else
        Shuffle();
}

BedShuffle::~BedShuffle(void) {

}

void BedShuffle::Shuffle() {

    if (_isBedpe == false) {
        BED bedEntry;
        _bed->Open();
        while (_bed->GetNextBed(bedEntry)) {
            if (_bed->_status == BED_VALID) {
                ChooseLocus(bedEntry);
                _bed->reportBedNewLine(bedEntry);
            }
        }
        _bed->Close();
    }
    // BEDPE input
    else {
        int lineNum = 0;     // current input line number
        BedLineStatus status;

        BEDPE bedEntry;
        _bedpe->Open();
        while ((status = _bedpe->GetNextBedPE(bedEntry, lineNum)) != BED_INVALID)
        {
            if (status == BED_VALID) {
                ChoosePairedLocus(bedEntry);
                _bedpe->reportBedPENewLine(bedEntry);
            }
        }
        _bedpe->Close();
    }
}

void BedShuffle::ShuffleWithExclusions() {

    if (_isBedpe == false) {
        BED bedEntry;
        _bed->Open();
        while (_bed->GetNextBed(bedEntry)) {
            if (_bed->_status == BED_VALID) {
                // keep looking as long as the chosen
                // locus happens to overlap with regions
                // that the user wishes to exclude.
                int  tries = 0;
                bool haveOverlap = false;
                do
                {
                    // choose a new locus
                    ChooseLocus(bedEntry);
                    haveOverlap = _exclude->anyHits(bedEntry.chrom,
                                                    bedEntry.start,
                                                    bedEntry.end,
                                                    bedEntry.strand,
                                                    false, false,
                                                    _overlapFraction, false);
                    tries++;
                } while ((haveOverlap == true) && (tries <= MAX_TRIES));

                if (tries > MAX_TRIES) {
                    cerr << "Error, line " << _bed->_lineNum
                         << ": tried " << MAX_TRIES
                         << " potential loci for entry, but could not avoid "
                         << "excluded regions.  Ignoring entry and moving on."
                         << endl;                }
                else {
                    _bed->reportBedNewLine(bedEntry);
                }
            }
        }
        _bed->Close();
    }
    // BEDPE input
    else {
        int lineNum = 0;     // current input line number
        BedLineStatus status;

        BEDPE bedEntry;
        _bedpe->Open();
        while ((status = _bedpe->GetNextBedPE(bedEntry, lineNum)) != BED_INVALID)
        {
            if (status == BED_VALID) {
                // keep looking as long as the chosen
                // locus happens to overlap with regions
                // that the user wishes to exclude.
                int  tries = 0;
                bool haveOverlap1 = false;
                bool haveOverlap2 = false;
                do
                {
                    // choose a new locus
                    ChoosePairedLocus(bedEntry);
                    haveOverlap1 = _exclude->anyHits(bedEntry.chrom1,
                                                     bedEntry.start1,
                                                     bedEntry.end1,
                                                     bedEntry.strand1,
                                                     false, false,
                                                     _overlapFraction, false);

                    haveOverlap2 = _exclude->anyHits(bedEntry.chrom2,
                                                     bedEntry.start2,
                                                     bedEntry.end2,
                                                     bedEntry.strand2,
                                                     false, false,
                                                     _overlapFraction, false);
                    tries++;
                } while (((haveOverlap1 == true) || (haveOverlap2 == true))
                        && (tries <= MAX_TRIES));

                if (tries > MAX_TRIES) {
                    cerr << "Error, line " << _bed->_lineNum
                         << ": tried " << MAX_TRIES
                         << " potential loci for entry, but could not avoid "
                         << "excluded regions.  Ignoring entry and moving on."
                         << endl;
                }
                else {
                    _bedpe->reportBedPENewLine(bedEntry);
                }

            }
        }
        _bedpe->Close();
    }
}

void BedShuffle::ShuffleWithInclusions() {

    BED bedEntry;     // used to store the current BED line from the BED file.

    _bed->Open();
    while (_bed->GetNextBed(bedEntry)) {
        if (_bed->_status == BED_VALID) {
            // choose a new locus
            ChooseLocusFromInclusionFile(bedEntry);
            _bed->reportBedNewLine(bedEntry);
        }
    }
    _bed->Close();
}

void BedShuffle::ChooseLocus(BED &bedEntry) {

    string randomChrom;
    CHRPOS randomStart;
    CHRPOS chromSize;
    string chrom    = bedEntry.chrom;
    CHRPOS start    = bedEntry.start;
    CHRPOS end      = bedEntry.end;
    CHRPOS length   = end - start;

    // choose a position randomly among the _entire_ genome.
    if (_chooseChrom == false)
    {
        do
        {
            // we need to combine two consective calls to rand()
            // because RAND_MAX is 2^31 (2147483648), whereas
            // mammalian genomes are obviously much larger.
            uint32_t randStart = ((rand() << 31) | rand()) % _genomeSize;
            // use the above randomStart (e.g., for human 0..3.1billion)
            // to identify the chrom and start on that chrom.
            pair<string, int> location = _genome->projectOnGenome(randStart);
            bedEntry.chrom = location.first;
            bedEntry.start = location.second;
            bedEntry.end   = bedEntry.start + length;
            chromSize      = _genome->getChromSize(location.first);
        } while (bedEntry.end > chromSize);
        // keep looking if we have exceeded the end of the chrom.
    }
    // OLD, quite arguably flawed, method.
    // 1. Choose a chrom randomly (i.e., not weighted by size)
    // 2. Choose a position on that chrom randomly
    else
    {
        do
        {
            if (_sameChrom == false) {
                randomChrom    = _chroms[rand() % _numChroms];
                chromSize      = _genome->getChromSize(randomChrom);
                randomStart    = rand() % chromSize;
                bedEntry.chrom = randomChrom;
                bedEntry.start = randomStart;
                bedEntry.end   = randomStart + length;
            }
            else {
                chromSize      = _genome->getChromSize(chrom);
                randomStart    = rand() % chromSize;
                bedEntry.start = randomStart;
                bedEntry.end   = randomStart + length;
            }
        } while (bedEntry.end > chromSize);
    }
}

void BedShuffle::ChoosePairedLocus(BEDPE &b) {

    CHRPOS foot1_len = b.end1 - b.start1;
    CHRPOS foot2_len = b.end2 - b.start2;
    CHRPOS length    = b.end2 - b.start1;

    if (b.chrom1 == b.chrom2)
    {
        CHRPOS chromSize;
        do
        {
            uint32_t randStart = ((rand() << 31) | rand()) % _genomeSize;
            pair<string, int> location = _genome->projectOnGenome(randStart);
            b.chrom1  = location.first;
            b.chrom2  = location.first;
            b.start1  = location.second;
            b.end1    = b.start1 + foot1_len;
            b.end2    = b.start1 + length;
            b.start2  = b.end2 - foot2_len;
            chromSize      = _genome->getChromSize(location.first);
        } while ((b.end1 > chromSize) ||
                (b.start2 > chromSize) ||
                (b.end2 > chromSize));
        // keep looking if we have exceeded the end of the chrom.
    }
    else
    {
        CHRPOS chromSize1, chromSize2;
        do
        {
            uint32_t rand1Start = ((rand() << 31) | rand()) % _genomeSize;
            uint32_t rand2Start = ((rand() << 31) | rand()) % _genomeSize;
            pair<string, int> location1 = _genome->projectOnGenome(rand1Start);
            pair<string, int> location2 = _genome->projectOnGenome(rand2Start);

            b.chrom1  = location1.first;
            b.chrom2  = location2.first;
            b.start1  = location1.second;
            b.start2  = location2.second;

            b.end1    = b.start1 + foot1_len;
            b.end2    = b.start2 + foot2_len;
            chromSize1      = _genome->getChromSize(location1.first);
            chromSize2      = _genome->getChromSize(location2.first);

        } while ((b.end1 > chromSize1) ||
                (b.end2 > chromSize2));
        // keep looking if we have exceeded the end of the chrom.
    }
}

void BedShuffle::ChooseLocusFromInclusionFile(BED &bedEntry) {

    string chrom    = bedEntry.chrom;
    CHRPOS length   = bedEntry.end - bedEntry.start;

    string randomChrom;
    CHRPOS randomStart;
    BED includeInterval;

    if (_sameChrom == false) {

        // grab a random chromosome from the inclusion file.
        randomChrom            = _includeChroms[rand() % _numIncludeChroms];
        // get the number of inclusion intervals for that chrom
        size_t size            =  _include->bedMapNoBin[randomChrom].size();
        // grab a random interval on the chosen chromosome.
        size_t interval        = rand() % size;
        // retreive a ranom -incl interval on the selected chrom
        includeInterval        = _include->bedMapNoBin[randomChrom][interval];

        bedEntry.chrom = randomChrom;
    }
    else {
        // get the number of inclusion intervals for the original chrom
        size_t size =  _include->bedMapNoBin[chrom].size();
        // grab a random interval on the chosen chromosome.
        includeInterval       = _include->bedMapNoBin[chrom][rand() % size];
    }

    randomStart    = includeInterval.start + rand() % (includeInterval.size());
    bedEntry.start = randomStart;
    bedEntry.end   = randomStart + length;

    // use recursion to ensure that the chosen location
    // doesn't go past the end of the chrom
    if (bedEntry.end > ((size_t) _genome->getChromSize(chrom))) {
        //bedEntry.end = _genome->getChromSize(chrom);
        ChooseLocusFromInclusionFile(bedEntry);
    }
}
<commit_msg>reset each bedpe<commit_after>/*****************************************************************************
  shuffleBed.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
#include "lineFileUtilities.h"
#include "shuffleBed.h"

BedShuffle::BedShuffle(string &bedFile, string &genomeFile,
                       string &excludeFile, string &includeFile,
                       bool haveSeed, bool haveExclude,
                       bool haveInclude, bool sameChrom,
                       float overlapFraction, int seed,
                       bool chooseChrom, bool isBedpe) {

    _bedFile         = bedFile;
    _genomeFile      = genomeFile;
    _excludeFile     = excludeFile;
    _includeFile     = includeFile;
    _sameChrom       = sameChrom;
    _haveExclude     = haveExclude;
    _haveInclude     = haveInclude;
    _overlapFraction = overlapFraction;
    _haveSeed        = haveSeed;
    _chooseChrom     = chooseChrom;
    _isBedpe         = isBedpe;

    // use the supplied seed for the random
    // number generation if given.  else,
    // roll our own.
    if (_haveSeed) {
        _seed = seed;
        srand(seed);
    }
    else {
        // thanks to Rob Long for the tip.
        _seed = (unsigned)time(0)+(unsigned)getpid();
        srand(_seed);
    }

    if (_isBedpe == false)
        _bed         = new BedFile(bedFile);
    else
        _bedpe       = new BedFilePE(bedFile);

    _genome      = new GenomeFile(genomeFile);
    _chroms      = _genome->getChromList();
    _numChroms   = _genome->getNumberOfChroms();
    _genomeSize  = _genome->getGenomeSize();

    if (_haveExclude) {
        _exclude = new BedFile(excludeFile);
        _exclude->loadBedFileIntoMap();
    }

    if (_haveInclude) {
        _include = new BedFile(includeFile);
        _include->loadBedFileIntoMapNoBin();

        _numIncludeChroms = 0;
        masterBedMapNoBin::const_iterator it    = _include->bedMapNoBin.begin();
        masterBedMapNoBin::const_iterator itEnd = _include->bedMapNoBin.end();
        for(; it != itEnd; ++it) {
            _includeChroms.push_back(it->first);
            _numIncludeChroms++;
        }
    }

    if (_haveExclude == true && _haveInclude == false)
        ShuffleWithExclusions();
    else if  (_haveExclude == false && _haveInclude == true)
        ShuffleWithInclusions();
    else
        Shuffle();
}

BedShuffle::~BedShuffle(void) {

}

void BedShuffle::Shuffle() {

    if (_isBedpe == false) {
        BED bedEntry;
        _bed->Open();
        while (_bed->GetNextBed(bedEntry)) {
            if (_bed->_status == BED_VALID) {
                ChooseLocus(bedEntry);
                _bed->reportBedNewLine(bedEntry);
            }
        }
        _bed->Close();
    }
    // BEDPE input
    else {
        int lineNum = 0;     // current input line number
        BedLineStatus status;

        BEDPE bedEntry, nullBedPE;
        _bedpe->Open();
        while ((status = _bedpe->GetNextBedPE(bedEntry, lineNum)) != BED_INVALID)
        {
            if (status == BED_VALID) {
                ChoosePairedLocus(bedEntry);
                _bedpe->reportBedPENewLine(bedEntry);
            }
            bedEntry = nullBedPE;
        }
        _bedpe->Close();
    }
}

void BedShuffle::ShuffleWithExclusions() {

    if (_isBedpe == false) {
        BED bedEntry;
        _bed->Open();
        while (_bed->GetNextBed(bedEntry)) {
            if (_bed->_status == BED_VALID) {
                // keep looking as long as the chosen
                // locus happens to overlap with regions
                // that the user wishes to exclude.
                int  tries = 0;
                bool haveOverlap = false;
                do
                {
                    // choose a new locus
                    ChooseLocus(bedEntry);
                    haveOverlap = _exclude->anyHits(bedEntry.chrom,
                                                    bedEntry.start,
                                                    bedEntry.end,
                                                    bedEntry.strand,
                                                    false, false,
                                                    _overlapFraction, false);
                    tries++;
                } while ((haveOverlap == true) && (tries <= MAX_TRIES));

                if (tries > MAX_TRIES) {
                    cerr << "Error, line " << _bed->_lineNum
                         << ": tried " << MAX_TRIES
                         << " potential loci for entry, but could not avoid "
                         << "excluded regions.  Ignoring entry and moving on."
                         << endl;                }
                else {
                    _bed->reportBedNewLine(bedEntry);
                }
            }
        }
        _bed->Close();
    }
    // BEDPE input
    else {
        int lineNum = 0;     // current input line number
        BedLineStatus status;

        BEDPE bedEntry;
        _bedpe->Open();
        while ((status = _bedpe->GetNextBedPE(bedEntry, lineNum)) != BED_INVALID)
        {
            if (status == BED_VALID) {
                // keep looking as long as the chosen
                // locus happens to overlap with regions
                // that the user wishes to exclude.
                int  tries = 0;
                bool haveOverlap1 = false;
                bool haveOverlap2 = false;
                do
                {
                    // choose a new locus
                    ChoosePairedLocus(bedEntry);
                    haveOverlap1 = _exclude->anyHits(bedEntry.chrom1,
                                                     bedEntry.start1,
                                                     bedEntry.end1,
                                                     bedEntry.strand1,
                                                     false, false,
                                                     _overlapFraction, false);

                    haveOverlap2 = _exclude->anyHits(bedEntry.chrom2,
                                                     bedEntry.start2,
                                                     bedEntry.end2,
                                                     bedEntry.strand2,
                                                     false, false,
                                                     _overlapFraction, false);
                    tries++;
                } while (((haveOverlap1 == true) || (haveOverlap2 == true))
                        && (tries <= MAX_TRIES));

                if (tries > MAX_TRIES) {
                    cerr << "Error, line " << _bed->_lineNum
                         << ": tried " << MAX_TRIES
                         << " potential loci for entry, but could not avoid "
                         << "excluded regions.  Ignoring entry and moving on."
                         << endl;
                }
                else {
                    _bedpe->reportBedPENewLine(bedEntry);
                }

            }
        }
        _bedpe->Close();
    }
}

void BedShuffle::ShuffleWithInclusions() {

    BED bedEntry;     // used to store the current BED line from the BED file.

    _bed->Open();
    while (_bed->GetNextBed(bedEntry)) {
        if (_bed->_status == BED_VALID) {
            // choose a new locus
            ChooseLocusFromInclusionFile(bedEntry);
            _bed->reportBedNewLine(bedEntry);
        }
    }
    _bed->Close();
}

void BedShuffle::ChooseLocus(BED &bedEntry) {

    string randomChrom;
    CHRPOS randomStart;
    CHRPOS chromSize;
    string chrom    = bedEntry.chrom;
    CHRPOS start    = bedEntry.start;
    CHRPOS end      = bedEntry.end;
    CHRPOS length   = end - start;

    // choose a position randomly among the _entire_ genome.
    if (_chooseChrom == false)
    {
        do
        {
            // we need to combine two consective calls to rand()
            // because RAND_MAX is 2^31 (2147483648), whereas
            // mammalian genomes are obviously much larger.
            uint32_t randStart = ((rand() << 31) | rand()) % _genomeSize;
            // use the above randomStart (e.g., for human 0..3.1billion)
            // to identify the chrom and start on that chrom.
            pair<string, int> location = _genome->projectOnGenome(randStart);
            bedEntry.chrom = location.first;
            bedEntry.start = location.second;
            bedEntry.end   = bedEntry.start + length;
            chromSize      = _genome->getChromSize(location.first);
        } while (bedEntry.end > chromSize);
        // keep looking if we have exceeded the end of the chrom.
    }
    // OLD, quite arguably flawed, method.
    // 1. Choose a chrom randomly (i.e., not weighted by size)
    // 2. Choose a position on that chrom randomly
    else
    {
        do
        {
            if (_sameChrom == false) {
                randomChrom    = _chroms[rand() % _numChroms];
                chromSize      = _genome->getChromSize(randomChrom);
                randomStart    = rand() % chromSize;
                bedEntry.chrom = randomChrom;
                bedEntry.start = randomStart;
                bedEntry.end   = randomStart + length;
            }
            else {
                chromSize      = _genome->getChromSize(chrom);
                randomStart    = rand() % chromSize;
                bedEntry.start = randomStart;
                bedEntry.end   = randomStart + length;
            }
        } while (bedEntry.end > chromSize);
    }
}

void BedShuffle::ChoosePairedLocus(BEDPE &b) {

    CHRPOS foot1_len = b.end1 - b.start1;
    CHRPOS foot2_len = b.end2 - b.start2;
    CHRPOS length    = b.end2 - b.start1;

    if (b.chrom1 == b.chrom2)
    {
        CHRPOS chromSize;
        do
        {
            uint32_t randStart = ((rand() << 31) | rand()) % _genomeSize;
            pair<string, int> location = _genome->projectOnGenome(randStart);
            b.chrom1  = location.first;
            b.chrom2  = location.first;
            b.start1  = location.second;
            b.end1    = b.start1 + foot1_len;
            b.end2    = b.start1 + length;
            b.start2  = b.end2 - foot2_len;
            chromSize      = _genome->getChromSize(location.first);
        } while ((b.end1 > chromSize) ||
                (b.start2 > chromSize) ||
                (b.end2 > chromSize));
        // keep looking if we have exceeded the end of the chrom.
    }
    else
    {
        CHRPOS chromSize1, chromSize2;
        do
        {
            uint32_t rand1Start = ((rand() << 31) | rand()) % _genomeSize;
            uint32_t rand2Start = ((rand() << 31) | rand()) % _genomeSize;
            pair<string, int> location1 = _genome->projectOnGenome(rand1Start);
            pair<string, int> location2 = _genome->projectOnGenome(rand2Start);

            b.chrom1  = location1.first;
            b.chrom2  = location2.first;
            b.start1  = location1.second;
            b.start2  = location2.second;

            b.end1    = b.start1 + foot1_len;
            b.end2    = b.start2 + foot2_len;
            chromSize1      = _genome->getChromSize(location1.first);
            chromSize2      = _genome->getChromSize(location2.first);

        } while ((b.end1 > chromSize1) ||
                (b.end2 > chromSize2));
        // keep looking if we have exceeded the end of the chrom.
    }
}

void BedShuffle::ChooseLocusFromInclusionFile(BED &bedEntry) {

    string chrom    = bedEntry.chrom;
    CHRPOS length   = bedEntry.end - bedEntry.start;

    string randomChrom;
    CHRPOS randomStart;
    BED includeInterval;

    if (_sameChrom == false) {

        // grab a random chromosome from the inclusion file.
        randomChrom            = _includeChroms[rand() % _numIncludeChroms];
        // get the number of inclusion intervals for that chrom
        size_t size            =  _include->bedMapNoBin[randomChrom].size();
        // grab a random interval on the chosen chromosome.
        size_t interval        = rand() % size;
        // retreive a ranom -incl interval on the selected chrom
        includeInterval        = _include->bedMapNoBin[randomChrom][interval];

        bedEntry.chrom = randomChrom;
    }
    else {
        // get the number of inclusion intervals for the original chrom
        size_t size =  _include->bedMapNoBin[chrom].size();
        // grab a random interval on the chosen chromosome.
        includeInterval       = _include->bedMapNoBin[chrom][rand() % size];
    }

    randomStart    = includeInterval.start + rand() % (includeInterval.size());
    bedEntry.start = randomStart;
    bedEntry.end   = randomStart + length;

    // use recursion to ensure that the chosen location
    // doesn't go past the end of the chrom
    if (bedEntry.end > ((size_t) _genome->getChromSize(chrom))) {
        //bedEntry.end = _genome->getChromSize(chrom);
        ChooseLocusFromInclusionFile(bedEntry);
    }
}
<|endoftext|>


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

#include "telemetryworker.h"
#include <QString>
#include <QUrl>
#include <QUrlQuery>
#include <QSysInfo>
#include <QByteArray>
#include <QTime>
#include <QRegExp>
#include <curl/curl.h>
#include <string>
#include "../Common/version.h"

void buildQuery(std::shared_ptr<Conectivity::AnalyticsUserEvent> &userEvent, const QString &userAgent, QUrlQuery &query) {
    query.addQueryItem(QLatin1String("idsite"), QLatin1String("1"));
    query.addQueryItem(QLatin1String("rec"), QLatin1String("1"));
    query.addQueryItem(QLatin1String("url"), QString("/client/%1").arg(userEvent->getActionString()));
    query.addQueryItem(QLatin1String("action_name"), userEvent->getActionString());
    query.addQueryItem(QLatin1String("_id"), userAgent);
    query.addQueryItem(QLatin1String("rand"), QString::number(qrand()));
    query.addQueryItem(QLatin1String("apiv"), QLatin1String("1"));
    query.addQueryItem(QLatin1String("h"), QString::number(userEvent->getHour()));
    query.addQueryItem(QLatin1String("m"), QString::number(userEvent->getMinute()));
    query.addQueryItem(QLatin1String("s"), QString::number(userEvent->getSecond()));
    query.addQueryItem(QLatin1String("send_image"), QLatin1String("0"));
}

namespace Conectivity {
    TelemetryWorker::TelemetryWorker(const QString &userAgent, const QString &reportingEndpoint, const QString &interfaceLanguage):
        m_UserAgentId(userAgent),
        m_ReportingEndpoint(reportingEndpoint),
        m_InterfaceLanguage(interfaceLanguage)
    {
    }

    bool TelemetryWorker::initWorker() {
        return true;
    }

    void TelemetryWorker::processOneItem(std::shared_ptr<AnalyticsUserEvent> &item) {
        LOG_INFO << "Reporting action:" << item->getActionString();

        QUrlQuery query;
        buildQuery(item, m_UserAgentId, query);

        QString customVarsStr = QString::fromLatin1("{\"1\":[\"OS_type\",\"%1\"],\"2\":[\"OS_version\",\"%2\"],\"3\":[\"Xpiks_version\",\"%3\"],\"4\":[\"UI_language\",\"%4\"]}");

#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
        query.addQueryItem(QLatin1String("_cvar"),
                           customVarsStr
                           .arg(QSysInfo::productType())
                           .arg(QSysInfo::productVersion())
                           .arg(XPIKS_VERSION_STRING)
                           .arg(m_InterfaceLanguage));
#else
        query.addQueryItem(QLatin1String("_cvar"),
                           customVarsStr
#ifdef Q_OS_WIN
                           .arg(QString("windows"))
#elsif Q_OS_DARWIN
                           .arg(QString("osx"))
#else
                           .arg(QString("Linux QT<5.4"))
#endif
                           .arg(QString("-"))
                           .arg(XPIKS_VERSION_STRING)
                           .arg(m_InterfaceLanguage));
#endif

#ifdef QT_DEBUG
        LOG_DEBUG << "Telemetry request:" << m_ReportingEndpoint << query.toString();
#endif

        sendOneReport(m_ReportingEndpoint, query.toString());
    }

    bool TelemetryWorker::sendOneReport(const QString &resource, const QString &payload) {
        CURL *curl_handle;
        CURLcode res;

        /* init the curl session */
        curl_handle = curl_easy_init();

        std::string resourceString = resource.toStdString();
        const char *url = resourceString.data();
        /* specify URL to get */
        curl_easy_setopt(curl_handle, CURLOPT_URL, url);

        /* some servers don't like requests that are made without a user-agent
             field, so we provide one */
        QString userAgent;
#if defined(Q_OS_DARWIN)
        userAgent = QString("Mozilla/5.0 (Macintosh; Mac OS X %2; rv:1.1) Qt Xpiks/1.1")
                .arg(QSysInfo::productVersion());
#elif defined(Q_OS_WIN)
        userAgent = QString("Mozilla/5.0 (Windows %2; rv:1.1) Qt Xpiks/1.1")
                .arg(QSysInfo::productVersion());
#elif defined(Q_OS_LINUX)
        userAgent = QString("Mozilla/5.0 (Linux %2; rv:1.1) Qt Xpiks/1.1")
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
                .arg(QSysInfo::productVersion());
#else
                .arg("?");
#endif
#endif
        std::string userAgentString = userAgent.toStdString();
        const char *userAgentData = userAgentString.data();
        curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, userAgentData);

        std::string postString = payload.toStdString();
        const char *postData = postString.data();
        /* Now specify the POST data */
        curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postData);

        /* get it! */
        res = curl_easy_perform(curl_handle);

        const bool success = (CURLE_OK == res);

        /* check for errors */
        if(!success) {
            LOG_WARNING << "curl_easy_perform() failed" << curl_easy_strerror(res);
        }

        /* cleanup curl stuff */
        curl_easy_cleanup(curl_handle);

        return success;
    }
}
<commit_msg>POST request size for telemetry worker<commit_after>/*
 * This file is a part of Xpiks - cross platform application for
 * keywording and uploading images for microstocks
 * Copyright (C) 2014-2016 Taras Kushnir <kushnirTV@gmail.com>
 *
 * Xpiks is distributed under the GNU General Public License, version 3.0
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "telemetryworker.h"
#include <QString>
#include <QUrl>
#include <QUrlQuery>
#include <QSysInfo>
#include <QByteArray>
#include <QTime>
#include <QRegExp>
#include <curl/curl.h>
#include <string>
#include "../Common/version.h"

void buildQuery(std::shared_ptr<Conectivity::AnalyticsUserEvent> &userEvent, const QString &userAgent, QUrlQuery &query) {
    query.addQueryItem(QLatin1String("idsite"), QLatin1String("1"));
    query.addQueryItem(QLatin1String("rec"), QLatin1String("1"));
    query.addQueryItem(QLatin1String("url"), QString("/client/%1").arg(userEvent->getActionString()));
    query.addQueryItem(QLatin1String("action_name"), userEvent->getActionString());
    query.addQueryItem(QLatin1String("_id"), userAgent);
    query.addQueryItem(QLatin1String("rand"), QString::number(qrand()));
    query.addQueryItem(QLatin1String("apiv"), QLatin1String("1"));
    query.addQueryItem(QLatin1String("h"), QString::number(userEvent->getHour()));
    query.addQueryItem(QLatin1String("m"), QString::number(userEvent->getMinute()));
    query.addQueryItem(QLatin1String("s"), QString::number(userEvent->getSecond()));
    query.addQueryItem(QLatin1String("send_image"), QLatin1String("0"));
}

namespace Conectivity {
    TelemetryWorker::TelemetryWorker(const QString &userAgent, const QString &reportingEndpoint, const QString &interfaceLanguage):
        m_UserAgentId(userAgent),
        m_ReportingEndpoint(reportingEndpoint),
        m_InterfaceLanguage(interfaceLanguage)
    {
    }

    bool TelemetryWorker::initWorker() {
        return true;
    }

    void TelemetryWorker::processOneItem(std::shared_ptr<AnalyticsUserEvent> &item) {
        LOG_INFO << "Reporting action:" << item->getActionString();

        QUrlQuery query;
        buildQuery(item, m_UserAgentId, query);

        QString customVarsStr = QString::fromLatin1("{\"1\":[\"OS_type\",\"%1\"],\"2\":[\"OS_version\",\"%2\"],\"3\":[\"Xpiks_version\",\"%3\"],\"4\":[\"UI_language\",\"%4\"]}");

#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
        query.addQueryItem(QLatin1String("_cvar"),
                           customVarsStr
                           .arg(QSysInfo::productType())
                           .arg(QSysInfo::productVersion())
                           .arg(XPIKS_VERSION_STRING)
                           .arg(m_InterfaceLanguage));
#else
        query.addQueryItem(QLatin1String("_cvar"),
                           customVarsStr
#ifdef Q_OS_WIN
                           .arg(QString("windows"))
#elsif Q_OS_DARWIN
                           .arg(QString("osx"))
#else
                           .arg(QString("Linux QT<5.4"))
#endif
                           .arg(QString("-"))
                           .arg(XPIKS_VERSION_STRING)
                           .arg(m_InterfaceLanguage));
#endif

#ifdef QT_DEBUG
        LOG_DEBUG << "Telemetry request:" << m_ReportingEndpoint << query.toString();
#endif

        sendOneReport(m_ReportingEndpoint, query.toString());
    }

    bool TelemetryWorker::sendOneReport(const QString &resource, const QString &payload) {
        CURL *curl_handle;
        CURLcode res;

        /* init the curl session */
        curl_handle = curl_easy_init();

        std::string resourceString = resource.toStdString();
        const char *url = resourceString.data();
        /* specify URL to get */
        curl_easy_setopt(curl_handle, CURLOPT_URL, url);

        /* some servers don't like requests that are made without a user-agent
             field, so we provide one */
        QString userAgent;
#if defined(Q_OS_DARWIN)
        userAgent = QString("Mozilla/5.0 (Macintosh; Mac OS X %2; rv:1.1) Qt Xpiks/1.1")
                .arg(QSysInfo::productVersion());
#elif defined(Q_OS_WIN)
        userAgent = QString("Mozilla/5.0 (Windows %2; rv:1.1) Qt Xpiks/1.1")
                .arg(QSysInfo::productVersion());
#elif defined(Q_OS_LINUX)
        userAgent = QString("Mozilla/5.0 (Linux %2; rv:1.1) Qt Xpiks/1.1")
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
                .arg(QSysInfo::productVersion());
#else
                .arg("?");
#endif
#endif
        std::string userAgentString = userAgent.toStdString();
        const char *userAgentData = userAgentString.data();
        curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, userAgentData);

        std::string postString = payload.toStdString();
        const char *postData = postString.data();
        /* Now specify the POST data */
        curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postData);

        curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, (long)postString.size());

        /* get it! */
        res = curl_easy_perform(curl_handle);

        const bool success = (CURLE_OK == res);

        /* check for errors */
        if(!success) {
            LOG_WARNING << "curl_easy_perform() failed" << curl_easy_strerror(res);
        }

        /* cleanup curl stuff */
        curl_easy_cleanup(curl_handle);

        return success;
    }
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2015, Microsoft Corporation
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//

#include "pch.h"

#include <sstream>

#include "Bridge.h"
#include "BridgeDevice.h"
#include "DeviceProperty.h"
#include "PropertyInterface.h"
#include "DeviceInterface.h"
#include "AllJoynProperty.h"
#include "AllJoynHelper.h"

using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation::Collections;
using namespace Windows::Foundation;

using namespace BridgeRT;
using namespace std;
using namespace Windows::Foundation;

DeviceProperty::DeviceProperty()
    : m_deviceProperty(nullptr),
    m_parent(nullptr),
    m_AJBusObject(NULL),
    m_registeredOnAllJoyn(false),
    m_propertyInterface(nullptr)
{
}

DeviceProperty::~DeviceProperty()
{
}

QStatus DeviceProperty::Initialize(IAdapterProperty ^deviceProperty,  PropertyInterface *propertyInterface, BridgeDevice ^parent, alljoyn_busobject busObject)
{
    QStatus status = ER_OK;
    string tempString;
    // sanity check
    if (nullptr == deviceProperty)
    {
        status = ER_BAD_ARG_1;
        goto leave;
    }
    if (nullptr == propertyInterface)
    {
        status = ER_BAD_ARG_2;
        goto leave;
    }
    if (nullptr == parent)
    {
        status = ER_BAD_ARG_3;
        goto leave;
    }

    m_deviceProperty = deviceProperty;
    m_propertyInterface = propertyInterface;
    m_parent = parent;
    m_AJBusObject = busObject;

    status = PairAjProperties();
    if (ER_OK != status)
    {
        goto leave;
    }
    m_registeredOnAllJoyn = true;

leave:
    return status;
}

void DeviceProperty::Shutdown()
{
    if (NULL != m_AJBusObject)
    {
        if (m_registeredOnAllJoyn)
        {
            // unregister bus object
            alljoyn_busattachment_unregisterbusobject(m_parent->GetBusAttachment(), m_AJBusObject);
            m_registeredOnAllJoyn = false;
        }
        alljoyn_busobject_destroy(m_AJBusObject);
        m_AJBusObject = NULL;
    }
    m_propertyInterface = nullptr;
    m_parent = nullptr;
    m_AJBusObjectPath.clear();
    m_AJpropertyAdapterValuePairs.clear();
}

QStatus BridgeRT::DeviceProperty::PairAjProperties()
{
    QStatus status = ER_OK;

    vector <IAdapterAttribute ^> tempList;

    // create temporary list of IAdapterValue that have to match with one of the
    // AllJoyn properties
    for (auto adapterAttr : m_deviceProperty->Attributes)
    {
        tempList.push_back(adapterAttr);
    }

    // go through AllJoyn properties and find matching IAdapterValue
    for (auto ajProperty : m_propertyInterface->GetAJProperties())
    {
        bool paired = false;

        auto adapterAttr = tempList.end();
        for (adapterAttr = tempList.begin(); adapterAttr != tempList.end(); adapterAttr++)
        {
            if (ajProperty->IsSameType(*adapterAttr))
            {
                AJpropertyAdapterValuePair tempPair = { ajProperty, *adapterAttr };
                m_AJpropertyAdapterValuePairs.insert(std::make_pair(*ajProperty->GetName(), tempPair));
                paired = true;
                break;
            }
        }
        if (!paired)
        {
            // a matching IAdapterValue must exist for each AllJoyn property
            status = ER_INVALID_DATA;
            goto leave;
        }

        // remove adapterValue from temp list
        tempList.erase(adapterAttr);
    }

leave:
    return status;
}

QStatus AJ_CALL DeviceProperty::GetProperty(_In_ const void* context, _In_z_ const char* ifcName, _In_z_ const char* propName, _Out_ alljoyn_msgarg val)
{
    QStatus status = ER_OK;
    uint32 adapterStatus = ERROR_SUCCESS;
    DeviceProperty *deviceProperty = nullptr;
    IAdapterAttribute ^adapterAttr = nullptr;
    IAdapterValue ^adapterValue = nullptr;
    AllJoynProperty *ajProperty = nullptr;
    IAdapterIoRequest^ request;

    UNREFERENCED_PARAMETER(ifcName);

    deviceProperty = (DeviceProperty *)context;
    if (nullptr == deviceProperty)	// sanity test
    {
        return ER_BAD_ARG_1;
    }

    // identify alljoyn property and its corresponding adapter value
    auto index = deviceProperty->m_AJpropertyAdapterValuePairs.find(propName);
    if (deviceProperty->m_AJpropertyAdapterValuePairs.end() == index)
    {
        status = ER_BUS_NO_SUCH_PROPERTY;
        goto leave;
    }

    ajProperty = index->second.ajProperty;
    adapterAttr = index->second.adapterAttr;
    adapterValue = adapterAttr->Value;

    // get value of adapter value
    adapterStatus = DsbBridge::SingleInstance()->GetAdapter()->GetPropertyValue(deviceProperty->m_deviceProperty, adapterValue->Name, &adapterValue, &request);
    if (ERROR_IO_PENDING == adapterStatus &&
        nullptr != request)
    {
        // wait for completion
        adapterStatus = request->Wait(WAIT_TIMEOUT_FOR_ADAPTER_OPERATION);
    }
    if (ERROR_SUCCESS != adapterStatus)
    {
        status = ER_OS_ERROR;
        goto leave;
    }

    // build alljoyn response to get
    status = AllJoynHelper::SetMsgArg(adapterValue, val);

leave:
    return status;
}

QStatus AJ_CALL DeviceProperty::SetProperty(_In_ const void* context, _In_z_ const char* ifcName, _In_z_ const char* propName, _In_ alljoyn_msgarg val)
{
    QStatus status = ER_OK;
    uint32 adapterStatus = ERROR_SUCCESS;
    DeviceProperty *deviceProperty = nullptr;
    IAdapterAttribute^ adapterAttr = nullptr;
    IAdapterValue ^adapterValue = nullptr;
    AllJoynProperty *ajProperty = nullptr;
    IAdapterIoRequest^ request;

    UNREFERENCED_PARAMETER(ifcName);

    deviceProperty = (DeviceProperty *)context;
    if (nullptr == deviceProperty)	// sanity test
    {
        return ER_BAD_ARG_1;
    }

    // identify alljoyn property and its corresponding adapter value
    auto index = deviceProperty->m_AJpropertyAdapterValuePairs.find(propName);
    if (deviceProperty->m_AJpropertyAdapterValuePairs.end() == index)
    {
        status = ER_BUS_NO_SUCH_PROPERTY;
        goto leave;
    }

    ajProperty = index->second.ajProperty;
    adapterAttr = index->second.adapterAttr;
    adapterValue = adapterAttr->Value;

    // update IAdapterValue from AllJoyn message
    status = AllJoynHelper::GetAdapterValue(adapterValue, val);
    if (ER_OK != status)
    {
        goto leave;
    }

    // set value in adapter
    adapterStatus = DsbBridge::SingleInstance()->GetAdapter()->SetPropertyValue(deviceProperty->m_deviceProperty, adapterValue, &request);
    if (ERROR_IO_PENDING == adapterStatus &&
        nullptr != request)
    {
        // wait for completion
        adapterStatus = request->Wait(WAIT_TIMEOUT_FOR_ADAPTER_OPERATION);
    }
    if (ERROR_ACCESS_DENIED == adapterStatus)
    {
        status = ER_BUS_PROPERTY_ACCESS_DENIED;
        goto leave;
    }
    if (ERROR_SUCCESS != adapterStatus)
    {
        status = ER_BUS_PROPERTY_VALUE_NOT_SET;
        goto leave;
    }

leave:
    return status;
}

void DeviceProperty::EmitSignalCOV(IAdapterValue ^newValue, const std::vector<alljoyn_sessionid>& sessionIds)
{
    QStatus status = ER_OK;
    alljoyn_msgarg msgArg = NULL;
    auto valuePair = m_AJpropertyAdapterValuePairs.end();

    // sanity check
    if (nullptr == newValue)
    {
        goto leave;
    }

    // get AllJoyn property that match with IAdapterValue that has changed
    for (valuePair = m_AJpropertyAdapterValuePairs.begin(); valuePair != m_AJpropertyAdapterValuePairs.end(); valuePair++)
    {
        if (valuePair->second.adapterAttr->Value->Name == newValue->Name)
        {
            break;
        }
    }
    if (valuePair == m_AJpropertyAdapterValuePairs.end())
    {
        // can't find any Alljoyn property that correspond to IAdapterValue
        goto leave;
    }

    // prepare signal arguments
    msgArg = alljoyn_msgarg_create();
    if (NULL == msgArg)
    {
        goto leave;
    }

    // build alljoyn message from IAdapterValue
    status = AllJoynHelper::SetMsgArg(newValue, msgArg);
    if (status != ER_OK)
    {
        goto leave;
    }

	for (auto sessionId : sessionIds)
	{
		// emit property change
		alljoyn_busobject_emitpropertychanged(m_AJBusObject,
			m_propertyInterface->GetInterface()->GetInterfaceName()->c_str(),
			valuePair->second.ajProperty->GetName()->c_str(),
			msgArg, sessionId);
	}

leave:
    if (NULL != msgArg)
    {
        alljoyn_msgarg_destroy(msgArg);
    }

    return;
}<commit_msg>Fixed crash on dispose of busobject<commit_after>//
// Copyright (c) 2015, Microsoft Corporation
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//

#include "pch.h"

#include <sstream>

#include "Bridge.h"
#include "BridgeDevice.h"
#include "DeviceProperty.h"
#include "PropertyInterface.h"
#include "DeviceInterface.h"
#include "AllJoynProperty.h"
#include "AllJoynHelper.h"

using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation::Collections;
using namespace Windows::Foundation;

using namespace BridgeRT;
using namespace std;
using namespace Windows::Foundation;

DeviceProperty::DeviceProperty()
    : m_deviceProperty(nullptr),
    m_parent(nullptr),
    m_AJBusObject(NULL),
    m_registeredOnAllJoyn(false),
    m_propertyInterface(nullptr)
{
}

DeviceProperty::~DeviceProperty()
{
}

QStatus DeviceProperty::Initialize(IAdapterProperty ^deviceProperty,  PropertyInterface *propertyInterface, BridgeDevice ^parent, alljoyn_busobject busObject)
{
    QStatus status = ER_OK;
    string tempString;
    // sanity check
    if (nullptr == deviceProperty)
    {
        status = ER_BAD_ARG_1;
        goto leave;
    }
    if (nullptr == propertyInterface)
    {
        status = ER_BAD_ARG_2;
        goto leave;
    }
    if (nullptr == parent)
    {
        status = ER_BAD_ARG_3;
        goto leave;
    }

    m_deviceProperty = deviceProperty;
    m_propertyInterface = propertyInterface;
    m_parent = parent;
    m_AJBusObject = busObject;

    status = PairAjProperties();
    if (ER_OK != status)
    {
        goto leave;
    }
    m_registeredOnAllJoyn = true;

leave:
    return status;
}

void DeviceProperty::Shutdown()
{
    m_propertyInterface = nullptr;
    m_parent = nullptr;
	m_AJBusObject = NULL;
	m_AJBusObjectPath.clear();
    m_AJpropertyAdapterValuePairs.clear();
}

QStatus BridgeRT::DeviceProperty::PairAjProperties()
{
    QStatus status = ER_OK;

    vector <IAdapterAttribute ^> tempList;

    // create temporary list of IAdapterValue that have to match with one of the
    // AllJoyn properties
    for (auto adapterAttr : m_deviceProperty->Attributes)
    {
        tempList.push_back(adapterAttr);
    }

    // go through AllJoyn properties and find matching IAdapterValue
    for (auto ajProperty : m_propertyInterface->GetAJProperties())
    {
        bool paired = false;

        auto adapterAttr = tempList.end();
        for (adapterAttr = tempList.begin(); adapterAttr != tempList.end(); adapterAttr++)
        {
            if (ajProperty->IsSameType(*adapterAttr))
            {
                AJpropertyAdapterValuePair tempPair = { ajProperty, *adapterAttr };
                m_AJpropertyAdapterValuePairs.insert(std::make_pair(*ajProperty->GetName(), tempPair));
                paired = true;
                break;
            }
        }
        if (!paired)
        {
            // a matching IAdapterValue must exist for each AllJoyn property
            status = ER_INVALID_DATA;
            goto leave;
        }

        // remove adapterValue from temp list
        tempList.erase(adapterAttr);
    }

leave:
    return status;
}

QStatus AJ_CALL DeviceProperty::GetProperty(_In_ const void* context, _In_z_ const char* ifcName, _In_z_ const char* propName, _Out_ alljoyn_msgarg val)
{
    QStatus status = ER_OK;
    uint32 adapterStatus = ERROR_SUCCESS;
    DeviceProperty *deviceProperty = nullptr;
    IAdapterAttribute ^adapterAttr = nullptr;
    IAdapterValue ^adapterValue = nullptr;
    AllJoynProperty *ajProperty = nullptr;
    IAdapterIoRequest^ request;

    UNREFERENCED_PARAMETER(ifcName);

    deviceProperty = (DeviceProperty *)context;
    if (nullptr == deviceProperty)	// sanity test
    {
        return ER_BAD_ARG_1;
    }

    // identify alljoyn property and its corresponding adapter value
    auto index = deviceProperty->m_AJpropertyAdapterValuePairs.find(propName);
    if (deviceProperty->m_AJpropertyAdapterValuePairs.end() == index)
    {
        status = ER_BUS_NO_SUCH_PROPERTY;
        goto leave;
    }

    ajProperty = index->second.ajProperty;
    adapterAttr = index->second.adapterAttr;
    adapterValue = adapterAttr->Value;

    // get value of adapter value
    adapterStatus = DsbBridge::SingleInstance()->GetAdapter()->GetPropertyValue(deviceProperty->m_deviceProperty, adapterValue->Name, &adapterValue, &request);
    if (ERROR_IO_PENDING == adapterStatus &&
        nullptr != request)
    {
        // wait for completion
        adapterStatus = request->Wait(WAIT_TIMEOUT_FOR_ADAPTER_OPERATION);
    }
    if (ERROR_SUCCESS != adapterStatus)
    {
        status = ER_OS_ERROR;
        goto leave;
    }

    // build alljoyn response to get
    status = AllJoynHelper::SetMsgArg(adapterValue, val);

leave:
    return status;
}

QStatus AJ_CALL DeviceProperty::SetProperty(_In_ const void* context, _In_z_ const char* ifcName, _In_z_ const char* propName, _In_ alljoyn_msgarg val)
{
    QStatus status = ER_OK;
    uint32 adapterStatus = ERROR_SUCCESS;
    DeviceProperty *deviceProperty = nullptr;
    IAdapterAttribute^ adapterAttr = nullptr;
    IAdapterValue ^adapterValue = nullptr;
    AllJoynProperty *ajProperty = nullptr;
    IAdapterIoRequest^ request;

    UNREFERENCED_PARAMETER(ifcName);

    deviceProperty = (DeviceProperty *)context;
    if (nullptr == deviceProperty)	// sanity test
    {
        return ER_BAD_ARG_1;
    }

    // identify alljoyn property and its corresponding adapter value
    auto index = deviceProperty->m_AJpropertyAdapterValuePairs.find(propName);
    if (deviceProperty->m_AJpropertyAdapterValuePairs.end() == index)
    {
        status = ER_BUS_NO_SUCH_PROPERTY;
        goto leave;
    }

    ajProperty = index->second.ajProperty;
    adapterAttr = index->second.adapterAttr;
    adapterValue = adapterAttr->Value;

    // update IAdapterValue from AllJoyn message
    status = AllJoynHelper::GetAdapterValue(adapterValue, val);
    if (ER_OK != status)
    {
        goto leave;
    }

    // set value in adapter
    adapterStatus = DsbBridge::SingleInstance()->GetAdapter()->SetPropertyValue(deviceProperty->m_deviceProperty, adapterValue, &request);
    if (ERROR_IO_PENDING == adapterStatus &&
        nullptr != request)
    {
        // wait for completion
        adapterStatus = request->Wait(WAIT_TIMEOUT_FOR_ADAPTER_OPERATION);
    }
    if (ERROR_ACCESS_DENIED == adapterStatus)
    {
        status = ER_BUS_PROPERTY_ACCESS_DENIED;
        goto leave;
    }
    if (ERROR_SUCCESS != adapterStatus)
    {
        status = ER_BUS_PROPERTY_VALUE_NOT_SET;
        goto leave;
    }

leave:
    return status;
}

void DeviceProperty::EmitSignalCOV(IAdapterValue ^newValue, const std::vector<alljoyn_sessionid>& sessionIds)
{
    QStatus status = ER_OK;
    alljoyn_msgarg msgArg = NULL;
    auto valuePair = m_AJpropertyAdapterValuePairs.end();

    // sanity check
    if (nullptr == newValue)
    {
        goto leave;
    }

    // get AllJoyn property that match with IAdapterValue that has changed
    for (valuePair = m_AJpropertyAdapterValuePairs.begin(); valuePair != m_AJpropertyAdapterValuePairs.end(); valuePair++)
    {
        if (valuePair->second.adapterAttr->Value->Name == newValue->Name)
        {
            break;
        }
    }
    if (valuePair == m_AJpropertyAdapterValuePairs.end())
    {
        // can't find any Alljoyn property that correspond to IAdapterValue
        goto leave;
    }

    // prepare signal arguments
    msgArg = alljoyn_msgarg_create();
    if (NULL == msgArg)
    {
        goto leave;
    }

    // build alljoyn message from IAdapterValue
    status = AllJoynHelper::SetMsgArg(newValue, msgArg);
    if (status != ER_OK)
    {
        goto leave;
    }

	for (auto sessionId : sessionIds)
	{
		// emit property change
		alljoyn_busobject_emitpropertychanged(m_AJBusObject,
			m_propertyInterface->GetInterface()->GetInterfaceName()->c_str(),
			valuePair->second.ajProperty->GetName()->c_str(),
			msgArg, sessionId);
	}

leave:
    if (NULL != msgArg)
    {
        alljoyn_msgarg_destroy(msgArg);
    }

    return;
}<|endoftext|>


<commit_before>#include <Input/InputManager.hpp>
#include <Input/KeyList.hpp>
#include <Triggers/TriggerDatabase.hpp>
#include <Utils/VectorUtils.hpp>

namespace obe::Input
{
    InputManager::InputManager()
        : Registrable("InputManager"),
          m_actionTriggers(
              Triggers::TriggerDatabase::GetInstance()->createTriggerGroup(
                  "Global", "Actions"),
              Triggers::TriggerGroupPtrRemover)
    {
    }

    InputAction& InputManager::getAction(const std::string& actionId)
    {
        for (auto& action : m_allActions)
        {
            if (action->getId() == actionId)
            {
                return *action.get();
            }
        }
        aube::ErrorHandler::Warn("ObEngine.Input.InputManager.UnknownAction",
                                 {{"action", actionId}});
        m_allActions.push_back(
            std::make_unique<InputAction>(m_actionTriggers.get(), actionId));
        return *m_allActions.back().get();
    }

    void InputManager::setEnabled(const bool state)
    {
        m_binderEnabled = state;
    }

    void InputManager::update()
    {
        if (m_binderEnabled)
        {
            const unsigned int actionsAmount = m_currentActions.size();
            for (unsigned int i = 0; i < actionsAmount; i++)
            {
                if (i <
                    m_currentActions.size()) // Performance issue ? <REVISION>
                    m_currentActions[i]->update();
            }
        }
    }

    bool InputManager::actionExists(const std::string& actionId)
    {
        for (auto& action : m_allActions)
        {
            if (action->getId() == actionId)
            {
                return true;
            }
        }
        return false;
    }

    void InputManager::clear()
    {
        m_currentActions.clear();
        for (auto& action : m_allActions)
            m_actionTriggers->removeTrigger(action->getId());
        m_allActions.clear();
    }

    void InputManager::configure(vili::ComplexNode& config)
    {
        std::vector<std::string> alreadyInFile;
        for (vili::ComplexNode* context : config.getAll<vili::ComplexNode>())
        {
            for (vili::Node* action : context->getAll())
            {
                if (!this->actionExists(action->getId()))
                {
                    m_allActions.push_back(std::make_unique<InputAction>(
                        m_actionTriggers.get(), action->getId()));
                }
                else if (!Utils::Vector::contains(action->getId(),
                                                  alreadyInFile))
                {
                    this->getAction(action->getId()).clearConditions();
                }
                auto inputCondition = [](InputManager* inputManager,
                                         vili::Node* action,
                                         vili::DataNode* condition) {
                    InputCondition actionCondition;
                    actionCondition.setCombinationCode(
                        condition->get<std::string>());
                    Debug::Log->debug(
                        "<InputManager> Associated Key '{0}' for Action '{1}'",
                        condition->get<std::string>(), action->getId());
                    inputManager->getAction(action->getId())
                        .addCondition(actionCondition);
                };
                if (action->getType() == vili::NodeType::DataNode)
                {
                    inputCondition(this, action,
                                   static_cast<vili::DataNode*>(action));
                }
                else if (action->getType() == vili::NodeType::ArrayNode)
                {
                    for (vili::DataNode* condition :
                         *static_cast<vili::ArrayNode*>(action))
                    {
                        inputCondition(this, action, condition);
                    }
                }
                this->getAction(action->getId()).addContext(context->getId());
                alreadyInFile.push_back(action->getId());
            }
        }
        // Add Context keys in real time <REVISION>
    }

    void InputManager::clearContexts()
    {
        m_currentActions.clear();
    }

    InputManager& InputManager::addContext(const std::string& context)
    {
        Debug::Log->debug("<InputManager> Adding Context '{0}'", context);
        for (auto& action : m_allActions)
        {
            if (Utils::Vector::contains(context, action->getContexts()) &&
                !Utils::Vector::contains(action.get(), m_currentActions))
            {
                Debug::Log->debug(
                    "<InputManager> Add Action '{0}' in Context '{1}'",
                    action.get()->getId(), context);
                m_currentActions.push_back(action.get());
            }
        }
        return *this;
    }

    InputManager& InputManager::removeContext(const std::string& context)
    {
        //<REVISION> Multiple context, keep which one, remove keys of wrong
        //context
        m_currentActions.erase(
            std::remove_if(
				m_currentActions.begin(), m_currentActions.end(),
                [&context](const InputAction* inputAction) -> bool {
                    auto& contexts = inputAction->getContexts();
                    return std::find(contexts.begin(),
                                    contexts.end(),
                                    context) != contexts.end();
                }),
            m_currentActions.end());

        return *this;
    }

    void InputManager::setContext(const std::string& context)
    {
        this->clearContexts();
        this->addContext(context);
    }

    std::vector<std::string> InputManager::getContexts()
    {
        std::vector<std::string> allContexts;
        for (const InputAction* action : m_currentActions)
        {
            for (const std::string& context : action->getContexts())
            {
                if (!Utils::Vector::contains(context, allContexts))
                {
                    allContexts.push_back(context);
                }
            }
        }
        return allContexts;
    }
} // namespace obe::Input<commit_msg>Fix macOS build (I hope)<commit_after>#include <Input/InputManager.hpp>
#include <Input/KeyList.hpp>
#include <Triggers/TriggerDatabase.hpp>
#include <Utils/VectorUtils.hpp>

namespace obe::Input
{
    InputManager::InputManager()
        : Registrable("InputManager"),
          m_actionTriggers(
              Triggers::TriggerDatabase::GetInstance()->createTriggerGroup(
                  "Global", "Actions"),
              Triggers::TriggerGroupPtrRemover)
    {
    }

    InputAction& InputManager::getAction(const std::string& actionId)
    {
        for (auto& action : m_allActions)
        {
            if (action->getId() == actionId)
            {
                return *action.get();
            }
        }
        aube::ErrorHandler::Warn("ObEngine.Input.InputManager.UnknownAction",
                                 {{"action", actionId}});
        m_allActions.push_back(
            std::make_unique<InputAction>(m_actionTriggers.get(), actionId));
        return *m_allActions.back().get();
    }

    void InputManager::setEnabled(const bool state)
    {
        m_binderEnabled = state;
    }

    void InputManager::update()
    {
        if (m_binderEnabled)
        {
            const unsigned int actionsAmount = m_currentActions.size();
            for (unsigned int i = 0; i < actionsAmount; i++)
            {
                if (i <
                    m_currentActions.size()) // Performance issue ? <REVISION>
                    m_currentActions[i]->update();
            }
        }
    }

    bool InputManager::actionExists(const std::string& actionId)
    {
        for (auto& action : m_allActions)
        {
            if (action->getId() == actionId)
            {
                return true;
            }
        }
        return false;
    }

    void InputManager::clear()
    {
        m_currentActions.clear();
        for (auto& action : m_allActions)
            m_actionTriggers->removeTrigger(action->getId());
        m_allActions.clear();
    }

    void InputManager::configure(vili::ComplexNode& config)
    {
        std::vector<std::string> alreadyInFile;
        for (vili::ComplexNode* context : config.getAll<vili::ComplexNode>())
        {
            for (vili::Node* action : context->getAll())
            {
                if (!this->actionExists(action->getId()))
                {
                    m_allActions.push_back(std::make_unique<InputAction>(
                        m_actionTriggers.get(), action->getId()));
                }
                else if (!Utils::Vector::contains(action->getId(),
                                                  alreadyInFile))
                {
                    this->getAction(action->getId()).clearConditions();
                }
                auto inputCondition = [](InputManager* inputManager,
                                         vili::Node* action,
                                         vili::DataNode* condition) {
                    InputCondition actionCondition;
                    actionCondition.setCombinationCode(
                        condition->get<std::string>());
                    Debug::Log->debug(
                        "<InputManager> Associated Key '{0}' for Action '{1}'",
                        condition->get<std::string>(), action->getId());
                    inputManager->getAction(action->getId())
                        .addCondition(actionCondition);
                };
                if (action->getType() == vili::NodeType::DataNode)
                {
                    inputCondition(this, action,
                                   static_cast<vili::DataNode*>(action));
                }
                else if (action->getType() == vili::NodeType::ArrayNode)
                {
                    for (vili::DataNode* condition :
                         *static_cast<vili::ArrayNode*>(action))
                    {
                        inputCondition(this, action, condition);
                    }
                }
                this->getAction(action->getId()).addContext(context->getId());
                alreadyInFile.push_back(action->getId());
            }
        }
        // Add Context keys in real time <REVISION>
    }

    void InputManager::clearContexts()
    {
        m_currentActions.clear();
    }

    InputManager& InputManager::addContext(const std::string& context)
    {
        Debug::Log->debug("<InputManager> Adding Context '{0}'", context);
        for (auto& action : m_allActions)
        {
            if (Utils::Vector::contains(context, action->getContexts()) &&
                !Utils::Vector::contains(action.get(), m_currentActions))
            {
                Debug::Log->debug(
                    "<InputManager> Add Action '{0}' in Context '{1}'",
                    action.get()->getId(), context);
                m_currentActions.push_back(action.get());
            }
        }
        return *this;
    }

    InputManager& InputManager::removeContext(const std::string& context)
    {
        //<REVISION> Multiple context, keep which one, remove keys of wrong
        //context
        m_currentActions.erase(
            std::remove_if(
				m_currentActions.begin(), m_currentActions.end(),
                [&context](const InputAction* inputAction) -> bool {
                    const auto& contexts = inputAction->getContexts();
                    return std::find(contexts.begin(),
                                    contexts.end(),
                                    context) != contexts.end();
                }),
            m_currentActions.end());

        return *this;
    }

    void InputManager::setContext(const std::string& context)
    {
        this->clearContexts();
        this->addContext(context);
    }

    std::vector<std::string> InputManager::getContexts()
    {
        std::vector<std::string> allContexts;
        for (const InputAction* action : m_currentActions)
        {
            for (const std::string& context : action->getContexts())
            {
                if (!Utils::Vector::contains(context, allContexts))
                {
                    allContexts.push_back(context);
                }
            }
        }
        return allContexts;
    }
} // namespace obe::Input<|endoftext|>


<commit_before>#include "TranslationOptionList.h"
#include "Util.h"
#include "TranslationOption.h"
#include <boost/foreach.hpp>

using namespace std;

namespace Moses
{

  TranslationOptionList::
  TranslationOptionList(const TranslationOptionList &copy)
  {
    const_iterator iter;
    for (iter = copy.begin(); iter != copy.end(); ++iter) {
      const TranslationOption &origTransOpt = **iter;
      TranslationOption *newTransOpt = new TranslationOption(origTransOpt);
      Add(newTransOpt);
    }
  }

  TranslationOptionList::
  ~TranslationOptionList()
  {
    RemoveAllInColl(m_coll);
  }

  TO_STRING_BODY(TranslationOptionList);

  std::ostream& operator<<(std::ostream& out, const TranslationOptionList& coll)
  {
    TranslationOptionList::const_iterator iter;
    for (iter = coll.begin(); iter != coll.end(); ++iter) {
      const TranslationOption &transOpt = **iter;
      out << transOpt << endl;
    }

    return out;
  }

  size_t
  TranslationOptionList::
  SelectNBest(size_t const N)
  {
    if (N == 0 || N <= m_coll.size()) return 0;
    static TranslationOption::Better cmp;
    NTH_ELEMENT4(m_coll.begin(), m_coll.begin() + N, m_coll.end(), cmp);
    // delete the rest
    for (size_t i = N ; i < m_coll.size() ; ++i) delete m_coll[i];
    size_t ret = m_coll.size() - N;
    m_coll.resize(N);
    return ret;
  }

  size_t
  TranslationOptionList::
  PruneByThreshold(float const th)
  {
    if (m_coll.size() <= 1) return 0;
    if (th == -std::numeric_limits<float>::infinity()) return 0;

    // first, find the best score
    float bestScore = -std::numeric_limits<float>::infinity();
    BOOST_FOREACH(TranslationOption const* t, m_coll)
      {
	if (t->GetFutureScore() > bestScore)
	  bestScore = t->GetFutureScore();
      }

    size_t old_size = m_coll.size();

    // then, remove items that are worse than best score + threshold
    // why '+' th ??? Does this ever hold?
    for (size_t i=0; i < m_coll.size() ; ++i)
      {
	if (m_coll[i]->GetFutureScore() < bestScore + th)
	  {
            delete m_coll[i];
	    if(i + 1 < m_coll.size())
	      std::swap(m_coll[i],m_coll.back());
	    m_coll.pop_back();
          }
      }

    m_coll.resize(m_coll.size());
    return old_size - m_coll.size();
  }

} // namespace
<commit_msg>Bug fix in TranslationOptionList::SelectNBest(N).<commit_after>#include "TranslationOptionList.h"
#include "Util.h"
#include "TranslationOption.h"
#include <boost/foreach.hpp>

using namespace std;

namespace Moses
{

  TranslationOptionList::
  TranslationOptionList(const TranslationOptionList &copy)
  {
    const_iterator iter;
    for (iter = copy.begin(); iter != copy.end(); ++iter) {
      const TranslationOption &origTransOpt = **iter;
      TranslationOption *newTransOpt = new TranslationOption(origTransOpt);
      Add(newTransOpt);
    }
  }

  TranslationOptionList::
  ~TranslationOptionList()
  {
    RemoveAllInColl(m_coll);
  }

  TO_STRING_BODY(TranslationOptionList);

  std::ostream& operator<<(std::ostream& out, const TranslationOptionList& coll)
  {
    TranslationOptionList::const_iterator iter;
    for (iter = coll.begin(); iter != coll.end(); ++iter) {
      const TranslationOption &transOpt = **iter;
      out << transOpt << endl;
    }

    return out;
  }

  size_t
  TranslationOptionList::
  SelectNBest(size_t const N)
  {
    if (N == 0 || N >= m_coll.size()) return 0;
    static TranslationOption::Better cmp;
    NTH_ELEMENT4(m_coll.begin(), m_coll.begin() + N, m_coll.end(), cmp);
    // delete the rest
    for (size_t i = N ; i < m_coll.size() ; ++i) delete m_coll[i];
    size_t ret = m_coll.size() - N;
    m_coll.resize(N);
    return ret;
  }

  size_t
  TranslationOptionList::
  PruneByThreshold(float const th)
  {
    if (m_coll.size() <= 1) return 0;
    if (th == -std::numeric_limits<float>::infinity()) return 0;

    // first, find the best score
    float bestScore = -std::numeric_limits<float>::infinity();
    BOOST_FOREACH(TranslationOption const* t, m_coll)
      {
	if (t->GetFutureScore() > bestScore)
	  bestScore = t->GetFutureScore();
      }

    size_t old_size = m_coll.size();

    // then, remove items that are worse than best score + threshold
    // why '+' th ??? Does this ever hold?
    for (size_t i=0; i < m_coll.size() ; ++i)
      {
	if (m_coll[i]->GetFutureScore() < bestScore + th)
	  {
            delete m_coll[i];
	    if(i + 1 < m_coll.size())
	      std::swap(m_coll[i],m_coll.back());
	    m_coll.pop_back();
          }
      }

    m_coll.resize(m_coll.size());
    return old_size - m_coll.size();
  }

} // namespace
<|endoftext|>


<commit_before>#pragma once
#include "event.hpp"
#include "sdlwrap.hpp"
#include "spinner/abstbuff.hpp"

namespace rs {
	template <class T>
	using UPtr = std::unique_ptr<T>;
	namespace msg {
		struct DrawInit : MsgBase {};
		struct MainInit : MsgBase {};
		//! 描画リクエスト
		struct DrawReq : MsgBase {};
		//! スレッド終了リクエスト
		struct QuitReq : MsgBase {};
		//! スレッド状態値更新
		struct State : MsgBase {
			int state;
			State(int st): state(st) {}
		};
	}
	struct IDrawProc {
		//! 描画コールバック
		/*! 描画スレッドから呼ばれる */
		/*! \param[in] accum 累積フレーム数
			\return backbufferのswapをかける時はtrue */
		virtual bool runU(uint64_t accum) = 0;
	};
	using UPDrawProc = UPtr<IDrawProc>;
	struct IMainProc {
		//! ゲームアップデートコールバック
		/*! メインスレッドから呼ばれる */
		/*! \return ゲーム終了時にfalseを返す */
		virtual bool runU() = 0;
		//! 描画コールバックインタフェースを作成
		/*! 描画スレッドから呼ばれる */
		virtual IDrawProc* initDraw() = 0;
	};
	using UPMainProc = UPtr<IMainProc>;
	using MPCreate = std::function<IMainProc* ()>;

	class DrawThread : public ThreadL<void (Looper&, SPGLContext&&, const SPWindow&, const UPMainProc&)> {
		using base = ThreadL<void (Looper&, SPGLContext&&, const SPWindow&, const UPMainProc&)>;
		int 			_state = 0;
		uint64_t		_accum = 0;
		mutable Mutex	_mutex;
		protected:
			void runL(Looper& mainLooper, SPGLContext&& ctx_b, const SPWindow& w, const UPMainProc& mp) override;
			void setState(int s);
		public:
			int getState() const;
	};
	using UPDrawTh = UPtr<DrawThread>;

	class MainThread : public ThreadL<void (Looper&,const SPWindow&)> {
		using base = ThreadL<void (Looper&, const SPWindow&)>;
		MPCreate	_mcr;
		protected:
			void runL(Looper& guiLooper, const SPWindow& w) override;
		public:
			MainThread(MPCreate mcr);
	};
	using UPMainTh = UPtr<MainThread>;

	const uint32_t EVID_SIGNAL = SDL_RegisterEvents(1);
	int GameLoop(MPCreate mcr, spn::To8Str title, int w, int h, uint32_t flag, int major=2, int minor=0, int depth=16);
}
<commit_msg>gameloop: インタフェースのデストラクタを仮想化<commit_after>#pragma once
#include "event.hpp"
#include "sdlwrap.hpp"
#include "spinner/abstbuff.hpp"

namespace rs {
	template <class T>
	using UPtr = std::unique_ptr<T>;
	namespace msg {
		struct DrawInit : MsgBase {};
		struct MainInit : MsgBase {};
		//! 描画リクエスト
		struct DrawReq : MsgBase {};
		//! スレッド終了リクエスト
		struct QuitReq : MsgBase {};
		//! スレッド状態値更新
		struct State : MsgBase {
			int state;
			State(int st): state(st) {}
		};
	}
	struct IDrawProc {
		//! 描画コールバック
		/*! 描画スレッドから呼ばれる */
		/*! \param[in] accum 累積フレーム数
			\return backbufferのswapをかける時はtrue */
		virtual bool runU(uint64_t accum) = 0;
		virtual ~IDrawProc() {}
	};
	using UPDrawProc = UPtr<IDrawProc>;
	struct IMainProc {
		//! ゲームアップデートコールバック
		/*! メインスレッドから呼ばれる */
		/*! \return ゲーム終了時にfalseを返す */
		virtual bool runU() = 0;
		//! 描画コールバックインタフェースを作成
		/*! 描画スレッドから呼ばれる */
		virtual IDrawProc* initDraw() = 0;
		virtual ~IMainProc() {}
	};
	using UPMainProc = UPtr<IMainProc>;
	using MPCreate = std::function<IMainProc* ()>;

	class DrawThread : public ThreadL<void (Looper&, SPGLContext&&, const SPWindow&, const UPMainProc&)> {
		using base = ThreadL<void (Looper&, SPGLContext&&, const SPWindow&, const UPMainProc&)>;
		int 			_state = 0;
		uint64_t		_accum = 0;
		mutable Mutex	_mutex;
		protected:
			void runL(Looper& mainLooper, SPGLContext&& ctx_b, const SPWindow& w, const UPMainProc& mp) override;
			void setState(int s);
		public:
			int getState() const;
	};
	using UPDrawTh = UPtr<DrawThread>;

	class MainThread : public ThreadL<void (Looper&,const SPWindow&)> {
		using base = ThreadL<void (Looper&, const SPWindow&)>;
		MPCreate	_mcr;
		protected:
			void runL(Looper& guiLooper, const SPWindow& w) override;
		public:
			MainThread(MPCreate mcr);
	};
	using UPMainTh = UPtr<MainThread>;

	const uint32_t EVID_SIGNAL = SDL_RegisterEvents(1);
	int GameLoop(MPCreate mcr, spn::To8Str title, int w, int h, uint32_t flag, int major=2, int minor=0, int depth=16);
}
<|endoftext|>


<commit_before>#include "AlignmentInfo.h"
#include "PhrasePairFeature.h"
#include "TargetPhrase.h"

using namespace std;

namespace Moses {

PhrasePairFeature::PhrasePairFeature
  (FactorType sourceFactorId, FactorType targetFactorId) :
  StatelessFeatureFunction("pp", ScoreProducer::unlimited),
  m_sourceFactorId(sourceFactorId),
  m_targetFactorId(targetFactorId) {}

string PhrasePairFeature::GetScoreProducerWeightShortName(unsigned) const
{
  return "pp";
}

size_t PhrasePairFeature::GetNumInputScores() const
{
  return 0;
}

void PhrasePairFeature::Evaluate(const TargetPhrase& target, ScoreComponentCollection* accumulator) const {
   const Phrase& source = target.GetSourcePhrase();
/*   const AlignmentInfo& align = cur_hypo.GetAlignmentInfo();
   for (AlignmentInfo::const_iterator i = align.begin(); i != align.end(); ++i) {
    const Factor* sourceFactor = source.GetWord(i->first).GetFactor(m_sourceFactorId);
    const Factor* targetFactor = cur_hypo.GetWord(i->second).GetFactor(m_targetFactorId);
    ostringstream namestr;
    namestr << sourceFactor->GetString();
    namestr << ":";
    namestr << targetFactor->GetString();
    accumulator->PlusEquals(this,namestr.str(),1);
  }*/
   ostringstream namestr;
   namestr << source.GetWord(0).GetFactor(m_sourceFactorId)->GetString();
   for (size_t i = 1; i < source.GetSize(); ++i) {
  	 const Factor* sourceFactor = source.GetWord(i).GetFactor(m_sourceFactorId);
  	 namestr << ",";
  	 namestr << sourceFactor->GetString();
   }
   namestr << "~";
   namestr << target.GetWord(0).GetFactor(m_targetFactorId)->GetString();
   for (size_t i = 1; i < target.GetSize(); ++i) {
  	 const Factor* targetFactor = target.GetWord(i).GetFactor(m_targetFactorId);
  	 namestr << ",";
  	 namestr << targetFactor->GetString();
   }
   accumulator->PlusEquals(this,namestr.str(),1);
}

bool PhrasePairFeature::ComputeValueInTranslationOption() const {
  return false;
}

}
<commit_msg>add comment<commit_after>#include "AlignmentInfo.h"
#include "PhrasePairFeature.h"
#include "TargetPhrase.h"

using namespace std;

namespace Moses {

PhrasePairFeature::PhrasePairFeature
  (FactorType sourceFactorId, FactorType targetFactorId) :
  StatelessFeatureFunction("pp", ScoreProducer::unlimited),
  m_sourceFactorId(sourceFactorId),
  m_targetFactorId(targetFactorId) {
  std::cerr << "Creating phrase pair feature.. " << endl;
}

string PhrasePairFeature::GetScoreProducerWeightShortName(unsigned) const
{
  return "pp";
}

size_t PhrasePairFeature::GetNumInputScores() const
{
  return 0;
}

void PhrasePairFeature::Evaluate(const TargetPhrase& target, ScoreComponentCollection* accumulator) const {
   const Phrase& source = target.GetSourcePhrase();
/*   const AlignmentInfo& align = cur_hypo.GetAlignmentInfo();
   for (AlignmentInfo::const_iterator i = align.begin(); i != align.end(); ++i) {
    const Factor* sourceFactor = source.GetWord(i->first).GetFactor(m_sourceFactorId);
    const Factor* targetFactor = cur_hypo.GetWord(i->second).GetFactor(m_targetFactorId);
    ostringstream namestr;
    namestr << sourceFactor->GetString();
    namestr << ":";
    namestr << targetFactor->GetString();
    accumulator->PlusEquals(this,namestr.str(),1);
  }*/
   ostringstream namestr;
   namestr << source.GetWord(0).GetFactor(m_sourceFactorId)->GetString();
   for (size_t i = 1; i < source.GetSize(); ++i) {
  	 const Factor* sourceFactor = source.GetWord(i).GetFactor(m_sourceFactorId);
  	 namestr << ",";
  	 namestr << sourceFactor->GetString();
   }
   namestr << "~";
   namestr << target.GetWord(0).GetFactor(m_targetFactorId)->GetString();
   for (size_t i = 1; i < target.GetSize(); ++i) {
  	 const Factor* targetFactor = target.GetWord(i).GetFactor(m_targetFactorId);
  	 namestr << ",";
  	 namestr << targetFactor->GetString();
   }
   accumulator->PlusEquals(this,namestr.str(),1);
}

bool PhrasePairFeature::ComputeValueInTranslationOption() const {
  return false;
}

}
<|endoftext|>


<commit_before>#include <string>

#include "ccspec/core.h"
#include "ccspec/expectation.h"
#include "ccspec/matchers.h"

using std::string;
using ccspec::core::before;
using ccspec::core::context;
using ccspec::core::describe;
using ccspec::core::it;
using ccspec::expect;
using ccspec::matchers::be_falsey;
using ccspec::matchers::be_truthy;
using ccspec::matchers::eq;

namespace spec {
namespace matchers {

auto eq_spec = describe("Eq", [] {
  it("matches if two const temp bools are equal", [] {
    expect(eq(false).match(false)).to(be_truthy);
  });

  it("matches if two bools are equal", [] {
    bool b0, b1;
    b0 = b1 = true;
    expect(eq(b0).match(b1)).to(be_truthy);
  });

  it("does not match if two bools are not equal", [] {
    bool b0 = true, b1 = false;
    expect(eq(b0).match(b1)).to(be_falsey);
  });

  it("matches if two const temp chars are equal", [] {
    expect(eq('x').match('x')).to(be_truthy);
  });

  it("matches if two chars are equal", [] {
    char c0, c1;
    c0 = c1 = 'z';
    expect(eq(c0).match(c1)).to(be_truthy);
  });

  it("does not match if two chars are not equal", [] {
    char c0 = 'x', c1 = 'y';
    expect(eq(c0).match(c1)).to(be_falsey);
  });

  it("matches if two const temp ints are equal", [] {
    expect(eq(42).match(42)).to(be_truthy);
  });

  it("matches if two ints are equal", [] {
    int i0, i1;
    i0 = i1 = 42;
    expect(eq(i0).match(i1)).to(be_truthy);
  });

  it("does not match if two ints are not equal", [] {
    int i0 = 42, i1 = 43;
    expect(eq(i0).match(i1)).to(be_falsey);
  });

  it("matches if two const temp doubles are equal", [] {
    expect(eq(3.14).match(3.14)).to(be_truthy);
  });

  it("matches if two doubles are equal", [] {
    double d0, d1;
    d0 = d1 = 2.718;
    expect(eq(d0).match(d1)).to(be_truthy);
  });

  it("does not match if two doubles are not equal", [] {
    double d0 = 3.14, d1 = 2.718;
    expect(eq(d0).match(d1)).to(be_falsey);
  });

  it("matches if two const temp char* point to the same string", [] {
    expect(eq("foo").match("foo")).to(be_truthy);
  });

  it("matches if two char* point to the same string", [] {
    const char* str0 = "test";
    const char* str1 = "test";
    expect(eq(str0).match(str1)).to(be_truthy);
  });

  it("does not match if two char* point to different string", [] {
    const char* str0 = "test";
    const char* str1 = "spec";
    expect(eq(str0).match(str1)).to(be_falsey);
  });

  it("does not match if two char* point to different copies of the same string",
     [] {
    const char* str0 = "test";
    char str1[] = "test";
    expect(eq(str0).match(str1)).to(be_falsey);
  });

  it("matches if two const temp strings are equal", [] {
    expect(eq(string("test")).match(string("test"))).to(be_truthy);
  });

  it("matches if two strings are equal", [] {
    string str0 = "test";
    string str1 = "test";
    expect(eq(str0).match(str1)).to(be_truthy);
  });

  it("does not match if two strings are not equal", [] {
    string str0 = "test";
    string str1 = "spec";
    expect(eq(str0).match(str1)).to(be_falsey);
  });

  context("when used for arbitrary types", [] {
    class T {
     public:
      explicit T(int i) : i_(i) {}
      bool operator ==(const T& t) const {
        return i_ == t.i_;
      }

     private:
      int i_;
    } t0(0), t1(2), t3(0);

    it("matches if two const temp instances of them are equal", [] {
      expect(eq(T(3)).match(T(3))).to(be_truthy);
    });

    it("matches if two instances of them are equal", [t0, t3] {
      expect(eq(t0).match(t3)).to(be_truthy);
    });

    it("does not match if two instances of them are not equal", [t1, t3] {
      expect(eq(t1).match(t3)).to(be_falsey);
    });
  });

  describe("#desc", [] {
    it("says 'equal $b' when expecting bool", [] {
      expect(eq(true).desc()).to(eq("equal true"));
    });

    it("says 'equal $c' when expecting char", [] {
      expect(eq('x').desc()).to(eq("equal x"));
    });

    it("says 'equal $i' when expecting int", [] {
      expect(eq(42).desc()).to(eq("equal 42"));
    });

    it("says 'equal $d' when expecting double", [] {
      expect(eq(3.14).desc()).to(eq("equal 3.14"));
    });

    it("says 'equal $s' when expecting char*", [] {
      expect(eq("test").desc()).to(eq("equal test"));
    });

    it("says 'equal $s' when expecting string", [] {
      expect(eq(string("test")).desc()).to(eq("equal test"));
    });
  });
});

}  // namespace matchers
}  // namespace spec
<commit_msg>Fix plural of words in spec description<commit_after>#include <string>

#include "ccspec/core.h"
#include "ccspec/expectation.h"
#include "ccspec/matchers.h"

using std::string;
using ccspec::core::before;
using ccspec::core::context;
using ccspec::core::describe;
using ccspec::core::it;
using ccspec::expect;
using ccspec::matchers::be_falsey;
using ccspec::matchers::be_truthy;
using ccspec::matchers::eq;

namespace spec {
namespace matchers {

auto eq_spec = describe("Eq", [] {
  it("matches if two const temp bools are equal", [] {
    expect(eq(false).match(false)).to(be_truthy);
  });

  it("matches if two bools are equal", [] {
    bool b0, b1;
    b0 = b1 = true;
    expect(eq(b0).match(b1)).to(be_truthy);
  });

  it("does not match if two bools are not equal", [] {
    bool b0 = true, b1 = false;
    expect(eq(b0).match(b1)).to(be_falsey);
  });

  it("matches if two const temp chars are equal", [] {
    expect(eq('x').match('x')).to(be_truthy);
  });

  it("matches if two chars are equal", [] {
    char c0, c1;
    c0 = c1 = 'z';
    expect(eq(c0).match(c1)).to(be_truthy);
  });

  it("does not match if two chars are not equal", [] {
    char c0 = 'x', c1 = 'y';
    expect(eq(c0).match(c1)).to(be_falsey);
  });

  it("matches if two const temp ints are equal", [] {
    expect(eq(42).match(42)).to(be_truthy);
  });

  it("matches if two ints are equal", [] {
    int i0, i1;
    i0 = i1 = 42;
    expect(eq(i0).match(i1)).to(be_truthy);
  });

  it("does not match if two ints are not equal", [] {
    int i0 = 42, i1 = 43;
    expect(eq(i0).match(i1)).to(be_falsey);
  });

  it("matches if two const temp doubles are equal", [] {
    expect(eq(3.14).match(3.14)).to(be_truthy);
  });

  it("matches if two doubles are equal", [] {
    double d0, d1;
    d0 = d1 = 2.718;
    expect(eq(d0).match(d1)).to(be_truthy);
  });

  it("does not match if two doubles are not equal", [] {
    double d0 = 3.14, d1 = 2.718;
    expect(eq(d0).match(d1)).to(be_falsey);
  });

  it("matches if two const temp char* point to the same string", [] {
    expect(eq("foo").match("foo")).to(be_truthy);
  });

  it("matches if two char* point to the same string", [] {
    const char* str0 = "test";
    const char* str1 = "test";
    expect(eq(str0).match(str1)).to(be_truthy);
  });

  it("does not match if two char* point to different strings", [] {
    const char* str0 = "test";
    const char* str1 = "spec";
    expect(eq(str0).match(str1)).to(be_falsey);
  });

  it("does not match if two char* point to different copies of the same string",
     [] {
    const char* str0 = "test";
    char str1[] = "test";
    expect(eq(str0).match(str1)).to(be_falsey);
  });

  it("matches if two const temp strings are equal", [] {
    expect(eq(string("test")).match(string("test"))).to(be_truthy);
  });

  it("matches if two strings are equal", [] {
    string str0 = "test";
    string str1 = "test";
    expect(eq(str0).match(str1)).to(be_truthy);
  });

  it("does not match if two strings are not equal", [] {
    string str0 = "test";
    string str1 = "spec";
    expect(eq(str0).match(str1)).to(be_falsey);
  });

  context("when used for arbitrary types", [] {
    class T {
     public:
      explicit T(int i) : i_(i) {}
      bool operator ==(const T& t) const {
        return i_ == t.i_;
      }

     private:
      int i_;
    } t0(0), t1(2), t3(0);

    it("matches if two const temp instances of them are equal", [] {
      expect(eq(T(3)).match(T(3))).to(be_truthy);
    });

    it("matches if two instances of them are equal", [t0, t3] {
      expect(eq(t0).match(t3)).to(be_truthy);
    });

    it("does not match if two instances of them are not equal", [t1, t3] {
      expect(eq(t1).match(t3)).to(be_falsey);
    });
  });

  describe("#desc", [] {
    it("says 'equal $b' when expecting bool", [] {
      expect(eq(true).desc()).to(eq("equal true"));
    });

    it("says 'equal $c' when expecting char", [] {
      expect(eq('x').desc()).to(eq("equal x"));
    });

    it("says 'equal $i' when expecting int", [] {
      expect(eq(42).desc()).to(eq("equal 42"));
    });

    it("says 'equal $d' when expecting double", [] {
      expect(eq(3.14).desc()).to(eq("equal 3.14"));
    });

    it("says 'equal $s' when expecting char*", [] {
      expect(eq("test").desc()).to(eq("equal test"));
    });

    it("says 'equal $s' when expecting string", [] {
      expect(eq(string("test")).desc()).to(eq("equal test"));
    });
  });
});

}  // namespace matchers
}  // namespace spec
<|endoftext|>


<commit_before>/*
 * Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
 * This file is part of SIGAR.
 *
 * SIGAR is free software; you can redistribute it and/or modify
 * it under the terms version 2 of the GNU General Public License as
 * published by the Free Software Foundation. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */

#ifdef WIN32

#include "win32bindings.h"
#include "javasigar.h"

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint SIGAR_JNI(win32_LocaleInfo_getSystemDefaultLCID)
(JNIEnv *env, jclass objcls)
{
    return GetSystemDefaultLCID();
}

JNIEXPORT jstring SIGAR_JNI(win32_LocaleInfo_getAttribute)
(JNIEnv *env, jclass objcls, jint lcid, jint attr)
{
    char value[8192];
    int retval =
        GetLocaleInfo(lcid,
                      attr,
                      value, sizeof(value));

    if (retval) {
        return env->NewStringUTF(value);
    }
    else {
        return NULL;
    }
}

#ifdef __cplusplus
}
#endif
#endif /* WIN32 */
<commit_msg>unicode-ize<commit_after>/*
 * Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
 * This file is part of SIGAR.
 *
 * SIGAR is free software; you can redistribute it and/or modify
 * it under the terms version 2 of the GNU General Public License as
 * published by the Free Software Foundation. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */

#ifdef WIN32
#define UNICODE
#define _UNICODE

#include "win32bindings.h"
#include "javasigar.h"

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint SIGAR_JNI(win32_LocaleInfo_getSystemDefaultLCID)
(JNIEnv *env, jclass objcls)
{
    return GetSystemDefaultLCID();
}

JNIEXPORT jstring SIGAR_JNI(win32_LocaleInfo_getAttribute)
(JNIEnv *env, jclass objcls, jint lcid, jint attr)
{
    TCHAR value[8192];
    int retval =
        GetLocaleInfo(lcid,
                      attr,
                      value, sizeof(value));

    if (retval) {
        int len = lstrlen(value);
        return env->NewString((const jchar *)value, len);
    }
    else {
        return NULL;
    }
}

#ifdef __cplusplus
}
#endif
#endif /* WIN32 */
<|endoftext|>