<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/random.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-base/thread/threadpool.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "fnord-eventdb/TableReader.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include "IndexReader.h"
#include "analytics/ReportBuilder.h"
#include "analytics/AnalyticsTableScanSource.h"
#include "analytics/JoinedQueryTableSource.h"
#include "analytics/CTRByPositionMapper.h"
#include "analytics/CTRByPageMapper.h"
#include "analytics/CTRBySearchQueryMapper.h"
#include "analytics/CTRByQueryAttributeMapper.h"
#include "analytics/CTRByShopMapper.h"
#include "analytics/CTRStatsMapper.h"
#include "analytics/CTRCounterMergeReducer.h"
#include "analytics/CTRCounterTableSink.h"
#include "analytics/CTRCounterTableSource.h"
#include "analytics/RelatedTermsMapper.h"
#include "analytics/TopCategoriesByTermMapper.h"
#include "analytics/TermInfoMergeReducer.h"

using namespace fnord;
using namespace cm;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "datadir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  //auto index_path = flags.getString("index");
  //auto conf_path = flags.getString("conf");
  auto tempdir = flags.getString("tempdir");
  auto datadir = flags.getString("datadir");

  /* open index */
  //auto index_reader = cm::IndexReader::openIndex(index_path);
  //auto analyzer = RefPtr<fts::Analyzer>(new fts::Analyzer(conf_path));

  /* set up reportbuilder */
  thread::ThreadPool tpool;
  cm::ReportBuilder report_builder(&tpool);

  Random rnd;
  auto buildid = rnd.hex128();

  auto table = eventdb::TableReader::open(
      "joined_sessions-dawanda",
      flags.getString("replica"),
      flags.getString("datadir"),
      joinedSessionsSchema());

  auto snap = table->getSnapshot();

/*
  Set<String> searchterm_x_e1_tables;
  Set<String> related_terms_tables;

  for (const auto& c : snap->head->chunks) {
    auto input_table = StringUtil::format(
        "$0/$1.$2.$3.cst",
        datadir,
        "joined_sessions-dawanda",
        c.replica_id,
        c.chunk_id);

    auto related_terms_table = StringUtil::format(
        "$0/dawanda_related_terms.$1.$2.sst",
        tempdir,
        c.replica_id,
        c.chunk_id);

    related_terms_tables.emplace(related_terms_table);
    report_builder.addReport(
        new RelatedTermsMapper(
            new AnalyticsTableScanSource(input_table),
            new TermInfoTableSink(related_terms_table)));

    auto searchterm_x_e1_table = StringUtil::format(
        "$0/dawanda_ctr_by_searchterm_cross_e1.$1.$2.sst",
        tempdir,
        c.replica_id,
        c.chunk_id);

    searchterm_x_e1_tables.emplace(searchterm_x_e1_table);
    report_builder.addReport(
        new CTRBySearchTermCrossCategoryMapper(
            new AnalyticsTableScanSource(input_table),
            new CTRCounterTableSink(0, 0, searchterm_x_e1_table),
            "category1"));
  }

  report_builder.addReport(
      new TermInfoMergeReducer(
          new TermInfoTableSource(related_terms_tables),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_related_terms.$1.sstable",
                  tempdir,
                  buildid))));

  report_builder.addReport(
      new TopCategoriesByTermMapper(
          new CTRCounterTableSource(searchterm_x_e1_tables),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_top_cats_by_searchterm_e1.$1.sstable",
                  tempdir,
                  buildid)),
          "e1-"));

  report_builder.addReport(
      new TermInfoMergeReducer(
          new TermInfoTableSource(Set<String> {
            StringUtil::format(
                  "$0/dawanda_related_terms.$1.sstable",
                  tempdir,
                  buildid),
            StringUtil::format(
                  "$0/dawanda_top_cats_by_searchterm_e1.$1.sstable",
                  tempdir,
                  buildid)
          }),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_termstats.$1.sstable",
                  tempdir,
                  buildid))));

  report_builder.buildAll();

  fnord::logInfo(
      "cm.reportbuild",
      "Build completed: dawanda_termstats.$0.sstable",
      buildid);

*/

  return 0;
}

<commit_msg>CTRByShopMapper stub<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/random.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-base/thread/threadpool.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "fnord-eventdb/TableReader.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include "IndexReader.h"
#include "analytics/ReportBuilder.h"
#include "analytics/AnalyticsTableScanSource.h"
#include "analytics/JoinedQueryTableSource.h"
#include "analytics/CTRByPositionMapper.h"
#include "analytics/CTRByPageMapper.h"
#include "analytics/CTRBySearchQueryMapper.h"
#include "analytics/CTRByQueryAttributeMapper.h"
#include "analytics/CTRByShopMapper.h"
#include "analytics/CTRStatsMapper.h"
#include "analytics/CTRCounterMergeReducer.h"
#include "analytics/CTRCounterTableSink.h"
#include "analytics/CTRCounterTableSource.h"
#include "analytics/RelatedTermsMapper.h"
#include "analytics/TopCategoriesByTermMapper.h"
#include "analytics/TermInfoMergeReducer.h"

using namespace fnord;
using namespace cm;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "datadir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  //auto index_path = flags.getString("index");
  //auto conf_path = flags.getString("conf");
  auto tempdir = flags.getString("tempdir");
  auto datadir = flags.getString("datadir");

  /* open index */
  //auto index_reader = cm::IndexReader::openIndex(index_path);
  //auto analyzer = RefPtr<fts::Analyzer>(new fts::Analyzer(conf_path));

  /* set up reportbuilder */
  thread::ThreadPool tpool;
  cm::ReportBuilder report_builder(&tpool);

  Random rnd;
  auto buildid = rnd.hex128();

  auto table = eventdb::TableReader::open(
      "joined_sessions-dawanda",
      flags.getString("replica"),
      flags.getString("datadir"),
      joinedSessionsSchema());

  auto snap = table->getSnapshot();

  Set<String> ctr_tables;

  for (const auto& c : snap->head->chunks) {
    auto input_table = StringUtil::format(
        "$0/$1.$2.$3.cst",
        datadir,
        "joined_sessions-dawanda",
        c.replica_id,
        c.chunk_id);

    auto ctr_table = StringUtil::format(
        "$0/shopstats-ctr-dawanda.$1.$2.sst",
        tempdir,
        c.replica_id,
        c.chunk_id);

    ctr_tables.emplace(ctr_table);
    report_builder.addReport(
        new CTRByShopMapper(
            new AnalyticsTableScanSource(input_table),
            new CTRCounterTableSink(0, 0, ctr_table)));
  }

  report_builder.buildAll();

  fnord::logInfo(
      "cm.reportbuild",
      "Build completed: shopstats-merged-dawanda.$0.sstable",
      buildid);

  return 0;
}

<|endoftext|>


<commit_before>#include <climits>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include "snarkfront.hpp"

using namespace snarkfront;
using namespace std;

void printUsage(const char* exeName) {
    const string
        AES = " -b 128|192|256",
        KEY = " -k key_in_hex",
        MODE = " -e|-d",
        ENC = " -e",
        DEC = " -d",
        INPUT = " -i hex_text",
        PAIR = " -p BN128|Edwards";

    cout << "encrypt: " << exeName << PAIR << AES << KEY << ENC << INPUT << endl
         << "decrypt: " << exeName << PAIR << AES << KEY << DEC << INPUT << endl;

    exit(EXIT_FAILURE);
}

template <typename AES, typename KEY_BLOCK, typename SCHEDULE_BLOCK>
void runTest(const vector<uint8_t>& keyOctets,
             const vector<uint8_t>& inOctets,
             typename AES::BlockType& outBlock)
{
    typename AES::BlockType inBlock;
    KEY_BLOCK keyBlock;
    SCHEDULE_BLOCK scheduleBlock;

    DataBufferStream keyBuf(keyOctets), inBuf(inOctets);
    bless(inBlock, inBuf);
    bless(keyBlock, keyBuf);

    typename AES::KeyExpansion keyExpand;
    keyExpand(keyBlock, scheduleBlock);

    AES cipherAlgo;
    cipherAlgo(inBlock, outBlock, scheduleBlock);
}

template <typename ZK_AES, typename EVAL_AES>
bool runTest(const vector<uint8_t>& keyOctets,
             const vector<uint8_t>& inOctets)
{
    typename ZK_AES::BlockType zkOut;
    typename EVAL_AES::BlockType evalOut;

    const auto keySize = keyOctets.size() * CHAR_BIT;
    if (128 == keySize) {
        // AES-128
        runTest<ZK_AES,
                typename ZK_AES::KeyExpansion::Key128Type,
                typename ZK_AES::KeyExpansion::Schedule128Type>(
                    keyOctets,
                    inOctets,
                    zkOut);

        runTest<EVAL_AES,
                typename EVAL_AES::KeyExpansion::Key128Type,
                typename EVAL_AES::KeyExpansion::Schedule128Type>(
                    keyOctets,
                    inOctets,
                    evalOut);

    } else if (192 == keySize) {
        // AES-192
        runTest<ZK_AES,
                typename ZK_AES::KeyExpansion::Key192Type,
                typename ZK_AES::KeyExpansion::Schedule192Type>(
                    keyOctets,
                    inOctets,
                    zkOut);

        runTest<EVAL_AES,
                typename EVAL_AES::KeyExpansion::Key192Type,
                typename EVAL_AES::KeyExpansion::Schedule192Type>(
                    keyOctets,
                    inOctets,
                    evalOut);

    } else if (256 == keySize) {
        // AES-256
        runTest<ZK_AES,
                typename ZK_AES::KeyExpansion::Key256Type,
                typename ZK_AES::KeyExpansion::Schedule256Type>(
                    keyOctets,
                    inOctets,
                    zkOut);

        runTest<EVAL_AES,
                typename EVAL_AES::KeyExpansion::Key256Type,
                typename EVAL_AES::KeyExpansion::Schedule256Type>(
                    keyOctets,
                    inOctets,
                    evalOut);
    }

    assert_true(zkOut == evalOut);

    DataBuffer<PrintHex> hexpr(cout, false);
    bool ok = true;

    // compare output blocks
    for (size_t i = 0; i < zkOut.size(); ++i) {
        if (zkOut[i]->value() != evalOut[i]) {
            ok = false;
            cout << "output[" << i << "] error zk: ";
            hexpr.push(zkOut[i]->value());
            cout << " eval: ";
            hexpr.push(evalOut[i]);
            cout << endl;
        }
    }

    if (ok) cout << "output: " << asciiHex(evalOut) << endl;

    return ok;
}

