<commit_before>// Copyright (c) 2021 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php.

#include "qt/pivx/governancemodel.h"

#include "budget/budgetmanager.h"
#include "budget/budgetutil.h"
#include "destination_io.h"
#include "guiconstants.h"
#include "masternode-sync.h"
#include "script/standard.h"
#include "qt/transactiontablemodel.h"
#include "qt/transactionrecord.h"
#include "qt/pivx/mnmodel.h"
#include "utilmoneystr.h"
#include "utilstrencodings.h"
#include "walletmodel.h"

#include <algorithm>
#include <QTimer>

GovernanceModel::GovernanceModel(ClientModel* _clientModel, MNModel* _mnModel) : clientModel(_clientModel), mnModel(_mnModel) {}
GovernanceModel::~GovernanceModel() {}

void GovernanceModel::setWalletModel(WalletModel* _walletModel)
{
    walletModel = _walletModel;
    connect(walletModel->getTransactionTableModel(), &TransactionTableModel::txLoaded, this, &GovernanceModel::txLoaded);
}

ProposalInfo GovernanceModel::buidProposalInfo(const CBudgetProposal* prop, bool isPassing, bool isPending)
{
    CTxDestination recipient;
    ExtractDestination(prop->GetPayee(), recipient);

    // Calculate status
    int votesYes = prop->GetYeas();
    int votesNo = prop->GetNays();
    ProposalInfo::Status status;

    if (isPending) {
        // Proposal waiting for confirmation to be broadcasted.
        status = ProposalInfo::WAITING_FOR_APPROVAL;
    } else {
        if (isPassing) {
            status = ProposalInfo::PASSING;
        } else if (votesYes > votesNo) {
            status = ProposalInfo::PASSING_NOT_FUNDED;
        } else {
            status = ProposalInfo::NOT_PASSING;
        }
    }

    return ProposalInfo(prop->GetHash(),
            prop->GetName(),
            prop->GetURL(),
            votesYes,
            votesNo,
            Standard::EncodeDestination(recipient),
            prop->GetAmount(),
            prop->GetTotalPaymentCount(),
            prop->GetRemainingPaymentCount(clientModel->getLastBlockProcessedHeight()),
            status);
}

std::list<ProposalInfo> GovernanceModel::getProposals()
{
    if (!clientModel) return {};
    std::list<ProposalInfo> ret;
    std::vector<CBudgetProposal> budget = g_budgetman.GetBudget();
    for (const auto& prop : g_budgetman.GetAllProposalsOrdered()) {
        bool isPassing = std::find(budget.begin(), budget.end(), *prop) != budget.end();
        ret.emplace_back(buidProposalInfo(prop, isPassing, false));
        if (isPassing) allocatedAmount += prop->GetAmount();
    }

    // Add pending proposals
    for (const auto& prop : waitingPropsForConfirmations) {
        ret.emplace_back(buidProposalInfo(&prop, false, true));
    }
    return ret;
}

bool GovernanceModel::hasProposals()
{
    return g_budgetman.HasAnyProposal();
}

CAmount GovernanceModel::getMaxAvailableBudgetAmount() const
{
    return g_budgetman.GetTotalBudget(clientModel->getNumBlocks());
}

int GovernanceModel::getNumBlocksPerBudgetCycle() const
{
    return Params().GetConsensus().nBudgetCycleBlocks;
}

int GovernanceModel::getPropMaxPaymentsCount() const
{
    return Params().GetConsensus().nMaxProposalPayments;
}

int GovernanceModel::getNextSuperblockHeight() const
{
    const int nBlocksPerCycle = getNumBlocksPerBudgetCycle();
    const int chainHeight = clientModel->getNumBlocks();
    return chainHeight - chainHeight % nBlocksPerCycle + nBlocksPerCycle;
}

std::vector<VoteInfo> GovernanceModel::getLocalMNsVotesForProposal(const ProposalInfo& propInfo)
{
    // First, get the local masternodes
    std::vector<std::pair<COutPoint, std::string>> vecLocalMn;
    for (int i = 0; i < mnModel->rowCount(); ++i) {
        vecLocalMn.emplace_back(std::make_pair(
                COutPoint(uint256S(mnModel->index(i, MNModel::COLLATERAL_ID, QModelIndex()).data().toString().toStdString()),
                mnModel->index(i, MNModel::COLLATERAL_OUT_INDEX, QModelIndex()).data().toInt()),
                mnModel->index(i, MNModel::ALIAS, QModelIndex()).data().toString().toStdString())
        );
    }

    std::vector<VoteInfo> localVotes;
    // Get the budget proposal, get the votes, then loop over it and return the ones that correspond to the local masternodes here.
    CBudgetProposal* prop = g_budgetman.FindProposal(propInfo.id);
    const auto& mapVotes = prop->GetVotes();
    for (const auto& it : mapVotes) {
        for (const auto& mn : vecLocalMn) {
            if (it.first == mn.first && it.second.IsValid()) {
                localVotes.emplace_back(mn.first, (VoteInfo::VoteDirection) it.second.GetDirection(), mn.second);
                break;
            }
        }
    }
    return localVotes;
}

OperationResult GovernanceModel::validatePropURL(const QString& url) const
{
    std::string strError;
    return {validateURL(url.toStdString(), strError, PROP_URL_MAX_SIZE), strError};
}

OperationResult GovernanceModel::validatePropAmount(CAmount amount) const
{
    if (amount > getMaxAvailableBudgetAmount()) {
        return {false, strprintf("Amount exceeding the maximum available budget amount of %s PIV", FormatMoney(amount))};
    }
    return {true};
}

OperationResult GovernanceModel::validatePropPaymentCount(int paymentCount) const
{
    if (paymentCount < 1) return { false, "Invalid payment count, must be greater than zero."};
    int nMaxPayments = getPropMaxPaymentsCount();
    if (paymentCount > nMaxPayments) {
        return { false, strprintf("Invalid payment count, cannot be greater than %d", nMaxPayments)};
    }
    return {true};
}

bool GovernanceModel::isTierTwoSync()
{
    return masternodeSync.IsBlockchainSynced();
}

OperationResult GovernanceModel::createProposal(const std::string& strProposalName,
                                                const std::string& strURL,
                                                int nPaymentCount,
                                                CAmount nAmount,
                                                const std::string& strPaymentAddr)
{
    // First get the next superblock height
    int nBlockStart = getNextSuperblockHeight();

    // Parse address
    const CTxDestination* dest = Standard::GetTransparentDestination(Standard::DecodeDestination(strPaymentAddr));
    if (!dest) return {false, "invalid recipient address for the proposal"};
    CScript scriptPubKey = GetScriptForDestination(*dest);

    // Validate proposal
    CBudgetProposal proposal(strProposalName, strURL, nPaymentCount, scriptPubKey, nAmount, nBlockStart, UINT256_ZERO);
    if (!proposal.IsWellFormed(g_budgetman.GetTotalBudget(proposal.GetBlockStart()))) {
        return {false, strprintf("Proposal is not valid %s", proposal.IsInvalidReason())};
    }

    // Craft and send transaction.
    auto opRes = walletModel->createAndSendProposalFeeTx(proposal);
    if (!opRes) return opRes;
    scheduleBroadcast(proposal);

    return {true};
}

OperationResult GovernanceModel::voteForProposal(const ProposalInfo& prop,
                                                 bool isVotePositive,
                                                 const std::vector<std::string>& mnVotingAlias)
{
    UniValue ret; // future: don't use UniValue here.
    for (const auto& mnAlias : mnVotingAlias) {
        bool fLegacyMN = true; // For now, only legacy MNs
        ret = mnBudgetVoteInner(nullptr,
                          fLegacyMN,
                          prop.id,
                          false,
                          isVotePositive ? CBudgetVote::VoteDirection::VOTE_YES : CBudgetVote::VoteDirection::VOTE_NO,
                          mnAlias);
        if (ret.exists("detail") && ret["detail"].isArray()) {
            const UniValue& obj = ret["detail"].get_array()[0];
            if (obj["result"].getValStr() != "success") {
                return {false, obj["error"].getValStr()};
            }
        }
    }
    // add more information with ret["overall"]
    return {true};
}

void GovernanceModel::scheduleBroadcast(const CBudgetProposal& proposal)
{
    // Cache the proposal to be sent as soon as it gets the minimum required confirmations
    // without requiring user interaction
    waitingPropsForConfirmations.emplace_back(proposal);

    // Launch timer if it's not already running
    if (!pollTimer) pollTimer = new QTimer(this);
    if (!pollTimer->isActive()) {
        connect(pollTimer, &QTimer::timeout, this, &GovernanceModel::pollGovernanceChanged);
        pollTimer->start(MODEL_UPDATE_DELAY * 60 * (walletModel->isTestNetwork() ? 0.5 : 3.5)); // Every 3.5 minutes
    }
}

