<commit_before>#include "querymanager.h"
#include <cassert>
#include <iostream>
#include <QDebug>

using namespace std;

QueryManager::QueryManager(){
    //create KDTrip
    std::string fname = string(DATA_DIR)+"sample_merged_1.kdtrip";
    fname = "/home/nivan/src/TaxiVis/src/preprocess/build/myTest.kdtrip";
    kdtrip = new KdTrip(fname);
}

QueryManager::~QueryManager(){
    if(kdtrip != NULL)
        delete kdtrip;
}

void QueryManager::queryData(SelectionGraph *queryGraph, QDateTime startDateTime,
                            QDateTime endDateTime, KdTrip::TripSet &resultSet) {
    //initial setup
    assert(queryGraph != NULL);
    resultSet.clear();

    //
    QDate startDate = startDateTime.date();
    QTime startTime = startDateTime.time();
    QDate endDate   = endDateTime.date();
    QTime endTime   = endDateTime.time();

    {//if graph is empry
        if(queryGraph->isEmpty()){
            //
            KdTrip::Query query;

            //
            query.setPickupTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                        query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));
            query.setDropoffTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                         query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));

            KdTrip::QueryResult result = kdtrip->execute(query);
            KdTrip::QueryResult::iterator it;
            for (it=result.begin(); it<result.end(); ++it) {
                resultSet.insert(it.trip());
//                qDebug() << "Trip: ";
//                qDebug() << "    fare: " << it.trip()->fare_amount;
//                qDebug() << "    distance: " << it.trip()->distance;
//                qDebug() << "    field1: " << it.trip()->field1;
//                qDebug() << "    id: " << it.trip()->id_taxi;
//                qDebug() << "    tip: " << it.trip()->tip_amount;
//                qDebug() << "    payment type: " << it.trip()->payment_type;
//                qDebug() << "    passengers: " << (uint)(it.trip()->passengers);
            }

            return;
        }

    }

    //
    set<Group> groups;
    map<Group, vector<SelectionGraphNode*> > mapGroupToNodes;
    map<Group, vector<SelectionGraphEdge*> > mapGroupToEdges;
    queryGraph->groupNodesAndEdgeByColor(groups,mapGroupToNodes, mapGroupToEdges);

    //edge queries
    SelectionGraph::EdgeIterator it;
    SelectionGraph::EdgeIterator edgesBegin;
    SelectionGraph::EdgeIterator edgesEnd;
    queryGraph->getEdgeIterator(edgesBegin,edgesEnd);
    set<int> alreadyProcessedNodes;
    //int countEdgeQuery = 1;
    for(it = edgesBegin ; it != edgesEnd ; ++it){
        //cout << "Executing edge query " << countEdgeQuery++ << endl;
        SelectionGraphEdge* edge = it->second;
        SelectionGraphNode* tail = edge->getTail();
        SelectionGraphNode* head = edge->getHead();

        //
        KdTrip::Query query;
        QRectF originRect = tail->getSelection()->boundingBox();
        query.setPickupArea(originRect.x(),originRect.y(),originRect.x() + originRect.width(),originRect.y() + originRect.height());
        QRectF destinationRect = head->getSelection()->boundingBox();
        query.setDropoffArea(destinationRect.x(),destinationRect.y(),destinationRect.x() + destinationRect.width(),destinationRect.y() + destinationRect.height());

//        qDebug() << "   Origin Rect " << originRect;
//        qDebug() << "   Destination Rect " << destinationRect;

        //
        query.setPickupTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                    query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));
        query.setDropoffTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                     query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));

        KdTrip::QueryResult result = kdtrip->execute(query);
        //cout << "   Query Result " << result.size() << endl;
        //resultSet.insert(result.begin(),result.end());
        KdTrip::QueryResult::iterator it;
        for (it=result.begin(); it<result.end(); ++it) {
            //
            if(tail->getSelection()->contains(QPointF(it->pickup_lat,it->pickup_long)) &&
                    head->getSelection()->contains(QPointF(it->dropoff_lat,it->dropoff_long)))
                resultSet.insert(it.trip());
        }

        //
        alreadyProcessedNodes.insert(tail->getId());
        alreadyProcessedNodes.insert(head->getId());
    }

    //cout << "   After edge queries " << resultSet.size() << endl;

    // node queries
    SelectionGraph::NodeIterator nodesit;
    SelectionGraph::NodeIterator nodesBegin;
    SelectionGraph::NodeIterator nodesEnd;
    queryGraph->getNodeIterator(nodesBegin,nodesEnd);
    //int countNodeQuery = 1;
    for(nodesit = nodesBegin ; nodesit != nodesEnd ; ++nodesit){
        //cout << "Executing Node Query " << countNodeQuery++ << endl;
        SelectionGraphNode* node = nodesit->second;
        if(alreadyProcessedNodes.count(node->getId()) > 0)
            continue;

        //
        KdTrip::Query query;
        KdTrip::Query extraQuery;

        //time constraints
        query.setPickupTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                    query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));
        query.setDropoffTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                     query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));

        extraQuery.setPickupTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                         query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));
        extraQuery.setDropoffTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                          query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));

        //
        if(node->getSelection()->getType() == Selection::START){
            QRectF originRect = node->getSelection()->boundingBox();
            query.setPickupArea(originRect.x(),originRect.y(),originRect.x() + originRect.width(),originRect.y() + originRect.height());
        }
        else if(node->getSelection()->getType() == Selection::END){
            QRectF destinationRect = node->getSelection()->boundingBox();
            query.setDropoffArea(destinationRect.x(),destinationRect.y(),destinationRect.x() + destinationRect.width(),destinationRect.y() + destinationRect.height());
        }
        else if(node->getSelection()->getType() == Selection::START_AND_END){
            //
            QRectF originRect = node->getSelection()->boundingBox();
            query.setPickupArea(originRect.x(),originRect.y(),originRect.x() + originRect.width(),originRect.y() + originRect.height());

            //
            QRectF destinationRect = node->getSelection()->boundingBox();
            extraQuery.setDropoffArea(destinationRect.x(),destinationRect.y(),destinationRect.x() + destinationRect.width(),destinationRect.y() + destinationRect.height());
        }

        KdTrip::QueryResult result = kdtrip->execute(query);
        KdTrip::QueryResult::iterator it;
        qDebug() << "Result " << result.size() ;
        for (it=result.begin(); it<result.end(); ++it) {
            const KdTrip::Trip *trip = it.trip();

            bool startContains = node->getSelection()->contains(QPointF(trip->pickup_lat, trip->pickup_long));
            bool endContains   = node->getSelection()->contains(QPointF(trip->dropoff_lat, trip->dropoff_long));

            if(node->getSelection()->getType() == Selection::START && !startContains)
                continue;
            else if(node->getSelection()->getType() == Selection::END && !endContains)
                continue;
            else if(node->getSelection()->getType() == Selection::START_AND_END && !startContains && !endContains)
                continue;

            resultSet.insert(trip);
        }

        if(node->getSelection()->getType() == Selection::START_AND_END){
            KdTrip::QueryResult result = kdtrip->execute(extraQuery);
            KdTrip::QueryResult::iterator it;
            for (it=result.begin(); it<result.end(); ++it) {
                const KdTrip::Trip *trip = it.trip();

                bool startContains = node->getSelection()->contains(QPointF(trip->pickup_lat, trip->pickup_long));
                bool endContains   = node->getSelection()->contains(QPointF(trip->dropoff_lat, trip->dropoff_long));

                if(node->getSelection()->getType() == Selection::START && !startContains)
                    continue;
                else if(node->getSelection()->getType() == Selection::END && !endContains)
                    continue;
                else if(node->getSelection()->getType() == Selection::START_AND_END && !startContains && !endContains)
                    continue;

                resultSet.insert(trip);
            }
        }
    }
    //cout << "After node queries " << resultSet.size() << endl;
}
<commit_msg>make it work out of the box with sample file provided<commit_after>#include "querymanager.h"
#include <cassert>
#include <iostream>
#include <QDebug>

using namespace std;

QueryManager::QueryManager(){
    //create KDTrip
    std::string fname = string(DATA_DIR)+"sample_merged_1.kdtrip";
    kdtrip = new KdTrip(fname);
}

QueryManager::~QueryManager(){
    if(kdtrip != NULL)
        delete kdtrip;
}