template <typename PAIRING>
bool runTest(const vector<uint8_t>& keyOctets,
             const bool encMode,
             const vector<uint8_t>& inOctets)
{
    reset<PAIRING>();

    typedef typename PAIRING::Fr FR;

    const bool valueOK = encMode
        ? runTest<zk::AES_Encrypt<FR>, eval::AES_Encrypt>(keyOctets, inOctets)
        : runTest<zk::AES_Decrypt<FR>, eval::AES_Decrypt>(keyOctets, inOctets);

    cout << "variable count " << variable_count<PAIRING>() << endl;

    GenericProgressBar progress1(cerr), progress2(cerr, 50);

    cerr << "generate key pair";
    const auto key = keypair<PAIRING>(progress2);
    cerr << endl;

    const auto in = input<PAIRING>();

    cerr << "generate proof";
    const auto p = proof(key, progress2);
    cerr << endl;

    cerr << "verify proof ";
    const bool proofOK = verify(key, in, p, progress1);
    cerr << endl;

    return valueOK && proofOK;
}

int main(int argc, char *argv[])
{
    Getopt cmdLine(argc, argv, "pki", "b", "ed");
    if (!cmdLine || cmdLine.empty()) printUsage(argv[0]);

    const auto
        pairing = cmdLine.getString('p'),
        keyText = cmdLine.getString('k'),
        inText = cmdLine.getString('i');

    const auto aesBits = cmdLine.getNumber('b');

    const auto
        encMode = cmdLine.getFlag('e'),
        decMode = cmdLine.getFlag('d');

    if (!validPairingName(pairing) || !validAESName(aesBits) || !(encMode ^ decMode))
        printUsage(argv[0]);

    vector<uint8_t> keyOctets;
    if (!asciiHexToVector(keyText, keyOctets)) {
        cerr << "error: malformed key" << endl;
        exit(EXIT_FAILURE);
    }

    const auto keySize = keyOctets.size() * CHAR_BIT;
    if (aesBits != keySize) {
        cerr << "error: key size is " << keySize << " bits" << endl;
        exit(EXIT_FAILURE);
    }

    vector<uint8_t> inOctets;
    if (!asciiHexToVector(inText, inOctets)) {
        cerr << "error: malformed input" << endl;
        exit(EXIT_FAILURE);
    }

    const auto inSize = inOctets.size() * CHAR_BIT;
    if (128 != inSize) {
        cerr << "error: input size is " << inSize << " bits" << endl;
        exit(EXIT_FAILURE);
    }

    bool result;

    if (pairingBN128(pairing)) {
        // Barreto-Naehrig 128 bits
        init_BN128();
        result = runTest<BN128_PAIRING>(keyOctets, encMode, inOctets);

    } else if (pairingEdwards(pairing)) {
        // Edwards 80 bits
        init_Edwards();
        result = runTest<EDWARDS_PAIRING>(keyOctets, encMode, inOctets);
    }

    cout << "test " << (result ? "passed" : "failed") << endl;

    exit(EXIT_SUCCESS);
}
<commit_msg>remove whitespace<commit_after>#include <climits>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include "snarkfront.hpp"

using namespace snarkfront;
using namespace std;

void printUsage(const char* exeName) {
    const string
        AES = " -b 128|192|256",
        KEY = " -k key_in_hex",
        MODE = " -e|-d",
        ENC = " -e",
        DEC = " -d",
        INPUT = " -i hex_text",
        PAIR = " -p BN128|Edwards";

    cout << "encrypt: " << exeName << PAIR << AES << KEY << ENC << INPUT << endl
         << "decrypt: " << exeName << PAIR << AES << KEY << DEC << INPUT << endl;

    exit(EXIT_FAILURE);
}

template <typename AES, typename KEY_BLOCK, typename SCHEDULE_BLOCK>
void runTest(const vector<uint8_t>& keyOctets,
             const vector<uint8_t>& inOctets,
             typename AES::BlockType& outBlock)
{
    typename AES::BlockType inBlock;
    KEY_BLOCK keyBlock;
    SCHEDULE_BLOCK scheduleBlock;

    DataBufferStream keyBuf(keyOctets), inBuf(inOctets);
    bless(inBlock, inBuf);
    bless(keyBlock, keyBuf);

    typename AES::KeyExpansion keyExpand;
    keyExpand(keyBlock, scheduleBlock);

    AES cipherAlgo;
    cipherAlgo(inBlock, outBlock, scheduleBlock);
}

template <typename ZK_AES, typename EVAL_AES>
bool runTest(const vector<uint8_t>& keyOctets,
             const vector<uint8_t>& inOctets)
{
    typename ZK_AES::BlockType zkOut;
    typename EVAL_AES::BlockType evalOut;

    const auto keySize = keyOctets.size() * CHAR_BIT;
    if (128 == keySize) {
        // AES-128
        runTest<ZK_AES,
                typename ZK_AES::KeyExpansion::Key128Type,
                typename ZK_AES::KeyExpansion::Schedule128Type>(
                    keyOctets,
                    inOctets,
                    zkOut);

        runTest<EVAL_AES,
                typename EVAL_AES::KeyExpansion::Key128Type,
                typename EVAL_AES::KeyExpansion::Schedule128Type>(
                    keyOctets,
                    inOctets,
                    evalOut);

    } else if (192 == keySize) {
        // AES-192
        runTest<ZK_AES,
                typename ZK_AES::KeyExpansion::Key192Type,
                typename ZK_AES::KeyExpansion::Schedule192Type>(
                    keyOctets,
                    inOctets,
                    zkOut);

        runTest<EVAL_AES,
                typename EVAL_AES::KeyExpansion::Key192Type,
                typename EVAL_AES::KeyExpansion::Schedule192Type>(
                    keyOctets,
                    inOctets,
                    evalOut);

    } else if (256 == keySize) {
        // AES-256
        runTest<ZK_AES,
                typename ZK_AES::KeyExpansion::Key256Type,
                typename ZK_AES::KeyExpansion::Schedule256Type>(
                    keyOctets,
                    inOctets,
                    zkOut);

        runTest<EVAL_AES,
                typename EVAL_AES::KeyExpansion::Key256Type,
                typename EVAL_AES::KeyExpansion::Schedule256Type>(
                    keyOctets,
                    inOctets,
                    evalOut);
    }

    assert_true(zkOut == evalOut);

    DataBuffer<PrintHex> hexpr(cout, false);
    bool ok = true;

    // compare output blocks
    for (size_t i = 0; i < zkOut.size(); ++i) {
        if (zkOut[i]->value() != evalOut[i]) {
            ok = false;
            cout << "output[" << i << "] error zk: ";
            hexpr.push(zkOut[i]->value());
            cout << " eval: ";
            hexpr.push(evalOut[i]);
            cout << endl;
        }
    }

    if (ok) cout << "output: " << asciiHex(evalOut) << endl;

    return ok;
}

template <typename PAIRING>
bool runTest(const vector<uint8_t>& keyOctets,
             const bool encMode,
             const vector<uint8_t>& inOctets)
{
    reset<PAIRING>();

    typedef typename PAIRING::Fr FR;

    const bool valueOK = encMode
        ? runTest<zk::AES_Encrypt<FR>, eval::AES_Encrypt>(keyOctets, inOctets)
        : runTest<zk::AES_Decrypt<FR>, eval::AES_Decrypt>(keyOctets, inOctets);

    cout << "variable count " << variable_count<PAIRING>() << endl;

    GenericProgressBar progress1(cerr), progress2(cerr, 50);

    cerr << "generate key pair";
    const auto key = keypair<PAIRING>(progress2);
    cerr << endl;

    const auto in = input<PAIRING>();

    cerr << "generate proof";
    const auto p = proof(key, progress2);
    cerr << endl;

    cerr << "verify proof ";
    const bool proofOK = verify(key, in, p, progress1);
    cerr << endl;

    return valueOK && proofOK;
}