void GovernanceModel::pollGovernanceChanged()
{
    if (!isTierTwoSync()) return;

    int chainHeight = clientModel->getNumBlocks();
    // Try to broadcast any pending for confirmations proposal
    auto it = waitingPropsForConfirmations.begin();
    while (it != waitingPropsForConfirmations.end()) {
        // Remove expired proposals
        if (it->IsExpired(clientModel->getNumBlocks())) {
            it = waitingPropsForConfirmations.erase(it);
            continue;
        }

        // Try to add it
        if (!g_budgetman.AddProposal(*it)) {
            LogPrint(BCLog::QT, "Cannot broadcast budget proposal - %s", it->IsInvalidReason());
            // Remove proposals who due a reorg lost their fee tx
            if (it->IsInvalidReason().find("Can't find collateral tx") != std::string::npos) {
                // future: notify the user about it.
                it = waitingPropsForConfirmations.erase(it);
                continue;
            }
            // Check if the proposal didn't exceed the superblock start height
            if (it->GetBlockStart() >= chainHeight) {
                // Edge case, the proposal was never broadcasted before the next superblock, can be removed.
                // future: notify the user about it.
                it = waitingPropsForConfirmations.erase(it);
            } else {
                it++;
            }
            continue;
        }
        it->Relay();
        it = waitingPropsForConfirmations.erase(it);
    }

    // If there are no more waiting proposals, turn the timer off.
    if (waitingPropsForConfirmations.empty()) {
        pollTimer->stop();
    }
}

void GovernanceModel::stopPolling()
{
    if (pollTimer && pollTimer->isActive()) {
        pollTimer->stop();
    }
}

void GovernanceModel::txLoaded(const QString& id, const int txType, const int txStatus)
{
    if (txType == TransactionRecord::SendToNobody) {
        // If this is a proposal fee, parse it.
        const auto& wtx = walletModel->getTx(uint256S(id.toStdString()));
        assert(wtx);
        const auto& it = wtx->mapValue.find("proposal");
        if (it != wtx->mapValue.end()) {
            const std::vector<unsigned char> vec = ParseHex(it->second);
            if (vec.empty()) return;
            CDataStream ss(vec, SER_DISK, CLIENT_VERSION);
            CBudgetProposal proposal;
            ss >> proposal;
            if (!g_budgetman.HaveProposal(proposal.GetHash()) &&
                !proposal.IsExpired(clientModel->getNumBlocks()) &&
                proposal.GetBlockStart() < clientModel->getNumBlocks()) {
                scheduleBroadcast(proposal);
            }
        }
    }
}
<commit_msg>GovernanceModel: Do not try to broadcast proposal whose fee tx is conflicted or not accepted.<commit_after>// Copyright (c) 2021 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php.

#include "qt/pivx/governancemodel.h"

#include "budget/budgetmanager.h"
#include "budget/budgetutil.h"
#include "destination_io.h"
#include "guiconstants.h"
#include "masternode-sync.h"
#include "script/standard.h"
#include "qt/transactiontablemodel.h"
#include "qt/transactionrecord.h"
#include "qt/pivx/mnmodel.h"
#include "utilmoneystr.h"
#include "utilstrencodings.h"
#include "walletmodel.h"

#include <algorithm>
#include <QTimer>

GovernanceModel::GovernanceModel(ClientModel* _clientModel, MNModel* _mnModel) : clientModel(_clientModel), mnModel(_mnModel) {}
GovernanceModel::~GovernanceModel() {}

void GovernanceModel::setWalletModel(WalletModel* _walletModel)
{
    walletModel = _walletModel;
    connect(walletModel->getTransactionTableModel(), &TransactionTableModel::txLoaded, this, &GovernanceModel::txLoaded);
}

ProposalInfo GovernanceModel::buidProposalInfo(const CBudgetProposal* prop, bool isPassing, bool isPending)
{
    CTxDestination recipient;
    ExtractDestination(prop->GetPayee(), recipient);

    // Calculate status
    int votesYes = prop->GetYeas();
    int votesNo = prop->GetNays();
    ProposalInfo::Status status;

    if (isPending) {
        // Proposal waiting for confirmation to be broadcasted.
        status = ProposalInfo::WAITING_FOR_APPROVAL;
    } else {
        if (isPassing) {
            status = ProposalInfo::PASSING;
        } else if (votesYes > votesNo) {
            status = ProposalInfo::PASSING_NOT_FUNDED;
        } else {
            status = ProposalInfo::NOT_PASSING;
        }
    }

    return ProposalInfo(prop->GetHash(),
            prop->GetName(),
            prop->GetURL(),
            votesYes,
            votesNo,
            Standard::EncodeDestination(recipient),
            prop->GetAmount(),
            prop->GetTotalPaymentCount(),
            prop->GetRemainingPaymentCount(clientModel->getLastBlockProcessedHeight()),
            status);
}

std::list<ProposalInfo> GovernanceModel::getProposals()
{
    if (!clientModel) return {};
    std::list<ProposalInfo> ret;
    std::vector<CBudgetProposal> budget = g_budgetman.GetBudget();
    for (const auto& prop : g_budgetman.GetAllProposalsOrdered()) {
        bool isPassing = std::find(budget.begin(), budget.end(), *prop) != budget.end();
        ret.emplace_back(buidProposalInfo(prop, isPassing, false));
        if (isPassing) allocatedAmount += prop->GetAmount();
    }

    // Add pending proposals
    for (const auto& prop : waitingPropsForConfirmations) {
        ret.emplace_back(buidProposalInfo(&prop, false, true));
    }
    return ret;
}

bool GovernanceModel::hasProposals()
{
    return g_budgetman.HasAnyProposal();
}

CAmount GovernanceModel::getMaxAvailableBudgetAmount() const
{
    return g_budgetman.GetTotalBudget(clientModel->getNumBlocks());
}

int GovernanceModel::getNumBlocksPerBudgetCycle() const
{
    return Params().GetConsensus().nBudgetCycleBlocks;
}

int GovernanceModel::getPropMaxPaymentsCount() const
{
    return Params().GetConsensus().nMaxProposalPayments;
}

int GovernanceModel::getNextSuperblockHeight() const
{
    const int nBlocksPerCycle = getNumBlocksPerBudgetCycle();
    const int chainHeight = clientModel->getNumBlocks();
    return chainHeight - chainHeight % nBlocksPerCycle + nBlocksPerCycle;
}

std::vector<VoteInfo> GovernanceModel::getLocalMNsVotesForProposal(const ProposalInfo& propInfo)
{
    // First, get the local masternodes
    std::vector<std::pair<COutPoint, std::string>> vecLocalMn;
    for (int i = 0; i < mnModel->rowCount(); ++i) {
        vecLocalMn.emplace_back(std::make_pair(
                COutPoint(uint256S(mnModel->index(i, MNModel::COLLATERAL_ID, QModelIndex()).data().toString().toStdString()),
                mnModel->index(i, MNModel::COLLATERAL_OUT_INDEX, QModelIndex()).data().toInt()),
                mnModel->index(i, MNModel::ALIAS, QModelIndex()).data().toString().toStdString())
        );
    }

    std::vector<VoteInfo> localVotes;
    // Get the budget proposal, get the votes, then loop over it and return the ones that correspond to the local masternodes here.
    CBudgetProposal* prop = g_budgetman.FindProposal(propInfo.id);
    const auto& mapVotes = prop->GetVotes();
    for (const auto& it : mapVotes) {
        for (const auto& mn : vecLocalMn) {
            if (it.first == mn.first && it.second.IsValid()) {
                localVotes.emplace_back(mn.first, (VoteInfo::VoteDirection) it.second.GetDirection(), mn.second);
                break;
            }
        }
    }
    return localVotes;
}

OperationResult GovernanceModel::validatePropURL(const QString& url) const
{
    std::string strError;
    return {validateURL(url.toStdString(), strError, PROP_URL_MAX_SIZE), strError};
}

OperationResult GovernanceModel::validatePropAmount(CAmount amount) const
{
    if (amount > getMaxAvailableBudgetAmount()) {
        return {false, strprintf("Amount exceeding the maximum available budget amount of %s PIV", FormatMoney(amount))};
    }
    return {true};
}

OperationResult GovernanceModel::validatePropPaymentCount(int paymentCount) const
{
    if (paymentCount < 1) return { false, "Invalid payment count, must be greater than zero."};
    int nMaxPayments = getPropMaxPaymentsCount();
    if (paymentCount > nMaxPayments) {
        return { false, strprintf("Invalid payment count, cannot be greater than %d", nMaxPayments)};
    }
    return {true};
}

bool GovernanceModel::isTierTwoSync()
{
    return masternodeSync.IsBlockchainSynced();
}

OperationResult GovernanceModel::createProposal(const std::string& strProposalName,
                                                const std::string& strURL,
                                                int nPaymentCount,
                                                CAmount nAmount,
                                                const std::string& strPaymentAddr)
{
    // First get the next superblock height
    int nBlockStart = getNextSuperblockHeight();

    // Parse address
    const CTxDestination* dest = Standard::GetTransparentDestination(Standard::DecodeDestination(strPaymentAddr));
    if (!dest) return {false, "invalid recipient address for the proposal"};
    CScript scriptPubKey = GetScriptForDestination(*dest);

    // Validate proposal
    CBudgetProposal proposal(strProposalName, strURL, nPaymentCount, scriptPubKey, nAmount, nBlockStart, UINT256_ZERO);
    if (!proposal.IsWellFormed(g_budgetman.GetTotalBudget(proposal.GetBlockStart()))) {
        return {false, strprintf("Proposal is not valid %s", proposal.IsInvalidReason())};
    }

    // Craft and send transaction.
    auto opRes = walletModel->createAndSendProposalFeeTx(proposal);
    if (!opRes) return opRes;
    scheduleBroadcast(proposal);

    return {true};
}