void QueryManager::queryData(SelectionGraph *queryGraph, QDateTime startDateTime,
                            QDateTime endDateTime, KdTrip::TripSet &resultSet) {
    //initial setup
    assert(queryGraph != NULL);
    resultSet.clear();

    //
    QDate startDate = startDateTime.date();
    QTime startTime = startDateTime.time();
    QDate endDate   = endDateTime.date();
    QTime endTime   = endDateTime.time();

    {//if graph is empry
        if(queryGraph->isEmpty()){
            //
            KdTrip::Query query;

            //
            query.setPickupTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                        query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));
            query.setDropoffTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                         query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));

            KdTrip::QueryResult result = kdtrip->execute(query);
            KdTrip::QueryResult::iterator it;
            for (it=result.begin(); it<result.end(); ++it) {
                resultSet.insert(it.trip());
//                qDebug() << "Trip: ";
//                qDebug() << "    fare: " << it.trip()->fare_amount;
//                qDebug() << "    distance: " << it.trip()->distance;
//                qDebug() << "    field1: " << it.trip()->field1;
//                qDebug() << "    id: " << it.trip()->id_taxi;
//                qDebug() << "    tip: " << it.trip()->tip_amount;
//                qDebug() << "    payment type: " << it.trip()->payment_type;
//                qDebug() << "    passengers: " << (uint)(it.trip()->passengers);
            }

            return;
        }

    }

    //
    set<Group> groups;
    map<Group, vector<SelectionGraphNode*> > mapGroupToNodes;
    map<Group, vector<SelectionGraphEdge*> > mapGroupToEdges;
    queryGraph->groupNodesAndEdgeByColor(groups,mapGroupToNodes, mapGroupToEdges);

    //edge queries
    SelectionGraph::EdgeIterator it;
    SelectionGraph::EdgeIterator edgesBegin;
    SelectionGraph::EdgeIterator edgesEnd;
    queryGraph->getEdgeIterator(edgesBegin,edgesEnd);
    set<int> alreadyProcessedNodes;
    //int countEdgeQuery = 1;
    for(it = edgesBegin ; it != edgesEnd ; ++it){
        //cout << "Executing edge query " << countEdgeQuery++ << endl;
        SelectionGraphEdge* edge = it->second;
        SelectionGraphNode* tail = edge->getTail();
        SelectionGraphNode* head = edge->getHead();

        //
        KdTrip::Query query;
        QRectF originRect = tail->getSelection()->boundingBox();
        query.setPickupArea(originRect.x(),originRect.y(),originRect.x() + originRect.width(),originRect.y() + originRect.height());
        QRectF destinationRect = head->getSelection()->boundingBox();
        query.setDropoffArea(destinationRect.x(),destinationRect.y(),destinationRect.x() + destinationRect.width(),destinationRect.y() + destinationRect.height());

//        qDebug() << "   Origin Rect " << originRect;
//        qDebug() << "   Destination Rect " << destinationRect;

        //
        query.setPickupTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                    query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));
        query.setDropoffTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                     query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));

        KdTrip::QueryResult result = kdtrip->execute(query);
        //cout << "   Query Result " << result.size() << endl;
        //resultSet.insert(result.begin(),result.end());
        KdTrip::QueryResult::iterator it;
        for (it=result.begin(); it<result.end(); ++it) {
            //
            if(tail->getSelection()->contains(QPointF(it->pickup_lat,it->pickup_long)) &&
                    head->getSelection()->contains(QPointF(it->dropoff_lat,it->dropoff_long)))
                resultSet.insert(it.trip());
        }

        //
        alreadyProcessedNodes.insert(tail->getId());
        alreadyProcessedNodes.insert(head->getId());
    }

    //cout << "   After edge queries " << resultSet.size() << endl;

    // node queries
    SelectionGraph::NodeIterator nodesit;
    SelectionGraph::NodeIterator nodesBegin;
    SelectionGraph::NodeIterator nodesEnd;
    queryGraph->getNodeIterator(nodesBegin,nodesEnd);
    //int countNodeQuery = 1;
    for(nodesit = nodesBegin ; nodesit != nodesEnd ; ++nodesit){
        //cout << "Executing Node Query " << countNodeQuery++ << endl;
        SelectionGraphNode* node = nodesit->second;
        if(alreadyProcessedNodes.count(node->getId()) > 0)
            continue;

        //
        KdTrip::Query query;
        KdTrip::Query extraQuery;

        //time constraints
        query.setPickupTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                    query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));
        query.setDropoffTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                     query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));

        extraQuery.setPickupTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                         query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));
        extraQuery.setDropoffTimeInterval(query.createTime(startDate.year(),startDate.month(),startDate.day(),startTime.hour(),startTime.minute(),startTime.second()),
                                          query.createTime(endDate.year(),endDate.month(),endDate.day(),endTime.hour(),endTime.minute(),endTime.second()));

        //
        if(node->getSelection()->getType() == Selection::START){
            QRectF originRect = node->getSelection()->boundingBox();
            query.setPickupArea(originRect.x(),originRect.y(),originRect.x() + originRect.width(),originRect.y() + originRect.height());
        }
        else if(node->getSelection()->getType() == Selection::END){
            QRectF destinationRect = node->getSelection()->boundingBox();
            query.setDropoffArea(destinationRect.x(),destinationRect.y(),destinationRect.x() + destinationRect.width(),destinationRect.y() + destinationRect.height());
        }
        else if(node->getSelection()->getType() == Selection::START_AND_END){
            //
            QRectF originRect = node->getSelection()->boundingBox();
            query.setPickupArea(originRect.x(),originRect.y(),originRect.x() + originRect.width(),originRect.y() + originRect.height());

            //
            QRectF destinationRect = node->getSelection()->boundingBox();
            extraQuery.setDropoffArea(destinationRect.x(),destinationRect.y(),destinationRect.x() + destinationRect.width(),destinationRect.y() + destinationRect.height());
        }

        KdTrip::QueryResult result = kdtrip->execute(query);
        KdTrip::QueryResult::iterator it;
        qDebug() << "Result " << result.size() ;
        for (it=result.begin(); it<result.end(); ++it) {
            const KdTrip::Trip *trip = it.trip();

            bool startContains = node->getSelection()->contains(QPointF(trip->pickup_lat, trip->pickup_long));
            bool endContains   = node->getSelection()->contains(QPointF(trip->dropoff_lat, trip->dropoff_long));

            if(node->getSelection()->getType() == Selection::START && !startContains)
                continue;
            else if(node->getSelection()->getType() == Selection::END && !endContains)
                continue;
            else if(node->getSelection()->getType() == Selection::START_AND_END && !startContains && !endContains)
                continue;

            resultSet.insert(trip);
        }

        if(node->getSelection()->getType() == Selection::START_AND_END){
            KdTrip::QueryResult result = kdtrip->execute(extraQuery);
            KdTrip::QueryResult::iterator it;
            for (it=result.begin(); it<result.end(); ++it) {
                const KdTrip::Trip *trip = it.trip();

                bool startContains = node->getSelection()->contains(QPointF(trip->pickup_lat, trip->pickup_long));
                bool endContains   = node->getSelection()->contains(QPointF(trip->dropoff_lat, trip->dropoff_long));

                if(node->getSelection()->getType() == Selection::START && !startContains)
                    continue;
                else if(node->getSelection()->getType() == Selection::END && !endContains)
                    continue;
                else if(node->getSelection()->getType() == Selection::START_AND_END && !startContains && !endContains)
                    continue;

                resultSet.insert(trip);
            }
        }
    }
    //cout << "After node queries " << resultSet.size() << endl;
}
<|endoftext|>


<commit_before><commit_msg>Fixed warning about conversion between signed/unsigned variables<commit_after><|endoftext|>


<commit_before>/*
 * ScriptCheck.cpp
 *
 *  Created on: Sep 2, 2014
 *      Author: ranger.shi
 */
#include "VmScriptRun.h"
#include "tx.h"
#include "util.h"
#include <boost/foreach.hpp>
CVmScriptRun::CVmScriptRun() {
	RawAccont.clear();
	NewAccont.clear();
	height = 0;
	m_ScriptDBTip = NULL;
	m_view = NULL;
	m_dblog = std::make_shared<std::vector<CScriptDBOperLog> >();
}
vector<shared_ptr<CAccount> > &CVmScriptRun::GetRawAccont() {
	return RawAccont;
}
vector<shared_ptr<CAccount> > &CVmScriptRun::GetNewAccont() {
	return NewAccont;
}

bool CVmScriptRun::intial(shared_ptr<CBaseTransaction> & Tx, CAccountViewCache& view, int nheight) {

	m_output.clear();
	listTx = Tx;
	height = nheight;
	m_view = &view;
	vector<unsigned char> vScript;

	if (Tx.get()->nTxType != CONTRACT_TX) {
		LogPrint("ERROR", "%s\r\n", "err param");
		assert(0);
		return false;
	}

	CTransaction* secure = static_cast<CTransaction*>(Tx.get());
	if (!m_ScriptDBTip->GetScript(boost::get<CRegID>(secure->desUserId), vScript)) {
		LogPrint("ERROR", "Script is not Registed %s\r\n", boost::get<CRegID>(secure->desUserId).ToString());
		return false;
	}

	CDataStream stream(vScript, SER_DISK, CLIENT_VERSION);
	try {
		stream >> vmScript;
	} catch (exception& e) {
		LogPrint("ERROR", "%s\r\n", "CVmScriptRun::intial() Unserialize to vmScript error");
		throw runtime_error("CVmScriptRun::intial() Unserialize to vmScript error:" + string(e.what()));
	}

	if (vmScript.IsValid() == false){
		LogPrint("ERROR", "%s\r\n", "CVmScriptRun::intial() vmScript.IsValid error");
		return false;
	}

	pMcu = make_shared<CVir8051>(vmScript.Rom, secure->vContract);
	return true;
}

CVmScriptRun::~CVmScriptRun() {

}
tuple<bool, uint64_t, string> CVmScriptRun::run(shared_ptr<CBaseTransaction>& Tx, CAccountViewCache& view, CScriptDBViewCache& VmDB, int nheight,
		uint64_t nBurnFactor, uint64_t &uRunStep) {

	if(nBurnFactor == 0)
	{
		assert(0);
		return std::make_tuple (false, 0, string("VmScript nBurnFactor == 0 \n"));
	}
	m_ScriptDBTip = &VmDB;

	CTransaction* tx = static_cast<CTransaction*>(Tx.get());
	uint64_t maxstep = tx->llFees;///nBurnFactor;
	tuple<bool, uint64_t, string> mytuple;
	if (!intial(Tx, view, nheight)) {
		return std::make_tuple (false, 0, string("VmScript inital Failed\n"));

	}

	int64_t step = pMcu.get()->run(maxstep,this);
	if (0 == step) {
		return std::make_tuple(false, 0, string("VmScript run Failed\n"));
	} else if (-1 == step) {
		return std::make_tuple(false, 0, string("execure tx contranct run step exceed the max step limit\n"));
	}

	uRunStep = step;
	LogPrint("CONTRACT_TX", "tx:%s,step:%ld\n", tx->ToString(view), step);
	shared_ptr<vector<unsigned char>> retData = pMcu.get()->GetRetData();
	CDataStream Contractstream(*retData.get(), SER_DISK, CLIENT_VERSION);
	vector<CVmOperate> retvmcode;
	Contractstream >> retvmcode;

	if (!CheckOperate(m_output)) {
		return std::make_tuple (false, 0, string("VmScript CheckOperate Failed \n"));

	}
	if (!OpeatorAccount(m_output, view)) {
		return std::make_tuple (false, 0, string("VmScript OpeatorAccount Failed\n"));
	}
	uint64_t spend = step*nBurnFactor;
	return std::make_tuple (true, spend, string("VmScript Sucess\n"));

}