int main(int argc, char *argv[])
{
    Getopt cmdLine(argc, argv, "pki", "b", "ed");
    if (!cmdLine || cmdLine.empty()) printUsage(argv[0]);

    const auto
        pairing = cmdLine.getString('p'),
        keyText = cmdLine.getString('k'),
        inText = cmdLine.getString('i');

    const auto aesBits = cmdLine.getNumber('b');

    const auto
        encMode = cmdLine.getFlag('e'),
        decMode = cmdLine.getFlag('d');

    if (!validPairingName(pairing) || !validAESName(aesBits) || !(encMode ^ decMode))
        printUsage(argv[0]);

    vector<uint8_t> keyOctets;
    if (!asciiHexToVector(keyText, keyOctets)) {
        cerr << "error: malformed key" << endl;
        exit(EXIT_FAILURE);
    }

    const auto keySize = keyOctets.size() * CHAR_BIT;
    if (aesBits != keySize) {
        cerr << "error: key size is " << keySize << " bits" << endl;
        exit(EXIT_FAILURE);
    }

    vector<uint8_t> inOctets;
    if (!asciiHexToVector(inText, inOctets)) {
        cerr << "error: malformed input" << endl;
        exit(EXIT_FAILURE);
    }

    const auto inSize = inOctets.size() * CHAR_BIT;
    if (128 != inSize) {
        cerr << "error: input size is " << inSize << " bits" << endl;
        exit(EXIT_FAILURE);
    }

    bool result;

    if (pairingBN128(pairing)) {
        // Barreto-Naehrig 128 bits
        init_BN128();
        result = runTest<BN128_PAIRING>(keyOctets, encMode, inOctets);

    } else if (pairingEdwards(pairing)) {
        // Edwards 80 bits
        init_Edwards();
        result = runTest<EDWARDS_PAIRING>(keyOctets, encMode, inOctets);
    }

    cout << "test " << (result ? "passed" : "failed") << endl;

    exit(EXIT_SUCCESS);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: padialog.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: pl $ $Date: 2001-06-19 13:47:44 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _PAD_PADIALOG_HXX_
#define _PAD_PADIALOG_HXX_
#ifndef __SGI_STL_LIST
#include <list>
#endif
#ifndef _RTL_USTRING
#include <rtl/ustring>
#endif
#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
#ifndef _SV_CONFIG_HXX
#include <vcl/config.hxx>
#endif
#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_GROUP_HXX
#include <vcl/group.hxx>
#endif
#ifndef _SV_EDIT_HXX
#include <vcl/edit.hxx>
#endif
#ifndef _PAD_HELPER_HXX_
#include <helper.hxx>
#endif

// forward declaration
namespace psp { class PrinterInfoManager; }

namespace padmin {

    class PADialog : public ModalDialog
    {
    private:
        DelListBox                          m_aDevicesLB;
        PushButton                          m_aConfPB;
        PushButton                          m_aRenamePB;
        PushButton                          m_aStdPB;
        PushButton                          m_aRemPB;
        PushButton                          m_aTestPagePB;
        FixedLine                           m_aPrintersFL;
        FixedText                           m_aDriverTxt;
        FixedText                           m_aDriver;
        FixedText                           m_aLocationTxt;
        FixedText                           m_aLocation;
        FixedText                           m_aCommandTxt;
        FixedText                           m_aCommand;
        FixedText                           m_aCommentTxt;
        FixedText                           m_aComment;

        FixedLine                           m_aSepButtonFL;
        PushButton                          m_aAddPB;
        PushButton                          m_aFontsPB;
        CancelButton                        m_aCancelButton;

        String                              m_aDefPrt;
        String                              m_aRenameStr;

        Printer*                            m_pPrinter;
        ::psp::PrinterInfoManager&          m_rPIManager;
        ::std::list< ::rtl::OUString >      m_aPrinters;

        Image                               m_aPrinterImg;
        Image                               m_aFaxImg;
        Image                               m_aPdfImg;

        DECL_LINK( ClickBtnHdl, PushButton* );
        DECL_LINK( DoubleClickHdl, ListBox* );
        DECL_LINK( SelectHdl, ListBox* );
        DECL_LINK( EndPrintHdl, void* );
        DECL_LINK( DelPressedHdl, ListBox* );

        PADialog( Window*,  BOOL );
        void Init();

        void UpdateDefPrt();
        void UpdateText();
        void UpdateDevice();
        void AddDevice();
        void RemDevice();
        void ConfigureDevice();
        void RenameDevice();
        void PrintTestPage();

        String getSelectedDevice();
    public:
        ~PADialog();

        static PADialog* Create( Window*,  BOOL );
    };

} // namespace

#endif
<commit_msg>INTEGRATION: CWS vclcleanup02 (1.4.116); FILE MERGED 2003/12/10 15:57:01 mt 1.4.116.1: #i23061# VCL cleanup, removed headers, methods and types...<commit_after>/*************************************************************************
 *
 *  $RCSfile: padialog.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2004-01-06 16:50:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _PAD_PADIALOG_HXX_
#define _PAD_PADIALOG_HXX_
#ifndef __SGI_STL_LIST
#include <list>
#endif
#ifndef _RTL_USTRING
#include <rtl/ustring>
#endif
#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
#ifndef _CONFIG_HXX
#include <tools/config.hxx>
#endif
#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_GROUP_HXX
#include <vcl/group.hxx>
#endif
#ifndef _SV_EDIT_HXX
#include <vcl/edit.hxx>
#endif
#ifndef _PAD_HELPER_HXX_
#include <helper.hxx>
#endif

// forward declaration
namespace psp { class PrinterInfoManager; }

namespace padmin {

    class PADialog : public ModalDialog
    {
    private:
        DelListBox                          m_aDevicesLB;
        PushButton                          m_aConfPB;
        PushButton                          m_aRenamePB;
        PushButton                          m_aStdPB;
        PushButton                          m_aRemPB;
        PushButton                          m_aTestPagePB;
        FixedLine                           m_aPrintersFL;
        FixedText                           m_aDriverTxt;
        FixedText                           m_aDriver;
        FixedText                           m_aLocationTxt;
        FixedText                           m_aLocation;
        FixedText                           m_aCommandTxt;
        FixedText                           m_aCommand;
        FixedText                           m_aCommentTxt;
        FixedText                           m_aComment;

        FixedLine                           m_aSepButtonFL;
        PushButton                          m_aAddPB;
        PushButton                          m_aFontsPB;
        CancelButton                        m_aCancelButton;

        String                              m_aDefPrt;
        String                              m_aRenameStr;

        Printer*                            m_pPrinter;
        ::psp::PrinterInfoManager&          m_rPIManager;
        ::std::list< ::rtl::OUString >      m_aPrinters;

        Image                               m_aPrinterImg;
        Image                               m_aFaxImg;
        Image                               m_aPdfImg;

        DECL_LINK( ClickBtnHdl, PushButton* );
        DECL_LINK( DoubleClickHdl, ListBox* );
        DECL_LINK( SelectHdl, ListBox* );
        DECL_LINK( EndPrintHdl, void* );
        DECL_LINK( DelPressedHdl, ListBox* );

        PADialog( Window*,  BOOL );
        void Init();

        void UpdateDefPrt();
        void UpdateText();
        void UpdateDevice();
        void AddDevice();
        void RemDevice();
        void ConfigureDevice();
        void RenameDevice();
        void PrintTestPage();

        String getSelectedDevice();
    public:
        ~PADialog();

        static PADialog* Create( Window*,  BOOL );
    };

} // namespace

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <QTimer>
#include <string>
#include <GL/glut.h>

#include "ui_watcher.h"
#include "watcherMainWindow.h"
#include "watcherScrollingGraphControl.h"

#include "logger.h"
#include "libconfig.h++"
#include "initConfig.h"
#include "singletonConfig.h"

using namespace std;
using namespace watcher;
using namespace libconfig;

int main(int argc, char *argv[])
{
    TRACE_ENTER();

    string configFilename;
    SingletonConfig::lock();
    Config &config=SingletonConfig::instance();
    if (false==initConfig(config, argc, argv, configFilename))
    {
        cerr << "Error reading configuration file, unable to continue." << endl;
        cerr << "Usage: " << basename(argv[0]) << " [-f|--configFile] configfile [standard watcher arguments]" << endl;
        return 1;
    }
    SingletonConfig::setConfigFile(configFilename);
    SingletonConfig::unlock();

    string logConf("watcher.log.properties");
    if (!config.lookupValue("logProperties", logConf))
    {
        cerr << "Unable to find logproperties setting in the configuration file, using default: " << logConf << endl;
        config.getRoot().add("logProperties", Setting::TypeString)=logConf;
    }

    LOAD_LOG_PROPS(logConf);

    LOG_INFO("Logger initialized from file \"" << logConf << "\"");
    LOG_INFO("Although the legacy watcher code does not use it, so it is not overly valuable");

    QApplication app(argc, argv);
    WatcherMainWindow *window = new WatcherMainWindow;
    Ui::MainWindow ui;
    ui.setupUi(window);

    ui.menuLayers->setTearOffEnabled(true);
    ui.menuView->setTearOffEnabled(true);

    QObject::connect(ui.quitButton, SIGNAL(clicked()), &app, SLOT(quit()));
    QObject::connect(&app, SIGNAL(aboutToQuit()), ui.manetGLViewWindow, SLOT(saveConfiguration()));

    //
    // Connect the scrolling graph dialog controller to other bits.
    //
    {
        WatcherScrollingGraphControl *sgc=WatcherScrollingGraphControl::getWatcherScrollingGraphControl();

        QObject::connect(ui.actionGraphBandwidth, SIGNAL(toggled(bool)), sgc, SLOT(showBandwidthGraphDialog(bool)));
        QObject::connect(sgc, SIGNAL(bandwidthDialogShowed(bool)), ui.actionGraphBandwidth, SLOT(setChecked(bool)));

        QObject::connect(ui.actionGraphLoadAverage, SIGNAL(toggled(bool)), sgc, SLOT(showLoadAverageGraphDialog(bool)));
        QObject::connect(sgc, SIGNAL(loadAverageDialogShowed(bool)), ui.actionGraphLoadAverage, SLOT(setChecked(bool)));

        // Support for generic graph-name-based dialogs is not yet supported by the main GUI window
        // Need to figure out how to do dynamic menus (or somesuch).

        QObject::connect(ui.manetGLViewWindow, SIGNAL(nodeDataInGraphsToggled(unsigned int)),
                          sgc, SLOT(toggleNodeDataInGraphs(unsigned int)));
        QObject::connect(sgc, SIGNAL(nodeDataInGraphsToggled(unsigned int)),
                          ui.manetGLViewWindow, SLOT(toggleNodeSelectedForGraph(unsigned int)));

        QObject::connect(ui.manetGLViewWindow, SIGNAL(nodeDataInGraphsShowed(unsigned int, bool)),
                          sgc, SLOT(showNodeDataInGraphs(unsigned int, bool)));
        QObject::connect(sgc, SIGNAL(nodeDataInGraphsShowed(unsigned int, bool)),
                          ui.manetGLViewWindow, SLOT(showNodeSelectedForGraph(unsigned int, bool)));
    }

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

    if (!ui.manetGLViewWindow->loadConfiguration())
    {
        LOG_FATAL("Error in cfg file, unable to continue");
        // write out what we have.
        SingletonConfig::saveConfig();
    }

    window->show();

    TRACE_EXIT();
    return app.exec();
}
<commit_msg>legacyWatcher: exit if given unreadable configuration.<commit_after>#include <iostream>
#include <QTimer>
#include <string>
#include <GL/glut.h>

#include "ui_watcher.h"
#include "watcherMainWindow.h"
#include "watcherScrollingGraphControl.h"

#include "logger.h"
#include "libconfig.h++"
#include "initConfig.h"
#include "singletonConfig.h"

using namespace std;
using namespace watcher;
using namespace libconfig;

int main(int argc, char *argv[])
{
    TRACE_ENTER();

    string configFilename;
    SingletonConfig::lock();
    Config &config=SingletonConfig::instance();
    if (false==initConfig(config, argc, argv, configFilename))
    {
        cerr << "Error reading configuration file, unable to continue." << endl;
        cerr << "Usage: " << basename(argv[0]) << " [-f|--configFile] configfile [standard watcher arguments]" << endl;
        return 1;
    }
    SingletonConfig::setConfigFile(configFilename);
    SingletonConfig::unlock();

    string logConf("watcher.log.properties");
    if (!config.lookupValue("logProperties", logConf))
    {
        cerr << "Unable to find logproperties setting in the configuration file, using default: " << logConf << endl;
        config.getRoot().add("logProperties", Setting::TypeString)=logConf;
    }

    LOAD_LOG_PROPS(logConf);

    LOG_INFO("Logger initialized from file \"" << logConf << "\"");
    LOG_INFO("Although the legacy watcher code does not use it, so it is not overly valuable");

    QApplication app(argc, argv);
    WatcherMainWindow *window = new WatcherMainWindow;
    Ui::MainWindow ui;
    ui.setupUi(window);

    ui.menuLayers->setTearOffEnabled(true);
    ui.menuView->setTearOffEnabled(true);

    QObject::connect(ui.quitButton, SIGNAL(clicked()), &app, SLOT(quit()));
    QObject::connect(&app, SIGNAL(aboutToQuit()), ui.manetGLViewWindow, SLOT(saveConfiguration()));

    //
    // Connect the scrolling graph dialog controller to other bits.
    //
    {
        WatcherScrollingGraphControl *sgc=WatcherScrollingGraphControl::getWatcherScrollingGraphControl();

        QObject::connect(ui.actionGraphBandwidth, SIGNAL(toggled(bool)), sgc, SLOT(showBandwidthGraphDialog(bool)));
        QObject::connect(sgc, SIGNAL(bandwidthDialogShowed(bool)), ui.actionGraphBandwidth, SLOT(setChecked(bool)));

        QObject::connect(ui.actionGraphLoadAverage, SIGNAL(toggled(bool)), sgc, SLOT(showLoadAverageGraphDialog(bool)));
        QObject::connect(sgc, SIGNAL(loadAverageDialogShowed(bool)), ui.actionGraphLoadAverage, SLOT(setChecked(bool)));

        // Support for generic graph-name-based dialogs is not yet supported by the main GUI window
        // Need to figure out how to do dynamic menus (or somesuch).

        QObject::connect(ui.manetGLViewWindow, SIGNAL(nodeDataInGraphsToggled(unsigned int)),
                          sgc, SLOT(toggleNodeDataInGraphs(unsigned int)));
        QObject::connect(sgc, SIGNAL(nodeDataInGraphsToggled(unsigned int)),
                          ui.manetGLViewWindow, SLOT(toggleNodeSelectedForGraph(unsigned int)));

        QObject::connect(ui.manetGLViewWindow, SIGNAL(nodeDataInGraphsShowed(unsigned int, bool)),
                          sgc, SLOT(showNodeDataInGraphs(unsigned int, bool)));
        QObject::connect(sgc, SIGNAL(nodeDataInGraphsShowed(unsigned int, bool)),
                          ui.manetGLViewWindow, SLOT(showNodeSelectedForGraph(unsigned int, bool)));
    }

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

    if (!ui.manetGLViewWindow->loadConfiguration())
    {
        LOG_FATAL("Error in cfg file, unable to continue");
        // write out what we have.
        SingletonConfig::saveConfig();
        TRACE_EXIT();
        return EXIT_FAILURE;
    }

    window->show();

    TRACE_EXIT();
    return app.exec();
}
<|endoftext|>


<commit_before>/* This file is part of Ingen.
 * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net>
 *
 * Ingen 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 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen 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 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.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "NodeBase.hpp"
#include <cassert>
#include <stdint.h>
#include "raul/List.hpp"
#include "raul/Array.hpp"
#include "util.hpp"
#include "PluginImpl.hpp"
#include "ClientBroadcaster.hpp"
#include "PortImpl.hpp"
#include "PatchImpl.hpp"
#include "EngineStore.hpp"
#include "ThreadManager.hpp"

using namespace std;

namespace Ingen {

NodeBase::NodeBase(PluginImpl* plugin, const Raul::Symbol& symbol, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size)
	: NodeImpl(parent, symbol, polyphonic)
	, _plugin(plugin)
	, _polyphony((polyphonic && parent) ? parent->internal_polyphony() : 1)
	, _srate(srate)
	, _buffer_size(buffer_size)
	, _valid_ports(NULL)
	, _input_ready(1)
	, _process_lock(0)
	, _n_inputs_ready(0)
	, _ports(NULL)
	, _providers(new Raul::List<NodeImpl*>())
	, _dependants(new Raul::List<NodeImpl*>())
	, _activated(false)
	, _traversed(false)
{
	assert(_plugin);
	assert(_polyphony > 0);
	assert(_parent == NULL || (_polyphony == parent->internal_polyphony() || _polyphony == 1));
}

NodeBase::~NodeBase()
{
	if (_activated)
		deactivate();

	delete _providers;
	delete _dependants;
	delete _ports;

	free(_valid_ports);
}

Shared::Port*
NodeBase::port(uint32_t index) const
{
	return (*_ports)[index];
}

const Shared::Plugin*
NodeBase::plugin() const
{
	return _plugin;
}

void
NodeBase::activate()
{
	ThreadManager::assert_thread(THREAD_PRE_PROCESS);
	assert(!_activated);
	_activated = true;
}

void
NodeBase::deactivate()
{
	// FIXME: Not true witn monolithic GUI/engine
	//ThreadManager::assert_thread(THREAD_POST_PROCESS);
	assert(_activated);
	_activated = false;
}

bool
NodeBase::prepare_poly(BufferFactory& bufs, uint32_t poly)
{
	ThreadManager::assert_thread(THREAD_PRE_PROCESS);

	if (!_polyphonic)
		return true;

	if (_ports)
		for (size_t i=0; i < _ports->size(); ++i)
			_ports->at(i)->prepare_poly(bufs, poly);

	return true;
}

bool
NodeBase::apply_poly(Raul::Maid& maid, uint32_t poly)
{
	ThreadManager::assert_thread(THREAD_PROCESS);

	if (!_polyphonic)
		return true;

	for (size_t i=0; i < num_ports(); ++i) {
		_ports->at(i)->apply_poly(maid, poly);
		assert(_ports->at(i)->poly() == poly);
	}

	for (uint32_t i=0; i < num_ports(); ++i)
		for (uint32_t j=0; j < _polyphony; ++j)
			set_port_buffer(j, i, _ports->at(i)->prepared_buffer(j));

	return true;
}

void
NodeBase::set_buffer_size(BufferFactory& bufs, size_t size)
{
	ThreadManager::assert_thread(THREAD_PROCESS);

	_buffer_size = size;

	if (_ports)
		for (size_t i=0; i < _ports->size(); ++i)
			_ports->at(i)->set_buffer_size(bufs, size);
}

void
NodeBase::reset_input_ready()
{
	_n_inputs_ready = 0;
	_process_lock = 0;
	_input_ready.reset(0);
}

bool
NodeBase::process_lock()
{
	return _process_lock.compare_and_exchange(0, 1);
}

void
NodeBase::process_unlock()
{
	_process_lock = 0;
}

void
NodeBase::wait_for_input(size_t num_providers)
{
	ThreadManager::assert_thread(THREAD_PROCESS);
	assert(_process_lock.get() == 1);

	while ((unsigned)_n_inputs_ready.get() < num_providers)
		_input_ready.wait();
}

void
NodeBase::signal_input_ready()
{
	ThreadManager::assert_thread(THREAD_PROCESS);
	++_n_inputs_ready;
	_input_ready.post();
}

/** Prepare to run a cycle (in the audio thread)
 */
void
NodeBase::pre_process(Context& context)
{
	ThreadManager::assert_thread(THREAD_PROCESS);

	// Mix down input ports
	for (uint32_t i = 0; i < num_ports(); ++i) {
		PortImpl* const port = _ports->at(i);
		if (port->context() == Context::AUDIO)
			port->pre_process(context);
	}
}

/** Prepare to run a cycle (in the audio thread)
 */
void
NodeBase::post_process(Context& context)
{
	ThreadManager::assert_thread(THREAD_PROCESS);

	// Write output ports
	for (size_t i = 0; _ports && i < _ports->size(); ++i) {
		PortImpl* const port = _ports->at(i);
		if (port->context() == Context::AUDIO)
			_ports->at(i)->post_process(context);
	}
}

/** Flag a port as set (for message context)
 */
void
NodeBase::set_port_valid(uint32_t port_index)
{
	// Allocate enough space for one bit per port
	if (!_valid_ports)
		_valid_ports = calloc(num_ports() / 8, 1);
	lv2_contexts_set_port_valid(_valid_ports, port_index);
}

void*
NodeBase::valid_ports()
{
	return _valid_ports;
}

void
NodeBase::reset_valid_ports()
{
	if (_valid_ports)
		memset(_valid_ports, '\0', num_ports() / 8);
}

} // namespace Ingen