OperationResult GovernanceModel::voteForProposal(const ProposalInfo& prop,
                                                 bool isVotePositive,
                                                 const std::vector<std::string>& mnVotingAlias)
{
    UniValue ret; // future: don't use UniValue here.
    for (const auto& mnAlias : mnVotingAlias) {
        bool fLegacyMN = true; // For now, only legacy MNs
        ret = mnBudgetVoteInner(nullptr,
                          fLegacyMN,
                          prop.id,
                          false,
                          isVotePositive ? CBudgetVote::VoteDirection::VOTE_YES : CBudgetVote::VoteDirection::VOTE_NO,
                          mnAlias);
        if (ret.exists("detail") && ret["detail"].isArray()) {
            const UniValue& obj = ret["detail"].get_array()[0];
            if (obj["result"].getValStr() != "success") {
                return {false, obj["error"].getValStr()};
            }
        }
    }
    // add more information with ret["overall"]
    return {true};
}

void GovernanceModel::scheduleBroadcast(const CBudgetProposal& proposal)
{
    // Cache the proposal to be sent as soon as it gets the minimum required confirmations
    // without requiring user interaction
    waitingPropsForConfirmations.emplace_back(proposal);

    // Launch timer if it's not already running
    if (!pollTimer) pollTimer = new QTimer(this);
    if (!pollTimer->isActive()) {
        connect(pollTimer, &QTimer::timeout, this, &GovernanceModel::pollGovernanceChanged);
        pollTimer->start(MODEL_UPDATE_DELAY * 60 * (walletModel->isTestNetwork() ? 0.5 : 3.5)); // Every 3.5 minutes
    }
}

void GovernanceModel::pollGovernanceChanged()
{
    if (!isTierTwoSync()) return;

    int chainHeight = clientModel->getNumBlocks();
    // Try to broadcast any pending for confirmations proposal
    auto it = waitingPropsForConfirmations.begin();
    while (it != waitingPropsForConfirmations.end()) {
        // Remove expired proposals
        if (it->IsExpired(clientModel->getNumBlocks())) {
            it = waitingPropsForConfirmations.erase(it);
            continue;
        }

        // Try to add it
        if (!g_budgetman.AddProposal(*it)) {
            LogPrint(BCLog::QT, "Cannot broadcast budget proposal - %s", it->IsInvalidReason());
            // Remove proposals who due a reorg lost their fee tx
            if (it->IsInvalidReason().find("Can't find collateral tx") != std::string::npos) {
                // future: notify the user about it.
                it = waitingPropsForConfirmations.erase(it);
                continue;
            }
            // Check if the proposal didn't exceed the superblock start height
            if (it->GetBlockStart() >= chainHeight) {
                // Edge case, the proposal was never broadcasted before the next superblock, can be removed.
                // future: notify the user about it.
                it = waitingPropsForConfirmations.erase(it);
            } else {
                it++;
            }
            continue;
        }
        it->Relay();
        it = waitingPropsForConfirmations.erase(it);
    }

    // If there are no more waiting proposals, turn the timer off.
    if (waitingPropsForConfirmations.empty()) {
        pollTimer->stop();
    }
}

void GovernanceModel::stopPolling()
{
    if (pollTimer && pollTimer->isActive()) {
        pollTimer->stop();
    }
}