shared_ptr<CAccount> CVmScriptRun::GetNewAccount(shared_ptr<CAccount>& vOldAccount) {
	if (NewAccont.size() == 0)
		return NULL;
	vector<shared_ptr<CAccount> >::iterator Iter;
	for (Iter = NewAccont.begin(); Iter != NewAccont.end(); Iter++) {
		shared_ptr<CAccount> temp = *Iter;
		if (temp.get()->keyID == vOldAccount.get()->keyID) {
			NewAccont.erase(Iter);
			return temp;
		}
	}
	return NULL;
}
shared_ptr<CAccount> CVmScriptRun::GetAccount(shared_ptr<CAccount>& Account) {
	if (RawAccont.size() == 0)
		return NULL;
	vector<shared_ptr<CAccount> >::iterator Iter;
	for (Iter = RawAccont.begin(); Iter != RawAccont.end(); Iter++) {
		shared_ptr<CAccount> temp = *Iter;
		if (Account.get()->keyID == temp.get()->keyID) {
			return temp;
		}
	}
	return NULL;
}
vector_unsigned_char CVmScriptRun::GetAccountID(CVmOperate value) {
	vector_unsigned_char accountid;
	//if (value.type == ACCOUNTID) {
	//	accountid.assign(value.accountid, value.accountid + 6);
	//} else if (value.type == KEYID) {
		//accountid.assign(value.accountid, value.accountid + 20);
	//}
	return accountid;
}
bool CVmScriptRun::CheckOperate(const vector<CVmOperate> &listoperate) const {
	// judge contract rulue
	uint64_t addmoey = 0, miusmoney = 0;
	uint64_t temp = 0;
	for (auto& it : listoperate) {

		if (it.opeatortype == ADD_FREE ) {
			memcpy(&temp,it.money,sizeof(it.money));
			addmoey += temp;
		}

		if (it.opeatortype == MINUS_FREE) {

			/// ӶǮʱ߶ȱڵǰtip߶
			if(it.outheight < height)
			{
				return false;
			}
			vector<unsigned char > accountid(it.accountid,it.accountid+sizeof(it.accountid));
			CRegID regId(accountid);
			CTransaction* secure = static_cast<CTransaction*>(listTx.get());
			/// current tx's script cant't mius other script's regid
			if(m_ScriptDBTip->HaveScript(regId) && regId != boost::get<CRegID>(secure->desUserId))
			{
				return false;
			}
			memcpy(&temp,it.money,sizeof(it.money));
			miusmoney += temp;
		}
		vector<unsigned char> accountid(it.accountid, it.accountid + sizeof(it.accountid));
		CRegID regId(accountid);
		if(regId.IsEmpty() || regId.getKeyID( *m_view) == uint160(0))
			return false;
		/// if account script id ,the it.opeatortype must be ADD_FREE or MINUS_FREE
		if (m_ScriptDBTip->HaveScript(regId)|| it.opeatortype != MINUS_FREE) {
			return false;
		}
	}
	if (addmoey != miusmoney)
	{
		return false;
	}
	return true;
}

shared_ptr<vector<CVmOperate>> CVmScriptRun::GetOperate() const {
	auto tem = make_shared<vector<CVmOperate>>();
	shared_ptr<vector<unsigned char>> retData = pMcu.get()->GetRetData();
	CDataStream Contractstream(*retData.get(), SER_DISK, CLIENT_VERSION);
	vector<CVmOperate> retvmcode;
	;
	Contractstream >> retvmcode;
	return tem;
}

bool CVmScriptRun::OpeatorAccount(const vector<CVmOperate>& listoperate, CAccountViewCache& view) {

	NewAccont.clear();
	for (auto& it : listoperate) {
		CTransaction* tx = static_cast<CTransaction*>(listTx.get());
		CFund fund;
		memcpy(&fund.value,it.money,sizeof(it.money));
		fund.nHeight = it.outheight;
		fund.appId = boost::get<CRegID>(tx->desUserId).GetVec6();

		auto tem = make_shared<CAccount>();
//		vector_unsigned_char accountid = GetAccountID(it);
//		if (accountid.size() == 0) {
//			return false;
//		}
		vector_unsigned_char accountid(it.accountid,it.accountid+sizeof(it.accountid));
		CRegID regid(accountid);
		CUserID userid(regid);
		view.GetAccount(userid, *tem.get());
		shared_ptr<CAccount> vmAccount = GetAccount(tem);
		if (vmAccount.get() == NULL) {
			RawAccont.push_back(tem);
			vmAccount = tem;
		}
		shared_ptr<CAccount> vnewAccount = GetNewAccount(tem);
		//// ˺ѾڣҪϲ
		if (vnewAccount.get() != NULL) {
			vmAccount = vnewAccount;
		}else{
			vmAccount.get()->CompactAccount(height);
		}
		if ((OperType) it.opeatortype == ADD_FREE) {
			fund.nFundType = FREEDOM_FUND;
		}

//		LogPrint("vm", "account id:%s\r\n", HexStr(accountid).c_str());
//		LogPrint("vm", "befer account:%s\r\n", vmAccount.get()->ToString().c_str());
//		LogPrint("vm", "fund:%s\r\n", fund.ToString().c_str());
		bool ret = false;
		vector<CScriptDBOperLog> vAuthorLog;
		//todolist
//		if(IsSignatureAccount(vmAccount.get()->regID) || vmAccount.get()->regID == boost::get<CRegID>(tx->appRegId))
		{
			ret = vmAccount.get()->OperateAccount((OperType)it.opeatortype, fund);
		}
//		else{
//			ret = vmAccount.get()->OperateAccount((OperType)it.opeatortype, fund, *m_ScriptDBTip, vAuthorLog,  height, &GetScriptRegID().GetVec6(), true);
//		}

//		LogPrint("vm", "after account:%s\r\n", vmAccount.get()->ToString().c_str());
		if (!ret) {
			return false;
		}
		NewAccont.push_back(vmAccount);
		m_dblog->insert(m_dblog->end(), vAuthorLog.begin(), vAuthorLog.end());

	}
	return true;
}

const CRegID& CVmScriptRun::GetScriptRegID()
{
	CTransaction* tx = static_cast<CTransaction*>(listTx.get());
	return boost::get<CRegID>(tx->desUserId);
}

const CRegID &CVmScriptRun::GetTxAccount() {
	CTransaction* tx = static_cast<CTransaction*>(listTx.get());
	return boost::get<CRegID>(tx->srcRegId);
}
uint64_t CVmScriptRun::GetValue() const{
	CTransaction* tx = static_cast<CTransaction*>(listTx.get());
		return tx->llValues;
}
const vector<unsigned char>& CVmScriptRun::GetTxContact()
{
	CTransaction* tx = static_cast<CTransaction*>(listTx.get());
		return tx->vContract;
}
int CVmScriptRun::GetComfirHeight()
{
	return height;
}
uint256 CVmScriptRun::GetCurTxHash()
{
	return listTx.get()->GetHash();
}
CScriptDBViewCache* CVmScriptRun::GetScriptDB()
{
	return m_ScriptDBTip;
}
CAccountViewCache * CVmScriptRun::GetCatchView()
{
	return m_view;
}
void CVmScriptRun::InsertOutputData(vector<CVmOperate> source)
{
	m_output.insert(m_output.end(),source.begin(),source.end());
}
shared_ptr<vector<CScriptDBOperLog> > CVmScriptRun::GetDbLog()
{
	return m_dblog;
}
<commit_msg>modify VmScriptRun.cpp<commit_after>/*
 * ScriptCheck.cpp
 *
 *  Created on: Sep 2, 2014
 *      Author: ranger.shi
 */
#include "VmScriptRun.h"
#include "tx.h"
#include "util.h"
#include <boost/foreach.hpp>
CVmScriptRun::CVmScriptRun() {
	RawAccont.clear();
	NewAccont.clear();
	height = 0;
	m_ScriptDBTip = NULL;
	m_view = NULL;
	m_dblog = std::make_shared<std::vector<CScriptDBOperLog> >();
}
vector<shared_ptr<CAccount> > &CVmScriptRun::GetRawAccont() {
	return RawAccont;
}
vector<shared_ptr<CAccount> > &CVmScriptRun::GetNewAccont() {
	return NewAccont;
}

bool CVmScriptRun::intial(shared_ptr<CBaseTransaction> & Tx, CAccountViewCache& view, int nheight) {

	m_output.clear();
	listTx = Tx;
	height = nheight;
	m_view = &view;
	vector<unsigned char> vScript;

	if (Tx.get()->nTxType != CONTRACT_TX) {
		LogPrint("ERROR", "%s\r\n", "err param");
		assert(0);
		return false;
	}

	CTransaction* secure = static_cast<CTransaction*>(Tx.get());
	if (!m_ScriptDBTip->GetScript(boost::get<CRegID>(secure->desUserId), vScript)) {
		LogPrint("ERROR", "Script is not Registed %s\r\n", boost::get<CRegID>(secure->desUserId).ToString());
		return false;
	}

	CDataStream stream(vScript, SER_DISK, CLIENT_VERSION);
	try {
		stream >> vmScript;
	} catch (exception& e) {
		LogPrint("ERROR", "%s\r\n", "CVmScriptRun::intial() Unserialize to vmScript error");
		throw runtime_error("CVmScriptRun::intial() Unserialize to vmScript error:" + string(e.what()));
	}

	if (vmScript.IsValid() == false){
		LogPrint("ERROR", "%s\r\n", "CVmScriptRun::intial() vmScript.IsValid error");
		return false;
	}

	pMcu = make_shared<CVir8051>(vmScript.Rom, secure->vContract);
	return true;
}

CVmScriptRun::~CVmScriptRun() {

}
tuple<bool, uint64_t, string> CVmScriptRun::run(shared_ptr<CBaseTransaction>& Tx, CAccountViewCache& view, CScriptDBViewCache& VmDB, int nheight,
		uint64_t nBurnFactor, uint64_t &uRunStep) {

	if(nBurnFactor == 0)
	{
		assert(0);
		return std::make_tuple (false, 0, string("VmScript nBurnFactor == 0 \n"));
	}
	m_ScriptDBTip = &VmDB;

	CTransaction* tx = static_cast<CTransaction*>(Tx.get());
	uint64_t maxstep = tx->llFees;///nBurnFactor;
	tuple<bool, uint64_t, string> mytuple;
	if (!intial(Tx, view, nheight)) {
		return std::make_tuple (false, 0, string("VmScript inital Failed\n"));

	}

	int64_t step = pMcu.get()->run(maxstep,this);
	if (0 == step) {
		return std::make_tuple(false, 0, string("VmScript run Failed\n"));
	} else if (-1 == step) {
		return std::make_tuple(false, 0, string("execure tx contranct run step exceed the max step limit\n"));
	}

	uRunStep = step;
	LogPrint("CONTRACT_TX", "tx:%s,step:%ld\n", tx->ToString(view), step);
	shared_ptr<vector<unsigned char>> retData = pMcu.get()->GetRetData();
	CDataStream Contractstream(*retData.get(), SER_DISK, CLIENT_VERSION);
	vector<CVmOperate> retvmcode;
	Contractstream >> retvmcode;

	if (!CheckOperate(m_output)) {
		return std::make_tuple (false, 0, string("VmScript CheckOperate Failed \n"));

	}
	if (!OpeatorAccount(m_output, view)) {
		return std::make_tuple (false, 0, string("VmScript OpeatorAccount Failed\n"));
	}
	uint64_t spend = step*nBurnFactor;
	return std::make_tuple (true, spend, string("VmScript Sucess\n"));

}