<commit_msg>Fix typo.<commit_after>/* This file is part of Ingen.
 * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net>
 *
 * Ingen 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 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen 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 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.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "NodeBase.hpp"
#include <cassert>
#include <stdint.h>
#include "raul/List.hpp"
#include "raul/Array.hpp"
#include "util.hpp"
#include "PluginImpl.hpp"
#include "ClientBroadcaster.hpp"
#include "PortImpl.hpp"
#include "PatchImpl.hpp"
#include "EngineStore.hpp"
#include "ThreadManager.hpp"

using namespace std;

namespace Ingen {

NodeBase::NodeBase(PluginImpl* plugin, const Raul::Symbol& symbol, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size)
	: NodeImpl(parent, symbol, polyphonic)
	, _plugin(plugin)
	, _polyphony((polyphonic && parent) ? parent->internal_polyphony() : 1)
	, _srate(srate)
	, _buffer_size(buffer_size)
	, _valid_ports(NULL)
	, _input_ready(1)
	, _process_lock(0)
	, _n_inputs_ready(0)
	, _ports(NULL)
	, _providers(new Raul::List<NodeImpl*>())
	, _dependants(new Raul::List<NodeImpl*>())
	, _activated(false)
	, _traversed(false)
{
	assert(_plugin);
	assert(_polyphony > 0);
	assert(_parent == NULL || (_polyphony == parent->internal_polyphony() || _polyphony == 1));
}

NodeBase::~NodeBase()
{
	if (_activated)
		deactivate();

	delete _providers;
	delete _dependants;
	delete _ports;

	free(_valid_ports);
}

Shared::Port*
NodeBase::port(uint32_t index) const
{
	return (*_ports)[index];
}

const Shared::Plugin*
NodeBase::plugin() const
{
	return _plugin;
}

void
NodeBase::activate()
{
	ThreadManager::assert_thread(THREAD_PRE_PROCESS);
	assert(!_activated);
	_activated = true;
}

void
NodeBase::deactivate()
{
	// FIXME: Not true with monolithic GUI/engine
	//ThreadManager::assert_thread(THREAD_POST_PROCESS);
	assert(_activated);
	_activated = false;
}

bool
NodeBase::prepare_poly(BufferFactory& bufs, uint32_t poly)
{
	ThreadManager::assert_thread(THREAD_PRE_PROCESS);

	if (!_polyphonic)
		return true;

	if (_ports)
		for (size_t i=0; i < _ports->size(); ++i)
			_ports->at(i)->prepare_poly(bufs, poly);

	return true;
}

bool
NodeBase::apply_poly(Raul::Maid& maid, uint32_t poly)
{
	ThreadManager::assert_thread(THREAD_PROCESS);

	if (!_polyphonic)
		return true;

	for (size_t i=0; i < num_ports(); ++i) {
		_ports->at(i)->apply_poly(maid, poly);
		assert(_ports->at(i)->poly() == poly);
	}

	for (uint32_t i=0; i < num_ports(); ++i)
		for (uint32_t j=0; j < _polyphony; ++j)
			set_port_buffer(j, i, _ports->at(i)->prepared_buffer(j));

	return true;
}

void
NodeBase::set_buffer_size(BufferFactory& bufs, size_t size)
{
	ThreadManager::assert_thread(THREAD_PROCESS);

	_buffer_size = size;

	if (_ports)
		for (size_t i=0; i < _ports->size(); ++i)
			_ports->at(i)->set_buffer_size(bufs, size);
}

void
NodeBase::reset_input_ready()
{
	_n_inputs_ready = 0;
	_process_lock = 0;
	_input_ready.reset(0);
}

bool
NodeBase::process_lock()
{
	return _process_lock.compare_and_exchange(0, 1);
}

void
NodeBase::process_unlock()
{
	_process_lock = 0;
}

void
NodeBase::wait_for_input(size_t num_providers)
{
	ThreadManager::assert_thread(THREAD_PROCESS);
	assert(_process_lock.get() == 1);

	while ((unsigned)_n_inputs_ready.get() < num_providers)
		_input_ready.wait();
}

void
NodeBase::signal_input_ready()
{
	ThreadManager::assert_thread(THREAD_PROCESS);
	++_n_inputs_ready;
	_input_ready.post();
}

/** Prepare to run a cycle (in the audio thread)
 */