void GovernanceModel::txLoaded(const QString& id, const int txType, const int txStatus)
{
    if (txType == TransactionRecord::SendToNobody) {
        // If the tx is not longer available in the mainchain, drop it.
        if (txStatus == TransactionStatus::Conflicted ||
            txStatus == TransactionStatus::NotAccepted) {
            return;
        }
        // If this is a proposal fee, parse it.
        const auto& wtx = walletModel->getTx(uint256S(id.toStdString()));
        assert(wtx);
        const auto& it = wtx->mapValue.find("proposal");
        if (it != wtx->mapValue.end()) {
            const std::vector<unsigned char> vec = ParseHex(it->second);
            if (vec.empty()) return;
            CDataStream ss(vec, SER_DISK, CLIENT_VERSION);
            CBudgetProposal proposal;
            ss >> proposal;
            if (!g_budgetman.HaveProposal(proposal.GetHash()) &&
                !proposal.IsExpired(clientModel->getNumBlocks()) &&
                proposal.GetBlockStart() < clientModel->getNumBlocks()) {
                scheduleBroadcast(proposal);
            }
        }
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: transliteration_Ignore.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2004-02-04 13:25:19 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

// prevent internal compiler error with MSVC6SP3
#include <utility>

#include <transliteration_Ignore.hxx>

using namespace com::sun::star::uno;
using namespace rtl;

namespace com { namespace sun { namespace star { namespace i18n {

inline sal_Int32 Min( sal_Int32 a, sal_Int32 b ) { return a > b ? b : a; }

sal_Bool SAL_CALL
transliteration_Ignore::equals(const OUString& str1, sal_Int32 pos1, sal_Int32 nCount1, sal_Int32& nMatch1,
        const OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2 ) throw(RuntimeException)
{
        Sequence< sal_Int32 > offset1;
        Sequence< sal_Int32 > offset2;

        // The method folding is defined in a sub class.
        OUString s1 = this->folding( str1, pos1, nCount1, offset1);
        OUString s2 = this->folding( str2, pos2, nCount2, offset2);

        const sal_Unicode * p1 = s1.getStr();
        const sal_Unicode * p2 = s2.getStr();
        sal_Int32 length = Min(s1.getLength(), s2.getLength());
        sal_Int32 nmatch;

        for ( nmatch = 0; nmatch < length; nmatch++)
            if (*p1++ != *p2++)
                break;

        if (nmatch > 0) {
            nMatch1 = offset1[ nmatch - 1 ] + 1; // Subtract 1 from nmatch because the index starts from zero.
            nMatch2 = offset2[ nmatch - 1 ] + 1; // And then, add 1 to position because it means the number of character matched.
        }
        else {
            nMatch1 = 0;  // No character was matched.
            nMatch2 = 0;
        }

        return (nmatch == s1.getLength()) && (nmatch == s2.getLength());
}

Sequence< OUString > SAL_CALL
transliteration_Ignore::transliterateRange( const OUString& str1, const OUString& str2 ) throw(RuntimeException)
{
        if (str1.getLength() < 1 || str2.getLength() < 1)
            throw RuntimeException();

        Sequence< OUString > r(2);
        r[0] = str1.copy(0, 1);
        r[1] = str2.copy(0, 1);
        return r;
}

sal_Int16 SAL_CALL
transliteration_Ignore::getType() throw(RuntimeException)
{
        // The type is also defined in com/sun/star/util/TransliterationType.hdl
        return TransliterationType::IGNORE;
}

OUString SAL_CALL
transliteration_Ignore::transliterate( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
        Sequence< sal_Int32 >& offset  ) throw(RuntimeException)
{
        // The method folding is defined in a sub class.
        return this->folding( inStr, startPos, nCount, offset);
}

Sequence< OUString > SAL_CALL
transliteration_Ignore::transliterateRange( const OUString& str1, const OUString& str2,
        XTransliteration& t1, XTransliteration& t2 ) throw(RuntimeException)
{
        if (str1.getLength() < 1 || str2.getLength() < 1)
            throw RuntimeException();

        Sequence< sal_Int32 > offset;
        OUString s11 = t1.transliterate( str1, 0, 1, offset );
        OUString s12 = t1.transliterate( str2, 0, 1, offset );
        OUString s21 = t2.transliterate( str1, 0, 1, offset );
        OUString s22 = t2.transliterate( str2, 0, 1, offset );

        if ( (s11 == s21) && (s12 == s22) ) {
            Sequence< OUString > r(2);
            r[0] = s11;
            r[1] = s12;
            return r;
        }

        Sequence< OUString > r(4);
        r[0] = s11;
        r[1] = s12;
        r[2] = s21;
        r[3] = s22;
        return r;
}

OUString SAL_CALL
transliteration_Ignore::folding( const OUString& inStr, sal_Int32 startPos,
    sal_Int32 nCount, Sequence< sal_Int32 >& offset)
    throw(RuntimeException)
{
    // Create a string buffer which can hold nCount + 1 characters.
    // The reference count is 0 now.
    rtl_uString * newStr = x_rtl_uString_new_WithLength( nCount ); // defined in x_rtl_ustring.h
    sal_Unicode * dst = newStr->buffer;
    const sal_Unicode * src = inStr.getStr() + startPos;

    // Allocate nCount length to offset argument.
    sal_Int32 *p, position;
    if (useOffset) {
        offset.realloc( nCount );
        p = offset.getArray();
        position = startPos;
    }

    if (map) {
        sal_Unicode previousChar = *src ++;
        sal_Unicode currentChar;

        // Translation
        while (-- nCount > 0) {
            currentChar = *src ++;

            Mapping *m;
            for (m = map; m->replaceChar; m++) {
                if (previousChar == m->previousChar &&  currentChar == m->currentChar ) {
                    if (useOffset) {
                        if (! m->two2one)
                            *p++ = position;
                        position++;
                        *p++ = position++;
                    }
                    *dst++ = m->replaceChar;
                    if (!m->two2one)
                        *dst++ = currentChar;
                    previousChar = *src++;
                    nCount--;
                    break;
                }
            }

            if (! m->replaceChar) {
                if (useOffset)
                    *p ++ = position ++;
                *dst ++ = previousChar;
                previousChar = currentChar;
            }
        }

        if (nCount == 0) {
            if (useOffset)
                *p = position;
            *dst ++ = previousChar;
        }
        newStr->length = sal_Int32(dst - newStr->buffer);
        if (useOffset)
            offset.realloc(newStr->length);
    } else {
        // Translation
        while (nCount -- > 0) {
            sal_Unicode c = *src++;
            c = func ? func( c) : (*table)[ c ];
            if (c != 0xffff)
                *dst ++ = c;
            if (useOffset) {
                if (c != 0xffff)
                    *p ++ = position;
                position++;
            }
        }
    }
    *dst = (sal_Unicode) 0;

    return OUString( newStr ); // defined in rtl/usrting. The reference count is increased from 0 to 1.
}

sal_Unicode SAL_CALL
transliteration_Ignore::transliterateChar2Char( sal_Unicode inChar) throw(RuntimeException, MultipleCharsOutputException)
{
    return func ? func( inChar) : table ? (*table)[ inChar ] : inChar;
}

} } } }
<commit_msg>INTEGRATION: CWS i18n11 (1.7.60); FILE MERGED 2004/01/06 22:30:47 khong 1.7.60.1: #105745# #107978# #109715# #110835# #112014# #112068# #112094# #112102# #112282# fix Japanese ambiguous search problems<commit_after>/*************************************************************************
 *
 *  $RCSfile: transliteration_Ignore.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2004-03-17 09:04:01 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

// prevent internal compiler error with MSVC6SP3
#include <utility>

#include <transliteration_Ignore.hxx>

using namespace com::sun::star::uno;
using namespace rtl;

namespace com { namespace sun { namespace star { namespace i18n {

inline sal_Int32 Min( sal_Int32 a, sal_Int32 b ) { return a > b ? b : a; }

sal_Bool SAL_CALL
transliteration_Ignore::equals(const OUString& str1, sal_Int32 pos1, sal_Int32 nCount1, sal_Int32& nMatch1,
        const OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2 ) throw(RuntimeException)
{
        Sequence< sal_Int32 > offset1;
        Sequence< sal_Int32 > offset2;

        // The method folding is defined in a sub class.
        OUString s1 = this->folding( str1, pos1, nCount1, offset1);
        OUString s2 = this->folding( str2, pos2, nCount2, offset2);

        const sal_Unicode * p1 = s1.getStr();
        const sal_Unicode * p2 = s2.getStr();
        sal_Int32 length = Min(s1.getLength(), s2.getLength());
        sal_Int32 nmatch;

        for ( nmatch = 0; nmatch < length; nmatch++)
            if (*p1++ != *p2++)
                break;

        if (nmatch > 0) {
            nMatch1 = offset1[ nmatch - 1 ] + 1; // Subtract 1 from nmatch because the index starts from zero.
            nMatch2 = offset2[ nmatch - 1 ] + 1; // And then, add 1 to position because it means the number of character matched.
        }
        else {
            nMatch1 = 0;  // No character was matched.
            nMatch2 = 0;
        }

        return (nmatch == s1.getLength()) && (nmatch == s2.getLength());
}

Sequence< OUString > SAL_CALL
transliteration_Ignore::transliterateRange( const OUString& str1, const OUString& str2 ) throw(RuntimeException)
{
        if (str1.getLength() < 1 || str2.getLength() < 1)
            throw RuntimeException();

        Sequence< OUString > r(2);
        r[0] = str1.copy(0, 1);
        r[1] = str2.copy(0, 1);
        return r;
}

sal_Int16 SAL_CALL
transliteration_Ignore::getType() throw(RuntimeException)
{
        // The type is also defined in com/sun/star/util/TransliterationType.hdl
        return TransliterationType::IGNORE;
}

OUString SAL_CALL
transliteration_Ignore::transliterate( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
        Sequence< sal_Int32 >& offset  ) throw(RuntimeException)
{
        // The method folding is defined in a sub class.
        return this->folding( inStr, startPos, nCount, offset);
}

Sequence< OUString > SAL_CALL
transliteration_Ignore::transliterateRange( const OUString& str1, const OUString& str2,
        XTransliteration& t1, XTransliteration& t2 ) throw(RuntimeException)
{
        if (str1.getLength() < 1 || str2.getLength() < 1)
            throw RuntimeException();

        Sequence< sal_Int32 > offset;
        OUString s11 = t1.transliterate( str1, 0, 1, offset );
        OUString s12 = t1.transliterate( str2, 0, 1, offset );
        OUString s21 = t2.transliterate( str1, 0, 1, offset );
        OUString s22 = t2.transliterate( str2, 0, 1, offset );

        if ( (s11 == s21) && (s12 == s22) ) {
            Sequence< OUString > r(2);
            r[0] = s11;
            r[1] = s12;
            return r;
        }

        Sequence< OUString > r(4);
        r[0] = s11;
        r[1] = s12;
        r[2] = s21;
        r[3] = s22;
        return r;
}

OUString SAL_CALL
transliteration_Ignore::folding( const OUString& inStr, sal_Int32 startPos,
    sal_Int32 nCount, Sequence< sal_Int32 >& offset)
    throw(RuntimeException)
{
    // Create a string buffer which can hold nCount + 1 characters.
    // The reference count is 0 now.
    rtl_uString * newStr = x_rtl_uString_new_WithLength( nCount ); // defined in x_rtl_ustring.h
    sal_Unicode * dst = newStr->buffer;
    const sal_Unicode * src = inStr.getStr() + startPos;

    // Allocate nCount length to offset argument.
    sal_Int32 *p, position;
    if (useOffset) {
        offset.realloc( nCount );
        p = offset.getArray();
        position = startPos;
    }

    if (map) {
        sal_Unicode previousChar = *src ++;
        sal_Unicode currentChar;

        // Translation
        while (-- nCount > 0) {
            currentChar = *src ++;

            Mapping *m;
            for (m = map; m->replaceChar; m++) {
                if (previousChar == m->previousChar &&  currentChar == m->currentChar ) {
                    if (useOffset) {
                        if (! m->two2one)
                            *p++ = position;
                        position++;
                        *p++ = position++;
                    }
                    *dst++ = m->replaceChar;
                    if (!m->two2one)
                        *dst++ = currentChar;
                    previousChar = *src++;
                    nCount--;
                    break;
                }
            }

            if (! m->replaceChar) {
                if (useOffset)
                    *p ++ = position ++;
                *dst ++ = previousChar;
                previousChar = currentChar;
            }
        }

        if (nCount == 0) {
            if (useOffset)
                *p = position;
            *dst ++ = previousChar;
        }
    } else {
        // Translation
        while (nCount -- > 0) {
            sal_Unicode c = *src++;
            c = func ? func( c) : (*table)[ c ];
            if (c != 0xffff)
                *dst ++ = c;
            if (useOffset) {
                if (c != 0xffff)
                    *p ++ = position;
                position++;
            }
        }
    }
    newStr->length = sal_Int32(dst - newStr->buffer);
    if (useOffset)
      offset.realloc(newStr->length);
    *dst = (sal_Unicode) 0;

    return OUString( newStr ); // defined in rtl/usrting. The reference count is increased from 0 to 1.
}

sal_Unicode SAL_CALL
transliteration_Ignore::transliterateChar2Char( sal_Unicode inChar) throw(RuntimeException, MultipleCharsOutputException)
{
    return func ? func( inChar) : table ? (*table)[ inChar ] : inChar;
}

} } } }
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Axel Isouard <axel@isouard.fr>
 *
 * 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 <memory>
#include <iostream>
#include "common.h"
#include "rtcsessiondescription.h"

Nan::Persistent<FunctionTemplate> RTCSessionDescription::constructor;

static const char sRTCSessionDescription[] = "RTCSessionDescription";

static const char kSdp[] = "sdp";
static const char kType[] = "type";

NAN_MODULE_INIT(RTCSessionDescription::Init) {
  Local<FunctionTemplate> ctor = Nan::New<FunctionTemplate>(New);

  ctor->SetClassName(Nan::New(sRTCSessionDescription).ToLocalChecked());
  ctor->InstanceTemplate()->SetInternalFieldCount(1);

  Local<ObjectTemplate> tpl = ctor->InstanceTemplate();

  Nan::SetAccessor(tpl, Nan::New(kSdp).ToLocalChecked(), GetSdp);
  Nan::SetAccessor(tpl, Nan::New(kType).ToLocalChecked(), GetType);

  constructor.Reset(ctor);
  Nan::Set(target, Nan::New(sRTCSessionDescription).ToLocalChecked(),
           ctor->GetFunction());
}

RTCSessionDescription::RTCSessionDescription(
    webrtc::SessionDescriptionInterface *sessionDescription)
    : _sessionDescription(sessionDescription) {
}

RTCSessionDescription::~RTCSessionDescription() {
  delete _sessionDescription;
}

NAN_METHOD(RTCSessionDescription::New) {
  CONSTRUCTOR_HEADER(RTCSessionDescription);

  ASSERT_CONSTRUCT_CALL;
  ASSERT_SINGLE_ARGUMENT;

  ASSERT_OBJECT_ARGUMENT(0, descriptionInitDict);

  ASSERT_OBJECT_PROPERTY(descriptionInitDict, kType, typeVal);
  ASSERT_PROPERTY_STRING(kType, typeVal, type);

  if (std::string("answer").compare(*type) &&
      std::string("offer").compare(*type) &&
      std::string("pranswer").compare(*type) &&
      std::string("rollback").compare(*type)) {
    errorStream << "The provided value '";
    errorStream << std::string(*type);
    errorStream << "' is not a valid enum value of type RTCSdpType.";
    return Nan::ThrowTypeError(errorStream.str().c_str());
  }

  ASSERT_OBJECT_PROPERTY(descriptionInitDict, kSdp, sdpVal);
  ASSERT_PROPERTY_STRING(kSdp, sdpVal, sdp);

  webrtc::SdpParseError error;
  webrtc::SessionDescriptionInterface *desc;
  desc = webrtc::CreateSessionDescription(*type, *sdp, &error);

  if (!desc) {
    errorStream << error.description;
    return Nan::ThrowTypeError(errorStream.str().c_str());
  }

  RTCSessionDescription *rtcIceCandidate = new RTCSessionDescription(desc);
  rtcIceCandidate->Wrap(info.This());

  info.GetReturnValue().Set(info.This());
}

NAN_GETTER(RTCSessionDescription::GetType) {
  RTCSessionDescription *object =
      Nan::ObjectWrap::Unwrap<RTCSessionDescription>(info.This());

  info.GetReturnValue().Set(
      Nan::New(object->_sessionDescription->type()).ToLocalChecked());
}

NAN_GETTER(RTCSessionDescription::GetSdp) {
  std::string sdp;
  RTCSessionDescription *object =
      Nan::ObjectWrap::Unwrap<RTCSessionDescription>(info.This());

  object->_sessionDescription->ToString(&sdp);
  info.GetReturnValue().Set(Nan::New(sdp).ToLocalChecked());
}
<commit_msg>RTCSessionDescription: Use new macros<commit_after>/*
 * Copyright (c) 2017 Axel Isouard <axel@isouard.fr>
 *
 * 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 <memory>
#include <iostream>
#include "common.h"
#include "rtcsessiondescription.h"

Nan::Persistent<FunctionTemplate> RTCSessionDescription::constructor;

static const char sRTCSessionDescription[] = "RTCSessionDescription";

static const char kSdp[] = "sdp";
static const char kType[] = "type";

static const char kAnswer[] = "answer";
static const char kOffer[] = "offer";
static const char kPranswer[] = "pranswer";
static const char kRollback[] = "rollback";

NAN_MODULE_INIT(RTCSessionDescription::Init) {
  Local<FunctionTemplate> ctor = Nan::New<FunctionTemplate>(New);

  ctor->SetClassName(LOCAL_STRING(sRTCSessionDescription));
  ctor->InstanceTemplate()->SetInternalFieldCount(1);

  Local<ObjectTemplate> tpl = ctor->InstanceTemplate();

  Nan::SetAccessor(tpl, LOCAL_STRING(kSdp), GetSdp);
  Nan::SetAccessor(tpl, LOCAL_STRING(kType), GetType);

  constructor.Reset(ctor);
  Nan::Set(target, LOCAL_STRING(sRTCSessionDescription), ctor->GetFunction());
}

RTCSessionDescription::RTCSessionDescription(
    webrtc::SessionDescriptionInterface *sessionDescription)
    : _sessionDescription(sessionDescription) {
}

RTCSessionDescription::~RTCSessionDescription() {
  delete _sessionDescription;
}

NAN_METHOD(RTCSessionDescription::New) {
  CONSTRUCTOR_HEADER(RTCSessionDescription);

  ASSERT_CONSTRUCT_CALL;
  ASSERT_SINGLE_ARGUMENT;

  ASSERT_OBJECT_ARGUMENT(0, descriptionInitDict);

  ASSERT_OBJECT_PROPERTY(descriptionInitDict, kType, typeVal);
  ASSERT_PROPERTY_STRING(kType, typeVal, type);

  if (std::string(kAnswer).compare(*type) &&
      std::string(kOffer).compare(*type) &&
      std::string(kPranswer).compare(*type) &&
      std::string(kRollback).compare(*type)) {
    errorStream << "The provided value '";
    errorStream << std::string(*type);
    errorStream << "' is not a valid enum value of type RTCSdpType.";
    return Nan::ThrowTypeError(errorStream.str().c_str());
  }

  ASSERT_OBJECT_PROPERTY(descriptionInitDict, kSdp, sdpVal);
  ASSERT_PROPERTY_STRING(kSdp, sdpVal, sdp);

  webrtc::SdpParseError error;
  webrtc::SessionDescriptionInterface *desc;
  desc = webrtc::CreateSessionDescription(*type, *sdp, &error);

  if (!desc) {
    errorStream << error.description;
    return Nan::ThrowTypeError(errorStream.str().c_str());
  }

  RTCSessionDescription *rtcIceCandidate = new RTCSessionDescription(desc);
  rtcIceCandidate->Wrap(info.This());

  info.GetReturnValue().Set(info.This());
}

NAN_GETTER(RTCSessionDescription::GetType) {
  RTCSessionDescription *object =
      Nan::ObjectWrap::Unwrap<RTCSessionDescription>(info.This());

  info.GetReturnValue().Set(LOCAL_STRING(object->_sessionDescription->type()));
}

NAN_GETTER(RTCSessionDescription::GetSdp) {
  std::string sdp;
  RTCSessionDescription *object =
      Nan::ObjectWrap::Unwrap<RTCSessionDescription>(info.This());

  object->_sessionDescription->ToString(&sdp);
  info.GetReturnValue().Set(LOCAL_STRING(sdp));
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*!
 * \file main.cc
 * \brief main entry point for host subprocess-based CRT
 */
#include <inttypes.h>
#include <time.h>
#include <tvm/runtime/c_runtime_api.h>
#include <tvm/runtime/crt/logging.h>
#include <tvm/runtime/crt/memory.h>
#include <tvm/runtime/crt/utvm_rpc_server.h>
#include <unistd.h>

#include <chrono>
#include <iostream>

#include "crt_config.h"

#ifdef TVM_HOST_USE_GRAPH_EXECUTOR_MODULE
#include <tvm/runtime/crt/graph_executor_module.h>
#endif

using namespace std::chrono;

extern "C" {

ssize_t UTvmWriteFunc(void* context, const uint8_t* data, size_t num_bytes) {
  ssize_t to_return = write(STDOUT_FILENO, data, num_bytes);
  fflush(stdout);
  fsync(STDOUT_FILENO);
  return to_return;
}

size_t TVMPlatformFormatMessage(char* out_buf, size_t out_buf_size_bytes, const char* fmt,
                                va_list args) {
  return vsnprintf(out_buf, out_buf_size_bytes, fmt, args);
}

void TVMPlatformAbort(tvm_crt_error_t error_code) {
  std::cerr << "TVMPlatformAbort: " << error_code << std::endl;
  throw "Aborted";
}

MemoryManagerInterface* memory_manager;

tvm_crt_error_t TVMPlatformMemoryAllocate(size_t num_bytes, DLDevice dev, void** out_ptr) {
  return memory_manager->Allocate(memory_manager, num_bytes, dev, out_ptr);
}

tvm_crt_error_t TVMPlatformMemoryFree(void* ptr, DLDevice dev) {
  return memory_manager->Free(memory_manager, ptr, dev);
}

steady_clock::time_point g_utvm_start_time;
int g_utvm_timer_running = 0;

tvm_crt_error_t TVMPlatformTimerStart() {
  if (g_utvm_timer_running) {
    std::cerr << "timer already running" << std::endl;
    return kTvmErrorPlatformTimerBadState;
  }
  g_utvm_start_time = std::chrono::steady_clock::now();
  g_utvm_timer_running = 1;
  return kTvmErrorNoError;
}

tvm_crt_error_t TVMPlatformTimerStop(double* elapsed_time_seconds) {
  if (!g_utvm_timer_running) {
    std::cerr << "timer not running" << std::endl;
    return kTvmErrorPlatformTimerBadState;
  }
  auto utvm_stop_time = std::chrono::steady_clock::now();
  std::chrono::microseconds time_span =
      std::chrono::duration_cast<std::chrono::microseconds>(utvm_stop_time - g_utvm_start_time);
  *elapsed_time_seconds = static_cast<double>(time_span.count()) / 1e6;
  g_utvm_timer_running = 0;
  return kTvmErrorNoError;
}

static_assert(RAND_MAX >= (1 << 8), "RAND_MAX is smaller than acceptable");
unsigned int random_seed = 0;
tvm_crt_error_t TVMPlatformGenerateRandom(uint8_t* buffer, size_t num_bytes) {
  if (random_seed == 0) {
    random_seed = (unsigned int)time(NULL);
  }
  for (size_t i = 0; i < num_bytes; ++i) {
    int random = rand_r(&random_seed);
    buffer[i] = (uint8_t)random;
  }

  return kTvmErrorNoError;
}
}

uint8_t memory[512 * 1024];

static char** g_argv = NULL;

int testonly_reset_server(TVMValue* args, int* type_codes, int num_args, TVMValue* out_ret_value,
                          int* out_ret_tcode, void* resource_handle) {
  execvp(g_argv[0], g_argv);
  perror("utvm runtime: error restarting");
  return -1;
}

int main(int argc, char** argv) {
  g_argv = argv;
  int status = MemoryManagerCreate(&memory_manager, memory, sizeof(memory), 8 /* page_size_log2 */);
  if (status != 0) {
    fprintf(stderr, "error initiailizing memory manager\n");
    return 2;
  }

  utvm_rpc_server_t rpc_server = UTvmRpcServerInit(&UTvmWriteFunc, nullptr);

#ifdef TVM_HOST_USE_GRAPH_EXECUTOR_MODULE
  CHECK_EQ(TVMGraphExecutorModule_Register(), kTvmErrorNoError,
           "failed to register GraphExecutor TVMModule");
#endif

  int error = TVMFuncRegisterGlobal("tvm.testing.reset_server",
                                    (TVMFunctionHandle)&testonly_reset_server, 0);
  if (error) {
    fprintf(stderr,
            "utvm runtime: internal error (error#: %x) registering global packedfunc; exiting\n",
            error);
    return 2;
  }

  setbuf(stdin, NULL);
  setbuf(stdout, NULL);

  for (;;) {
    uint8_t c;
    int ret_code = read(STDIN_FILENO, &c, 1);
    if (ret_code < 0) {
      perror("utvm runtime: read failed");
      return 2;
    } else if (ret_code == 0) {
      fprintf(stderr, "utvm runtime: 0-length read, exiting!\n");
      return 2;
    }
    uint8_t* cursor = &c;
    size_t bytes_to_process = 1;
    while (bytes_to_process > 0) {
      tvm_crt_error_t err = UTvmRpcServerLoop(rpc_server, &cursor, &bytes_to_process);
      if (err == kTvmErrorPlatformShutdown) {
        break;
      } else if (err != kTvmErrorNoError) {
        char buf[1024];
        snprintf(buf, sizeof(buf), "utvm runtime: UTvmRpcServerLoop error: %08x", err);
        perror(buf);
        return 2;
      }
    }
  }
  return 0;
}
<commit_msg>[microTVM] Increase host memory size (#7933)<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*!
 * \file main.cc
 * \brief main entry point for host subprocess-based CRT
 */
#include <inttypes.h>
#include <time.h>
#include <tvm/runtime/c_runtime_api.h>
#include <tvm/runtime/crt/logging.h>
#include <tvm/runtime/crt/memory.h>
#include <tvm/runtime/crt/utvm_rpc_server.h>
#include <unistd.h>

#include <chrono>
#include <iostream>

#include "crt_config.h"

#ifdef TVM_HOST_USE_GRAPH_EXECUTOR_MODULE
#include <tvm/runtime/crt/graph_executor_module.h>
#endif

using namespace std::chrono;

extern "C" {

ssize_t UTvmWriteFunc(void* context, const uint8_t* data, size_t num_bytes) {
  ssize_t to_return = write(STDOUT_FILENO, data, num_bytes);
  fflush(stdout);
  fsync(STDOUT_FILENO);
  return to_return;
}

size_t TVMPlatformFormatMessage(char* out_buf, size_t out_buf_size_bytes, const char* fmt,
                                va_list args) {
  return vsnprintf(out_buf, out_buf_size_bytes, fmt, args);
}

void TVMPlatformAbort(tvm_crt_error_t error_code) {
  std::cerr << "TVMPlatformAbort: " << error_code << std::endl;
  throw "Aborted";
}

MemoryManagerInterface* memory_manager;

tvm_crt_error_t TVMPlatformMemoryAllocate(size_t num_bytes, DLDevice dev, void** out_ptr) {
  return memory_manager->Allocate(memory_manager, num_bytes, dev, out_ptr);
}

tvm_crt_error_t TVMPlatformMemoryFree(void* ptr, DLDevice dev) {
  return memory_manager->Free(memory_manager, ptr, dev);
}

steady_clock::time_point g_utvm_start_time;
int g_utvm_timer_running = 0;

tvm_crt_error_t TVMPlatformTimerStart() {
  if (g_utvm_timer_running) {
    std::cerr << "timer already running" << std::endl;
    return kTvmErrorPlatformTimerBadState;
  }
  g_utvm_start_time = std::chrono::steady_clock::now();
  g_utvm_timer_running = 1;
  return kTvmErrorNoError;
}

tvm_crt_error_t TVMPlatformTimerStop(double* elapsed_time_seconds) {
  if (!g_utvm_timer_running) {
    std::cerr << "timer not running" << std::endl;
    return kTvmErrorPlatformTimerBadState;
  }
  auto utvm_stop_time = std::chrono::steady_clock::now();
  std::chrono::microseconds time_span =
      std::chrono::duration_cast<std::chrono::microseconds>(utvm_stop_time - g_utvm_start_time);
  *elapsed_time_seconds = static_cast<double>(time_span.count()) / 1e6;
  g_utvm_timer_running = 0;
  return kTvmErrorNoError;
}

static_assert(RAND_MAX >= (1 << 8), "RAND_MAX is smaller than acceptable");
unsigned int random_seed = 0;
tvm_crt_error_t TVMPlatformGenerateRandom(uint8_t* buffer, size_t num_bytes) {
  if (random_seed == 0) {
    random_seed = (unsigned int)time(NULL);
  }
  for (size_t i = 0; i < num_bytes; ++i) {
    int random = rand_r(&random_seed);
    buffer[i] = (uint8_t)random;
  }

  return kTvmErrorNoError;
}
}

uint8_t memory[2048 * 1024];

static char** g_argv = NULL;

int testonly_reset_server(TVMValue* args, int* type_codes, int num_args, TVMValue* out_ret_value,
                          int* out_ret_tcode, void* resource_handle) {
  execvp(g_argv[0], g_argv);
  perror("utvm runtime: error restarting");
  return -1;
}

int main(int argc, char** argv) {
  g_argv = argv;
  int status = MemoryManagerCreate(&memory_manager, memory, sizeof(memory), 8 /* page_size_log2 */);
  if (status != 0) {
    fprintf(stderr, "error initiailizing memory manager\n");
    return 2;
  }

  utvm_rpc_server_t rpc_server = UTvmRpcServerInit(&UTvmWriteFunc, nullptr);

#ifdef TVM_HOST_USE_GRAPH_EXECUTOR_MODULE
  CHECK_EQ(TVMGraphExecutorModule_Register(), kTvmErrorNoError,
           "failed to register GraphExecutor TVMModule");
#endif

  int error = TVMFuncRegisterGlobal("tvm.testing.reset_server",
                                    (TVMFunctionHandle)&testonly_reset_server, 0);
  if (error) {
    fprintf(stderr,
            "utvm runtime: internal error (error#: %x) registering global packedfunc; exiting\n",
            error);
    return 2;
  }

  setbuf(stdin, NULL);
  setbuf(stdout, NULL);

  for (;;) {
    uint8_t c;
    int ret_code = read(STDIN_FILENO, &c, 1);
    if (ret_code < 0) {
      perror("utvm runtime: read failed");
      return 2;
    } else if (ret_code == 0) {
      fprintf(stderr, "utvm runtime: 0-length read, exiting!\n");
      return 2;
    }
    uint8_t* cursor = &c;
    size_t bytes_to_process = 1;
    while (bytes_to_process > 0) {
      tvm_crt_error_t err = UTvmRpcServerLoop(rpc_server, &cursor, &bytes_to_process);
      if (err == kTvmErrorPlatformShutdown) {
        break;
      } else if (err != kTvmErrorNoError) {
        char buf[1024];
        snprintf(buf, sizeof(buf), "utvm runtime: UTvmRpcServerLoop error: %08x", err);
        perror(buf);
        return 2;
      }
    }
  }
  return 0;
}
<|endoftext|>


<commit_before>#include "logger.h"
#include "FilterParser.h"
#include "Parser.h"
#include <utils.h>

using namespace newsboat;

FilterParser::FilterParser() : root(0), curpos(0), next_must_descend_right(false) { }

FilterParser::~FilterParser() {
	cleanup();
}

FilterParser::FilterParser(const FilterParser& p) {
	LOG(level::DEBUG,"FilterParser: copy constructor called!");
	parse_string(p.strexpr);
}

FilterParser& FilterParser::operator=(FilterParser& p) {
	LOG(level::DEBUG,"FilterParser: operator= called!");
	if (this != &p) {
		cleanup();
		parse_string(p.strexpr);
	}
	return *this;
}

void FilterParser::add_logop(int op) {
	//fprintf(stderr,"add_logop: op = %d\n", op);
	expression * expr = new expression(op);
	if (!root) {
		printf("error: there can't be a logical expression w/o a prior expression!");
		// TODO: add proper error handling
	} else {
		if (curpos != root) {
			expr->l = curpos;
			curpos->parent->r = expr;
			expr->parent = curpos->parent;
			curpos = expr;
		} else {
			expr->l = root;
			curpos = root = expr;
		}
	}
	// printf("logop: %d\n", op);
}

void FilterParser::add_matchexpr(char * name, int op, char * lit) {
	//fprintf(stderr,"add_matchexpr: name = %s op = %d lit = %s\n", name, op, lit);
	expression * expr = new expression(name, lit, op);
	if (next_must_descend_right) {
		next_must_descend_right = false;
		if (!curpos) {
			curpos = root = expr;
		} else {
			expr->parent = curpos;
			curpos->r = expr;
			curpos = expr;
		}
	} else {
		if (!curpos) {
			curpos = root = expr;
		} else {
			expr->parent = curpos;
			curpos->r = expr;
		}
	}
	coco_string_delete(name);
	coco_string_delete(lit);
	// printf("matchexpr: %ls lit = %ls op = %d\n", name, lit, op);
}

void FilterParser::open_block() {
	//fprintf(stderr,"open_block\n");
	next_must_descend_right = true;
}

void FilterParser::close_block() {
	//fprintf(stderr,"close_block\n");
	if (curpos != root) {
		curpos = curpos->parent;
	}
}

bool FilterParser::parse_string(const std::string& str) {
	cleanup();
	strexpr = str;

	Scanner s((const unsigned char *)str.c_str(), str.length());
	Parser p(&s);
	p.gen = this;
	p.Parse();
	if (0 == p.errors->count) {
		return true;
	}
	errmsg = p.errors->errors[0];
	cleanup();
	return false;
}

void FilterParser::cleanup() {
	cleanup_r(root);
	root = curpos = NULL;
}

void FilterParser::cleanup_r(expression * e) {
	if (e) {
		LOG(level::DEBUG,"cleanup_r: e = %p", e);
		cleanup_r(e->l);
		cleanup_r(e->r);
		delete e;
	}
}

expression::expression(const std::string& n, const std::string& lit, int o) : name(n), literal(lit), op(o), l(NULL), r(NULL), parent(NULL), regex(NULL) {
	if (literal[0] == '"' && literal[literal.length()-1] == '"') {
		literal = literal.substr(1,literal.length()-2);
	}
}

expression::expression(int o) : op(o), l(NULL), r(NULL), parent(NULL), regex(NULL) {
}

expression::~expression() {
	if (regex)
		regfree(regex);
	delete regex;
}
<commit_msg>Fix resource leak in FilterParser<commit_after>#include "logger.h"
#include "FilterParser.h"
#include "Parser.h"
#include <utils.h>

using namespace newsboat;

FilterParser::FilterParser() : root(0), curpos(0), next_must_descend_right(false) { }

FilterParser::~FilterParser() {
	cleanup();
}

FilterParser::FilterParser(const FilterParser& p) {
	LOG(level::DEBUG,"FilterParser: copy constructor called!");
	parse_string(p.strexpr);
}

FilterParser& FilterParser::operator=(FilterParser& p) {
	LOG(level::DEBUG,"FilterParser: operator= called!");
	if (this != &p) {
		cleanup();
		parse_string(p.strexpr);
	}
	return *this;
}

void FilterParser::add_logop(int op) {
	//fprintf(stderr,"add_logop: op = %d\n", op);
	expression * expr = new expression(op);
	if (!root) {
		printf("error: there can't be a logical expression w/o a prior expression!");
		delete expr;
		// TODO: add proper error handling
	} else {
		if (curpos != root) {
			expr->l = curpos;
			curpos->parent->r = expr;
			expr->parent = curpos->parent;
			curpos = expr;
		} else {
			expr->l = root;
			curpos = root = expr;
		}
	}
	// printf("logop: %d\n", op);
}

void FilterParser::add_matchexpr(char * name, int op, char * lit) {
	//fprintf(stderr,"add_matchexpr: name = %s op = %d lit = %s\n", name, op, lit);
	expression * expr = new expression(name, lit, op);
	if (next_must_descend_right) {
		next_must_descend_right = false;
		if (!curpos) {
			curpos = root = expr;
		} else {
			expr->parent = curpos;
			curpos->r = expr;
			curpos = expr;
		}
	} else {
		if (!curpos) {
			curpos = root = expr;
		} else {
			expr->parent = curpos;
			curpos->r = expr;
		}
	}
	coco_string_delete(name);
	coco_string_delete(lit);
	// printf("matchexpr: %ls lit = %ls op = %d\n", name, lit, op);
}

void FilterParser::open_block() {
	//fprintf(stderr,"open_block\n");
	next_must_descend_right = true;
}

void FilterParser::close_block() {
	//fprintf(stderr,"close_block\n");
	if (curpos != root) {
		curpos = curpos->parent;
	}
}

bool FilterParser::parse_string(const std::string& str) {
	cleanup();
	strexpr = str;

	Scanner s((const unsigned char *)str.c_str(), str.length());
	Parser p(&s);
	p.gen = this;
	p.Parse();
	if (0 == p.errors->count) {
		return true;
	}
	errmsg = p.errors->errors[0];
	cleanup();
	return false;
}

void FilterParser::cleanup() {
	cleanup_r(root);
	root = curpos = NULL;
}

void FilterParser::cleanup_r(expression * e) {
	if (e) {
		LOG(level::DEBUG,"cleanup_r: e = %p", e);
		cleanup_r(e->l);
		cleanup_r(e->r);
		delete e;
	}
}

expression::expression(const std::string& n, const std::string& lit, int o) : name(n), literal(lit), op(o), l(NULL), r(NULL), parent(NULL), regex(NULL) {
	if (literal[0] == '"' && literal[literal.length()-1] == '"') {
		literal = literal.substr(1,literal.length()-2);
	}
}

expression::expression(int o) : op(o), l(NULL), r(NULL), parent(NULL), regex(NULL) {
}

expression::~expression() {
	if (regex)
		regfree(regex);
	delete regex;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImporter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkImporter.h"
#include "vtkRendererCollection.h"
#include "vtkRenderWindow.h"

vtkCxxSetObjectMacro(vtkImporter,RenderWindow,vtkRenderWindow);

vtkImporter::vtkImporter ()
{
  this->Renderer = NULL;
  this->RenderWindow = NULL;
}

vtkImporter::~vtkImporter ()
{
  this->SetRenderWindow(NULL);

  if (this->Renderer)
    {
    this->Renderer->UnRegister( NULL );
    this->Renderer = NULL;
    }

}

void vtkImporter::ReadData()
{
  // this->Import actors, cameras, lights and properties
  this->ImportActors (this->Renderer);
  this->ImportCameras (this->Renderer);
  this->ImportLights (this->Renderer);
  this->ImportProperties (this->Renderer);
}

void vtkImporter::Read ()
{
  vtkRenderer *renderer;

  // if there is no render window, create one
  if (this->RenderWindow == NULL)
    {
    vtkDebugMacro( <<"Creating a RenderWindow\n");
    this->RenderWindow = vtkRenderWindow::New ();
    }

  // Get the first renderer in the render window
  renderer = this->RenderWindow->GetRenderers()->GetFirstRenderer();
  if (renderer == NULL)
    {
    vtkDebugMacro( <<"Creating a Renderer\n");
    this->Renderer = vtkRenderer::New ();
    renderer = this->Renderer;
    this->RenderWindow->AddRenderer (renderer);
    this->Renderer->UnRegister(NULL);

    }
  else
    {
    this->Renderer = renderer;
    this->Renderer->Register( this );
    }

  if (this->ImportBegin ())
    {
    this->ReadData();
    this->ImportEnd();
    }
}

void vtkImporter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Render Window: ";
  if ( this->RenderWindow )
    {
    os << this->RenderWindow << "\n";
    }
  else
    {
    os << "(none)\n";
    }

  os << indent << "Renderer: ";
  if ( this->Renderer )
    {
    os << this->Renderer << "\n";
    }
  else
    {
    os << "(none)\n";
    }

}

<commit_msg>BUG: Remove double delete of vtkRenderer.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImporter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkImporter.h"
#include "vtkRendererCollection.h"
#include "vtkRenderWindow.h"

vtkCxxSetObjectMacro(vtkImporter,RenderWindow,vtkRenderWindow);

vtkImporter::vtkImporter ()
{
  this->Renderer = NULL;
  this->RenderWindow = NULL;
}

vtkImporter::~vtkImporter ()
{
  this->SetRenderWindow(NULL);

  if (this->Renderer)
    {
    this->Renderer->UnRegister( NULL );
    this->Renderer = NULL;
    }

}

void vtkImporter::ReadData()
{
  // this->Import actors, cameras, lights and properties
  this->ImportActors (this->Renderer);
  this->ImportCameras (this->Renderer);
  this->ImportLights (this->Renderer);
  this->ImportProperties (this->Renderer);
}

void vtkImporter::Read ()
{
  vtkRenderer *renderer;

  // if there is no render window, create one
  if (this->RenderWindow == NULL)
    {
    vtkDebugMacro( <<"Creating a RenderWindow\n");
    this->RenderWindow = vtkRenderWindow::New ();
    }

  // Get the first renderer in the render window
  renderer = this->RenderWindow->GetRenderers()->GetFirstRenderer();
  if (renderer == NULL)
    {
    vtkDebugMacro( <<"Creating a Renderer\n");
    this->Renderer = vtkRenderer::New ();
    renderer = this->Renderer;
    this->RenderWindow->AddRenderer (renderer);
    }
  else
    {
    this->Renderer = renderer;
    this->Renderer->Register( this );
    }

  if (this->ImportBegin ())
    {
    this->ReadData();
    this->ImportEnd();
    }
}

void vtkImporter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Render Window: ";
  if ( this->RenderWindow )
    {
    os << this->RenderWindow << "\n";
    }
  else
    {
    os << "(none)\n";
    }

  os << indent << "Renderer: ";
  if ( this->Renderer )
    {
    os << this->Renderer << "\n";
    }
  else
    {
    os << "(none)\n";
    }

}

<|endoftext|>


<commit_before>#include <iostream>
#include "Vector.h"

int main()
{

	Vector c(3);			//    3
	c[0] = 1;				//
	std::cout << c[1]		//
		<<std::endl;
	Vector p(c);			//
	p[2] = 3;
	std::cout << "c ";
	c.print();
	std::cout << "p ";
	p.print();
	Vector z(3);
	std::cout << "z ";
	z.print();
	z += c;
	std::cout << "z+=c ";
	z.print();
	std::cout << "p+z ";
	(p+z).print();
	std::cout << "p-c ";
	(p - c).print();
	z -= c;
	std::cout << "z-=c";
	z.print();
	Vector x = p +c +c;
	std::cout << "x ";
	x.print();
	std::cout << "x*=2 ";
	x *= 2;
	x.print();
	std::cout << "x*5 ";
	(x * 5).print();
	std::cout << "z/5 ";
	(z / 5).print();
	std::cout << "p%c=";
	std::cout << p%c<<std::endl;

	Vector m(4);
	for (int i = 0; i < 4; i++)
		m[i] = i;
	std::cout << "m ";
	m.print();
	Vector b(2);
	for (int i = 0; i < 2; i++)
		b[i] = i;
	std::cout << "b ";
	b.print();
	//
	std::cout << "m+b ";
	(m+b).print();
	std::cout << "b+m ";
	(b + m).print();
	b += m;
	m += b;
	std::cout << "b+=m ";
	b.print();
	std::cout << "m+=b ";
	m.print();
	Vector w(4);
	w[1] = 3;
	std::cout << "w  ";
	w.print();
	std::cout << "c-=w ";
	c -= w;
	c.print();
	std::cout << "c-m ";
	(c - w).print();
	std::cout << "m%c=";
	std::cout << m%c<<std::endl;

	return 0;
}<commit_msg>Update hw3_part_one.cpp<commit_after>#include <iostream>
#include "Vector.h"

int main()
{

	Vector c(3);
	c[0] = 1;
	std::cout << c[1]
		<<std::endl;
	Vector p(c);
	p[2] = 3;
	std::cout << "c ";
	c.print();
	std::cout << "p ";
	p.print();
	Vector z(3);
	std::cout << "z ";
	z.print();
	z += c;
	std::cout << "z+=c ";
	z.print();
	std::cout << "p+z ";
	(p+z).print();
	std::cout << "p-c ";
	(p - c).print();
	z -= c;
	std::cout << "z-=c";
	z.print();
	Vector x = p +c +c;
	std::cout << "x ";
	x.print();
	std::cout << "x*=2 ";
	x *= 2;
	x.print();
	std::cout << "x*5 ";
	(x * 5).print();
	std::cout << "z/5 ";
	(z / 5).print();
	std::cout << "p%c=";
	std::cout << p%c<<std::endl;

	Vector m(4);
	for (int i = 0; i < 4; i++)
		m[i] = i;
	std::cout << "m ";
	m.print();
	Vector b(2);
	for (int i = 0; i < 2; i++)
		b[i] = i;
	std::cout << "b ";
	b.print();

	std::cout << "m+b ";
	(m+b).print();
	std::cout << "b+m ";
	(b + m).print();
	b += m;
	m += b;
	std::cout << "b+=m ";
	b.print();
	std::cout << "m+=b ";
	m.print();
	Vector w(4);
	w[1] = 3;
	std::cout << "w  ";
	w.print();
	std::cout << "c-=w ";
	c -= w;
	c.print();
	std::cout << "c-m ";
	(c - w).print();
	std::cout << "m%c=";
	std::cout << m%c<<std::endl;

	return 0;
}
<|endoftext|>


<commit_before>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2014-03-31 Chongyu Zhu <i@lembacon.com>
//
#include <stdint.h> // for uint32_t
#include <utf8.h>
#include <rime/candidate.h>
#include <rime/common.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/dict/vocabulary.h>
#include <rime/gear/charset_filter.h>

namespace rime {

bool is_extended_cjk(uint32_t ch)
{
  if ((ch >= 0x3400 && ch <= 0x4DBF) ||    // CJK Unified Ideographs Extension A
      (ch >= 0x20000 && ch <= 0x2A6DF) ||  // CJK Unified Ideographs Extension B
      (ch >= 0x2A700 && ch <= 0x2B73F) ||  // CJK Unified Ideographs Extension C
      (ch >= 0x2B740 && ch <= 0x2B81F) ||  // CJK Unified Ideographs Extension D
      (ch >= 0x2B820 && ch <= 0x2CEAF) ||  // CJK Unified Ideographs Extension E
      (ch >= 0x2CEB0 && ch <= 0x2EBEF) ||  // CJK Unified Ideographs Extension F
      (ch >= 0x2F800 && ch <= 0x2FA1F))    // CJK Compatibility Ideographs Supplement
    return true;

  return false;
}

bool contains_extended_cjk(const string& text)
{
  const char *p = text.c_str();
  uint32_t ch;

  while ((ch = utf8::unchecked::next(p)) != 0) {
    if (is_extended_cjk(ch)) {
      return true;
    }
  }

  return false;
}

// CharsetFilterTranslation

CharsetFilterTranslation::CharsetFilterTranslation(an<Translation> translation)
    : translation_(translation) {
  LocateNextCandidate();
}

bool CharsetFilterTranslation::Next() {
  if (exhausted())
    return false;
  if (!translation_->Next()) {
    set_exhausted(true);
    return false;
  }
  return LocateNextCandidate();
}

an<Candidate> CharsetFilterTranslation::Peek() {
  return translation_->Peek();
}

bool CharsetFilterTranslation::FilterCandidate(an<Candidate> cand) {
  return CharsetFilter::FilterText(cand->text());
}

bool CharsetFilterTranslation::LocateNextCandidate() {
  while (!translation_->exhausted()) {
    auto cand = translation_->Peek();
    if (cand && FilterCandidate(cand))
      return true;
    translation_->Next();
  }
  set_exhausted(true);
  return false;
}

// CharsetFilter

bool CharsetFilter::FilterText(const string& text) {
  return !contains_extended_cjk(text);
}

bool CharsetFilter::FilterDictEntry(an<DictEntry> entry) {
  return entry && FilterText(entry->text);
}

CharsetFilter::CharsetFilter(const Ticket& ticket)
    : Filter(ticket), TagMatching(ticket) {
}

an<Translation> CharsetFilter::Apply(
    an<Translation> translation, CandidateList* candidates) {
  if (name_space_.empty() &&
      !engine_->context()->get_option("extended_charset")) {
    return New<CharsetFilterTranslation>(translation);
  }
  if (!name_space_.empty()) {
    LOG(ERROR) << "charset parameter is unsupported by basic charset_filter";
  }
  return translation;
}

}  // namespace rime
<commit_msg>feat(charset_filter): support CJK Unified Ideographs Extension G (#393)<commit_after>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2014-03-31 Chongyu Zhu <i@lembacon.com>
//
#include <stdint.h> // for uint32_t
#include <utf8.h>
#include <rime/candidate.h>
#include <rime/common.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/dict/vocabulary.h>
#include <rime/gear/charset_filter.h>

namespace rime {

bool is_extended_cjk(uint32_t ch)
{
  if ((ch >= 0x3400 && ch <= 0x4DBF) ||    // CJK Unified Ideographs Extension A
      (ch >= 0x20000 && ch <= 0x2A6DF) ||  // CJK Unified Ideographs Extension B
      (ch >= 0x2A700 && ch <= 0x2B73F) ||  // CJK Unified Ideographs Extension C
      (ch >= 0x2B740 && ch <= 0x2B81F) ||  // CJK Unified Ideographs Extension D
      (ch >= 0x2B820 && ch <= 0x2CEAF) ||  // CJK Unified Ideographs Extension E
      (ch >= 0x2CEB0 && ch <= 0x2EBEF) ||  // CJK Unified Ideographs Extension F
      (ch >= 0x30000 && ch <= 0x3134F) ||  // CJK Unified Ideographs Extension G
      (ch >= 0x2F800 && ch <= 0x2FA1F))    // CJK Compatibility Ideographs Supplement
    return true;

  return false;
}

bool contains_extended_cjk(const string& text)
{
  const char *p = text.c_str();
  uint32_t ch;

  while ((ch = utf8::unchecked::next(p)) != 0) {
    if (is_extended_cjk(ch)) {
      return true;
    }
  }

  return false;
}

// CharsetFilterTranslation

CharsetFilterTranslation::CharsetFilterTranslation(an<Translation> translation)
    : translation_(translation) {
  LocateNextCandidate();
}

bool CharsetFilterTranslation::Next() {
  if (exhausted())
    return false;
  if (!translation_->Next()) {
    set_exhausted(true);
    return false;
  }
  return LocateNextCandidate();
}

an<Candidate> CharsetFilterTranslation::Peek() {
  return translation_->Peek();
}

bool CharsetFilterTranslation::FilterCandidate(an<Candidate> cand) {
  return CharsetFilter::FilterText(cand->text());
}

bool CharsetFilterTranslation::LocateNextCandidate() {
  while (!translation_->exhausted()) {
    auto cand = translation_->Peek();
    if (cand && FilterCandidate(cand))
      return true;
    translation_->Next();
  }
  set_exhausted(true);
  return false;
}

// CharsetFilter

bool CharsetFilter::FilterText(const string& text) {
  return !contains_extended_cjk(text);
}

bool CharsetFilter::FilterDictEntry(an<DictEntry> entry) {
  return entry && FilterText(entry->text);
}

CharsetFilter::CharsetFilter(const Ticket& ticket)
    : Filter(ticket), TagMatching(ticket) {
}

an<Translation> CharsetFilter::Apply(
    an<Translation> translation, CandidateList* candidates) {
  if (name_space_.empty() &&
      !engine_->context()->get_option("extended_charset")) {
    return New<CharsetFilterTranslation>(translation);
  }
  if (!name_space_.empty()) {
    LOG(ERROR) << "charset parameter is unsupported by basic charset_filter";
  }
  return translation;
}

}  // namespace rime
<|endoftext|>