shared_ptr<CAccount> CVmScriptRun::GetNewAccount(shared_ptr<CAccount>& vOldAccount) {
	if (NewAccont.size() == 0)
		return NULL;
	vector<shared_ptr<CAccount> >::iterator Iter;
	for (Iter = NewAccont.begin(); Iter != NewAccont.end(); Iter++) {
		shared_ptr<CAccount> temp = *Iter;
		if (temp.get()->keyID == vOldAccount.get()->keyID) {
			NewAccont.erase(Iter);
			return temp;
		}
	}
	return NULL;
}
shared_ptr<CAccount> CVmScriptRun::GetAccount(shared_ptr<CAccount>& Account) {
	if (RawAccont.size() == 0)
		return NULL;
	vector<shared_ptr<CAccount> >::iterator Iter;
	for (Iter = RawAccont.begin(); Iter != RawAccont.end(); Iter++) {
		shared_ptr<CAccount> temp = *Iter;
		if (Account.get()->keyID == temp.get()->keyID) {
			return temp;
		}
	}
	return NULL;
}
vector_unsigned_char CVmScriptRun::GetAccountID(CVmOperate value) {
	vector_unsigned_char accountid;
	//if (value.type == ACCOUNTID) {
	//	accountid.assign(value.accountid, value.accountid + 6);
	//} else if (value.type == KEYID) {
		//accountid.assign(value.accountid, value.accountid + 20);
	//}
	return accountid;
}
bool CVmScriptRun::CheckOperate(const vector<CVmOperate> &listoperate) const {
	// judge contract rulue
	uint64_t addmoey = 0, miusmoney = 0;
	uint64_t temp = 0;
	for (auto& it : listoperate) {

		if (it.opeatortype == ADD_FREE ) {
			memcpy(&temp,it.money,sizeof(it.money));
			addmoey += temp;
		}

		if (it.opeatortype == MINUS_FREE) {

			vector<unsigned char > accountid(it.accountid,it.accountid+sizeof(it.accountid));
			CRegID regId(accountid);
			CTransaction* secure = static_cast<CTransaction*>(listTx.get());
			/// current tx's script cant't mius other script's regid
			if(m_ScriptDBTip->HaveScript(regId) && regId != boost::get<CRegID>(secure->desUserId))
			{
				return false;
			}
			memcpy(&temp,it.money,sizeof(it.money));
			miusmoney += temp;
		}
		vector<unsigned char> accountid(it.accountid, it.accountid + sizeof(it.accountid));
		CRegID regId(accountid);
		if(regId.IsEmpty() || regId.getKeyID( *m_view) == uint160(0))
			return false;
		//  app only be allowed minus self money
		if (!m_ScriptDBTip->HaveScript(regId) && it.opeatortype == MINUS_FREE) {
			return false;
		}
	}
	if (addmoey != miusmoney)
	{
		return false;
	}
	return true;
}

shared_ptr<vector<CVmOperate>> CVmScriptRun::GetOperate() const {
	auto tem = make_shared<vector<CVmOperate>>();
	shared_ptr<vector<unsigned char>> retData = pMcu.get()->GetRetData();
	CDataStream Contractstream(*retData.get(), SER_DISK, CLIENT_VERSION);
	vector<CVmOperate> retvmcode;
	;
	Contractstream >> retvmcode;
	return tem;
}

bool CVmScriptRun::OpeatorAccount(const vector<CVmOperate>& listoperate, CAccountViewCache& view) {

	NewAccont.clear();
	for (auto& it : listoperate) {
		CTransaction* tx = static_cast<CTransaction*>(listTx.get());
		CFund fund;
		memcpy(&fund.value,it.money,sizeof(it.money));
		fund.nHeight = it.outheight;
		fund.appId = boost::get<CRegID>(tx->desUserId).GetVec6();

		auto tem = make_shared<CAccount>();
//		vector_unsigned_char accountid = GetAccountID(it);
//		if (accountid.size() == 0) {
//			return false;
//		}
		vector_unsigned_char accountid(it.accountid,it.accountid+sizeof(it.accountid));
		CRegID regid(accountid);
		CUserID userid(regid);
		view.GetAccount(userid, *tem.get());
		shared_ptr<CAccount> vmAccount = GetAccount(tem);
		if (vmAccount.get() == NULL) {
			RawAccont.push_back(tem);
			vmAccount = tem;
		}
		shared_ptr<CAccount> vnewAccount = GetNewAccount(tem);
		//// ˺ѾڣҪϲ
		if (vnewAccount.get() != NULL) {
			vmAccount = vnewAccount;
		}else{
			vmAccount.get()->CompactAccount(height);
		}
		if ((OperType) it.opeatortype == ADD_FREE) {
			fund.nFundType = FREEDOM_FUND;
		}

//		LogPrint("vm", "account id:%s\r\n", HexStr(accountid).c_str());
//		LogPrint("vm", "befer account:%s\r\n", vmAccount.get()->ToString().c_str());
//		LogPrint("vm", "fund:%s\r\n", fund.ToString().c_str());
		bool ret = false;
		vector<CScriptDBOperLog> vAuthorLog;
		//todolist
//		if(IsSignatureAccount(vmAccount.get()->regID) || vmAccount.get()->regID == boost::get<CRegID>(tx->appRegId))
		{
			ret = vmAccount.get()->OperateAccount((OperType)it.opeatortype, fund);
		}
//		else{
//			ret = vmAccount.get()->OperateAccount((OperType)it.opeatortype, fund, *m_ScriptDBTip, vAuthorLog,  height, &GetScriptRegID().GetVec6(), true);
//		}

//		LogPrint("vm", "after account:%s\r\n", vmAccount.get()->ToString().c_str());
		if (!ret) {
			return false;
		}
		NewAccont.push_back(vmAccount);
		m_dblog->insert(m_dblog->end(), vAuthorLog.begin(), vAuthorLog.end());

	}
	return true;
}

const CRegID& CVmScriptRun::GetScriptRegID()
{
	CTransaction* tx = static_cast<CTransaction*>(listTx.get());
	return boost::get<CRegID>(tx->desUserId);
}

const CRegID &CVmScriptRun::GetTxAccount() {
	CTransaction* tx = static_cast<CTransaction*>(listTx.get());
	return boost::get<CRegID>(tx->srcRegId);
}
uint64_t CVmScriptRun::GetValue() const{
	CTransaction* tx = static_cast<CTransaction*>(listTx.get());
		return tx->llValues;
}
const vector<unsigned char>& CVmScriptRun::GetTxContact()
{
	CTransaction* tx = static_cast<CTransaction*>(listTx.get());
		return tx->vContract;
}
int CVmScriptRun::GetComfirHeight()
{
	return height;
}
uint256 CVmScriptRun::GetCurTxHash()
{
	return listTx.get()->GetHash();
}
CScriptDBViewCache* CVmScriptRun::GetScriptDB()
{
	return m_ScriptDBTip;
}
CAccountViewCache * CVmScriptRun::GetCatchView()
{
	return m_view;
}
void CVmScriptRun::InsertOutputData(vector<CVmOperate> source)
{
	m_output.insert(m_output.end(),source.begin(),source.end());
}
shared_ptr<vector<CScriptDBOperLog> > CVmScriptRun::GetDbLog()
{
	return m_dblog;
}
<|endoftext|>


<commit_before>
// FastNBT.cpp

// Implements the fast NBT parser and writer

#include "Globals.h"
#include "FastNBT.h"

// The number of NBT tags that are reserved when an NBT parsing is started.
// You can override this by using a cmdline define
#ifndef NBT_RESERVE_SIZE
	#define NBT_RESERVE_SIZE 200
#endif  // NBT_RESERVE_SIZE

#ifdef _MSC_VER
	// Dodge a C4127 (conditional expression is constant) for this specific macro usage
	#define RETURN_FALSE_IF_FALSE(X) do { if (!X) return false; } while ((false, false))
#else
	#define RETURN_FALSE_IF_FALSE(X) do { if (!X) return false; } while (false)
#endif

////////////////////////////////////////////////////////////////////////////////
// cParsedNBT:

#define NEEDBYTES(N) \
	if (m_Length - m_Pos < (size_t)N) \
	{ \
		return false; \
	}

cParsedNBT::cParsedNBT(const char * a_Data, size_t a_Length) :
	m_Data(a_Data),
	m_Length(a_Length),
	m_Pos(0)
{
	m_IsValid = Parse();
}

bool cParsedNBT::Parse(void)
{
	if (m_Length < 3)
	{
		// Data too short
		return false;
	}
	if (m_Data[0] != TAG_Compound)
	{
		// The top-level tag must be a Compound
		return false;
	}

	m_Tags.reserve(NBT_RESERVE_SIZE);

	m_Tags.push_back(cFastNBTTag(TAG_Compound, -1));

	m_Pos = 1;

	RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength));
	RETURN_FALSE_IF_FALSE(ReadCompound());

	return true;
}

bool cParsedNBT::ReadString(size_t & a_StringStart, size_t & a_StringLen)
{
	NEEDBYTES(2);
	a_StringStart = m_Pos + 2;
	a_StringLen = (size_t)GetBEShort(m_Data + m_Pos);
	if (a_StringLen > 0xffff)
	{
		// Suspicious string length
		return false;
	}
	m_Pos += 2 + a_StringLen;
	return true;
}

bool cParsedNBT::ReadCompound(void)
{
	ASSERT(m_Tags.size() > 0);

	// Reads the latest tag as a compound
	int ParentIdx = (int)m_Tags.size() - 1;
	int PrevSibling = -1;
	for (;;)
	{
		NEEDBYTES(1);
		eTagType TagType = (eTagType)(m_Data[m_Pos]);
		m_Pos++;
		if (TagType == TAG_End)
		{
			break;
		}
		m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling));
		if (PrevSibling >= 0)
		{
			m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
		}
		else
		{
			m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
		}
		PrevSibling = (int)m_Tags.size() - 1;
		RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength));
		RETURN_FALSE_IF_FALSE(ReadTag());
	}  // while (true)
	m_Tags[ParentIdx].m_LastChild = PrevSibling;
	return true;
}