void
NodeBase::pre_process(Context& context)
{
	ThreadManager::assert_thread(THREAD_PROCESS);

	// Mix down input ports
	for (uint32_t i = 0; i < num_ports(); ++i) {
		PortImpl* const port = _ports->at(i);
		if (port->context() == Context::AUDIO)
			port->pre_process(context);
	}
}

/** Prepare to run a cycle (in the audio thread)
 */
void
NodeBase::post_process(Context& context)
{
	ThreadManager::assert_thread(THREAD_PROCESS);

	// Write output ports
	for (size_t i = 0; _ports && i < _ports->size(); ++i) {
		PortImpl* const port = _ports->at(i);
		if (port->context() == Context::AUDIO)
			_ports->at(i)->post_process(context);
	}
}

/** Flag a port as set (for message context)
 */
void
NodeBase::set_port_valid(uint32_t port_index)
{
	// Allocate enough space for one bit per port
	if (!_valid_ports)
		_valid_ports = calloc(num_ports() / 8, 1);
	lv2_contexts_set_port_valid(_valid_ports, port_index);
}

void*
NodeBase::valid_ports()
{
	return _valid_ports;
}

void
NodeBase::reset_valid_ports()
{
	if (_valid_ports)
		memset(_valid_ports, '\0', num_ports() / 8);
}

} // namespace Ingen

<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <sstream>
#include <inttypes.h>
#include <signal.h>
#include <Context.h>
#include <Color.h>
#include <text.h>
#include <util.h>
#include <i18n.h>
#include <CmdSync.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
CmdSync::CmdSync ()
{
  _keyword     = "synchronize";
  _usage       = "task          synchronize [initialize]";
  _description = STRING_CMD_SYNC_USAGE;
  _read_only   = false;
  _displays_id = false;
}

////////////////////////////////////////////////////////////////////////////////
int CmdSync::execute (std::string& output)
{
  int status = 0;
#ifdef HAVE_LIBGNUTLS
  std::stringstream out;

  // Loog for the 'init' keyword to indicate one-time pending.data upload.
  bool first_time_init = false;
  std::vector <std::string> words = context.a3.extract_words ();
  std::vector <std::string>::iterator word;
  for (word = words.begin (); word != words.end (); ++word)
  {
    if (closeEnough ("initialize", *word, 4))
    {
      if (!context.config.getBoolean ("confirmation") ||
          confirm (STRING_CMD_SYNC_INIT))
        first_time_init = true;
      else
        throw std::string (STRING_CMD_SYNC_NO_INIT);
    }
  }

  // If no server is set up, quit.
  std::string connection = context.config.get ("taskd.server");
  if (connection == "" ||
      connection.rfind (':') == std::string::npos)
    throw std::string (STRING_CMD_SYNC_NO_SERVER);

  // Obtain credentials.
  std::string credentials_string = context.config.get ("taskd.credentials");
  if (credentials_string == "")
    throw std::string (STRING_CMD_SYNC_BAD_CRED);

  std::vector <std::string> credentials;
  split (credentials, credentials_string, "/");
  if (credentials.size () != 3)
    throw std::string (STRING_CMD_SYNC_BAD_CRED);

  enum TLSClient::trust_level trust = TLSClient::strict;
  if (context.config.get ("taskd.trust") == "allow all")
    trust = TLSClient::allow_all;
  else if (context.config.get ("taskd.trust") == "ignore hostname")
    trust = TLSClient::ignore_hostname;

  // CA must exist, if provided.
  File ca (context.config.get ("taskd.ca"));
  if (ca._data != "" && ! ca.exists ())
    throw std::string (STRING_CMD_SYNC_BAD_CA);

  if (trust == TLSClient::allow_all && ca._data != "")
    throw std::string (STRING_CMD_SYNC_TRUST_CA);

  File certificate (context.config.get ("taskd.certificate"));
  if (! certificate.exists ())
    throw std::string (STRING_CMD_SYNC_BAD_CERT);

  File key (context.config.get ("taskd.key"));
  if (! key.exists ())
    throw std::string (STRING_CMD_SYNC_BAD_KEY);

  // If this is a first-time initialization, send pending.data, not
  // backlog.data.
  std::string payload = "";
  int upload_count = 0;
  if (first_time_init)
  {
    // Delete backlog.data.  Because if we're uploading everything, the list of
    // deltas is meaningless.
    context.tdb2.backlog._file.truncate ();

    std::vector <Task> pending = context.tdb2.pending.get_tasks ();
    std::vector <Task>::iterator i;
    for (i = pending.begin (); i != pending.end (); ++i)
    {
      payload += i->composeJSON () + "\n";
      ++upload_count;
    }
  }
  else
  {
    std::vector <std::string> lines = context.tdb2.backlog.get_lines ();
    std::vector <std::string>::iterator i;
    for (i = lines.begin (); i != lines.end (); ++i)
    {
      if ((*i)[0] == '{')
        ++upload_count;

      payload += *i + "\n";
    }
  }

  // Send 'sync' + payload.
  Msg request;
  request.set ("protocol", "v1");
  request.set ("type",     "sync");
  request.set ("org",      credentials[0]);
  request.set ("user",     credentials[1]);
  request.set ("key",      credentials[2]);

  request.setPayload (payload);

  if (context.verbose ("sync"))
    out << format (STRING_CMD_SYNC_PROGRESS, connection)
        << "\n";

  // Ignore harmful signals.
  signal (SIGHUP,    SIG_IGN);
  signal (SIGINT,    SIG_IGN);
  signal (SIGKILL,   SIG_IGN);
  signal (SIGPIPE,   SIG_IGN);
  signal (SIGTERM,   SIG_IGN);
  signal (SIGUSR1,   SIG_IGN);
  signal (SIGUSR2,   SIG_IGN);

  Msg response;
  if (send (connection, ca._data, certificate._data, key._data, trust, request, response))
  {
    std::string code = response.get ("code");
    if (code == "200")
    {
      Color colorAdded    (context.config.get ("color.sync.added"));
      Color colorChanged  (context.config.get ("color.sync.changed"));

      int download_count = 0;
      payload = response.getPayload ();
      std::vector <std::string> lines;
      split (lines, payload, '\n');

      // Load all tasks, but only if necessary.  There is always a sync key in
      // the payload, so if there are two or more lines, then we have merging
      // to perform, otherwise it's just a backlog.data update.
      if (lines.size () > 1)
        context.tdb2.all_tasks ();

      std::string sync_key = "";
      std::vector <std::string>::iterator line;
      for (line = lines.begin (); line != lines.end (); ++line)
      {
        if ((*line)[0] == '{')
        {
          ++download_count;

          Task from_server (*line);
          std::string uuid = from_server.get ("uuid");

          // Is it a new task from the server, or an update to an existing one?
          Task dummy;
          if (context.tdb2.get (uuid, dummy))
          {
            if (context.verbose ("sync"))
              out << "  "
                  << colorChanged.colorize (
                       format (STRING_CMD_SYNC_MOD,
                               uuid,
                               from_server.get ("description")))
                  << "\n";
            context.tdb2.modify (from_server, false);
          }
          else
          {
            if (context.verbose ("sync"))
              out << "  "
                  << colorAdded.colorize (
                       format (STRING_CMD_SYNC_ADD,
                               uuid,
                               from_server.get ("description")))
                  << "\n";
            context.tdb2.add (from_server, false);
          }
        }
        else if (*line != "")
        {
          sync_key = *line;
          context.debug ("Sync key " + sync_key);
        }

        // Otherwise line is blank, so ignore it.
      }

      // Only update everything if there is a new sync_key.  No sync_key means
      // something horrible happened on the other end of the wire.
      if (sync_key != "")
      {
        // Truncate backlog.data, save new sync_key.
        context.tdb2.backlog._file.truncate ();
        context.tdb2.backlog.clear_tasks ();
        context.tdb2.backlog.clear_lines ();
        context.tdb2.backlog.add_line (sync_key + "\n");

        // Commit all changes.
        context.tdb2.commit ();

        // Present a clear status message.
        if (upload_count == 0 && download_count == 0)
          // Note: should not happen - expect code 201 instead.
          context.footnote (STRING_CMD_SYNC_SUCCESS0);
        else if (upload_count == 0 && download_count > 0)
          context.footnote (format (STRING_CMD_SYNC_SUCCESS2, download_count));
        else if (upload_count > 0 && download_count == 0)
          context.footnote (format (STRING_CMD_SYNC_SUCCESS1, upload_count));
        else if (upload_count > 0 && download_count > 0)
          context.footnote (format (STRING_CMD_SYNC_SUCCESS3, upload_count, download_count));
      }
    }
    else if (code == "201")
    {
      context.footnote (STRING_CMD_SYNC_SUCCESS_NOP);
    }
    else if (code == "301")
    {
      std::string new_server = response.get ("info");
      context.config.set ("taskd.server", new_server);
      context.error (STRING_CMD_SYNC_RELOCATE0);
      context.error ("  " + format (STRING_CMD_SYNC_RELOCATE1, new_server));
    }
    else if (code == "430")
    {
      context.error (STRING_CMD_SYNC_FAIL_ACCOUNT);
      status = 2;
    }
    else
    {
      context.error (format (STRING_CMD_SYNC_FAIL_ERROR,
                             code,
                             response.get ("status")));
      status = 2;
    }

    // Display all errors returned.  This is recommended by the server protocol.
    std::string to_be_displayed = response.get ("messages");
    if (to_be_displayed != "")
    {
      if (context.verbose ("footnote"))
        context.footnote (to_be_displayed);
      else
        context.debug (to_be_displayed);
    }
  }

  // Some kind of low-level error:
  //   - Server down
  //   - Wrong address
  //   - Wrong port
  //   - Firewall
  //   - Network error
  //   - No signal/cable
  else
  {
    context.error (STRING_CMD_SYNC_FAIL_CONNECT);
    status = 1;
  }

  if (context.verbose ("sync"))
    out << "\n";
  output = out.str ();

  // Restore signal handling.
  signal (SIGHUP,    SIG_DFL);
  signal (SIGINT,    SIG_DFL);
  signal (SIGKILL,   SIG_DFL);
  signal (SIGPIPE,   SIG_DFL);
  signal (SIGTERM,   SIG_DFL);
  signal (SIGUSR1,   SIG_DFL);
  signal (SIGUSR2,   SIG_DFL);

#else
  // Without GnuTLS found at compile time, there is no working sync command.
  throw std::string (STRING_CMD_SYNC_NO_TLS);
#endif
  return status;
}