bool cParsedNBT::ReadList(eTagType a_ChildrenType)
{
	// Reads the latest tag as a list of items of type a_ChildrenType

	// Read the count:
	NEEDBYTES(4);
	int Count = GetBEInt(m_Data + m_Pos);
	m_Pos += 4;
	if (Count < 0)
	{
		return false;
	}

	// Read items:
	int ParentIdx = (int)m_Tags.size() - 1;
	int PrevSibling = -1;
	for (int i = 0; i < Count; i++)
	{
		m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling));
		if (PrevSibling >= 0)
		{
			m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
		}
		else
		{
			m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
		}
		PrevSibling = (int)m_Tags.size() - 1;
		RETURN_FALSE_IF_FALSE(ReadTag());
	}  // for (i)
	m_Tags[ParentIdx].m_LastChild = PrevSibling;
	return true;
}

#define CASE_SIMPLE_TAG(TAGTYPE, LEN) \
	case TAG_##TAGTYPE: \
	{ \
		NEEDBYTES(LEN); \
		Tag.m_DataStart = m_Pos; \
		Tag.m_DataLength = LEN; \
		m_Pos += LEN; \
		return true; \
	}

bool cParsedNBT::ReadTag(void)
{
	cFastNBTTag & Tag = m_Tags.back();
	switch (Tag.m_Type)
	{
		CASE_SIMPLE_TAG(Byte,   1)
		CASE_SIMPLE_TAG(Short,  2)
		CASE_SIMPLE_TAG(Int,    4)
		CASE_SIMPLE_TAG(Long,   8)
		CASE_SIMPLE_TAG(Float,  4)
		CASE_SIMPLE_TAG(Double, 8)

		case TAG_String:
		{
			return ReadString(Tag.m_DataStart, Tag.m_DataLength);
		}

		case TAG_ByteArray:
		{
			NEEDBYTES(4);
			int len = GetBEInt(m_Data + m_Pos);
			m_Pos += 4;
			if (len < 0)
			{
				// Invalid length
				return false;
			}
			NEEDBYTES(len);
			Tag.m_DataLength = len;
			Tag.m_DataStart = m_Pos;
			m_Pos += len;
			return true;
		}

		case TAG_List:
		{
			NEEDBYTES(1);
			eTagType ItemType = (eTagType)m_Data[m_Pos];
			m_Pos++;
			RETURN_FALSE_IF_FALSE(ReadList(ItemType));
			return true;
		}

		case TAG_Compound:
		{
			RETURN_FALSE_IF_FALSE(ReadCompound());
			return true;
		}

		case TAG_IntArray:
		{
			NEEDBYTES(4);
			int len = GetBEInt(m_Data + m_Pos);
			m_Pos += 4;
			if (len < 0)
			{
				// Invalid length
				return false;
			}
			len *= 4;
			NEEDBYTES(len);
			Tag.m_DataLength = len;
			Tag.m_DataStart = m_Pos;
			m_Pos += len;
			return true;
		}

		default:
		{
			ASSERT(!"Unhandled NBT tag type");
			return false;
		}
	}  // switch (iType)
}

#undef CASE_SIMPLE_TAG

int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength) const
{
	if (a_Tag < 0)
	{
		return -1;
	}
	if (m_Tags[a_Tag].m_Type != TAG_Compound)
	{
		return -1;
	}

	if (a_NameLength == 0)
	{
		a_NameLength = strlen(a_Name);
	}
	for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling)
	{
		if (
			(m_Tags[Child].m_NameLength == a_NameLength) &&
			(memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0)
		)
		{
			return Child;
		}
	}  // for Child - children of a_Tag
	return -1;
}

int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const
{
	if (a_Tag < 0)
	{
		return -1;
	}
	size_t Begin = 0;
	size_t Length = a_Path.length();
	int Tag = a_Tag;
	for (size_t i = 0; i < Length; i++)
	{
		if (a_Path[i] != '\\')
		{
			continue;
		}
		Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin - 1);
		if (Tag < 0)
		{
			return -1;
		}
		Begin = i + 1;
	}  // for i - a_Path[]

	if (Begin < Length)
	{
		Tag = FindChildByName(Tag, a_Path.c_str() + Begin, Length - Begin);
	}
	return Tag;
}

////////////////////////////////////////////////////////////////////////////////
// cFastNBTWriter:

cFastNBTWriter::cFastNBTWriter(const AString & a_RootTagName) :
	m_CurrentStack(0)
{
	m_Stack[0].m_Type = TAG_Compound;
	m_Result.reserve(100 * 1024);
	m_Result.push_back(TAG_Compound);
	WriteString(a_RootTagName.data(), (UInt16)a_RootTagName.size());
}

void cFastNBTWriter::BeginCompound(const AString & a_Name)
{
	if (m_CurrentStack >= MAX_STACK - 1)
	{
		ASSERT(!"Stack overflow");
		return;
	}

	TagCommon(a_Name, TAG_Compound);

	++m_CurrentStack;
	m_Stack[m_CurrentStack].m_Type = TAG_Compound;
}

void cFastNBTWriter::EndCompound(void)
{
	ASSERT(m_CurrentStack > 0);
	ASSERT(IsStackTopCompound());

	m_Result.push_back(TAG_End);
	--m_CurrentStack;
}

void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType)
{
	if (m_CurrentStack >= MAX_STACK - 1)
	{
		ASSERT(!"Stack overflow");
		return;
	}

	TagCommon(a_Name, TAG_List);

	m_Result.push_back((char)a_ChildrenType);
	m_Result.append(4, (char)0);

	++m_CurrentStack;
	m_Stack[m_CurrentStack].m_Type     = TAG_List;
	m_Stack[m_CurrentStack].m_Pos      = (int)m_Result.size() - 4;
	m_Stack[m_CurrentStack].m_Count    = 0;
	m_Stack[m_CurrentStack].m_ItemType = a_ChildrenType;
}

void cFastNBTWriter::EndList(void)
{
	ASSERT(m_CurrentStack > 0);
	ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List);

	// Update the list count:
	SetBEInt((char *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count);

	--m_CurrentStack;
}

void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value)
{
	TagCommon(a_Name, TAG_Byte);
	m_Result.push_back(a_Value);
}

void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value)
{
	TagCommon(a_Name, TAG_Short);
	Int16 Value = htons(a_Value);
	m_Result.append((const char *)&Value, 2);
}

void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value)
{
	TagCommon(a_Name, TAG_Int);
	Int32 Value = htonl(a_Value);
	m_Result.append((const char *)&Value, 4);
}

void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value)
{
	TagCommon(a_Name, TAG_Long);
	Int64 Value = HostToNetwork8(&a_Value);
	m_Result.append((const char *)&Value, 8);
}

void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value)
{
	TagCommon(a_Name, TAG_Float);
	Int32 Value = HostToNetwork4(&a_Value);
	m_Result.append((const char *)&Value, 4);
}

void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value)
{
	TagCommon(a_Name, TAG_Double);
	Int64 Value = HostToNetwork8(&a_Value);
	m_Result.append((const char *)&Value, 8);
}

void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value)
{
	TagCommon(a_Name, TAG_String);
	Int16 len = htons((short)(a_Value.size()));
	m_Result.append((const char *)&len, 2);
	m_Result.append(a_Value.c_str(), a_Value.size());
}

void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements)
{
	TagCommon(a_Name, TAG_ByteArray);
	u_long len = htonl((u_long)a_NumElements);
	m_Result.append((const char *)&len, 4);
	m_Result.append(a_Value, a_NumElements);
}

void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements)
{
	TagCommon(a_Name, TAG_IntArray);
	u_long len = htonl((u_long)a_NumElements);
	size_t cap = m_Result.capacity();
	size_t size = m_Result.length();
	if ((cap - size) < (4 + a_NumElements * 4))
	{
		m_Result.reserve(size + 4 + (a_NumElements * 4));
	}
	m_Result.append((const char *)&len, 4);
	for (size_t i = 0; i < a_NumElements; i++)
	{
		int Element = htonl(a_Value[i]);
		m_Result.append((const char *)&Element, 4);
	}
}

void cFastNBTWriter::Finish(void)
{
	ASSERT(m_CurrentStack == 0);
	m_Result.push_back(TAG_End);
}

void cFastNBTWriter::WriteString(const char * a_Data, UInt16 a_Length)
{
	Int16 Len = htons(a_Length);
	m_Result.append((const char *)&Len, 2);
	m_Result.append(a_Data, a_Length);
}

<commit_msg>Fixed cParsedNBT::FindTagByPath().<commit_after>
// FastNBT.cpp

// Implements the fast NBT parser and writer

#include "Globals.h"
#include "FastNBT.h"

// The number of NBT tags that are reserved when an NBT parsing is started.
// You can override this by using a cmdline define
#ifndef NBT_RESERVE_SIZE
	#define NBT_RESERVE_SIZE 200
#endif  // NBT_RESERVE_SIZE

#ifdef _MSC_VER
	// Dodge a C4127 (conditional expression is constant) for this specific macro usage
	#define RETURN_FALSE_IF_FALSE(X) do { if (!X) return false; } while ((false, false))
#else
	#define RETURN_FALSE_IF_FALSE(X) do { if (!X) return false; } while (false)
#endif

////////////////////////////////////////////////////////////////////////////////
// cParsedNBT:

#define NEEDBYTES(N) \
	if (m_Length - m_Pos < (size_t)N) \
	{ \
		return false; \
	}

cParsedNBT::cParsedNBT(const char * a_Data, size_t a_Length) :
	m_Data(a_Data),
	m_Length(a_Length),
	m_Pos(0)
{
	m_IsValid = Parse();
}

bool cParsedNBT::Parse(void)
{
	if (m_Length < 3)
	{
		// Data too short
		return false;
	}
	if (m_Data[0] != TAG_Compound)
	{
		// The top-level tag must be a Compound
		return false;
	}

	m_Tags.reserve(NBT_RESERVE_SIZE);

	m_Tags.push_back(cFastNBTTag(TAG_Compound, -1));

	m_Pos = 1;

	RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength));
	RETURN_FALSE_IF_FALSE(ReadCompound());

	return true;
}

bool cParsedNBT::ReadString(size_t & a_StringStart, size_t & a_StringLen)
{
	NEEDBYTES(2);
	a_StringStart = m_Pos + 2;
	a_StringLen = (size_t)GetBEShort(m_Data + m_Pos);
	if (a_StringLen > 0xffff)
	{
		// Suspicious string length
		return false;
	}
	m_Pos += 2 + a_StringLen;
	return true;
}

bool cParsedNBT::ReadCompound(void)
{
	ASSERT(m_Tags.size() > 0);

	// Reads the latest tag as a compound
	int ParentIdx = (int)m_Tags.size() - 1;
	int PrevSibling = -1;
	for (;;)
	{
		NEEDBYTES(1);
		eTagType TagType = (eTagType)(m_Data[m_Pos]);
		m_Pos++;
		if (TagType == TAG_End)
		{
			break;
		}
		m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling));
		if (PrevSibling >= 0)
		{
			m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
		}
		else
		{
			m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
		}
		PrevSibling = (int)m_Tags.size() - 1;
		RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength));
		RETURN_FALSE_IF_FALSE(ReadTag());
	}  // while (true)
	m_Tags[ParentIdx].m_LastChild = PrevSibling;
	return true;
}

bool cParsedNBT::ReadList(eTagType a_ChildrenType)
{
	// Reads the latest tag as a list of items of type a_ChildrenType

	// Read the count:
	NEEDBYTES(4);
	int Count = GetBEInt(m_Data + m_Pos);
	m_Pos += 4;
	if (Count < 0)
	{
		return false;
	}

	// Read items:
	int ParentIdx = (int)m_Tags.size() - 1;
	int PrevSibling = -1;
	for (int i = 0; i < Count; i++)
	{
		m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling));
		if (PrevSibling >= 0)
		{
			m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
		}
		else
		{
			m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
		}
		PrevSibling = (int)m_Tags.size() - 1;
		RETURN_FALSE_IF_FALSE(ReadTag());
	}  // for (i)
	m_Tags[ParentIdx].m_LastChild = PrevSibling;
	return true;
}

#define CASE_SIMPLE_TAG(TAGTYPE, LEN) \
	case TAG_##TAGTYPE: \
	{ \
		NEEDBYTES(LEN); \
		Tag.m_DataStart = m_Pos; \
		Tag.m_DataLength = LEN; \
		m_Pos += LEN; \
		return true; \
	}

bool cParsedNBT::ReadTag(void)
{
	cFastNBTTag & Tag = m_Tags.back();
	switch (Tag.m_Type)
	{
		CASE_SIMPLE_TAG(Byte,   1)
		CASE_SIMPLE_TAG(Short,  2)
		CASE_SIMPLE_TAG(Int,    4)
		CASE_SIMPLE_TAG(Long,   8)
		CASE_SIMPLE_TAG(Float,  4)
		CASE_SIMPLE_TAG(Double, 8)

		case TAG_String:
		{
			return ReadString(Tag.m_DataStart, Tag.m_DataLength);
		}

		case TAG_ByteArray:
		{
			NEEDBYTES(4);
			int len = GetBEInt(m_Data + m_Pos);
			m_Pos += 4;
			if (len < 0)
			{
				// Invalid length
				return false;
			}
			NEEDBYTES(len);
			Tag.m_DataLength = len;
			Tag.m_DataStart = m_Pos;
			m_Pos += len;
			return true;
		}

		case TAG_List:
		{
			NEEDBYTES(1);
			eTagType ItemType = (eTagType)m_Data[m_Pos];
			m_Pos++;
			RETURN_FALSE_IF_FALSE(ReadList(ItemType));
			return true;
		}

		case TAG_Compound:
		{
			RETURN_FALSE_IF_FALSE(ReadCompound());
			return true;
		}

		case TAG_IntArray:
		{
			NEEDBYTES(4);
			int len = GetBEInt(m_Data + m_Pos);
			m_Pos += 4;
			if (len < 0)
			{
				// Invalid length
				return false;
			}
			len *= 4;
			NEEDBYTES(len);
			Tag.m_DataLength = len;
			Tag.m_DataStart = m_Pos;
			m_Pos += len;
			return true;
		}

		default:
		{
			ASSERT(!"Unhandled NBT tag type");
			return false;
		}
	}  // switch (iType)
}

#undef CASE_SIMPLE_TAG

int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength) const
{
	if (a_Tag < 0)
	{
		return -1;
	}
	if (m_Tags[a_Tag].m_Type != TAG_Compound)
	{
		return -1;
	}

	if (a_NameLength == 0)
	{
		a_NameLength = strlen(a_Name);
	}
	for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling)
	{
		if (
			(m_Tags[Child].m_NameLength == a_NameLength) &&
			(memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0)
		)
		{
			return Child;
		}
	}  // for Child - children of a_Tag
	return -1;
}

int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const
{
	if (a_Tag < 0)
	{
		return -1;
	}
	size_t Begin = 0;
	size_t Length = a_Path.length();
	int Tag = a_Tag;
	for (size_t i = 0; i < Length; i++)
	{
		if (a_Path[i] != '\\')
		{
			continue;
		}
		Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin);
		if (Tag < 0)
		{
			return -1;
		}
		Begin = i + 1;
	}  // for i - a_Path[]

	if (Begin < Length)
	{
		Tag = FindChildByName(Tag, a_Path.c_str() + Begin, Length - Begin);
	}
	return Tag;
}

////////////////////////////////////////////////////////////////////////////////
// cFastNBTWriter:

cFastNBTWriter::cFastNBTWriter(const AString & a_RootTagName) :
	m_CurrentStack(0)
{
	m_Stack[0].m_Type = TAG_Compound;
	m_Result.reserve(100 * 1024);
	m_Result.push_back(TAG_Compound);
	WriteString(a_RootTagName.data(), (UInt16)a_RootTagName.size());
}

void cFastNBTWriter::BeginCompound(const AString & a_Name)
{
	if (m_CurrentStack >= MAX_STACK - 1)
	{
		ASSERT(!"Stack overflow");
		return;
	}

	TagCommon(a_Name, TAG_Compound);

	++m_CurrentStack;
	m_Stack[m_CurrentStack].m_Type = TAG_Compound;
}

void cFastNBTWriter::EndCompound(void)
{
	ASSERT(m_CurrentStack > 0);
	ASSERT(IsStackTopCompound());

	m_Result.push_back(TAG_End);
	--m_CurrentStack;
}

void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType)
{
	if (m_CurrentStack >= MAX_STACK - 1)
	{
		ASSERT(!"Stack overflow");
		return;
	}

	TagCommon(a_Name, TAG_List);

	m_Result.push_back((char)a_ChildrenType);
	m_Result.append(4, (char)0);

	++m_CurrentStack;
	m_Stack[m_CurrentStack].m_Type     = TAG_List;
	m_Stack[m_CurrentStack].m_Pos      = (int)m_Result.size() - 4;
	m_Stack[m_CurrentStack].m_Count    = 0;
	m_Stack[m_CurrentStack].m_ItemType = a_ChildrenType;
}

void cFastNBTWriter::EndList(void)
{
	ASSERT(m_CurrentStack > 0);
	ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List);

	// Update the list count:
	SetBEInt((char *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count);

	--m_CurrentStack;
}

void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value)
{
	TagCommon(a_Name, TAG_Byte);
	m_Result.push_back(a_Value);
}

void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value)
{
	TagCommon(a_Name, TAG_Short);
	Int16 Value = htons(a_Value);
	m_Result.append((const char *)&Value, 2);
}

void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value)
{
	TagCommon(a_Name, TAG_Int);
	Int32 Value = htonl(a_Value);
	m_Result.append((const char *)&Value, 4);
}

void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value)
{
	TagCommon(a_Name, TAG_Long);
	Int64 Value = HostToNetwork8(&a_Value);
	m_Result.append((const char *)&Value, 8);
}

void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value)
{
	TagCommon(a_Name, TAG_Float);
	Int32 Value = HostToNetwork4(&a_Value);
	m_Result.append((const char *)&Value, 4);
}

void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value)
{
	TagCommon(a_Name, TAG_Double);
	Int64 Value = HostToNetwork8(&a_Value);
	m_Result.append((const char *)&Value, 8);
}

void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value)
{
	TagCommon(a_Name, TAG_String);
	Int16 len = htons((short)(a_Value.size()));
	m_Result.append((const char *)&len, 2);
	m_Result.append(a_Value.c_str(), a_Value.size());
}

void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements)
{
	TagCommon(a_Name, TAG_ByteArray);
	u_long len = htonl((u_long)a_NumElements);
	m_Result.append((const char *)&len, 4);
	m_Result.append(a_Value, a_NumElements);
}

void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements)
{
	TagCommon(a_Name, TAG_IntArray);
	u_long len = htonl((u_long)a_NumElements);
	size_t cap = m_Result.capacity();
	size_t size = m_Result.length();
	if ((cap - size) < (4 + a_NumElements * 4))
	{
		m_Result.reserve(size + 4 + (a_NumElements * 4));
	}
	m_Result.append((const char *)&len, 4);
	for (size_t i = 0; i < a_NumElements; i++)
	{
		int Element = htonl(a_Value[i]);
		m_Result.append((const char *)&Element, 4);
	}
}

void cFastNBTWriter::Finish(void)
{
	ASSERT(m_CurrentStack == 0);
	m_Result.push_back(TAG_End);
}

void cFastNBTWriter::WriteString(const char * a_Data, UInt16 a_Length)
{
	Int16 Len = htons(a_Length);
	m_Result.append((const char *)&Len, 2);
	m_Result.append(a_Data, a_Length);
}

<|endoftext|>


<commit_before><commit_msg>Fix yet another mkl_eager_op build failure<commit_after><|endoftext|>


<commit_before><commit_msg>iox-#85 remove blinking roudi warning<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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.
 */

#ifndef __ARCH_SPARC_INTERRUPT_HH__
#define __ARCH_SPARC_INTERRUPT_HH__

#include "arch/sparc/faults.hh"
#include "cpu/thread_context.hh"

namespace SparcISA
{

enum interrupts_t {
    trap_level_zero,
    hstick_match,
    interrupt_vector,
    cpu_mondo,
    dev_mondo,
    resumable_error,
    soft_interrupt,
    num_interrupt_types
};

    class Interrupts
    {

      private:

        bool interrupts[num_interrupt_types];
        int numPosted;

      public:
        Interrupts()
        {
            for (int i = 0; i < num_interrupt_types; ++i) {
                interrupts[i] = false;
            }
            numPosted = 0;
        }

        void post(int int_type)
        {
            if (int_type < 0 || int_type >= num_interrupt_types)
                panic("posting unknown interrupt!\n");
            interrupts[int_type] = true;
            ++numPosted;
        }

        void post(int int_num, int index)
        {

        }