////////////////////////////////////////////////////////////////////////////////
bool CmdSync::send (
  const std::string& to,
  const std::string& ca,
  const std::string& certificate,
  const std::string& key,
  const enum TLSClient::trust_level trust,
  const Msg& request,
  Msg& response)
{
#ifdef HAVE_LIBGNUTLS
  std::string::size_type colon = to.rfind (':');
  if (colon == std::string::npos)
    throw format (STRING_CMD_SYNC_BAD_SERVER, to);

  std::string server = to.substr (0, colon);
  std::string port = to.substr (colon + 1);

  try
  {
    TLSClient client;
    client.debug (context.config.getInteger ("debug.tls"));

    client.trust (trust);
    client.ciphers (context.config.get ("taskd.ciphers"));
    client.init (ca, certificate, key);
    client.connect (server, port);
    client.send (request.serialize () + "\n");

    std::string incoming;
    client.recv (incoming);
    client.bye ();

    response.parse (incoming);
    return true;
  }

  catch (std::string& error)
  {
    context.error (error);
  }

  // Indicate message failed.
#endif
  return false;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>CmdSync<commit_after>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <sstream>
#include <inttypes.h>
#include <signal.h>
#include <Context.h>
#include <Color.h>
#include <text.h>
#include <util.h>
#include <i18n.h>
#include <CmdSync.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
CmdSync::CmdSync ()
{
  _keyword     = "synchronize";
  _usage       = "task          synchronize [initialize]";
  _description = STRING_CMD_SYNC_USAGE;
  _read_only   = false;
  _displays_id = false;
}

////////////////////////////////////////////////////////////////////////////////
int CmdSync::execute (std::string& output)
{
  int status = 0;
#ifdef HAVE_LIBGNUTLS
  std::stringstream out;

  // Loog for the 'init' keyword to indicate one-time pending.data upload.
  bool first_time_init = false;
  std::vector <std::string> words = context.a3t.getWords ();
  std::vector <std::string>::iterator word;
  for (word = words.begin (); word != words.end (); ++word)
  {
    if (closeEnough ("initialize", *word, 4))
    {
      if (!context.config.getBoolean ("confirmation") ||
          confirm (STRING_CMD_SYNC_INIT))
        first_time_init = true;
      else
        throw std::string (STRING_CMD_SYNC_NO_INIT);
    }
  }

  // If no server is set up, quit.
  std::string connection = context.config.get ("taskd.server");
  if (connection == "" ||
      connection.rfind (':') == std::string::npos)
    throw std::string (STRING_CMD_SYNC_NO_SERVER);

  // Obtain credentials.
  std::string credentials_string = context.config.get ("taskd.credentials");
  if (credentials_string == "")
    throw std::string (STRING_CMD_SYNC_BAD_CRED);

  std::vector <std::string> credentials;
  split (credentials, credentials_string, "/");
  if (credentials.size () != 3)
    throw std::string (STRING_CMD_SYNC_BAD_CRED);

  enum TLSClient::trust_level trust = TLSClient::strict;
  if (context.config.get ("taskd.trust") == "allow all")
    trust = TLSClient::allow_all;
  else if (context.config.get ("taskd.trust") == "ignore hostname")
    trust = TLSClient::ignore_hostname;

  // CA must exist, if provided.
  File ca (context.config.get ("taskd.ca"));
  if (ca._data != "" && ! ca.exists ())
    throw std::string (STRING_CMD_SYNC_BAD_CA);

  if (trust == TLSClient::allow_all && ca._data != "")
    throw std::string (STRING_CMD_SYNC_TRUST_CA);

  File certificate (context.config.get ("taskd.certificate"));
  if (! certificate.exists ())
    throw std::string (STRING_CMD_SYNC_BAD_CERT);

  File key (context.config.get ("taskd.key"));
  if (! key.exists ())
    throw std::string (STRING_CMD_SYNC_BAD_KEY);

  // If this is a first-time initialization, send pending.data, not
  // backlog.data.
  std::string payload = "";
  int upload_count = 0;
  if (first_time_init)
  {
    // Delete backlog.data.  Because if we're uploading everything, the list of
    // deltas is meaningless.
    context.tdb2.backlog._file.truncate ();

    std::vector <Task> pending = context.tdb2.pending.get_tasks ();
    std::vector <Task>::iterator i;
    for (i = pending.begin (); i != pending.end (); ++i)
    {
      payload += i->composeJSON () + "\n";
      ++upload_count;
    }
  }
  else
  {
    std::vector <std::string> lines = context.tdb2.backlog.get_lines ();
    std::vector <std::string>::iterator i;
    for (i = lines.begin (); i != lines.end (); ++i)
    {
      if ((*i)[0] == '{')
        ++upload_count;

      payload += *i + "\n";
    }
  }

  // Send 'sync' + payload.
  Msg request;
  request.set ("protocol", "v1");
  request.set ("type",     "sync");
  request.set ("org",      credentials[0]);
  request.set ("user",     credentials[1]);
  request.set ("key",      credentials[2]);

  request.setPayload (payload);

  if (context.verbose ("sync"))
    out << format (STRING_CMD_SYNC_PROGRESS, connection)
        << "\n";

  // Ignore harmful signals.
  signal (SIGHUP,    SIG_IGN);
  signal (SIGINT,    SIG_IGN);
  signal (SIGKILL,   SIG_IGN);
  signal (SIGPIPE,   SIG_IGN);
  signal (SIGTERM,   SIG_IGN);
  signal (SIGUSR1,   SIG_IGN);
  signal (SIGUSR2,   SIG_IGN);

  Msg response;
  if (send (connection, ca._data, certificate._data, key._data, trust, request, response))
  {
    std::string code = response.get ("code");
    if (code == "200")
    {
      Color colorAdded    (context.config.get ("color.sync.added"));
      Color colorChanged  (context.config.get ("color.sync.changed"));

      int download_count = 0;
      payload = response.getPayload ();
      std::vector <std::string> lines;
      split (lines, payload, '\n');

      // Load all tasks, but only if necessary.  There is always a sync key in
      // the payload, so if there are two or more lines, then we have merging
      // to perform, otherwise it's just a backlog.data update.
      if (lines.size () > 1)
        context.tdb2.all_tasks ();

      std::string sync_key = "";
      std::vector <std::string>::iterator line;
      for (line = lines.begin (); line != lines.end (); ++line)
      {
        if ((*line)[0] == '{')
        {
          ++download_count;

          Task from_server (*line);
          std::string uuid = from_server.get ("uuid");

          // Is it a new task from the server, or an update to an existing one?
          Task dummy;
          if (context.tdb2.get (uuid, dummy))
          {
            if (context.verbose ("sync"))
              out << "  "
                  << colorChanged.colorize (
                       format (STRING_CMD_SYNC_MOD,
                               uuid,
                               from_server.get ("description")))
                  << "\n";
            context.tdb2.modify (from_server, false);
          }
          else
          {
            if (context.verbose ("sync"))
              out << "  "
                  << colorAdded.colorize (
                       format (STRING_CMD_SYNC_ADD,
                               uuid,
                               from_server.get ("description")))
                  << "\n";
            context.tdb2.add (from_server, false);
          }
        }
        else if (*line != "")
        {
          sync_key = *line;
          context.debug ("Sync key " + sync_key);
        }

        // Otherwise line is blank, so ignore it.
      }

      // Only update everything if there is a new sync_key.  No sync_key means
      // something horrible happened on the other end of the wire.
      if (sync_key != "")
      {
        // Truncate backlog.data, save new sync_key.
        context.tdb2.backlog._file.truncate ();
        context.tdb2.backlog.clear_tasks ();
        context.tdb2.backlog.clear_lines ();
        context.tdb2.backlog.add_line (sync_key + "\n");

        // Commit all changes.
        context.tdb2.commit ();

        // Present a clear status message.
        if (upload_count == 0 && download_count == 0)
          // Note: should not happen - expect code 201 instead.
          context.footnote (STRING_CMD_SYNC_SUCCESS0);
        else if (upload_count == 0 && download_count > 0)
          context.footnote (format (STRING_CMD_SYNC_SUCCESS2, download_count));
        else if (upload_count > 0 && download_count == 0)
          context.footnote (format (STRING_CMD_SYNC_SUCCESS1, upload_count));
        else if (upload_count > 0 && download_count > 0)
          context.footnote (format (STRING_CMD_SYNC_SUCCESS3, upload_count, download_count));
      }
    }
    else if (code == "201")
    {
      context.footnote (STRING_CMD_SYNC_SUCCESS_NOP);
    }
    else if (code == "301")
    {
      std::string new_server = response.get ("info");
      context.config.set ("taskd.server", new_server);
      context.error (STRING_CMD_SYNC_RELOCATE0);
      context.error ("  " + format (STRING_CMD_SYNC_RELOCATE1, new_server));
    }
    else if (code == "430")
    {
      context.error (STRING_CMD_SYNC_FAIL_ACCOUNT);
      status = 2;
    }
    else
    {
      context.error (format (STRING_CMD_SYNC_FAIL_ERROR,
                             code,
                             response.get ("status")));
      status = 2;
    }

    // Display all errors returned.  This is recommended by the server protocol.
    std::string to_be_displayed = response.get ("messages");
    if (to_be_displayed != "")
    {
      if (context.verbose ("footnote"))
        context.footnote (to_be_displayed);
      else
        context.debug (to_be_displayed);
    }
  }

  // Some kind of low-level error:
  //   - Server down
  //   - Wrong address
  //   - Wrong port
  //   - Firewall
  //   - Network error
  //   - No signal/cable
  else
  {
    context.error (STRING_CMD_SYNC_FAIL_CONNECT);
    status = 1;
  }

  if (context.verbose ("sync"))
    out << "\n";
  output = out.str ();

  // Restore signal handling.
  signal (SIGHUP,    SIG_DFL);
  signal (SIGINT,    SIG_DFL);
  signal (SIGKILL,   SIG_DFL);
  signal (SIGPIPE,   SIG_DFL);
  signal (SIGTERM,   SIG_DFL);
  signal (SIGUSR1,   SIG_DFL);
  signal (SIGUSR2,   SIG_DFL);

#else
  // Without GnuTLS found at compile time, there is no working sync command.
  throw std::string (STRING_CMD_SYNC_NO_TLS);
#endif
  return status;
}

////////////////////////////////////////////////////////////////////////////////
bool CmdSync::send (
  const std::string& to,
  const std::string& ca,
  const std::string& certificate,
  const std::string& key,
  const enum TLSClient::trust_level trust,
  const Msg& request,
  Msg& response)
{
#ifdef HAVE_LIBGNUTLS
  std::string::size_type colon = to.rfind (':');
  if (colon == std::string::npos)
    throw format (STRING_CMD_SYNC_BAD_SERVER, to);

  std::string server = to.substr (0, colon);
  std::string port = to.substr (colon + 1);

  try
  {
    TLSClient client;
    client.debug (context.config.getInteger ("debug.tls"));

    client.trust (trust);
    client.ciphers (context.config.get ("taskd.ciphers"));
    client.init (ca, certificate, key);
    client.connect (server, port);
    client.send (request.serialize () + "\n");

    std::string incoming;
    client.recv (incoming);
    client.bye ();

    response.parse (incoming);
    return true;
  }

  catch (std::string& error)
  {
    context.error (error);
  }

  // Indicate message failed.
#endif
  return false;
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


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

#include "triangle.hpp"

namespace vka {
vk::ApplicationInfo create_application_info(const std::string name,
                                            const Version version) {
  vk::ApplicationInfo info;
  info.pApplicationName = name.c_str();
  info.applicationVersion =
      VK_MAKE_VERSION(version.major, version.minor, version.patch);
  info.apiVersion = VK_API_VERSION_1_0;
  return info;
}
vk::UniqueInstance create_instance(const vk::ApplicationInfo application_info) {
  vk::InstanceCreateInfo info;
  info.pApplicationInfo = &application_info;
  return vk::createInstanceUnique(info);
}
std::vector<vk::PhysicalDevice>
get_physical_devices(const vk::UniqueInstance &instance) {
  return instance.get().enumeratePhysicalDevices();
}
vk::PhysicalDevice
select_physical_device(const std::vector<vk::PhysicalDevice> &devices) {
  if (devices.size() < 1) {
    return vk::PhysicalDevice();
  }
  return devices[0];
}
}
<commit_msg>Check for emptiness of a vector<commit_after>/*
 *Copyright 2017 Lukasz Towarek
 *
 *Licensed under the Apache License, Version 2.0 (the "License");
 *you may not use this file except in compliance with the License.
 *You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 *distributed under the License is distributed on an "AS IS" BASIS,
 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *See the License for the specific language governing permissions and
 *limitations under the License.
 */

#include "triangle.hpp"

namespace vka {
vk::ApplicationInfo create_application_info(const std::string name,
                                            const Version version) {
  vk::ApplicationInfo info;
  info.pApplicationName = name.c_str();
  info.applicationVersion =
      VK_MAKE_VERSION(version.major, version.minor, version.patch);
  info.apiVersion = VK_API_VERSION_1_0;
  return info;
}
vk::UniqueInstance create_instance(const vk::ApplicationInfo application_info) {
  vk::InstanceCreateInfo info;
  info.pApplicationInfo = &application_info;
  return vk::createInstanceUnique(info);
}
std::vector<vk::PhysicalDevice>
get_physical_devices(const vk::UniqueInstance &instance) {
  return instance.get().enumeratePhysicalDevices();
}
vk::PhysicalDevice
select_physical_device(const std::vector<vk::PhysicalDevice> &devices) {
  if (devices.empty()) {
    return vk::PhysicalDevice();
  }
  return devices[0];
}
}
<|endoftext|>


<commit_before>#include <sstream>

#include <boost/format.hpp>

#include "Colors.h"
#include "Trace.h"

Trace::Trace()
{
}

Trace::~Trace()
{
}

/* Add an instruction in the trace */
void Trace::addInstruction(Inst *instruction)
{
  this->instructions.push_back(instruction);
}

/* Returns the instructions list in the trace */
std::list<Inst *> &Trace::getInstructions()
{
  return this->instructions;
}

void Trace::display(std::ostream &os)
{
  boost::format outputInstruction("%1% %|15t| %2% %|55t|");

  for (auto inst : this->instructions){
    uint64_t count = 0;
    if (inst != nullptr) {
      std::stringstream expr(""), colr(ENDC);

      for (auto se : inst->getSymbolicElements()){

        if (count == 0) expr << se->getExpression()->str();
        else            expr << std::endl << boost::format(outputInstruction) % "" % "" << se->getExpression()->str();

        if (se->isTainted)
          colr.str(GREEN);

        count++;
      }

      os << colr.str()
         << boost::format(outputInstruction)
          % boost::io::group(std::hex, std::showbase, inst->getAddress())
          % inst->getDisassembly()
         << expr.str()
         << ENDC
         << std::endl;
    }
  }
}
<commit_msg>Add the threadID viewing in the output<commit_after>#include <sstream>

#include <boost/format.hpp>

#include "Colors.h"
#include "Trace.h"

Trace::Trace()
{
}

Trace::~Trace()
{
}

/* Add an instruction in the trace */
void Trace::addInstruction(Inst *instruction)
{
  this->instructions.push_back(instruction);
}

/* Returns the instructions list in the trace */
std::list<Inst *> &Trace::getInstructions()
{
  return this->instructions;
}

void Trace::display(std::ostream &os)
{
  boost::format outputInstruction("[%1%] %|3t| %2% %|21t| %3% %|61t|");
  boost::format outputExpression("%|61t|");

  for (auto inst : this->instructions){
    uint64_t count = 0;
    if (inst != nullptr) {
      std::stringstream expr(""), colr(ENDC);

      for (auto se : inst->getSymbolicElements()){

        if (count == 0) expr << se->getExpression()->str();
        else            expr << std::endl << boost::format(outputExpression) << se->getExpression()->str();

        if (se->isTainted)
          colr.str(GREEN);

        count++;
      }

      os << colr.str()
         << boost::format(outputInstruction)
          % std::to_string(inst->getThreadId())
          % boost::io::group(std::hex, std::showbase, inst->getAddress())
          % inst->getDisassembly()
         << expr.str()
         << ENDC
         << std::endl;
    }
  }
}
<|endoftext|>


<commit_before>//
// Created by hippomormor on 6/4/16.
//

#include "Cascade.h"

using namespace cv;

Cascade::Cascade(void) {

    if(!cascade_classifier.load("../workspaces/dronemis_ws/src/dronemis/src/OpenCv/cascades/cascade700.xml")){
        ROS_INFO("ERROR LOADING DEFAULT CASCADE..");
    };
}

Cascade::~Cascade(void) {

}

bool Cascade::setCascade(const int cascadeNumber) {

    String cascadeName;

    switch(cascadeNumber) {
        case 0:
            cascadeName = "../workspaces/dronemis_ws/src/dronemis/src/OpenCv/cascades/cascade700.xml";
            break;
        case 1:
            cascadeName = "../workspaces/dronemis_ws/src/dronemis/src/OpenCv/cascades/cascade.xml";
            break;
        case 2:
            cascadeName = "../workspaces/dronemis_ws/src/dronemis/src/OpenCv/cascades/cascadeX.xml";
            break;
    }

    if(!cascade_classifier.load(cascadeName)){
        ROS_INFO("ERROR LOADING CASCADE..");
        return false;
    };

    return true;
}

std::vector<Cascade::cubeInfo> Cascade::checkCascade(cv::Mat image) {
    std::vector<Rect> cubes;

    Mat frame_modified;

    equalizeHist(image, frame_modified);

    cascade_classifier.detectMultiScale( frame_modified, cubes, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(20, 20) );

    std::vector<cubeInfo> cascades(cubes.size());

    for( size_t i = 0; i < cubes.size(); i++ )
    {
        Point center( cubes[i].x + cubes[i].width*0.5, cubes[i].y + cubes[i].height*0.5 );
        cascades[i].x = center.x;
        cascades[i].y = center.y;
        cascades[i].width = cubes[i].width;
        cascades[i].height = cubes[i].height;
    }
    std::cout << cubes.size() << std::endl;

    return cascades;
}<commit_msg>Fixed vector arrays<commit_after>//
// Created by hippomormor on 6/4/16.
//

#include "Cascade.h"

using namespace cv;

Cascade::Cascade(void) {

    if(!cascade_classifier.load("../workspaces/dronemis_ws/src/dronemis/src/OpenCv/cascades/cascade700.xml")){
        ROS_INFO("ERROR LOADING DEFAULT CASCADE..");
    };
}

Cascade::~Cascade(void) {

}

bool Cascade::setCascade(const int cascadeNumber) {

    String cascadeName;

    switch(cascadeNumber) {
        case 0:
            cascadeName = "../workspaces/dronemis_ws/src/dronemis/src/OpenCv/cascades/cascade700.xml";
            break;
        case 1:
            cascadeName = "../workspaces/dronemis_ws/src/dronemis/src/OpenCv/cascades/cascade.xml";
            break;
        case 2:
            cascadeName = "../workspaces/dronemis_ws/src/dronemis/src/OpenCv/cascades/cascadeX.xml";
            break;
    }

    if(!cascade_classifier.load(cascadeName)){
        ROS_INFO("ERROR LOADING CASCADE..");
        return false;
    };

    return true;
}

std::vector<Cascade::cubeInfo> Cascade::checkCascade(cv::Mat image) {
    std::vector<Rect> cubes;
    std::vector<cubeInfo> cascades;
    Mat frame_modified;

    equalizeHist(image, frame_modified);

    cascade_classifier.detectMultiScale( frame_modified, cubes, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(20, 20) );

    for( size_t i = 0; i < cubes.size(); i++ )
    {
        cubeInfo cube;
        Point center( cubes[i].x + cubes[i].width*0.5, cubes[i].y + cubes[i].height*0.5 );
        cube.x = center.x;
        cube.y = center.y;
        cube.width = cubes[i].width;
        cube.height = cubes[i].height;
        cascades.push_back(cube);
    }
    std::cout << cubes.size() << std::endl;

    return cascades;
}<|endoftext|>


<commit_before>// Copyright 2011, 2012 Bastien Léonard. All rights reserved.

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

//    1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.

//    2. Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.

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

#include "hacks.hpp"
#include "sf.h"

#include <iostream>

#include <cassert>
#include <cstdio>

// This file contains code that couldn't be written in Cython.

// This should be big enough to contain any message error
static const int ERROR_MESSAGE_BUFFER_SIZE = 512;

sf::Drawable* transformable_to_drawable(sf::Transformable *t)
{
    return dynamic_cast<sf::Drawable*>(t);
}

// A custom streambuf that will put error messages in a Python dict
class MyBuff : public std::streambuf
{
public:
    MyBuff()
    {
        buffer = new char[ERROR_MESSAGE_BUFFER_SIZE];
        setp(buffer, buffer + ERROR_MESSAGE_BUFFER_SIZE);
    }

    ~MyBuff()
    {
        delete[] pbase();
    }

private:
    char* buffer;

    // This code is from SFML's bufstream. In our case overflow()
    // should never get called, unless I missed something. But I don't
    // undestand why it would get called when there's no overflow
    // either (i.e., when pptr() != epptr()), so let's be on the safe
    // side.
    virtual int overflow(int character)
    {
        if (character != EOF && pptr() != epptr())
        {
            // Valid character
            return sputc(static_cast<char>(character));
        }
        else if (character != EOF)
        {
            // Not enough space in the buffer: synchronize output and try again
            sync();
            return overflow(character);
        }
        else
        {
            // Invalid character: synchronize output
            return sync();
        }
    }

    virtual int sync()
    {
        if (pbase() != pptr())
        {
            // Replace '\n' at the end of the message with '\0'
            *(pptr() - 1) = '\0';

            // Call the function in sf.pyx that handles new messages
            set_error_message(pbase());

            setp(pbase(), epptr());
        }

        return 0;
    }
};

void replace_error_handler()
{
    static MyBuff my_buff;
    sf::err().rdbuf(&my_buff);
}

CppDrawable::CppDrawable()
{
}

CppDrawable::CppDrawable(void* drawable):
    sf::Drawable(),
    drawable(drawable)
{
}

void CppDrawable::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    // The string parameters to PyObject_CallMethod() are char*, so in
    // theory they can be modified, and string litterals are const char*
    char method_name[] = "draw";
    char format[] = "(O, O)";
    PyObject* py_target = (PyObject*)wrap_render_target_instance(&target);
    PyObject* py_states = (PyObject*)wrap_render_states_instance(
        new sf::RenderStates(states));

    // The caller needs to use PyErr_Occurred() to know if this
    // function failed
    PyObject* ret = PyObject_CallMethod(
        static_cast<PyObject*>(drawable), method_name, format,
        py_target, py_states);

    if (ret != NULL)
    {
        Py_DECREF(ret);
    }

    Py_DECREF(py_target);
    Py_DECREF(py_states);
}

CppShape::CppShape()
{
}

CppShape::CppShape(void* shape) : shape(shape)
{
}

unsigned int CppShape::getPointCount() const
{
    char method_name[] = "get_point_count";
    char format[] = "";
    PyObject* ret = PyObject_CallMethod(
        static_cast<PyObject*>(shape), method_name, format);
    long count = 0;

    if (ret != NULL)
    {
#ifndef IS_PY3K
        if (!PyInt_Check(ret))
#else
        if (!PyLong_Check(ret))
#endif
        {
            PyErr_SetString(PyExc_TypeError,
                            "get_point_count() must return an integer");
        }

#ifndef IS_PY3K
        count = PyInt_AsLong(ret);
#else
        count = PyLong_AsLong(ret);
#endif
        Py_DECREF(ret);
    }

    return count;
}

sf::Vector2f CppShape::getPoint(unsigned int index) const
{
    char method_name[] = "get_point";
    char format[] ="I";
    PyObject *ret = PyObject_CallMethod(
        static_cast<PyObject*>(shape), method_name, format, index);
    sf::Vector2f point;

    if (ret != NULL)
    {
        point = convert_to_vector2f(ret);
        Py_DECREF(ret);
    }

    return point;
}

void CppShape::update()
{
    sf::Shape::update();
}

CppSoundStream::CppSoundStream()
{
}

CppSoundStream::CppSoundStream(void* sound_stream) : sound_stream(sound_stream)
{
}

void CppSoundStream::initialize(unsigned int channel_count,
                                unsigned int sample_rate)
{
    sf::SoundStream::initialize(channel_count, sample_rate);
}

bool CppSoundStream::onGetData(sf::SoundStream::Chunk& data)
{
    char method_name[] = "on_get_data";
    char format[] = "O";
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();
    PyObject *py_chunk = (PyObject*)wrap_chunk_instance(&data, false);
    PyObject *ret = PyObject_CallMethod(
        static_cast<PyObject*>(sound_stream), method_name, format, py_chunk);
    bool status = false;

    if (ret == NULL)
    {
        PyErr_Print();
    }
    else
    {
        if (ret == Py_True)
        {
            status = true;
        }
        else if (ret != Py_False)
        {
            PyErr_SetString(PyExc_TypeError,
                            "on_get_data() must return a boolean");
            PyErr_Print();
        }

        Py_DECREF(ret);
    }

    Py_DECREF(py_chunk);
    PyGILState_Release(gstate);

    return status;
}

void CppSoundStream::onSeek(sf::Time time_offset)
{
    char method_name[] = "on_seek";
    char format[] = "O";
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();
    PyObject *py_time = (PyObject*)wrap_time_instance(
        new sf::Time(time_offset));
    PyObject *ret = PyObject_CallMethod(
        static_cast<PyObject*>(sound_stream), method_name, format, py_time);

    if (ret == NULL)
    {
        PyErr_Print();
    }
    else
    {
        Py_DECREF(ret);
    }

    Py_DECREF(py_time);
    PyGILState_Release(gstate);
}
<commit_msg>Added an include that will hopefully solve build problems for a user<commit_after>// Copyright 2011, 2012 Bastien Léonard. All rights reserved.

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

//    1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.

//    2. Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.

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

// This file contains code that couldn't be written in Cython.

#include "hacks.hpp"
#include "sf.h"

#include <iostream>

#include <cassert>
#include <cstdio>

// For some users, compilation seems to fail because the compiler
// doesn't know about sf::Transformable. This might fix it.
#include <SFML/Graphics/Transformable.hpp>

// This should be big enough to contain any message error
static const int ERROR_MESSAGE_BUFFER_SIZE = 512;

sf::Drawable* transformable_to_drawable(sf::Transformable *t)
{
    return dynamic_cast<sf::Drawable*>(t);
}

// A custom streambuf that will put error messages in a Python dict
class MyBuff : public std::streambuf
{
public:
    MyBuff()
    {
        buffer = new char[ERROR_MESSAGE_BUFFER_SIZE];
        setp(buffer, buffer + ERROR_MESSAGE_BUFFER_SIZE);
    }

    ~MyBuff()
    {
        delete[] pbase();
    }

private:
    char* buffer;

    // This code is from SFML's bufstream. In our case overflow()
    // should never get called, unless I missed something. But I don't
    // undestand why it would get called when there's no overflow
    // either (i.e., when pptr() != epptr()), so let's be on the safe
    // side.
    virtual int overflow(int character)
    {
        if (character != EOF && pptr() != epptr())
        {
            // Valid character
            return sputc(static_cast<char>(character));
        }
        else if (character != EOF)
        {
            // Not enough space in the buffer: synchronize output and try again
            sync();
            return overflow(character);
        }
        else
        {
            // Invalid character: synchronize output
            return sync();
        }
    }

    virtual int sync()
    {
        if (pbase() != pptr())
        {
            // Replace '\n' at the end of the message with '\0'
            *(pptr() - 1) = '\0';

            // Call the function in sf.pyx that handles new messages
            set_error_message(pbase());

            setp(pbase(), epptr());
        }

        return 0;
    }
};

void replace_error_handler()
{
    static MyBuff my_buff;
    sf::err().rdbuf(&my_buff);
}

CppDrawable::CppDrawable()
{
}

CppDrawable::CppDrawable(void* drawable):
    sf::Drawable(),
    drawable(drawable)
{
}

void CppDrawable::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    // The string parameters to PyObject_CallMethod() are char*, so in
    // theory they can be modified, and string litterals are const char*
    char method_name[] = "draw";
    char format[] = "(O, O)";
    PyObject* py_target = (PyObject*)wrap_render_target_instance(&target);
    PyObject* py_states = (PyObject*)wrap_render_states_instance(
        new sf::RenderStates(states));

    // The caller needs to use PyErr_Occurred() to know if this
    // function failed
    PyObject* ret = PyObject_CallMethod(
        static_cast<PyObject*>(drawable), method_name, format,
        py_target, py_states);

    if (ret != NULL)
    {
        Py_DECREF(ret);
    }

    Py_DECREF(py_target);
    Py_DECREF(py_states);
}