        void clear(int int_num, int index)
        {

        }

        void clear_all()
        {

        }

        bool check_interrupts(ThreadContext * tc) const
        {
            if (numPosted)
                return true;
            else
                return false;
        }

        Fault getInterrupt(ThreadContext * tc)
        {
            int hpstate = tc->readMiscReg(MISCREG_HPSTATE);
            int pstate = tc->readMiscReg(MISCREG_PSTATE);
            bool ie = pstate & PSTATE::ie;

            // THESE ARE IN ORDER OF PRIORITY
            // since there are early returns, and the highest
            // priority interrupts should get serviced,
            // it is v. important that new interrupts are inserted
            // in the right order of processing
            if (hpstate & HPSTATE::hpriv) {
                if (ie) {
                    if (interrupts[hstick_match]) {
                        if (tc->readMiscReg(MISCREG_HINTP) & 1) {
                            interrupts[hstick_match] = false;
                            --numPosted;
                            return new HstickMatch;
                        }
                    }
                    if (interrupts[interrupt_vector]) {
                        interrupts[interrupt_vector] = false;
                        --numPosted;
                        //HAVEN'T IMPLed THIS YET
                        return NoFault;
                    }
                } else {
                    if (interrupts[hstick_match]) {
                        return NoFault;
                    }

                }
            } else {
                if (interrupts[trap_level_zero]) {
                    if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) {
                        interrupts[trap_level_zero] = false;
                        --numPosted;
                        return new TrapLevelZero;
                    }
                }
                if (interrupts[hstick_match]) {
                    if (tc->readMiscReg(MISCREG_HINTP) & 1) {
                        interrupts[hstick_match] = false;
                        --numPosted;
                        return new HstickMatch;
                        }
                }
                if (ie) {
                    if (interrupts[cpu_mondo]) {
                        interrupts[cpu_mondo] = false;
                        --numPosted;
                        return new CpuMondo;
                    }
                    if (interrupts[dev_mondo]) {
                        interrupts[dev_mondo] = false;
                        --numPosted;
                        return new DevMondo;
                    }
                    if (interrupts[soft_interrupt]) {
                        int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
                        // it seems that interrupt vectors are right in
                        // the middle of interrupt levels with regard to
                        // priority, so have to check
                        if ((il < 6) &&
                            interrupts[interrupt_vector]) {
                                // may require more details here since there
                                // may be lots of interrupts embedded in an
                                // platform interrupt vector
                                interrupts[interrupt_vector] = false;
                                --numPosted;
                                //HAVEN'T IMPLed YET
                                return NoFault;
                        } else {
                            if (il > tc->readMiscReg(MISCREG_PIL)) {
                                uint64_t si = tc->readMiscReg(MISCREG_SOFTINT);
                                uint64_t more = si & ~(1 << (il + 1));
                                if (!InterruptLevel(more)) {
                                    interrupts[soft_interrupt] = false;
                                    --numPosted;
                                }
                                return new InterruptLevelN(il);
                            }
                        }
                    }
                    if (interrupts[resumable_error]) {
                        interrupts[resumable_error] = false;
                        --numPosted;
                        return new ResumableError;
                    }
                }
            }
            return NoFault;
        }

        void updateIntrInfo(ThreadContext * tc)
        {

        }

        void serialize(std::ostream &os)
        {
        }

        void unserialize(Checkpoint *cp, const std::string &section)
        {
        }
    };
}

#endif // __ARCH_SPARC_INTERRUPT_HH__
<commit_msg>make interrupt code serialize itself and fix indenting<commit_after>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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.
 */

#ifndef __ARCH_SPARC_INTERRUPT_HH__
#define __ARCH_SPARC_INTERRUPT_HH__

#include "arch/sparc/faults.hh"
#include "cpu/thread_context.hh"

namespace SparcISA
{

enum interrupts_t {
    trap_level_zero,
    hstick_match,
    interrupt_vector,
    cpu_mondo,
    dev_mondo,
    resumable_error,
    soft_interrupt,
    num_interrupt_types
};

class Interrupts
{

  private:

    bool interrupts[num_interrupt_types];
    int numPosted;

  public:
    Interrupts()
    {
        for (int i = 0; i < num_interrupt_types; ++i) {
            interrupts[i] = false;
        }
        numPosted = 0;
    }

    void post(int int_type)
    {
        if (int_type < 0 || int_type >= num_interrupt_types)
            panic("posting unknown interrupt!\n");
        interrupts[int_type] = true;
        ++numPosted;
    }

    void post(int int_num, int index)
    {

    }

    void clear(int int_num, int index)
    {

    }

    void clear_all()
    {

    }

    bool check_interrupts(ThreadContext * tc) const
    {
        if (numPosted)
            return true;
        else
            return false;
    }

    Fault getInterrupt(ThreadContext * tc)
    {
        int hpstate = tc->readMiscReg(MISCREG_HPSTATE);
        int pstate = tc->readMiscReg(MISCREG_PSTATE);
        bool ie = pstate & PSTATE::ie;

        // THESE ARE IN ORDER OF PRIORITY
        // since there are early returns, and the highest
        // priority interrupts should get serviced,
        // it is v. important that new interrupts are inserted
        // in the right order of processing
        if (hpstate & HPSTATE::hpriv) {
            if (ie) {
                if (interrupts[hstick_match]) {
                    if (tc->readMiscReg(MISCREG_HINTP) & 1) {
                        interrupts[hstick_match] = false;
                        --numPosted;
                        return new HstickMatch;
                    }
                }
                if (interrupts[interrupt_vector]) {
                    interrupts[interrupt_vector] = false;
                    --numPosted;
                    //HAVEN'T IMPLed THIS YET
                    return NoFault;
                }
            } else {
                if (interrupts[hstick_match]) {
                    return NoFault;
                }

            }
        } else {
            if (interrupts[trap_level_zero]) {
                if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) {
                    interrupts[trap_level_zero] = false;
                    --numPosted;
                    return new TrapLevelZero;
                }
            }
            if (interrupts[hstick_match]) {
                if (tc->readMiscReg(MISCREG_HINTP) & 1) {
                    interrupts[hstick_match] = false;
                    --numPosted;
                    return new HstickMatch;
                    }
            }
            if (ie) {
                if (interrupts[cpu_mondo]) {
                    interrupts[cpu_mondo] = false;
                    --numPosted;
                    return new CpuMondo;
                }
                if (interrupts[dev_mondo]) {
                    interrupts[dev_mondo] = false;
                    --numPosted;
                    return new DevMondo;
                }
                if (interrupts[soft_interrupt]) {
                    int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
                    // it seems that interrupt vectors are right in
                    // the middle of interrupt levels with regard to
                    // priority, so have to check
                    if ((il < 6) &&
                        interrupts[interrupt_vector]) {
                            // may require more details here since there
                            // may be lots of interrupts embedded in an
                            // platform interrupt vector
                            interrupts[interrupt_vector] = false;
                            --numPosted;
                            //HAVEN'T IMPLed YET
                            return NoFault;
                    } else {
                        if (il > tc->readMiscReg(MISCREG_PIL)) {
                            uint64_t si = tc->readMiscReg(MISCREG_SOFTINT);
                            uint64_t more = si & ~(1 << (il + 1));
                            if (!InterruptLevel(more)) {
                                interrupts[soft_interrupt] = false;
                                --numPosted;
                            }
                            return new InterruptLevelN(il);
                        }
                    }
                }
                if (interrupts[resumable_error]) {
                    interrupts[resumable_error] = false;
                    --numPosted;
                    return new ResumableError;
                }
            }
        }
        return NoFault;
    }

    void updateIntrInfo(ThreadContext * tc)
    {

    }

    void serialize(std::ostream &os)
    {
        SERIALIZE_ARRAY(interrupts,num_interrupt_types);
        SERIALIZE_SCALAR(numPosted);
    }

    void unserialize(Checkpoint *cp, const std::string &section)
    {
        UNSERIALIZE_ARRAY(interrupts,num_interrupt_types);
        UNSERIALIZE_SCALAR(numPosted);
    }
};
} // namespace SPARC_ISA

#endif // __ARCH_SPARC_INTERRUPT_HH__
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MasterPageContainerFiller.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: kz $ $Date: 2006-04-26 20:49:09 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#include "MasterPageContainerFiller.hxx"

#include "MasterPageDescriptor.hxx"
#include "MasterPageContainerProviders.hxx"
#include "TemplateScanner.hxx"

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::sd::toolpanel::controls;

namespace sd { namespace toolpanel { namespace controls {

MasterPageContainerFiller::MasterPageContainerFiller (ContainerAdapter& rpAdapter)
    : mrContainerAdapter(rpAdapter),
      meState(INITIALIZE_TEMPLATE_SCANNER),
      mpScannerTask(),
      mpLastAddedEntry(NULL),
      mnIndex(1)
{
    // Add one entry for the default master page.  We use temporarily the
    // DefaultPagePreviewProvider to prevent the rendering (and the
    // expensive creation) of the default page.  It is replaced later one by
    // another.
    SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
        MasterPageContainer::DEFAULT,
        0,
        String(),
        String(),
        String(),
        ::boost::shared_ptr<PageObjectProvider>(new DefaultPageObjectProvider()),
        ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider())));
    mrContainerAdapter.PutMasterPage(pDescriptor);
}

MasterPageContainerFiller::~MasterPageContainerFiller (void)
{
}

void MasterPageContainerFiller::RunNextStep (void)
{
    switch (meState)
    {
        case INITIALIZE_TEMPLATE_SCANNER:
            mpScannerTask.reset(new TemplateScanner());
            meState = SCAN_TEMPLATE;
            break;

        case SCAN_TEMPLATE:
            meState = ScanTemplate();
            break;

        case ADD_TEMPLATE:
            meState = AddTemplate();
            break;

        case DONE:
        case ERROR:
        default:
            mrContainerAdapter.FillingDone();
            mpScannerTask.reset();
            break;
    }
}

bool MasterPageContainerFiller::HasNextStep (void)
{
    switch (meState)
    {
        case DONE:
        case ERROR:
            return false;

        default:
            return true;
    }
}

MasterPageContainerFiller::State MasterPageContainerFiller::ScanTemplate (void)
{
    State eState (ERROR);

    if (mpScannerTask.get() != NULL)
    {
        if (mpScannerTask->HasNextStep())
        {
            mpScannerTask->RunNextStep();
            if (mpScannerTask->GetLastAddedEntry() != mpLastAddedEntry)
            {
                mpLastAddedEntry = mpScannerTask->GetLastAddedEntry();
                if (mpLastAddedEntry != NULL)
                    eState = ADD_TEMPLATE;
                else
                    eState = SCAN_TEMPLATE;
            }
            else
                eState = SCAN_TEMPLATE;
        }
        else
            eState = DONE;
    }

    return eState;
}

MasterPageContainerFiller::State MasterPageContainerFiller::AddTemplate (void)
{
    if (mpLastAddedEntry != NULL)
    {
        SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
            MasterPageContainer::TEMPLATE,
            mnIndex,
            mpLastAddedEntry->msPath,
            mpLastAddedEntry->msTitle,
            String(),
            ::boost::shared_ptr<PageObjectProvider>(
                new TemplatePageObjectProvider(mpLastAddedEntry->msPath)),
            ::boost::shared_ptr<PreviewProvider>(
                new TemplatePreviewProvider(mpLastAddedEntry->msPath))));
        // For user supplied templates we use a different preview provider:
        // The preview in the document shows not only shapes on the master
        // page but also shapes on the foreground.  This is misleading and
        // therefore these previews are discarded and created directly from
        // the page objects.
        if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER)
            pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(
                new PagePreviewProvider());

        mrContainerAdapter.PutMasterPage(pDescriptor);
        ++mnIndex;
    }

    return SCAN_TEMPLATE;
}

} } } // end of namespace ::sd::toolpanel::controls
<commit_msg>INTEGRATION: CWS impress96 (1.2.16); FILE MERGED 2006/05/22 11:51:01 af 1.2.16.1: #i65688# The coe in RunNextStep() for finishing the template scanning is now really executed.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MasterPageContainerFiller.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2006-07-13 10:30:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#include "MasterPageContainerFiller.hxx"

#include "MasterPageDescriptor.hxx"
#include "MasterPageContainerProviders.hxx"
#include "TemplateScanner.hxx"

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::sd::toolpanel::controls;

namespace sd { namespace toolpanel { namespace controls {

MasterPageContainerFiller::MasterPageContainerFiller (ContainerAdapter& rpAdapter)
    : mrContainerAdapter(rpAdapter),
      meState(INITIALIZE_TEMPLATE_SCANNER),
      mpScannerTask(),
      mpLastAddedEntry(NULL),
      mnIndex(1)
{
    // Add one entry for the default master page.  We use temporarily the
    // DefaultPagePreviewProvider to prevent the rendering (and the
    // expensive creation) of the default page.  It is replaced later one by
    // another.
    SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
        MasterPageContainer::DEFAULT,
        0,
        String(),
        String(),
        String(),
        ::boost::shared_ptr<PageObjectProvider>(new DefaultPageObjectProvider()),
        ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider())));
    mrContainerAdapter.PutMasterPage(pDescriptor);
}

MasterPageContainerFiller::~MasterPageContainerFiller (void)
{
}

void MasterPageContainerFiller::RunNextStep (void)
{
    switch (meState)
    {
        case INITIALIZE_TEMPLATE_SCANNER:
            mpScannerTask.reset(new TemplateScanner());
            meState = SCAN_TEMPLATE;
            break;

        case SCAN_TEMPLATE:
            meState = ScanTemplate();
            break;

        case ADD_TEMPLATE:
            meState = AddTemplate();
            break;

        case DONE:
        case ERROR:
        default:
            break;
    }

    // When the state has just been set to DONE or ERROR then tell the
    // container that no more templates will be coming and stop the
    // scanning.
    switch (meState)
    {
        case DONE:
        case ERROR:
            if (mpScannerTask.get() != NULL)
            {
                mrContainerAdapter.FillingDone();
                mpScannerTask.reset();
            }
    }
}

bool MasterPageContainerFiller::HasNextStep (void)
{
    switch (meState)
    {
        case DONE:
        case ERROR:
            return false;

        default:
            return true;
    }
}

MasterPageContainerFiller::State MasterPageContainerFiller::ScanTemplate (void)
{
    State eState (ERROR);

    if (mpScannerTask.get() != NULL)
    {
        if (mpScannerTask->HasNextStep())
        {
            mpScannerTask->RunNextStep();
            if (mpScannerTask->GetLastAddedEntry() != mpLastAddedEntry)
            {
                mpLastAddedEntry = mpScannerTask->GetLastAddedEntry();
                if (mpLastAddedEntry != NULL)
                    eState = ADD_TEMPLATE;
                else
                    eState = SCAN_TEMPLATE;
            }
            else
                eState = SCAN_TEMPLATE;
        }
        else
            eState = DONE;
    }

    return eState;
}

MasterPageContainerFiller::State MasterPageContainerFiller::AddTemplate (void)
{
    if (mpLastAddedEntry != NULL)
    {
        SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
            MasterPageContainer::TEMPLATE,
            mnIndex,
            mpLastAddedEntry->msPath,
            mpLastAddedEntry->msTitle,
            String(),
            ::boost::shared_ptr<PageObjectProvider>(
                new TemplatePageObjectProvider(mpLastAddedEntry->msPath)),
            ::boost::shared_ptr<PreviewProvider>(
                new TemplatePreviewProvider(mpLastAddedEntry->msPath))));
        // For user supplied templates we use a different preview provider:
        // The preview in the document shows not only shapes on the master
        // page but also shapes on the foreground.  This is misleading and
        // therefore these previews are discarded and created directly from
        // the page objects.
        if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER)
            pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(
                new PagePreviewProvider());

        mrContainerAdapter.PutMasterPage(pDescriptor);
        ++mnIndex;
    }

    return SCAN_TEMPLATE;
}

} } } // end of namespace ::sd::toolpanel::controls
<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "APMFlightModesComponentController.h"
#include "QGCMAVLink.h"

#include <QVariant>
#include <QQmlProperty>

APMFlightModesComponentController::APMFlightModesComponentController(void)
    : _activeFlightMode(0)
    , _channelCount(Vehicle::cMaxRcChannels)
{
    _modeParamPrefix = _vehicle->rover() ? QStringLiteral("MODE") : QStringLiteral("FLTMODE");
    _modeChannelParam = _vehicle->rover() ? QStringLiteral("MODE_CH") : QStringLiteral("FLTMODE_CH");

    QStringList usedParams;
    for (int i=1; i<7; i++) {
        usedParams << QStringLiteral("%1%2").arg(_modeParamPrefix).arg(i);
    }
    if (!_allParametersExists(FactSystem::defaultComponentId, usedParams)) {
        return;
    }

    _rgChannelOptionEnabled << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false);

    connect(_vehicle, &Vehicle::rcChannelsChanged, this, &APMFlightModesComponentController::_rcChannelsChanged);
}

/// Connected to Vehicle::rcChannelsChanged signal
void APMFlightModesComponentController::_rcChannelsChanged(int channelCount, int pwmValues[Vehicle::cMaxRcChannels])
{
    int flightModeChannel = 4;

    if (parameterExists(FactSystem::defaultComponentId, _modeChannelParam)) {
        flightModeChannel = getParameterFact(FactSystem::defaultComponentId, _modeChannelParam)->rawValue().toInt() - 1;
    }

    if (flightModeChannel >= channelCount) {
        return;
    }

    _activeFlightMode = 0;
    int channelValue = pwmValues[flightModeChannel];
    if (channelValue != -1) {
        bool found = false;
        int rgThreshold[] = { 1230, 1360, 1490, 1620, 1749 };
        for (int i=0; i<5; i++) {
            if (channelValue <= rgThreshold[i]) {
                _activeFlightMode = i + 1;
                found = true;
                break;
            }
        }
        if (!found) {
            _activeFlightMode = 6;
        }
    }
    emit activeFlightModeChanged(_activeFlightMode);

    for (int i=0; i<6; i++) {
        _rgChannelOptionEnabled[i] = QVariant(false);
        channelValue = pwmValues[i+6];
        if (channelValue != -1 && channelValue > 1800) {
            _rgChannelOptionEnabled[i] = QVariant(true);
        }
    }
    emit channelOptionEnabledChanged();
}
<commit_msg>APMFlightModesComponentController: Remove redundant logic<commit_after>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "APMFlightModesComponentController.h"
#include "QGCMAVLink.h"

#include <QVariant>
#include <QQmlProperty>

APMFlightModesComponentController::APMFlightModesComponentController(void)
    : _activeFlightMode(0)
    , _channelCount(Vehicle::cMaxRcChannels)
{
    _modeParamPrefix = _vehicle->rover() ? QStringLiteral("MODE") : QStringLiteral("FLTMODE");
    _modeChannelParam = _vehicle->rover() ? QStringLiteral("MODE_CH") : QStringLiteral("FLTMODE_CH");

    QStringList usedParams;
    for (int i=1; i<7; i++) {
        usedParams << QStringLiteral("%1%2").arg(_modeParamPrefix).arg(i);
    }
    if (!_allParametersExists(FactSystem::defaultComponentId, usedParams)) {
        return;
    }

    _rgChannelOptionEnabled << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false);

    connect(_vehicle, &Vehicle::rcChannelsChanged, this, &APMFlightModesComponentController::_rcChannelsChanged);
}

/// Connected to Vehicle::rcChannelsChanged signal
void APMFlightModesComponentController::_rcChannelsChanged(int channelCount, int pwmValues[Vehicle::cMaxRcChannels])
{
    int flightModeChannel = 4;

    if (parameterExists(FactSystem::defaultComponentId, _modeChannelParam)) {
        flightModeChannel = getParameterFact(FactSystem::defaultComponentId, _modeChannelParam)->rawValue().toInt() - 1;
    }

    if (flightModeChannel >= channelCount) {
        return;
    }

    _activeFlightMode = 0;
    int channelValue = pwmValues[flightModeChannel];
    if (channelValue != -1) {
        bool found = false;
        int rgThreshold[] = { 1230, 1360, 1490, 1620, 1749 };
        for (int i=0; i<5; i++) {
            if (channelValue <= rgThreshold[i]) {
                _activeFlightMode = i + 1;
                found = true;
                break;
            }
        }
        if (!found) {
            _activeFlightMode = 6;
        }
    }
    emit activeFlightModeChanged(_activeFlightMode);

    for (int i=0; i<6; i++) {
        _rgChannelOptionEnabled[i] = QVariant(false);
        channelValue = pwmValues[i+6];
        if (channelValue > 1800) {
            _rgChannelOptionEnabled[i] = QVariant(true);
        }
    }
    emit channelOptionEnabledChanged();
}
<|endoftext|>