CppShape::CppShape()
{
}

CppShape::CppShape(void* shape) : shape(shape)
{
}

unsigned int CppShape::getPointCount() const
{
    char method_name[] = "get_point_count";
    char format[] = "";
    PyObject* ret = PyObject_CallMethod(
        static_cast<PyObject*>(shape), method_name, format);
    long count = 0;

    if (ret != NULL)
    {
#ifndef IS_PY3K
        if (!PyInt_Check(ret))
#else
        if (!PyLong_Check(ret))
#endif
        {
            PyErr_SetString(PyExc_TypeError,
                            "get_point_count() must return an integer");
        }

#ifndef IS_PY3K
        count = PyInt_AsLong(ret);
#else
        count = PyLong_AsLong(ret);
#endif
        Py_DECREF(ret);
    }

    return count;
}

sf::Vector2f CppShape::getPoint(unsigned int index) const
{
    char method_name[] = "get_point";
    char format[] ="I";
    PyObject *ret = PyObject_CallMethod(
        static_cast<PyObject*>(shape), method_name, format, index);
    sf::Vector2f point;

    if (ret != NULL)
    {
        point = convert_to_vector2f(ret);
        Py_DECREF(ret);
    }

    return point;
}

void CppShape::update()
{
    sf::Shape::update();
}

CppSoundStream::CppSoundStream()
{
}

CppSoundStream::CppSoundStream(void* sound_stream) : sound_stream(sound_stream)
{
}

void CppSoundStream::initialize(unsigned int channel_count,
                                unsigned int sample_rate)
{
    sf::SoundStream::initialize(channel_count, sample_rate);
}

bool CppSoundStream::onGetData(sf::SoundStream::Chunk& data)
{
    char method_name[] = "on_get_data";
    char format[] = "O";
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();
    PyObject *py_chunk = (PyObject*)wrap_chunk_instance(&data, false);
    PyObject *ret = PyObject_CallMethod(
        static_cast<PyObject*>(sound_stream), method_name, format, py_chunk);
    bool status = false;

    if (ret == NULL)
    {
        PyErr_Print();
    }
    else
    {
        if (ret == Py_True)
        {
            status = true;
        }
        else if (ret != Py_False)
        {
            PyErr_SetString(PyExc_TypeError,
                            "on_get_data() must return a boolean");
            PyErr_Print();
        }

        Py_DECREF(ret);
    }

    Py_DECREF(py_chunk);
    PyGILState_Release(gstate);

    return status;
}

void CppSoundStream::onSeek(sf::Time time_offset)
{
    char method_name[] = "on_seek";
    char format[] = "O";
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();
    PyObject *py_time = (PyObject*)wrap_time_instance(
        new sf::Time(time_offset));
    PyObject *ret = PyObject_CallMethod(
        static_cast<PyObject*>(sound_stream), method_name, format, py_time);

    if (ret == NULL)
    {
        PyErr_Print();
    }
    else
    {
        Py_DECREF(ret);
    }

    Py_DECREF(py_time);
    PyGILState_Release(gstate);
}
<|endoftext|>