<commit_before>#include <arc/loader/Plugin.h>
#include <arc/message/PayloadSOAP.h>

#include <stdio.h>

#define R_NO_REMAP 1
#include <R.h>
#include <Rembedded.h>
#include <Rinternals.h>

#include "eqtlservice.h"

typedef enum {
    PARSE_NULL,
    PARSE_OK,
    PARSE_INCOMPLETE,
    PARSE_ERROR,
    PARSE_EOF
} ParseStatus;

extern "C" SEXP R_ParseVector(SEXP, int, ParseStatus *);

/**
 * Initializes the expression qtl service and returns it.
 */
static Arc::Plugin* get_service(Arc::PluginArgument* arg)
{
	Arc::ServicePluginArgument* mccarg = dynamic_cast<Arc::ServicePluginArgument*>(arg);
	if(!mccarg) return NULL;
	return new ArcService::ExpressionQtlService((Arc::Config*)(*mccarg));
}

/**
 * This PLUGINS_TABLE_NAME is defining basic entities of the implemented .
 * service. It is used to get the correct entry point to the plugin.
 * FORMAT: {name, kind, version, constructor}, null terminated
 */
Arc::PluginDescriptor PLUGINS_TABLE_NAME[] = {
	{"eQTL","HED:SERVICE",1,&get_service},
	{ NULL, NULL, 0, NULL }
};

using namespace Arc;

namespace ArcService
{

	ExpressionQtlService::ExpressionQtlService(Arc::Config *cfg) : Service(cfg),logger(Logger::rootLogger, "eQTL"),
	 mysql("eQTL_Stockholm","localhost","root","")
	{

		// synchronize this with eqtl_arc.wsdl
		ns_["arc"]="http://uni-luebeck.de/eqtl/arc/";

		// init embedded R
		char *argv[] = {"REmbeddedPostgres", "--gui=none", "--silent"};
		Rf_initEmbeddedR(sizeof(argv)/sizeof(argv[0]), argv);

		// read config like this: prefix_=(std::string)((*cfg)["prefix"]);
	}

	ExpressionQtlService::~ExpressionQtlService(void)
	{
	}

	/**
	* Method which creates a fault payload
	*/
	Arc::MCC_Status ExpressionQtlService::makeFault(Arc::Message& outmsg, const std::string &reason)
	{
		logger.msg(Arc::WARNING, "Creating fault! Reason: \"%s\"",reason);
		// The boolean true indicates that inside of PayloadSOAP,
		// an object SOAPFault will be created inside.
		Arc::PayloadSOAP* outpayload = new Arc::PayloadSOAP(ns_,true);
		Arc::SOAPFault* fault = outpayload->Fault();
		if(fault) {
			fault->Code(Arc::SOAPFault::Sender);
			fault->Reason(reason);
		};
		outmsg.Payload(outpayload);

		return Arc::MCC_Status(Arc::STATUS_OK);
	}

	/**
	* Processes the incoming message and generates an outgoing message.
	* @param inmsg incoming message
	* @param outmsg outgoing message
	* @return Status of the result achieved
	*/
	Arc::MCC_Status ExpressionQtlService::process(Arc::Message& inmsg, Arc::Message& outmsg)
	{
		logger.msg(Arc::DEBUG, "eQTL service started...");

		/**  Extracting incoming payload */
		Arc::PayloadSOAP* inpayload  = NULL;
		try {
			inpayload = dynamic_cast<Arc::PayloadSOAP*>(inmsg.Payload());
		} catch(std::exception& e) { };
		if(!inpayload) {
//FIXME: causes compile error. dunno why 			logger.msg(Arc::ERROR,"Input is not SOAP");
			return makeFault(outmsg, "Received message was not a valid SOAP message.");
		};
		/** */

		/** Analyzing and execute request */
		Arc::PayloadSOAP* outpayload = new Arc::PayloadSOAP(ns_);

		Arc::XMLNode requestNode  = inpayload->Child();
		logger.msg(Arc::DEBUG, "Called WSDL Operation: \"%s\"",requestNode.Name());
		if( requestNode.Name() == "QTL_FindByPosition" || requestNode.Name() == "QTL_FindByPosition_R" ) {
			bool searchMarker = true;
			bool searchGene = true;
			if( ((std::string)requestNode["searchType"]).length() ) {
				std::string searchType = (std::string) requestNode["searchType"];
				if(searchType == "marker") searchGene = false;
				if(searchType == "gene") searchMarker = false;
			}
			Arc::XMLNode searchRequest = requestNode["searchRequest"];
			mysqlpp::Query sql = mysql.query();
			sql << "SELECT * FROM hajo_qtl_nocov WHERE 1 ";

			if( ((std::string)searchRequest["lodScore"]["from"]).length() )
				sql << " AND lod >= " << mysqlpp::quote << (std::string) searchRequest["lodScore"]["from"];
			if( ((std::string)searchRequest["lodScore"]["to"]).length() )
				sql << " AND lod <= " << mysqlpp::quote << (std::string) searchRequest["lodScore"]["to"];

			Arc::XMLNode position = searchRequest["position"];
			if( position.Size()>0 ) {
				sql << " AND ( FALSE ";

				while(position) {
					if( searchMarker ) {
						sql << " OR ( marker_chromosome=" << mysqlpp::quote << (std::string) position["chromosome"];
						if( ((std::string)position["fromBP"]).length() )
							sql << " AND marker_positionBP >= " << mysqlpp::quote << (std::string) position["fromBP"];
						if( ((std::string)position["toBP"]).length() )
							sql << " AND marker_positionBP <= " << mysqlpp::quote << (std::string) position["toBP"];
						sql << ") ";
					}
					if( searchGene ) {
						sql << " OR ( genePosition_chromosome=" << mysqlpp::quote << (std::string) position["chromosome"];
						if( ((std::string)position["fromBP"]).length() )
							sql << " AND genePosition_toBP >= " << mysqlpp::quote << (std::string) position["fromBP"];
						if( ((std::string)position["toBP"]).length() )
							sql << " AND genePosition_fromBP <= " << mysqlpp::quote << (std::string) position["toBP"];
						sql << ") ";
					}
					++position;
				}
				sql << " ) ";
			}

			if( ((std::string)searchRequest["sameChromosome"]).length() ) {
				int what = atoi( ((std::string) searchRequest["sameChromosome"]).c_str() );
				if( what == 1 ) sql << " AND sameChromosome='1' ";
				else if( what == -1 ) sql << " AND sameChromosome='0' ";
			}

			if( ((std::string)searchRequest["locusToGeneDistance"]["from"]).length() )
				sql << " AND locusToGeneDistance >= " << mysqlpp::quote << (std::string) searchRequest["locusToGeneDistance"]["from"];
			if( ((std::string)searchRequest["locusToGeneDistance"]["to"]).length() )
				sql << " AND locusToGeneDistance <= " << mysqlpp::quote << (std::string) searchRequest["locusToGeneDistance"]["to"];

			std::string orderBy = "lod DESC";
			if( ((std::string)searchRequest["orderBy"]).length() ) {
				std::string order = searchRequest["orderBy"];
				if( order == "LodScore" ) orderBy = "lod DESC";
			}
			sql << " ORDER BY " << orderBy;
			if( ((std::string)searchRequest["maxNumResults"]).length() )
				sql << " LIMIT "<< atoi( ((std::string) searchRequest["maxNumResults"]).c_str() );

			logger.msg(Arc::DEBUG, "SQL Query: \"%s\"",sql.str());
			mysqlpp::StoreQueryResult res;
			try{
				res = sql.store();
			}catch(mysqlpp::Exception e) {
				return makeFault(outmsg, e.what());
			}
			logger.msg(Arc::DEBUG, "Number of results: \"%d\"",res.num_rows());

			if( requestNode.Name() == "QTL_FindByPosition" ) {
				Arc::XMLNode addToMe = outpayload->NewChild("arc:QTL_FindByPositionResponse");
				for(size_t i=0;i<res.num_rows();i++) {
					Arc::XMLNode curAdd = addToMe.NewChild("qtls");
					curAdd.NewChild("lod") = res[i]["lod"];
					curAdd.NewChild("marker");
					curAdd["marker"].NewChild("name") = res[i]["marker_name"];
					curAdd["marker"].NewChild("chromosome") = res[i]["marker_chromosome"];
					curAdd["marker"].NewChild("positionBP") = res[i]["marker_positionBP"];
					curAdd.NewChild("genePosition");
					curAdd["genePosition"].NewChild("chromosome") = res[i]["genePosition_chromosome"];
					curAdd["genePosition"].NewChild("fromBP") = res[i]["genePosition_fromBP"];
					curAdd["genePosition"].NewChild("toBP") = res[i]["genePosition_toBP"];
					curAdd.NewChild("geneEntrezID") = res[i]["geneEntrezID"];
					curAdd.NewChild("statistics");
					curAdd["statistics"].NewChild("mean") = res[i]["statistics_mean"];
					curAdd["statistics"].NewChild("sd") = res[i]["statistics_sd"];
					curAdd["statistics"].NewChild("median") = res[i]["statistics_median"];
					curAdd["statistics"].NewChild("variance") = res[i]["statistics_variance"];
				}
			} else if( requestNode.Name() == "QTL_FindByPosition_R" ) {
				Arc::XMLNode addToMe = outpayload->NewChild("arc:QTL_FindByPosition_RResponse");
				int numCol = 1+3+3+1+4;
				int numRow = res.num_rows();
				SEXP dataForR = Rf_allocMatrix(VECSXP, numRow, numCol);
				PROTECT( dataForR ); //we dont want R to garbage collect this
				for(size_t i=0;i<res.num_rows();i++) {
					int rowOff = i * numCol;
					SET_VECTOR_ELT(dataForR, rowOff+0, Rf_mkString(res[i]["lod"]));
					SET_VECTOR_ELT(dataForR, rowOff+1, Rf_mkString(res[i]["marker_name"]));
					SET_VECTOR_ELT(dataForR, rowOff+2, Rf_mkString(res[i]["marker_chromosome"]));
					SET_VECTOR_ELT(dataForR, rowOff+3, Rf_mkString(res[i]["marker_positionBP"]));
					SET_VECTOR_ELT(dataForR, rowOff+4, Rf_mkString(res[i]["genePosition_chromosome"]));
					SET_VECTOR_ELT(dataForR, rowOff+5, Rf_mkString(res[i]["genePosition_fromBP"]));
					SET_VECTOR_ELT(dataForR, rowOff+6, Rf_mkString(res[i]["genePosition_toBP"]));
					SET_VECTOR_ELT(dataForR, rowOff+7, Rf_mkString(res[i]["geneEntrezID"]));
					SET_VECTOR_ELT(dataForR, rowOff+8, Rf_mkString(res[i]["statistics_mean"]));
					SET_VECTOR_ELT(dataForR, rowOff+9, Rf_mkString(res[i]["statistics_sd"]));
					SET_VECTOR_ELT(dataForR, rowOff+10, Rf_mkString(res[i]["statistics_median"]));
					SET_VECTOR_ELT(dataForR, rowOff+11, Rf_mkString(res[i]["statistics_variance"]));
				}
/*
				SEXP colnames = Rf_GetColNames(dataForR);
				SET_VECTOR_ELT(colnames, 0, Rf_mkString("lod"));
				SET_VECTOR_ELT(colnames, 1, Rf_mkString("marker_name"));
				SET_VECTOR_ELT(colnames, 2, Rf_mkString("marker_chromosome"));
				SET_VECTOR_ELT(colnames, 3, Rf_mkString("marker_positionBP"));
				SET_VECTOR_ELT(colnames, 4, Rf_mkString("genePosition_chromosome"));
				SET_VECTOR_ELT(colnames, 5, Rf_mkString("genePosition_fromBP"));
				SET_VECTOR_ELT(colnames, 6, Rf_mkString("genePosition_toBP"));
				SET_VECTOR_ELT(colnames, 7, Rf_mkString("geneEntrezID"));
				SET_VECTOR_ELT(colnames, 8, Rf_mkString("statistics_mean"));
				SET_VECTOR_ELT(colnames, 9, Rf_mkString("statistics_sd"));
				SET_VECTOR_ELT(colnames, 10, Rf_mkString("statistics_median"));
				SET_VECTOR_ELT(colnames, 11, Rf_mkString("statistics_variance"));
*/
				logger.msg(Arc::DEBUG, "Registring data into R...");
				Rf_defineVar(Rf_install("data"), dataForR, R_GlobalEnv);
				logger.msg(Arc::DEBUG, "Variable \"data\" set.");
				ParseStatus status;
				const char* commandStr = ((std::string)requestNode["script"]).c_str();
				logger.msg(Arc::DEBUG, "R script : %s", commandStr);
				SEXP str = Rf_mkString(commandStr);
				logger.msg(Arc::DEBUG, "mkString succeeded");
				SEXP commands = R_ParseVector(str, -1, &status);
				logger.msg(Arc::DEBUG, "parseString succeeded");
				PROTECT(commands);
				Rf_PrintValue(commands);
				int errorStatus;
				SEXP result = R_tryEval(commands, R_GlobalEnv, &errorStatus);
				Rf_PrintValue(result);
				UNPROTECT(2); //commands + dataForR

				addToMe = "done";
			}
		}

		logger.msg(Arc::DEBUG, "eQTL service done...");
		outmsg.Payload(outpayload);
		return Arc::MCC_Status(Arc::STATUS_OK);
	}

}//namespace
<commit_msg>R interface seems to work in valgrind. i rock :)<commit_after>#include <arc/loader/Plugin.h>
#include <arc/message/PayloadSOAP.h>

#include <stdio.h>

#define R_NO_REMAP 1
#include <R.h>
#include <Rembedded.h>
#include <Rinternals.h>

#include "eqtlservice.h"

typedef enum {
    PARSE_NULL,
    PARSE_OK,
    PARSE_INCOMPLETE,
    PARSE_ERROR,
    PARSE_EOF
} ParseStatus;

extern "C" SEXP R_ParseVector(SEXP, int, ParseStatus *, SEXP);

/**
 * Initializes the expression qtl service and returns it.
 */
static Arc::Plugin* get_service(Arc::PluginArgument* arg)
{
	Arc::ServicePluginArgument* mccarg = dynamic_cast<Arc::ServicePluginArgument*>(arg);
	if(!mccarg) return NULL;
	return new ArcService::ExpressionQtlService((Arc::Config*)(*mccarg));
}

/**
 * This PLUGINS_TABLE_NAME is defining basic entities of the implemented .
 * service. It is used to get the correct entry point to the plugin.
 * FORMAT: {name, kind, version, constructor}, null terminated
 */
Arc::PluginDescriptor PLUGINS_TABLE_NAME[] = {
	{"eQTL","HED:SERVICE",1,&get_service},
	{ NULL, NULL, 0, NULL }
};

using namespace Arc;

namespace ArcService
{

	ExpressionQtlService::ExpressionQtlService(Arc::Config *cfg) : Service(cfg),logger(Logger::rootLogger, "eQTL"),
	 mysql("eQTL_Stockholm","localhost","root","")
	{

		// synchronize this with eqtl_arc.wsdl
		ns_["arc"]="http://uni-luebeck.de/eqtl/arc/";

		// init embedded R
		char *argv[] = {"R", "--gui=none", "--silent"};
		Rf_initEmbeddedR(sizeof(argv)/sizeof(argv[0]), argv);

		// read config like this: prefix_=(std::string)((*cfg)["prefix"]);
	}

	ExpressionQtlService::~ExpressionQtlService(void)
	{
	}

	/**
	* Method which creates a fault payload
	*/
	Arc::MCC_Status ExpressionQtlService::makeFault(Arc::Message& outmsg, const std::string &reason)
	{
		logger.msg(Arc::WARNING, "Creating fault! Reason: \"%s\"",reason);
		// The boolean true indicates that inside of PayloadSOAP,
		// an object SOAPFault will be created inside.
		Arc::PayloadSOAP* outpayload = new Arc::PayloadSOAP(ns_,true);
		Arc::SOAPFault* fault = outpayload->Fault();
		if(fault) {
			fault->Code(Arc::SOAPFault::Sender);
			fault->Reason(reason);
		};
		outmsg.Payload(outpayload);

		return Arc::MCC_Status(Arc::STATUS_OK);
	}

	/**
	* Processes the incoming message and generates an outgoing message.
	* @param inmsg incoming message
	* @param outmsg outgoing message
	* @return Status of the result achieved
	*/
	Arc::MCC_Status ExpressionQtlService::process(Arc::Message& inmsg, Arc::Message& outmsg)
	{
		logger.msg(Arc::DEBUG, "eQTL service started...");

		/**  Extracting incoming payload */
		Arc::PayloadSOAP* inpayload  = NULL;
		try {
			inpayload = dynamic_cast<Arc::PayloadSOAP*>(inmsg.Payload());
		} catch(std::exception& e) { };
		if(!inpayload) {
//FIXME: causes compile error. dunno why 			logger.msg(Arc::ERROR,"Input is not SOAP");
			return makeFault(outmsg, "Received message was not a valid SOAP message.");
		};
		/** */

		/** Analyzing and execute request */
		Arc::PayloadSOAP* outpayload = new Arc::PayloadSOAP(ns_);

		Arc::XMLNode requestNode  = inpayload->Child();
		logger.msg(Arc::DEBUG, "Called WSDL Operation: \"%s\"",requestNode.Name());
		if( requestNode.Name() == "QTL_FindByPosition" || requestNode.Name() == "QTL_FindByPosition_R" ) {
			bool searchMarker = true;
			bool searchGene = true;
			if( ((std::string)requestNode["searchType"]).length() ) {
				std::string searchType = (std::string) requestNode["searchType"];
				if(searchType == "marker") searchGene = false;
				if(searchType == "gene") searchMarker = false;
			}
			Arc::XMLNode searchRequest = requestNode["searchRequest"];
			mysqlpp::Query sql = mysql.query();
			sql << "SELECT * FROM hajo_qtl_nocov WHERE 1 ";

			if( ((std::string)searchRequest["lodScore"]["from"]).length() )
				sql << " AND lod >= " << mysqlpp::quote << (std::string) searchRequest["lodScore"]["from"];
			if( ((std::string)searchRequest["lodScore"]["to"]).length() )
				sql << " AND lod <= " << mysqlpp::quote << (std::string) searchRequest["lodScore"]["to"];

			Arc::XMLNode position = searchRequest["position"];
			if( position.Size()>0 ) {
				sql << " AND ( FALSE ";

				while(position) {
					if( searchMarker ) {
						sql << " OR ( marker_chromosome=" << mysqlpp::quote << (std::string) position["chromosome"];
						if( ((std::string)position["fromBP"]).length() )
							sql << " AND marker_positionBP >= " << mysqlpp::quote << (std::string) position["fromBP"];
						if( ((std::string)position["toBP"]).length() )
							sql << " AND marker_positionBP <= " << mysqlpp::quote << (std::string) position["toBP"];
						sql << ") ";
					}
					if( searchGene ) {
						sql << " OR ( genePosition_chromosome=" << mysqlpp::quote << (std::string) position["chromosome"];
						if( ((std::string)position["fromBP"]).length() )
							sql << " AND genePosition_toBP >= " << mysqlpp::quote << (std::string) position["fromBP"];
						if( ((std::string)position["toBP"]).length() )
							sql << " AND genePosition_fromBP <= " << mysqlpp::quote << (std::string) position["toBP"];
						sql << ") ";
					}
					++position;
				}
				sql << " ) ";
			}

			if( ((std::string)searchRequest["sameChromosome"]).length() ) {
				int what = atoi( ((std::string) searchRequest["sameChromosome"]).c_str() );
				if( what == 1 ) sql << " AND sameChromosome='1' ";
				else if( what == -1 ) sql << " AND sameChromosome='0' ";
			}

			if( ((std::string)searchRequest["locusToGeneDistance"]["from"]).length() )
				sql << " AND locusToGeneDistance >= " << mysqlpp::quote << (std::string) searchRequest["locusToGeneDistance"]["from"];
			if( ((std::string)searchRequest["locusToGeneDistance"]["to"]).length() )
				sql << " AND locusToGeneDistance <= " << mysqlpp::quote << (std::string) searchRequest["locusToGeneDistance"]["to"];

			std::string orderBy = "lod DESC";
			if( ((std::string)searchRequest["orderBy"]).length() ) {
				std::string order = searchRequest["orderBy"];
				if( order == "LodScore" ) orderBy = "lod DESC";
			}
			sql << " ORDER BY " << orderBy;
			if( ((std::string)searchRequest["maxNumResults"]).length() )
				sql << " LIMIT "<< atoi( ((std::string) searchRequest["maxNumResults"]).c_str() );

			logger.msg(Arc::DEBUG, "SQL Query: \"%s\"",sql.str());
			mysqlpp::StoreQueryResult res;
			try{
				res = sql.store();
			}catch(mysqlpp::Exception e) {
				return makeFault(outmsg, e.what());
			}
			logger.msg(Arc::DEBUG, "Number of results: \"%d\"",res.num_rows());

			if( requestNode.Name() == "QTL_FindByPosition" ) {
				Arc::XMLNode addToMe = outpayload->NewChild("arc:QTL_FindByPositionResponse");
				for(size_t i=0;i<res.num_rows();i++) {
					Arc::XMLNode curAdd = addToMe.NewChild("qtls");
					curAdd.NewChild("lod") = res[i]["lod"];
					curAdd.NewChild("marker");
					curAdd["marker"].NewChild("name") = res[i]["marker_name"];
					curAdd["marker"].NewChild("chromosome") = res[i]["marker_chromosome"];
					curAdd["marker"].NewChild("positionBP") = res[i]["marker_positionBP"];
					curAdd.NewChild("genePosition");
					curAdd["genePosition"].NewChild("chromosome") = res[i]["genePosition_chromosome"];
					curAdd["genePosition"].NewChild("fromBP") = res[i]["genePosition_fromBP"];
					curAdd["genePosition"].NewChild("toBP") = res[i]["genePosition_toBP"];
					curAdd.NewChild("geneEntrezID") = res[i]["geneEntrezID"];
					curAdd.NewChild("statistics");
					curAdd["statistics"].NewChild("mean") = res[i]["statistics_mean"];
					curAdd["statistics"].NewChild("sd") = res[i]["statistics_sd"];
					curAdd["statistics"].NewChild("median") = res[i]["statistics_median"];
					curAdd["statistics"].NewChild("variance") = res[i]["statistics_variance"];
				}
			} else if( requestNode.Name() == "QTL_FindByPosition_R" ) {
				Arc::XMLNode addToMe = outpayload->NewChild("arc:QTL_FindByPosition_RResponse");
				int numCol = 1+3+3+1+4;
				int numRow = res.num_rows();
				SEXP dataForR = Rf_allocMatrix(VECSXP, numRow, numCol);
				PROTECT( dataForR ); //we dont want R to garbage collect this
				for(size_t i=0;i<res.num_rows();i++) {
					int rowOff = i * numCol;
					SET_VECTOR_ELT(dataForR, rowOff+0, Rf_mkString(res[i]["lod"]));
					SET_VECTOR_ELT(dataForR, rowOff+1, Rf_mkString(res[i]["marker_name"]));
					SET_VECTOR_ELT(dataForR, rowOff+2, Rf_mkString(res[i]["marker_chromosome"]));
					SET_VECTOR_ELT(dataForR, rowOff+3, Rf_mkString(res[i]["marker_positionBP"]));
					SET_VECTOR_ELT(dataForR, rowOff+4, Rf_mkString(res[i]["genePosition_chromosome"]));
					SET_VECTOR_ELT(dataForR, rowOff+5, Rf_mkString(res[i]["genePosition_fromBP"]));
					SET_VECTOR_ELT(dataForR, rowOff+6, Rf_mkString(res[i]["genePosition_toBP"]));
					SET_VECTOR_ELT(dataForR, rowOff+7, Rf_mkString(res[i]["geneEntrezID"]));
					SET_VECTOR_ELT(dataForR, rowOff+8, Rf_mkString(res[i]["statistics_mean"]));
					SET_VECTOR_ELT(dataForR, rowOff+9, Rf_mkString(res[i]["statistics_sd"]));
					SET_VECTOR_ELT(dataForR, rowOff+10, Rf_mkString(res[i]["statistics_median"]));
					SET_VECTOR_ELT(dataForR, rowOff+11, Rf_mkString(res[i]["statistics_variance"]));
				}
/*
				SEXP colnames = Rf_GetColNames(dataForR);
				SET_VECTOR_ELT(colnames, 0, Rf_mkString("lod"));
				SET_VECTOR_ELT(colnames, 1, Rf_mkString("marker_name"));
				SET_VECTOR_ELT(colnames, 2, Rf_mkString("marker_chromosome"));
				SET_VECTOR_ELT(colnames, 3, Rf_mkString("marker_positionBP"));
				SET_VECTOR_ELT(colnames, 4, Rf_mkString("genePosition_chromosome"));
				SET_VECTOR_ELT(colnames, 5, Rf_mkString("genePosition_fromBP"));
				SET_VECTOR_ELT(colnames, 6, Rf_mkString("genePosition_toBP"));
				SET_VECTOR_ELT(colnames, 7, Rf_mkString("geneEntrezID"));
				SET_VECTOR_ELT(colnames, 8, Rf_mkString("statistics_mean"));
				SET_VECTOR_ELT(colnames, 9, Rf_mkString("statistics_sd"));
				SET_VECTOR_ELT(colnames, 10, Rf_mkString("statistics_median"));
				SET_VECTOR_ELT(colnames, 11, Rf_mkString("statistics_variance"));
*/
				logger.msg(Arc::DEBUG, "Registring data into R...");
				Rf_defineVar(Rf_install("data"), dataForR, R_GlobalEnv);
				logger.msg(Arc::DEBUG, "Variable \"data\" set.");

				ParseStatus status;
				char* commandStr = strdup( ((std::string)requestNode["script"]).c_str() );
				logger.msg(Arc::DEBUG, "R script: %s", commandStr);

				SEXP str = Rf_mkString(commandStr);
				free(commandStr);
				PROTECT(str);
				//Rf_PrintValue(str);

				SEXP commands = R_ParseVector(str, -1, &status, R_NilValue);
				if( status == PARSE_OK )
					logger.msg(Arc::DEBUG, "R_ParseVector succeeded.");
				else {
					logger.msg(Arc::DEBUG, "R_ParseVector failed with status %d.", status);
					return makeFault(outmsg, "The script you provided could not be parsed by R using R_ParseVector.");
				}
				PROTECT(commands);

				int nCommands = Rf_length(commands);
				for(int i=0;i<nCommands;i++) {
					Arc::XMLNode lineResult = addToMe.NewChild("scriptResults");
					int errorStatus;
					SEXP curCommand = VECTOR_ELT(commands,i);
					//Rf_PrintValue(curCommand);
					SEXP result = R_tryEval(curCommand, R_GlobalEnv, &errorStatus);
					logger.msg(Arc::DEBUG, "R_tryEval number %d of %d returned error status %d.", i+1, nCommands, errorStatus);

					if( errorStatus == 0 ) {
						//Rf_PrintValue(result);
						logger.msg(Arc::DEBUG, "Returned SEXP is of type %d.", TYPEOF(result));
						if( ! Rf_isNull(result) ) {

							SEXP printExpr = Rf_allocVector(EXPRSXP, 1);
							PROTECT(printExpr);
							SET_VECTOR_ELT(printExpr, 0, result);
							//Rf_PrintValue(printExpr);

							SEXP printCall, tmp;
							PROTECT(tmp = printCall = Rf_allocList(2));
							SET_TYPEOF(printCall, LANGSXP);
							SETCAR(tmp, Rf_install("capture.output"));
							tmp = CDR(tmp);
							SETCAR(tmp, printExpr);
							//Rf_PrintValue(printCall);

							SEXP capturedString = R_tryEval(printCall, R_GlobalEnv, &errorStatus);
							logger.msg(Arc::DEBUG, "R_tryEval to format result returned error status %d.", errorStatus);
							UNPROTECT(2); // printCall + printExpr

							if(errorStatus == 0) {
								logger.msg(Arc::DEBUG, "capturedString is of type %d.", TYPEOF(capturedString));
								int nLines = Rf_length(capturedString);
								for(int j=0;j<nLines;j++)
									lineResult.NewChild("output") = Rf_translateCharUTF8(STRING_ELT(capturedString,j));
							}
						}
					} else {
						std::stringstream statusStr;
						statusStr << errorStatus;
						lineResult.NewChild("errorStatus") = statusStr.str();
					}
				}
				UNPROTECT(3); //command str + commands + dataForR
			}
		}

		logger.msg(Arc::DEBUG, "eQTL service done...");
		outmsg.Payload(outpayload);
		return Arc::MCC_Status(Arc::STATUS_OK);
	}

}//namespace
<|endoftext|>


<commit_before>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2018 Michael Fink
//
/// \file GeoTagTool\MainFrame.cpp GeoTagTool main frame
//
#include "stdafx.h"
#include "res/Ribbon.h"
#include "resource.h"
#include "AboutDlg.hpp"
#include "GeoTagToolView.hpp"
#include "MainFrame.hpp"
#include "SerialPortDlg.hpp"

BOOL MainFrame::PreTranslateMessage(MSG* pMsg)
{
   if (CRibbonFrameWindowImpl<MainFrame>::PreTranslateMessage(pMsg))
      return TRUE;

   return m_tabView.PreTranslateMessage(pMsg);
}

BOOL MainFrame::OnIdle()
{
   return FALSE;
}

LRESULT MainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
   m_cmdBar.Create(m_hWnd, rcDefault, NULL, WS_CHILD);
   m_cmdBar.AttachMenu(GetMenu());
   m_cmdBar.LoadImages(IDR_MAINFRAME);

   CreateSimpleStatusBar();

   m_hWndClient = m_tabView.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);

   // create tab views
   //m_view.Create(m_tabView);
   //m_tabView.AddPage(m_satelliteInfoView.m_hWnd, _T("Geo Tagging"));

   m_satelliteInfoView.Create(m_tabView);
   m_tabView.AddPage(m_satelliteInfoView.m_hWnd, _T("Satellite Info"));

   // register object for message filtering and idle updates
   CMessageLoop* pLoop = _Module.GetMessageLoop();
   ATLASSERT(pLoop != NULL);
   pLoop->AddMessageFilter(this);
   pLoop->AddIdleHandler(this);

   ShowRibbonUI(true);

   return 0;
}

LRESULT MainFrame::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
   // unregister message filtering and idle updates
   CMessageLoop* pLoop = _Module.GetMessageLoop();
   ATLASSERT(pLoop != NULL);
   pLoop->RemoveMessageFilter(this);
   pLoop->RemoveIdleHandler(this);

   bHandled = FALSE;
   return 1;
}

LRESULT MainFrame::OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   PostMessage(WM_CLOSE);
   return 0;
}

LRESULT MainFrame::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   AboutDlg dlg;
   dlg.DoModal();

   return 0;
}

LRESULT MainFrame::OnDataSourceOpenGPSReceiver(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   if (m_liveTrack == nullptr)
   {
      m_liveTrack = std::make_unique<GPS::Track>();
   }

   SerialPortDlg dlg;
   if (IDOK != dlg.DoModal(m_hWnd))
      return 0;

   m_gpsReceiver = std::make_unique<GPS::Receiver>();
   m_gpsReceiver->Configure(dlg.GetSerialPortDeviceName());

   m_view.OnStartingGPSReceiver(*m_gpsReceiver);

   try
   {
      m_gpsReceiver->Start(*m_liveTrack.get());
   }
   catch (const std::exception& ex)
   {
      CString text;
      text.Format(_T("Error while opening serial port: %hs"), ex.what());
      AtlMessageBox(m_hWnd, text.GetString());

      return 0;
   }

   return 0;
}

LRESULT MainFrame::OnDataSourceImportTrack(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{

   return 0;
}

LRESULT MainFrame::OnActionsTagImages(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   return 0;
}

LRESULT MainFrame::OnActionsSaveLiveTrack(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   return 0;
}
<commit_msg>added file open dialog and track importing<commit_after>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2018 Michael Fink
//
/// \file GeoTagTool\MainFrame.cpp GeoTagTool main frame
//
#include "stdafx.h"
#include "res/Ribbon.h"
#include "resource.h"
#include "AboutDlg.hpp"
#include "GeoTagToolView.hpp"
#include "MainFrame.hpp"
#include "SerialPortDlg.hpp"
#include "Import/TrackImport.hpp"

BOOL MainFrame::PreTranslateMessage(MSG* pMsg)
{
   if (CRibbonFrameWindowImpl<MainFrame>::PreTranslateMessage(pMsg))
      return TRUE;

   return m_tabView.PreTranslateMessage(pMsg);
}

BOOL MainFrame::OnIdle()
{
   return FALSE;
}

LRESULT MainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
   m_cmdBar.Create(m_hWnd, rcDefault, NULL, WS_CHILD);
   m_cmdBar.AttachMenu(GetMenu());
   m_cmdBar.LoadImages(IDR_MAINFRAME);

   CreateSimpleStatusBar();

   m_hWndClient = m_tabView.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);

   // create tab views
   //m_view.Create(m_tabView);
   //m_tabView.AddPage(m_satelliteInfoView.m_hWnd, _T("Geo Tagging"));

   m_satelliteInfoView.Create(m_tabView);
   m_tabView.AddPage(m_satelliteInfoView.m_hWnd, _T("Satellite Info"));

   // register object for message filtering and idle updates
   CMessageLoop* pLoop = _Module.GetMessageLoop();
   ATLASSERT(pLoop != NULL);
   pLoop->AddMessageFilter(this);
   pLoop->AddIdleHandler(this);

   ShowRibbonUI(true);

   return 0;
}

LRESULT MainFrame::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
   // unregister message filtering and idle updates
   CMessageLoop* pLoop = _Module.GetMessageLoop();
   ATLASSERT(pLoop != NULL);
   pLoop->RemoveMessageFilter(this);
   pLoop->RemoveIdleHandler(this);

   bHandled = FALSE;
   return 1;
}

LRESULT MainFrame::OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   PostMessage(WM_CLOSE);
   return 0;
}

LRESULT MainFrame::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   AboutDlg dlg;
   dlg.DoModal();

   return 0;
}

LRESULT MainFrame::OnDataSourceOpenGPSReceiver(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   if (m_liveTrack == nullptr)
   {
      m_liveTrack = std::make_unique<GPS::Track>();
   }

   SerialPortDlg dlg;
   if (IDOK != dlg.DoModal(m_hWnd))
      return 0;

   m_gpsReceiver = std::make_unique<GPS::Receiver>();
   m_gpsReceiver->Configure(dlg.GetSerialPortDeviceName());

   m_view.OnStartingGPSReceiver(*m_gpsReceiver);

   try
   {
      m_gpsReceiver->Start(*m_liveTrack.get());
   }
   catch (const std::exception& ex)
   {
      CString text;
      text.Format(_T("Error while opening serial port: %hs"), ex.what());
      AtlMessageBox(m_hWnd, text.GetString());

      return 0;
   }

   return 0;
}

LRESULT MainFrame::OnDataSourceImportTrack(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   CFileDialog dlg(TRUE,
      NULL,
      _T(""),
      OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
      _T("GPX Files (*.gpx)\0*.gpx\0")
      _T("NMEA 0183 Log Files (*.txt; *.nmea)\0*.txt;*.nmea\0")
      _T("All Files (*.*)\0*.*\0"),
      m_hWnd);

   int ret = dlg.DoModal(m_hWnd);

   if (ret != IDOK)
      return 0;

   CString filename = dlg.m_szFileName;

   try
   {
      GPS::Track track;
      Import::TrackImport::ImportTrack(filename, track);

      // TODO add to list
   }
   catch (const std::exception& ex)
   {
      CString text;
      text.Format(_T("Error while opening serial port: %hs"), ex.what());
      AtlMessageBox(m_hWnd, text.GetString());
   }

   return 0;
}

LRESULT MainFrame::OnActionsTagImages(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   return 0;
}

LRESULT MainFrame::OnActionsSaveLiveTrack(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   return 0;
}
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/logging.h"
#include "xenia/cpu/processor.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/objects/xuser_module.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/util/xex2.h"
#include "xenia/kernel/xboxkrnl_private.h"
#include "xenia/xbox.h"

namespace xe {
namespace kernel {

X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting,
                               void* buffer, uint16_t buffer_size,
                               uint16_t* required_size) {
  uint16_t setting_size = 0;
  uint32_t value = 0;

  // TODO(benvanik): have real structs here that just get copied from.
  // http://free60.org/XConfig
  // http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/Generic/ExConfig.h
  switch (category) {
    case 0x0002:
      // XCONFIG_SECURED_CATEGORY
      switch (setting) {
        case 0x0002:  // XCONFIG_SECURED_AV_REGION
          setting_size = 4;
          value = 0x00001000;  // USA/Canada
          break;
        default:
          assert_unhandled_case(setting);
          return X_STATUS_INVALID_PARAMETER_2;
      }
      break;
    case 0x0003:
      // XCONFIG_USER_CATEGORY
      switch (setting) {
        case 0x0001:  // XCONFIG_USER_TIME_ZONE_BIAS
        case 0x0002:  // XCONFIG_USER_TIME_ZONE_STD_NAME
        case 0x0003:  // XCONFIG_USER_TIME_ZONE_DLT_NAME
        case 0x0004:  // XCONFIG_USER_TIME_ZONE_STD_DATE
        case 0x0005:  // XCONFIG_USER_TIME_ZONE_DLT_DATE
        case 0x0006:  // XCONFIG_USER_TIME_ZONE_STD_BIAS
        case 0x0007:  // XCONFIG_USER_TIME_ZONE_DLT_BIAS
          setting_size = 4;
          // TODO(benvanik): get this value.
          value = 0;
          break;
        case 0x0009:  // XCONFIG_USER_LANGUAGE
          setting_size = 4;
          value = 0x00000001;  // English
          break;
        case 0x000A:  // XCONFIG_USER_VIDEO_FLAGS
          setting_size = 4;
          value = 0x00040000;
          break;
        case 0x000C:  // XCONFIG_USER_RETAIL_FLAGS
          setting_size = 4;
          // TODO(benvanik): get this value.
          value = 0;
          break;
        case 0x000E:  // XCONFIG_USER_COUNTRY
          setting_size = 4;
          // TODO(benvanik): get this value.
          value = 0;
          break;
        default:
          assert_unhandled_case(setting);
          return X_STATUS_INVALID_PARAMETER_2;
      }
      break;
    default:
      assert_unhandled_case(category);
      return X_STATUS_INVALID_PARAMETER_1;
  }

  if (buffer_size < setting_size) {
    return X_STATUS_BUFFER_TOO_SMALL;
  }
  if (!buffer && buffer_size) {
    return X_STATUS_INVALID_PARAMETER_3;
  }

  if (buffer) {
    xe::store_and_swap<uint32_t>(buffer, value);
  }
  if (required_size) {
    *required_size = setting_size;
  }

  return X_STATUS_SUCCESS;
}

SHIM_CALL ExGetXConfigSetting_shim(PPCContext* ppc_context,
                                   KernelState* kernel_state) {
  uint16_t category = SHIM_GET_ARG_16(0);
  uint16_t setting = SHIM_GET_ARG_16(1);
  uint32_t buffer_ptr = SHIM_GET_ARG_32(2);
  uint16_t buffer_size = SHIM_GET_ARG_16(3);
  uint32_t required_size_ptr = SHIM_GET_ARG_32(4);

  XELOGD("ExGetXConfigSetting(%.4X, %.4X, %.8X, %.4X, %.8X)", category, setting,
         buffer_ptr, buffer_size, required_size_ptr);

  void* buffer = buffer_ptr ? SHIM_MEM_ADDR(buffer_ptr) : NULL;
  uint16_t required_size = 0;
  X_STATUS result = xeExGetXConfigSetting(category, setting, buffer,
                                          buffer_size, &required_size);

  if (required_size_ptr) {
    SHIM_SET_MEM_16(required_size_ptr, required_size);
  }

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL XexCheckExecutablePrivilege_shim(PPCContext* ppc_context,
                                           KernelState* kernel_state) {
  uint32_t privilege = SHIM_GET_ARG_32(0);

  XELOGD("XexCheckExecutablePrivilege(%.8X)", privilege);

  // BOOL
  // DWORD Privilege

  // Privilege is bit position in xe_xex2_system_flags enum - so:
  // Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
  uint32_t mask = 1 << privilege;

  auto module = kernel_state->GetExecutableModule();
  if (!module) {
    SHIM_SET_RETURN_32(0);
    return;
  }

  uint32_t flags = 0;
  module->GetOptHeader<uint32_t>(XEX_HEADER_SYSTEM_FLAGS, &flags);

  SHIM_SET_RETURN_32((flags & mask) > 0);
}

SHIM_CALL XexGetModuleHandle_shim(PPCContext* ppc_context,
                                  KernelState* kernel_state) {
  uint32_t module_name_ptr = SHIM_GET_ARG_32(0);
  const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr);
  uint32_t hmodule_ptr = SHIM_GET_ARG_32(1);

  XELOGD("XexGetModuleHandle(%s, %.8X)", module_name, hmodule_ptr);

  object_ref<XModule> module;
  if (!module_name) {
    module = kernel_state->GetExecutableModule();
  } else {
    module = kernel_state->GetModule(module_name);
  }
  if (!module) {
    SHIM_SET_MEM_32(hmodule_ptr, 0);
    SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND);
    return;
  }

  // NOTE: we don't retain the handle for return.
  SHIM_SET_MEM_32(hmodule_ptr, module->hmodule_ptr());

  SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
}

SHIM_CALL XexGetModuleSection_shim(PPCContext* ppc_context,
                                   KernelState* kernel_state) {
  uint32_t hmodule = SHIM_GET_ARG_32(0);
  uint32_t name_ptr = SHIM_GET_ARG_32(1);
  const char* name = (const char*)SHIM_MEM_ADDR(name_ptr);
  uint32_t data_ptr = SHIM_GET_ARG_32(2);
  uint32_t size_ptr = SHIM_GET_ARG_32(3);

  XELOGD("XexGetModuleSection(%.8X, %s, %.8X, %.8X)", hmodule, name, data_ptr,
         size_ptr);

  X_STATUS result = X_STATUS_SUCCESS;

  auto module = XModule::GetFromHModule(kernel_state, SHIM_MEM_ADDR(hmodule));
  if (module) {
    uint32_t section_data = 0;
    uint32_t section_size = 0;
    result = module->GetSection(name, &section_data, &section_size);
    if (XSUCCEEDED(result)) {
      SHIM_SET_MEM_32(data_ptr, section_data);
      SHIM_SET_MEM_32(size_ptr, section_size);
    }
  } else {
    result = X_STATUS_INVALID_HANDLE;
  }

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL XexLoadImage_shim(PPCContext* ppc_context,
                            KernelState* kernel_state) {
  uint32_t module_name_ptr = SHIM_GET_ARG_32(0);
  const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr);
  uint32_t module_flags = SHIM_GET_ARG_32(1);
  uint32_t min_version = SHIM_GET_ARG_32(2);
  uint32_t hmodule_ptr = SHIM_GET_ARG_32(3);

  XELOGD("XexLoadImage(%s, %.8X, %.8X, %.8X)", module_name, module_flags,
         min_version, hmodule_ptr);

  X_STATUS result = X_STATUS_NO_SUCH_FILE;

  uint32_t hmodule = 0;
  auto module = kernel_state->GetModule(module_name);
  if (module) {
    // Existing module found.
    hmodule = module->hmodule_ptr();
    result = X_STATUS_SUCCESS;
  } else {
    // Not found; attempt to load as a user module.
    auto user_module = kernel_state->LoadUserModule(module_name);
    if (user_module) {
      user_module->RetainHandle();
      hmodule = user_module->hmodule_ptr();
      result = X_STATUS_SUCCESS;
    }
  }

  // Increment the module's load count.
  if (hmodule) {
    auto ldr_data =
        kernel_memory()->TranslateVirtual<X_LDR_DATA_TABLE_ENTRY*>(hmodule);
    ldr_data->load_count++;
  }

  SHIM_SET_MEM_32(hmodule_ptr, hmodule);

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL XexUnloadImage_shim(PPCContext* ppc_context,
                              KernelState* kernel_state) {
  uint32_t hmodule = SHIM_GET_ARG_32(0);

  XELOGD("XexUnloadImage(%.8X)", hmodule);

  auto module = XModule::GetFromHModule(kernel_state, SHIM_MEM_ADDR(hmodule));
  if (!module) {
    SHIM_SET_RETURN_32(X_STATUS_INVALID_HANDLE);
    return;
  }

  // Can't unload kernel modules from user code.
  if (module->module_type() != XModule::ModuleType::kKernelModule) {
    auto ldr_data =
        kernel_state->memory()->TranslateVirtual<X_LDR_DATA_TABLE_ENTRY*>(
            hmodule);
    if (--ldr_data->load_count == 0) {
      // No more references, free it.
      kernel_state->object_table()->RemoveHandle(module->handle());
    }
  }

  SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
}

SHIM_CALL XexGetProcedureAddress_shim(PPCContext* ppc_context,
                                      KernelState* kernel_state) {
  uint32_t hmodule = SHIM_GET_ARG_32(0);
  uint32_t ordinal = SHIM_GET_ARG_32(1);
  uint32_t out_function_ptr = SHIM_GET_ARG_32(2);

  // May be entry point?
  assert_not_zero(ordinal);

  bool is_string_name = (ordinal & 0xFFFF0000) != 0;
  auto string_name = reinterpret_cast<const char*>(SHIM_MEM_ADDR(ordinal));

  if (is_string_name) {
    XELOGD("XexGetProcedureAddress(%.8X, %.8X(%s), %.8X)", hmodule, ordinal,
           string_name, out_function_ptr);
  } else {
    XELOGD("XexGetProcedureAddress(%.8X, %.8X, %.8X)", hmodule, ordinal,
           out_function_ptr);
  }

  X_STATUS result = X_STATUS_INVALID_HANDLE;

  object_ref<XModule> module;
  if (!hmodule) {
    module = kernel_state->GetExecutableModule();
  } else {
    module = XModule::GetFromHModule(kernel_state, SHIM_MEM_ADDR(hmodule));
  }
  if (module) {
    uint32_t ptr;
    if (is_string_name) {
      ptr = module->GetProcAddressByName(string_name);
    } else {
      ptr = module->GetProcAddressByOrdinal(ordinal);
    }
    if (ptr) {
      SHIM_SET_MEM_32(out_function_ptr, ptr);
      result = X_STATUS_SUCCESS;
    } else {
      XELOGW("ERROR: XexGetProcedureAddress ordinal not found!");
      SHIM_SET_MEM_32(out_function_ptr, 0);
      result = X_STATUS_DRIVER_ORDINAL_NOT_FOUND;
    }
  }

  SHIM_SET_RETURN_32(result);
}

void AppendParam(StringBuffer& string_buffer,
                 pointer_t<X_EX_TITLE_TERMINATE_REGISTRATION> reg) {
  string_buffer.AppendFormat("%.8X(%.8X, %.8X)", reg.guest_address(),
                             reg->notification_routine, reg->priority);
}

void ExRegisterTitleTerminateNotification(
    pointer_t<X_EX_TITLE_TERMINATE_REGISTRATION> reg, dword_t create) {
  if (create) {
    // Adding.
    kernel_state()->RegisterTitleTerminateNotification(
        reg->notification_routine, reg->priority);
  } else {
    // Removing.
    kernel_state()->RemoveTitleTerminateNotification(reg->notification_routine);
  }
}
DECLARE_XBOXKRNL_EXPORT(ExRegisterTitleTerminateNotification,
                        ExportTag::kImplemented);

}  // namespace kernel
}  // namespace xe

void xe::kernel::xboxkrnl::RegisterModuleExports(
    xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) {
  SHIM_SET_MAPPING("xboxkrnl.exe", ExGetXConfigSetting, state);

  SHIM_SET_MAPPING("xboxkrnl.exe", XexCheckExecutablePrivilege, state);

  SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleHandle, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleSection, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", XexLoadImage, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", XexUnloadImage, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", XexGetProcedureAddress, state);
}
<commit_msg>module Retain instead of RetainHandle<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/logging.h"
#include "xenia/cpu/processor.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/objects/xuser_module.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/util/xex2.h"
#include "xenia/kernel/xboxkrnl_private.h"
#include "xenia/xbox.h"

namespace xe {
namespace kernel {

X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting,
                               void* buffer, uint16_t buffer_size,
                               uint16_t* required_size) {
  uint16_t setting_size = 0;
  uint32_t value = 0;

  // TODO(benvanik): have real structs here that just get copied from.
  // http://free60.org/XConfig
  // http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/Generic/ExConfig.h
  switch (category) {
    case 0x0002:
      // XCONFIG_SECURED_CATEGORY
      switch (setting) {
        case 0x0002:  // XCONFIG_SECURED_AV_REGION
          setting_size = 4;
          value = 0x00001000;  // USA/Canada
          break;
        default:
          assert_unhandled_case(setting);
          return X_STATUS_INVALID_PARAMETER_2;
      }
      break;
    case 0x0003:
      // XCONFIG_USER_CATEGORY
      switch (setting) {
        case 0x0001:  // XCONFIG_USER_TIME_ZONE_BIAS
        case 0x0002:  // XCONFIG_USER_TIME_ZONE_STD_NAME
        case 0x0003:  // XCONFIG_USER_TIME_ZONE_DLT_NAME
        case 0x0004:  // XCONFIG_USER_TIME_ZONE_STD_DATE
        case 0x0005:  // XCONFIG_USER_TIME_ZONE_DLT_DATE
        case 0x0006:  // XCONFIG_USER_TIME_ZONE_STD_BIAS
        case 0x0007:  // XCONFIG_USER_TIME_ZONE_DLT_BIAS
          setting_size = 4;
          // TODO(benvanik): get this value.
          value = 0;
          break;
        case 0x0009:  // XCONFIG_USER_LANGUAGE
          setting_size = 4;
          value = 0x00000001;  // English
          break;
        case 0x000A:  // XCONFIG_USER_VIDEO_FLAGS
          setting_size = 4;
          value = 0x00040000;
          break;
        case 0x000C:  // XCONFIG_USER_RETAIL_FLAGS
          setting_size = 4;
          // TODO(benvanik): get this value.
          value = 0;
          break;
        case 0x000E:  // XCONFIG_USER_COUNTRY
          setting_size = 4;
          // TODO(benvanik): get this value.
          value = 0;
          break;
        default:
          assert_unhandled_case(setting);
          return X_STATUS_INVALID_PARAMETER_2;
      }
      break;
    default:
      assert_unhandled_case(category);
      return X_STATUS_INVALID_PARAMETER_1;
  }

  if (buffer_size < setting_size) {
    return X_STATUS_BUFFER_TOO_SMALL;
  }
  if (!buffer && buffer_size) {
    return X_STATUS_INVALID_PARAMETER_3;
  }

  if (buffer) {
    xe::store_and_swap<uint32_t>(buffer, value);
  }
  if (required_size) {
    *required_size = setting_size;
  }

  return X_STATUS_SUCCESS;
}

SHIM_CALL ExGetXConfigSetting_shim(PPCContext* ppc_context,
                                   KernelState* kernel_state) {
  uint16_t category = SHIM_GET_ARG_16(0);
  uint16_t setting = SHIM_GET_ARG_16(1);
  uint32_t buffer_ptr = SHIM_GET_ARG_32(2);
  uint16_t buffer_size = SHIM_GET_ARG_16(3);
  uint32_t required_size_ptr = SHIM_GET_ARG_32(4);

  XELOGD("ExGetXConfigSetting(%.4X, %.4X, %.8X, %.4X, %.8X)", category, setting,
         buffer_ptr, buffer_size, required_size_ptr);

  void* buffer = buffer_ptr ? SHIM_MEM_ADDR(buffer_ptr) : NULL;
  uint16_t required_size = 0;
  X_STATUS result = xeExGetXConfigSetting(category, setting, buffer,
                                          buffer_size, &required_size);

  if (required_size_ptr) {
    SHIM_SET_MEM_16(required_size_ptr, required_size);
  }

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL XexCheckExecutablePrivilege_shim(PPCContext* ppc_context,
                                           KernelState* kernel_state) {
  uint32_t privilege = SHIM_GET_ARG_32(0);

  XELOGD("XexCheckExecutablePrivilege(%.8X)", privilege);

  // BOOL
  // DWORD Privilege

  // Privilege is bit position in xe_xex2_system_flags enum - so:
  // Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
  uint32_t mask = 1 << privilege;

  auto module = kernel_state->GetExecutableModule();
  if (!module) {
    SHIM_SET_RETURN_32(0);
    return;
  }

  uint32_t flags = 0;
  module->GetOptHeader<uint32_t>(XEX_HEADER_SYSTEM_FLAGS, &flags);

  SHIM_SET_RETURN_32((flags & mask) > 0);
}

SHIM_CALL XexGetModuleHandle_shim(PPCContext* ppc_context,
                                  KernelState* kernel_state) {
  uint32_t module_name_ptr = SHIM_GET_ARG_32(0);
  const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr);
  uint32_t hmodule_ptr = SHIM_GET_ARG_32(1);

  XELOGD("XexGetModuleHandle(%s, %.8X)", module_name, hmodule_ptr);

  object_ref<XModule> module;
  if (!module_name) {
    module = kernel_state->GetExecutableModule();
  } else {
    module = kernel_state->GetModule(module_name);
  }
  if (!module) {
    SHIM_SET_MEM_32(hmodule_ptr, 0);
    SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND);
    return;
  }

  // NOTE: we don't retain the handle for return.
  SHIM_SET_MEM_32(hmodule_ptr, module->hmodule_ptr());

  SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
}

SHIM_CALL XexGetModuleSection_shim(PPCContext* ppc_context,
                                   KernelState* kernel_state) {
  uint32_t hmodule = SHIM_GET_ARG_32(0);
  uint32_t name_ptr = SHIM_GET_ARG_32(1);
  const char* name = (const char*)SHIM_MEM_ADDR(name_ptr);
  uint32_t data_ptr = SHIM_GET_ARG_32(2);
  uint32_t size_ptr = SHIM_GET_ARG_32(3);

  XELOGD("XexGetModuleSection(%.8X, %s, %.8X, %.8X)", hmodule, name, data_ptr,
         size_ptr);

  X_STATUS result = X_STATUS_SUCCESS;

  auto module = XModule::GetFromHModule(kernel_state, SHIM_MEM_ADDR(hmodule));
  if (module) {
    uint32_t section_data = 0;
    uint32_t section_size = 0;
    result = module->GetSection(name, &section_data, &section_size);
    if (XSUCCEEDED(result)) {
      SHIM_SET_MEM_32(data_ptr, section_data);
      SHIM_SET_MEM_32(size_ptr, section_size);
    }
  } else {
    result = X_STATUS_INVALID_HANDLE;
  }

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL XexLoadImage_shim(PPCContext* ppc_context,
                            KernelState* kernel_state) {
  uint32_t module_name_ptr = SHIM_GET_ARG_32(0);
  const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr);
  uint32_t module_flags = SHIM_GET_ARG_32(1);
  uint32_t min_version = SHIM_GET_ARG_32(2);
  uint32_t hmodule_ptr = SHIM_GET_ARG_32(3);

  XELOGD("XexLoadImage(%s, %.8X, %.8X, %.8X)", module_name, module_flags,
         min_version, hmodule_ptr);

  X_STATUS result = X_STATUS_NO_SUCH_FILE;

  uint32_t hmodule = 0;
  auto module = kernel_state->GetModule(module_name);
  if (module) {
    // Existing module found.
    hmodule = module->hmodule_ptr();
    result = X_STATUS_SUCCESS;
  } else {
    // Not found; attempt to load as a user module.
    auto user_module = kernel_state->LoadUserModule(module_name);
    if (user_module) {
      user_module->Retain();
      hmodule = user_module->hmodule_ptr();
      result = X_STATUS_SUCCESS;
    }
  }

  // Increment the module's load count.
  if (hmodule) {
    auto ldr_data =
        kernel_memory()->TranslateVirtual<X_LDR_DATA_TABLE_ENTRY*>(hmodule);
    ldr_data->load_count++;
  }

  SHIM_SET_MEM_32(hmodule_ptr, hmodule);

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL XexUnloadImage_shim(PPCContext* ppc_context,
                              KernelState* kernel_state) {
  uint32_t hmodule = SHIM_GET_ARG_32(0);

  XELOGD("XexUnloadImage(%.8X)", hmodule);

  auto module = XModule::GetFromHModule(kernel_state, SHIM_MEM_ADDR(hmodule));
  if (!module) {
    SHIM_SET_RETURN_32(X_STATUS_INVALID_HANDLE);
    return;
  }

  // Can't unload kernel modules from user code.
  if (module->module_type() != XModule::ModuleType::kKernelModule) {
    auto ldr_data =
        kernel_state->memory()->TranslateVirtual<X_LDR_DATA_TABLE_ENTRY*>(
            hmodule);
    if (--ldr_data->load_count == 0) {
      // No more references, free it.
      module->Release();
      kernel_state->object_table()->RemoveHandle(module->handle());
    }
  }

  SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
}

SHIM_CALL XexGetProcedureAddress_shim(PPCContext* ppc_context,
                                      KernelState* kernel_state) {
  uint32_t hmodule = SHIM_GET_ARG_32(0);
  uint32_t ordinal = SHIM_GET_ARG_32(1);
  uint32_t out_function_ptr = SHIM_GET_ARG_32(2);

  // May be entry point?
  assert_not_zero(ordinal);

  bool is_string_name = (ordinal & 0xFFFF0000) != 0;
  auto string_name = reinterpret_cast<const char*>(SHIM_MEM_ADDR(ordinal));

  if (is_string_name) {
    XELOGD("XexGetProcedureAddress(%.8X, %.8X(%s), %.8X)", hmodule, ordinal,
           string_name, out_function_ptr);
  } else {
    XELOGD("XexGetProcedureAddress(%.8X, %.8X, %.8X)", hmodule, ordinal,
           out_function_ptr);
  }

  X_STATUS result = X_STATUS_INVALID_HANDLE;

  object_ref<XModule> module;
  if (!hmodule) {
    module = kernel_state->GetExecutableModule();
  } else {
    module = XModule::GetFromHModule(kernel_state, SHIM_MEM_ADDR(hmodule));
  }
  if (module) {
    uint32_t ptr;
    if (is_string_name) {
      ptr = module->GetProcAddressByName(string_name);
    } else {
      ptr = module->GetProcAddressByOrdinal(ordinal);
    }
    if (ptr) {
      SHIM_SET_MEM_32(out_function_ptr, ptr);
      result = X_STATUS_SUCCESS;
    } else {
      XELOGW("ERROR: XexGetProcedureAddress ordinal not found!");
      SHIM_SET_MEM_32(out_function_ptr, 0);
      result = X_STATUS_DRIVER_ORDINAL_NOT_FOUND;
    }
  }

  SHIM_SET_RETURN_32(result);
}

void AppendParam(StringBuffer& string_buffer,
                 pointer_t<X_EX_TITLE_TERMINATE_REGISTRATION> reg) {
  string_buffer.AppendFormat("%.8X(%.8X, %.8X)", reg.guest_address(),
                             reg->notification_routine, reg->priority);
}

void ExRegisterTitleTerminateNotification(
    pointer_t<X_EX_TITLE_TERMINATE_REGISTRATION> reg, dword_t create) {
  if (create) {
    // Adding.
    kernel_state()->RegisterTitleTerminateNotification(
        reg->notification_routine, reg->priority);
  } else {
    // Removing.
    kernel_state()->RemoveTitleTerminateNotification(reg->notification_routine);
  }
}
DECLARE_XBOXKRNL_EXPORT(ExRegisterTitleTerminateNotification,
                        ExportTag::kImplemented);

}  // namespace kernel
}  // namespace xe

void xe::kernel::xboxkrnl::RegisterModuleExports(
    xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) {
  SHIM_SET_MAPPING("xboxkrnl.exe", ExGetXConfigSetting, state);

  SHIM_SET_MAPPING("xboxkrnl.exe", XexCheckExecutablePrivilege, state);

  SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleHandle, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleSection, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", XexLoadImage, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", XexUnloadImage, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", XexGetProcedureAddress, state);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ccoll.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 22:37:33 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#include "cmdid.h"

#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif
#include "swmodule.hxx"
#include "view.hxx"
#include "wrtsh.hxx"
#include "globals.hrc"
#include "helpid.h"

#ifndef _SFX_STYFITEM_HXX //autogen
#include <sfx2/styfitem.hxx>
#endif

#include "uitool.hxx"
#include "ccoll.hxx"
#include "fmtcol.hxx"
#include "hintids.hxx"
#include "docsh.hxx"
#include "docstyle.hxx"
#include "hints.hxx"

#include "chrdlg.hrc"
#include "ccoll.hrc"

#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif

#define C2U(x) rtl::OUString::createFromAscii(x)

// ******************************************************************

//!! order of entries has to be the same as in
//!! CommandStruct SwCondCollItem::aCmds[]

const char *aCommandContext[COND_COMMAND_COUNT] =
{
    "TableHeader",
    "Table",
    "Frame",
    "Section",
    "Footnote",
    "Endnote",
    "Header",
    "Footer",
    "OutlineLevel1",
    "OutlineLevel2",
    "OutlineLevel3",
    "OutlineLevel4",
    "OutlineLevel5",
    "OutlineLevel6",
    "OutlineLevel7",
    "OutlineLevel8",
    "OutlineLevel9",
    "OutlineLevel10",
    "NumberingLevel1",
    "NumberingLevel2",
    "NumberingLevel3",
    "NumberingLevel4",
    "NumberingLevel5",
    "NumberingLevel6",
    "NumberingLevel7",
    "NumberingLevel8",
    "NumberingLevel9",
    "NumberingLevel10"
};

sal_Int16 GetCommandContextIndex( const rtl::OUString &rContextName )
{
    sal_Int16 nRes = -1;
    for (sal_Int16 i = 0;  nRes == -1 && i < COND_COMMAND_COUNT;  ++i)
    {
        if (rContextName.equalsAscii( aCommandContext[i] ))
            nRes = i;
    }
    return nRes;
}

rtl::OUString GetCommandContextByIndex( sal_Int16 nIndex )
{
    rtl::OUString aRes;
    if (0 <= nIndex  &&  nIndex < COND_COMMAND_COUNT)
    {
        aRes = C2U( aCommandContext[ nIndex ] );
    }
    return aRes;
}

// Globals ******************************************************************

//CHINA001 static USHORT __FAR_DATA aPageRg[] = {
//CHINA001 FN_COND_COLL, FN_COND_COLL,
//CHINA001 0
//CHINA001 };

// Achtung im Code wird dieses Array direkt (0, 1, ...) indiziert
//CHINA001 static long nTabs[] =
//CHINA001  {   2, // Number of Tabs
//CHINA001 0, 100
//CHINA001  };

CommandStruct SwCondCollItem::aCmds[] = {
         PARA_IN_TABLEHEAD, 0,
         PARA_IN_TABLEBODY, 0,
         PARA_IN_FRAME,     0,
         PARA_IN_SECTION,   0,
         PARA_IN_FOOTENOTE, 0,
         PARA_IN_ENDNOTE,   0,
         PARA_IN_HEADER,    0,
         PARA_IN_FOOTER,    0,
         PARA_IN_OUTLINE,   0,
         PARA_IN_OUTLINE,   1,
         PARA_IN_OUTLINE,   2,
         PARA_IN_OUTLINE,   3,
         PARA_IN_OUTLINE,   4,
         PARA_IN_OUTLINE,   5,
         PARA_IN_OUTLINE,   6,
         PARA_IN_OUTLINE,   7,
         PARA_IN_OUTLINE,   8,
         PARA_IN_OUTLINE,   9,
         PARA_IN_LIST,      0,
         PARA_IN_LIST,      1,
         PARA_IN_LIST,      2,
         PARA_IN_LIST,      3,
         PARA_IN_LIST,      4,
         PARA_IN_LIST,      5,
         PARA_IN_LIST,      6,
         PARA_IN_LIST,      7,
         PARA_IN_LIST,      8,
         PARA_IN_LIST,      9
    };

TYPEINIT1_AUTOFACTORY(SwCondCollItem, SfxPoolItem)

/****************************************************************************
Page: Ctor
****************************************************************************/

//CHINA001 SwCondCollPage::SwCondCollPage(Window *pParent, const SfxItemSet &rSet)
//CHINA001
//CHINA001 : SfxTabPage(pParent, SW_RES(TP_CONDCOLL), rSet),
//CHINA001 aConditionFL( this, ResId( FL_CONDITION )),
//CHINA001 aConditionCB( this, ResId( CB_CONDITION ) ),
//CHINA001 aContextFT  ( this, ResId( FT_CONTEXT    ) ),
//CHINA001 aUsedFT     ( this, ResId( FT_USED       ) ),
//CHINA001 aTbLinks(      this, ResId( TB_CONDCOLLS ) ),
//CHINA001 aStyleFT    ( this, ResId( FT_STYLE  ) ),
//CHINA001 aStyleLB    ( this, ResId( LB_STYLE  ) ),
//CHINA001 aFilterLB   ( this, ResId( LB_FILTER     ) ),
//CHINA001 aRemovePB   ( this, ResId( PB_REMOVE     ) ),
//CHINA001 aAssignPB   ( this, ResId( PB_ASSIGN     ) ),
//CHINA001 sNoTmpl      (       ResId( STR_NOTEMPL  ) ),
//CHINA001 aStrArr  (       ResId( STR_REGIONS  ) ),
//CHINA001 rSh(::GetActiveView()->GetWrtShell()),
//CHINA001 pFmt(0),
//CHINA001 pCmds( SwCondCollItem::GetCmds() ),
//CHINA001 bNewTemplate(FALSE)
//CHINA001 {
//CHINA001 FreeResource();
//CHINA001 SetExchangeSupport();
//CHINA001
//CHINA001 // Handler installieren
//CHINA001 aConditionCB.SetClickHdl(    LINK(this, SwCondCollPage, OnOffHdl));
//CHINA001 aTbLinks.SetDoubleClickHdl( LINK(this, SwCondCollPage, AssignRemoveHdl ));
//CHINA001 aStyleLB.SetDoubleClickHdl( LINK(this, SwCondCollPage, AssignRemoveHdl ));
//CHINA001 aRemovePB.SetClickHdl(       LINK(this, SwCondCollPage, AssignRemoveHdl ));
//CHINA001 aAssignPB.SetClickHdl(       LINK(this, SwCondCollPage, AssignRemoveHdl ));
//CHINA001 aTbLinks.SetSelectHdl(       LINK(this, SwCondCollPage, SelectHdl));
//CHINA001 aStyleLB.SetSelectHdl(       LINK(this, SwCondCollPage, SelectHdl));
//CHINA001 aFilterLB.SetSelectHdl(      LINK(this, SwCondCollPage, SelectHdl));
//CHINA001
//CHINA001 aTbLinks.SetWindowBits(WB_HSCROLL|WB_CLIPCHILDREN);
//CHINA001 aTbLinks.SetSelectionMode( SINGLE_SELECTION );
//CHINA001 aTbLinks.SetTabs( &nTabs[0], MAP_APPFONT );
//CHINA001 aTbLinks.Resize();   // OS: Hack fuer richtige Selektion
//CHINA001 aTbLinks.SetSpaceBetweenEntries( 0 );
//CHINA001 aTbLinks.SetHelpId(HID_COND_COLL_TABLIST);
//CHINA001
//CHINA001 SfxStyleFamilies aFamilies(SW_RES(DLG_STYLE_DESIGNER));
//CHINA001 const SfxStyleFamilyItem* pFamilyItem;
//CHINA001 USHORT nCount = aFamilies.Count();
//CHINA001 USHORT i;
//CHINA001
//CHINA001 for( i = 0; i < nCount; ++i)
//CHINA001 {
//CHINA001 if(SFX_STYLE_FAMILY_PARA == (USHORT)(pFamilyItem = aFamilies.GetObject(i))->GetFamily())
//CHINA001 break;
//CHINA001  }
//CHINA001
//CHINA001 const SfxStyleFilter& rFilterList = pFamilyItem->GetFilterList();
//CHINA001 for( i = 0; i < rFilterList.Count(); ++i)
//CHINA001 {
//CHINA001 aFilterLB.InsertEntry(rFilterList.GetObject(i)->aName);
//CHINA001 USHORT* pFilter = new USHORT(rFilterList.GetObject(i)->nFlags);
//CHINA001 aFilterLB.SetEntryData(i, pFilter);
//CHINA001  }
//CHINA001 aFilterLB.SelectEntryPos(1);
//CHINA001
//CHINA001 aTbLinks.Show();
//CHINA001
//CHINA001 }

/****************************************************************************
Page: Dtor
****************************************************************************/

//CHINA001 __EXPORT SwCondCollPage::~SwCondCollPage()
//CHINA001 {
//CHINA001 for(USHORT i = 0; i < aFilterLB.GetEntryCount(); ++i)
//CHINA001 delete (USHORT*)aFilterLB.GetEntryData(i);
//CHINA001
//CHINA001 }

//CHINA001 int __EXPORT SwCondCollPage::DeactivatePage(SfxItemSet * pSet)
//CHINA001 {
//CHINA001 if( pSet )
//CHINA001 FillItemSet(*pSet);
//CHINA001
//CHINA001 return LEAVE_PAGE;
//CHINA001 }

/****************************************************************************
Page: Factory
****************************************************************************/

//CHINA001 SfxTabPage* __EXPORT SwCondCollPage::Create(Window *pParent, const SfxItemSet &rSet)
//CHINA001 {
//CHINA001 return new SwCondCollPage(pParent, rSet);
//CHINA001 }

/****************************************************************************
Page: FillItemSet-Overload
****************************************************************************/

//CHINA001 BOOL __EXPORT SwCondCollPage::FillItemSet(SfxItemSet &rSet)
//CHINA001 {
//CHINA001 BOOL bModified = TRUE;
//CHINA001 SwCondCollItem aCondItem;
//CHINA001 for(USHORT i = 0; i < aStrArr.Count(); i++)
//CHINA001  {
//CHINA001 String sEntry = aTbLinks.GetEntryText(i, 1);
//CHINA001 aCondItem.SetStyle( &sEntry, i);
//CHINA001  }
//CHINA001 rSet.Put(aCondItem);
//CHINA001 return bModified;
//CHINA001 }

/****************************************************************************
Page: Reset-Overload
****************************************************************************/

//CHINA001 void __EXPORT SwCondCollPage::Reset(const SfxItemSet &rSet)
//CHINA001 {
//CHINA001 if(bNewTemplate)
//CHINA001 aConditionCB.Enable();
//CHINA001 if(RES_CONDTXTFMTCOLL == pFmt->Which())
//CHINA001 aConditionCB.Check();
//CHINA001 OnOffHdl(&aConditionCB);
//CHINA001
//CHINA001 aTbLinks.Clear();
//CHINA001
//CHINA001 SfxStyleSheetBasePool* pPool = rSh.GetView().GetDocShell()->GetStyleSheetPool();
//CHINA001 pPool->SetSearchMask(SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL);
//CHINA001 aStyleLB.Clear();
//CHINA001 const SfxStyleSheetBase* pBase = pPool->First();
//CHINA001 while( pBase )
//CHINA001  {
//CHINA001 if(!pFmt || pBase->GetName() != pFmt->GetName())
//CHINA001 aStyleLB.InsertEntry(pBase->GetName());
//CHINA001 pBase = pPool->Next();
//CHINA001  }
//CHINA001 aStyleLB.SelectEntryPos(0);
//CHINA001
//CHINA001 for( USHORT n = 0; n < aStrArr.Count(); n++)
//CHINA001  {
//CHINA001 String aEntry( aStrArr.GetString(n) );
//CHINA001 aEntry += '\t';
//CHINA001
//CHINA001 const SwCollCondition* pCond;
//CHINA001 if( pFmt && RES_CONDTXTFMTCOLL == pFmt->Which() &&
//CHINA001 0 != ( pCond = ((SwConditionTxtFmtColl*)pFmt)->
//CHINA001 HasCondition( SwCollCondition( 0, pCmds[n].nCnd, pCmds[n].nSubCond ) ) )
//CHINA001 && pCond->GetTxtFmtColl() )
//CHINA001      {
//CHINA001 aEntry += pCond->GetTxtFmtColl()->GetName();
//CHINA001      }
//CHINA001
//CHINA001 SvLBoxEntry* pE = aTbLinks.InsertEntry( aEntry, n );
//CHINA001 if(0 == n)
//CHINA001 aTbLinks.Select(pE);
//CHINA001  }
//CHINA001
//CHINA001 }

/****************************************************************************

****************************************************************************/

//CHINA001 USHORT* __EXPORT SwCondCollPage::GetRanges()
//CHINA001 {
//CHINA001 return aPageRg;
//CHINA001 }

/****************************************************************************

****************************************************************************/

//CHINA001 IMPL_LINK( SwCondCollPage, OnOffHdl, CheckBox*, pBox )
//CHINA001 {
//CHINA001 const BOOL bEnable = pBox->IsChecked();
//CHINA001 aContextFT.Enable( bEnable );
//CHINA001 aUsedFT   .Enable( bEnable );
//CHINA001 aTbLinks  .Enable( bEnable );
//CHINA001 aStyleFT  .Enable( bEnable );
//CHINA001 aStyleLB  .Enable( bEnable );
//CHINA001 aFilterLB .Enable( bEnable );
//CHINA001 aRemovePB .Enable( bEnable );
//CHINA001 aAssignPB .Enable( bEnable );
//CHINA001 if( bEnable )
//CHINA001 SelectHdl(0);
//CHINA001 return 0;
//CHINA001 }
//CHINA001
/****************************************************************************

****************************************************************************/

//CHINA001 IMPL_LINK( SwCondCollPage, AssignRemoveHdl, PushButton*, pBtn)
//CHINA001 {
//CHINA001 SvLBoxEntry* pE = aTbLinks.FirstSelected();
//CHINA001 ULONG nPos;
//CHINA001 if( !pE || LISTBOX_ENTRY_NOTFOUND ==
//CHINA001 ( nPos = aTbLinks.GetModel()->GetAbsPos( pE ) ) )
//CHINA001  {
//CHINA001 ASSERT( pE, "wo kommt der leere Eintrag her?" );
//CHINA001 return 0;
//CHINA001  }
//CHINA001
//CHINA001 String sSel = aStrArr.GetString( USHORT(nPos) );
//CHINA001 sSel += '\t';
//CHINA001
//CHINA001 const BOOL bAssEnabled = pBtn != &aRemovePB && aAssignPB.IsEnabled();
//CHINA001 aAssignPB.Enable( !bAssEnabled );
//CHINA001 aRemovePB.Enable(  bAssEnabled );
//CHINA001 if ( bAssEnabled )
//CHINA001 sSel += aStyleLB.GetSelectEntry();
//CHINA001
//CHINA001 aTbLinks.SetUpdateMode(FALSE);
//CHINA001 aTbLinks.GetModel()->Remove(pE);
//CHINA001 pE = aTbLinks.InsertEntry(sSel, nPos);
//CHINA001 aTbLinks.Select(pE);
//CHINA001 aTbLinks.MakeVisible(pE);
//CHINA001 aTbLinks.SetUpdateMode(TRUE);
//CHINA001 return 0;
//CHINA001 }
//CHINA001
/****************************************************************************

****************************************************************************/

//CHINA001 IMPL_LINK( SwCondCollPage, SelectHdl, ListBox*, pBox)
//CHINA001 {
//CHINA001 if(pBox == &aFilterLB)
//CHINA001  {
//CHINA001 aStyleLB.Clear();
//CHINA001 USHORT nSearchFlags = pBox->GetSelectEntryPos();
//CHINA001 nSearchFlags = *(USHORT*)aFilterLB.GetEntryData(nSearchFlags);
//CHINA001 SfxStyleSheetBasePool* pPool = rSh.GetView().GetDocShell()->GetStyleSheetPool();
//CHINA001 pPool->SetSearchMask(SFX_STYLE_FAMILY_PARA, nSearchFlags);
//CHINA001 const SfxStyleSheetBase* pBase = pPool->First();
//CHINA001 while( pBase )
//CHINA001      {
//CHINA001 if(!pFmt || pBase->GetName() != pFmt->GetName())
//CHINA001 aStyleLB.InsertEntry(pBase->GetName());
//CHINA001 pBase = pPool->Next();
//CHINA001      }
//CHINA001 aStyleLB.SelectEntryPos(0);
//CHINA001 SelectHdl(&aStyleLB);
//CHINA001
//CHINA001  }
//CHINA001  else
//CHINA001  {
//CHINA001 String sTbEntry;
//CHINA001 SvLBoxEntry* pE = aTbLinks.FirstSelected();
//CHINA001 if(pE)
//CHINA001 sTbEntry = aTbLinks.GetEntryText(pE);
//CHINA001 sTbEntry = sTbEntry.GetToken(1, '\t');
//CHINA001 String sStyle = aStyleLB.GetSelectEntry();
//CHINA001
//CHINA001 aAssignPB.Enable( sStyle != sTbEntry && aConditionCB.IsChecked() );
//CHINA001
//CHINA001 if(pBox != &aStyleLB)
//CHINA001 aRemovePB.Enable( aConditionCB.IsChecked() && sTbEntry.Len() );
//CHINA001  }
//CHINA001 return 0;
//CHINA001 }

/****************************************************************************

****************************************************************************/

//CHINA001 void SwCondCollPage::SetCollection( SwFmt* pFormat, BOOL bNew )
//CHINA001 {
//CHINA001 pFmt = pFormat;
//CHINA001 bNewTemplate = bNew;
//CHINA001 }

/****************************************************************************
    Item fuer den Transport der Bedingungstabelle
****************************************************************************/

SwCondCollItem::SwCondCollItem(USHORT nWhich ) :
    SfxPoolItem(nWhich)
{

}
/****************************************************************************

****************************************************************************/

SwCondCollItem::~SwCondCollItem()
{
}

/****************************************************************************

****************************************************************************/

SfxPoolItem*   SwCondCollItem::Clone( SfxItemPool *pPool ) const
{
    return new SwCondCollItem(*this);
}

/****************************************************************************

****************************************************************************/

int SwCondCollItem::operator==( const SfxPoolItem& rItem) const
{
    DBG_ASSERT( SfxPoolItem::operator==(rItem), "unterschiedliche Typen" );
    BOOL bReturn = TRUE;
    for(USHORT i = 0; i < COND_COMMAND_COUNT; i++)
        if(sStyles[i] != ((SwCondCollItem&)rItem).sStyles[i])
        {
            bReturn = FALSE;
            break;
        }

    return bReturn;
}

/****************************************************************************

****************************************************************************/

const String&   SwCondCollItem::GetStyle(USHORT nPos) const
{
#ifndef IRIX
    return nPos < COND_COMMAND_COUNT ? sStyles[nPos] : aEmptyStr;
#else
    return nPos < COND_COMMAND_COUNT ? (String)sStyles[nPos] : aEmptyStr;
#endif
}

/****************************************************************************

****************************************************************************/

void SwCondCollItem::SetStyle(const String* pStyle, USHORT nPos)
{
    if( nPos < COND_COMMAND_COUNT )
#ifndef IRIX
        sStyles[nPos] = pStyle ? *pStyle : aEmptyStr;
#else
        sStyles[nPos] = pStyle ? (String)*pStyle : aEmptyStr;
#endif
}

/****************************************************************************

****************************************************************************/

const CommandStruct* SwCondCollItem::GetCmds()
{
    return aCmds;
}

<commit_msg>INTEGRATION: CWS swwarnings (1.13.222); FILE MERGED 2007/06/01 07:17:40 tl 1.13.222.5: #i69287# warning-free code 2007/04/13 12:17:44 tl 1.13.222.4: #i69287# binfilter related comments removed 2007/04/03 13:01:01 tl 1.13.222.3: #i69287# warning-free code 2007/03/26 12:08:47 tl 1.13.222.2: #i69287# warning-free code 2007/03/05 12:45:38 tl 1.13.222.1: #i69287# warning-free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ccoll.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 10:19:10 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#include "cmdid.h"

#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif
#include "swmodule.hxx"
#include "view.hxx"
#include "wrtsh.hxx"
#include "globals.hrc"
#include "helpid.h"

#ifndef _SFX_STYFITEM_HXX //autogen
#include <sfx2/styfitem.hxx>
#endif

#include "uitool.hxx"
#include "ccoll.hxx"
#include "fmtcol.hxx"
#include "hintids.hxx"
#include "docsh.hxx"
#include "docstyle.hxx"
#include "hints.hxx"

#include "chrdlg.hrc"
#include "ccoll.hrc"

#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif

#include <unomid.h>

// ******************************************************************

//!! order of entries has to be the same as in
//!! CommandStruct SwCondCollItem::aCmds[]

const char *aCommandContext[COND_COMMAND_COUNT] =
{
    "TableHeader",
    "Table",
    "Frame",
    "Section",
    "Footnote",
    "Endnote",
    "Header",
    "Footer",
    "OutlineLevel1",
    "OutlineLevel2",
    "OutlineLevel3",
    "OutlineLevel4",
    "OutlineLevel5",
    "OutlineLevel6",
    "OutlineLevel7",
    "OutlineLevel8",
    "OutlineLevel9",
    "OutlineLevel10",
    "NumberingLevel1",
    "NumberingLevel2",
    "NumberingLevel3",
    "NumberingLevel4",
    "NumberingLevel5",
    "NumberingLevel6",
    "NumberingLevel7",
    "NumberingLevel8",
    "NumberingLevel9",
    "NumberingLevel10"
};

sal_Int16 GetCommandContextIndex( const rtl::OUString &rContextName )
{
    sal_Int16 nRes = -1;
    for (sal_Int16 i = 0;  nRes == -1 && i < COND_COMMAND_COUNT;  ++i)
    {
        if (rContextName.equalsAscii( aCommandContext[i] ))
            nRes = i;
    }
    return nRes;
}

rtl::OUString GetCommandContextByIndex( sal_Int16 nIndex )
{
    rtl::OUString aRes;
    if (0 <= nIndex  &&  nIndex < COND_COMMAND_COUNT)
    {
        aRes = C2U( aCommandContext[ nIndex ] );
    }
    return aRes;
}

// Globals ******************************************************************

CommandStruct SwCondCollItem::aCmds[] =
{
    { PARA_IN_TABLEHEAD,    0 },
    { PARA_IN_TABLEBODY,    0 },
    { PARA_IN_FRAME,        0 },
    { PARA_IN_SECTION,      0 },
    { PARA_IN_FOOTENOTE,    0 },
    { PARA_IN_ENDNOTE,      0 },
    { PARA_IN_HEADER,       0 },
    { PARA_IN_FOOTER,       0 },
    { PARA_IN_OUTLINE,      0 },
    { PARA_IN_OUTLINE,      1 },
    { PARA_IN_OUTLINE,      2 },
    { PARA_IN_OUTLINE,      3 },
    { PARA_IN_OUTLINE,      4 },
    { PARA_IN_OUTLINE,      5 },
    { PARA_IN_OUTLINE,      6 },
    { PARA_IN_OUTLINE,      7 },
    { PARA_IN_OUTLINE,      8 },
    { PARA_IN_OUTLINE,      9 },
    { PARA_IN_LIST,         0 },
    { PARA_IN_LIST,         1 },
    { PARA_IN_LIST,         2 },
    { PARA_IN_LIST,         3 },
    { PARA_IN_LIST,         4 },
    { PARA_IN_LIST,         5 },
    { PARA_IN_LIST,         6 },
    { PARA_IN_LIST,         7 },
    { PARA_IN_LIST,         8 },
    { PARA_IN_LIST,         9 }
};

TYPEINIT1_AUTOFACTORY(SwCondCollItem, SfxPoolItem)

/****************************************************************************
    Item fuer den Transport der Bedingungstabelle
****************************************************************************/

SwCondCollItem::SwCondCollItem(USHORT _nWhich ) :
    SfxPoolItem(_nWhich)
{

}
/****************************************************************************

****************************************************************************/

SwCondCollItem::~SwCondCollItem()
{
}

/****************************************************************************

****************************************************************************/

SfxPoolItem*   SwCondCollItem::Clone( SfxItemPool * /*pPool*/ ) const
{
    return new SwCondCollItem(*this);
}

/****************************************************************************

****************************************************************************/

int SwCondCollItem::operator==( const SfxPoolItem& rItem) const
{
    DBG_ASSERT( SfxPoolItem::operator==(rItem), "unterschiedliche Typen" );
    BOOL bReturn = TRUE;
    for(USHORT i = 0; i < COND_COMMAND_COUNT; i++)
        if(sStyles[i] != ((SwCondCollItem&)rItem).sStyles[i])
        {
            bReturn = FALSE;
            break;
        }

    return bReturn;
}

/****************************************************************************

****************************************************************************/

const String&   SwCondCollItem::GetStyle(USHORT nPos) const
{
#ifndef IRIX
    return nPos < COND_COMMAND_COUNT ? sStyles[nPos] : aEmptyStr;
#else
    return nPos < COND_COMMAND_COUNT ? (String)sStyles[nPos] : aEmptyStr;
#endif
}

/****************************************************************************

****************************************************************************/

void SwCondCollItem::SetStyle(const String* pStyle, USHORT nPos)
{
    if( nPos < COND_COMMAND_COUNT )
#ifndef IRIX
        sStyles[nPos] = pStyle ? *pStyle : aEmptyStr;
#else
        sStyles[nPos] = pStyle ? (String)*pStyle : aEmptyStr;
#endif
}

/****************************************************************************

****************************************************************************/

const CommandStruct* SwCondCollItem::GetCmds()
{
    return aCmds;
}

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#include    "../Characters/Character.h"
#include    "../Characters/String.h"
#include    "../Characters/StringBuilder.h"
#include    "../Containers/Common.h"
#include    "../Debug/Trace.h"

#include    "InputStream.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Streams;

using   Characters::Character;
using   Characters::String;
using   Characters::StringBuilder;
using   Memory::BLOB;
using   Memory::Byte;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

/*
 ********************************************************************************
 ************************* Streams::InputStream<ELEMENT_TYPE> *******************
 ********************************************************************************
 */
template    <>
template    <>
String InputStream<Character>::ReadLine () const
{
    Require (IsSeekable ());
    StringBuilder   result;
    while (true) {
        Character   c   =   ReadCharacter ();
        if (c.GetCharacterCode () == '\0') {
            // EOF
            return result.str ();
        }
        result.push_back (c);
        if (c == '\n') {
            return result.str ();
        }
        else if (c == '\r') {
            Character   c   =   ReadCharacter ();
            // if CR is follwed by LF, append that to result too before returning. Otherwise, put the character back
            if (c == '\n') {
                result.push_back (c);
                return result.str ();
            }
            else {
                Seek (Whence::eFromCurrent, -1);
            }
            return result.str ();
        }
    }
}

template    <>
template    <>
Characters::Character   InputStream<Characters::Character>::ReadCharacter () const
{
    Characters::Character   c;
    if (Read (&c, &c + 1) == 1) {
        return c;
    }
    return '\0';
}

template    <>
template    <>
Traversal::Iterable<String> InputStream<Character>::ReadLines () const
{
    InputStream<Character> copyOfStream =  *this;
    return Traversal::CreateGenerator<String> ([copyOfStream] () -> Memory::Optional<String> {
        String  line = copyOfStream.ReadLine ();
        if (line.empty ())
        {
            return Memory::Optional<String> ();
        }
        else {
            return line;
        }
    });
}

template    <>
template    <>
String InputStream<Character>::ReadAll (size_t upTo) const
{
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    Debug::TraceContextBumper ctx (L"InputStream<Character>::ReadAll");
    DbgTrace (L"(upTo: %u)", upTo);
#endif
    Characters::StringBuilder result;
    size_t  nEltsLeft = upTo;
    while (nEltsLeft > 0) {
        Character buf[16 * 1024];
        Character*  s   =   std::begin (buf);
        Character*  e   =   std::end (buf);
        if (nEltsLeft < NEltsOf (buf)) {
            e = s + nEltsLeft;
        }
        size_t n = Read (s, e);
        Assert (0 <= n and n <= nEltsLeft);
        Assert (0 <= n and n <= NEltsOf (buf));
        if (n == 0) {
            break;
        }
        else {
            Assert (n <= nEltsLeft);
            nEltsLeft -= n;
            result.Append (s, s + n);
        }
    }
    return result.str ();
}

template    <>
template    <>
Memory::BLOB InputStream<Byte>::ReadAll (size_t upTo) const
{
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    Debug::TraceContextBumper ctx (L"InputStream<Byte>::ReadAll");
    DbgTrace (L"(upTo: %u)", upTo);
#endif
    if (IsSeekable ()) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("Seekable case");
#endif
        SeekOffsetType  size = GetOffsetToEndOfStream ();
        if (size >= numeric_limits<size_t>::max ()) {
            Execution::Throw (bad_alloc ());
        }
        size_t sb = static_cast<size_t> (size);
        sb = min (sb, upTo);
        if (sb == 0) {
            return BLOB ();
        }
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("Seekable case: sb=%d", sb);
#endif
        // @todo this isn't crazy worse than SmallStackBuffer, because if sb is the size read and wouldn't
        // fit in a small stack buffer (stack part) - we avoid a second allocation.
        // But - on balance - thats a lot of iffs. And we probably should use SmallStackBuffer and just
        // do another alloc if needed. Maybe use an artificially large stack allocaiton here so we are likely to
        // actually use the stack, or new stl 'get_temporeary_buffer' or wahtever the new routine is for stack allocs
        //
        Byte* b = new Byte[sb];   // if this fails, we had no way to create the BLOB
        try {
            size_t n = this->Read (b, b + sb);
            Assert (n <= sb);
            return BLOB::Attach (b, b + n);
        }
        catch (...) {
            delete[] (b);
            Execution::ReThrow ();
        }
    }
    else {
        // Less efficient implementation
        vector<Byte>    r;
        for (size_t nEltsLeft = upTo; nEltsLeft != 0; ) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
            DbgTrace ("Unseekable case: nEltsLeft=%d", nEltsLeft);
#endif
            Byte            buf[64 * 1024];
            Byte*           s           =   std::begin (buf);
            Byte*           e           =   std::end (buf);
            if (nEltsLeft < NEltsOf (buf)) {
                e = s + nEltsLeft;
            }
            Assert (s < e);
            size_t          n           =   Read (s, e);
            Assert (0 <= n and n <= nEltsLeft);
            Assert (0 <= n and n <= NEltsOf (buf));
            if (n == 0) {
                break;
            }
            else {
                // @todo???
                //      could also maintain linked list - std::list<> - of BLOBs, and then construct BLOB from
                //      list of BLOBs - that would be quite efficeint too - maybe more
                Containers::ReserveSpeedTweekAddNCapacity (r, n, 32 * 1024); // grow exponentially, so not too many reallocs
                Assert (n <= nEltsLeft);
                nEltsLeft -= n;
                r.insert (r.end (), s, s + n);
            }
        }
        return BLOB (r);
    }
}
<commit_msg>improved DBGTrace code for InputStream::ReadAll logic; Tightened some assertions; and fixed important bug (still not perfrect)  on InputStream<Byte>::ReadAll() seekable case<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#include    "../Characters/Character.h"
#include    "../Characters/String.h"
#include    "../Characters/StringBuilder.h"
#include    "../Containers/Common.h"
#include    "../Debug/Trace.h"

#include    "InputStream.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Streams;

using   Characters::Character;
using   Characters::String;
using   Characters::StringBuilder;
using   Memory::BLOB;
using   Memory::Byte;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

/*
 ********************************************************************************
 ************************* Streams::InputStream<ELEMENT_TYPE> *******************
 ********************************************************************************
 */
template    <>
template    <>
String InputStream<Character>::ReadLine () const
{
    Require (IsSeekable ());
    StringBuilder   result;
    while (true) {
        Character   c   =   ReadCharacter ();
        if (c.GetCharacterCode () == '\0') {
            // EOF
            return result.str ();
        }
        result.push_back (c);
        if (c == '\n') {
            return result.str ();
        }
        else if (c == '\r') {
            Character   c   =   ReadCharacter ();
            // if CR is follwed by LF, append that to result too before returning. Otherwise, put the character back
            if (c == '\n') {
                result.push_back (c);
                return result.str ();
            }
            else {
                Seek (Whence::eFromCurrent, -1);
            }
            return result.str ();
        }
    }
}

template    <>
template    <>
Characters::Character   InputStream<Characters::Character>::ReadCharacter () const
{
    Characters::Character   c;
    if (Read (&c, &c + 1) == 1) {
        return c;
    }
    return '\0';
}

template    <>
template    <>
Traversal::Iterable<String> InputStream<Character>::ReadLines () const
{
    InputStream<Character> copyOfStream =  *this;
    return Traversal::CreateGenerator<String> ([copyOfStream] () -> Memory::Optional<String> {
        String  line = copyOfStream.ReadLine ();
        if (line.empty ())
        {
            return Memory::Optional<String> ();
        }
        else {
            return line;
        }
    });
}

template    <>
template    <>
String InputStream<Character>::ReadAll (size_t upTo) const
{
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    Debug::TraceContextBumper ctx (L"InputStream<Character>::ReadAll");
    DbgTrace (L"(upTo: %u)", upTo);
#endif
    Characters::StringBuilder result;
    size_t  nEltsLeft = upTo;
    while (nEltsLeft > 0) {
        Character buf[16 * 1024];
        Character*  s   =   std::begin (buf);
        Character*  e   =   std::end (buf);
        if (nEltsLeft < NEltsOf (buf)) {
            e = s + nEltsLeft;
        }
        size_t n = Read (s, e);
        Assert (0 <= n and n <= nEltsLeft);
        Assert (0 <= n and n < NEltsOf (buf));
        if (n == 0) {
            break;
        }
        else {
            Assert (n <= nEltsLeft);
            nEltsLeft -= n;
            result.Append (s, s + n);
        }
    }
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    DbgTrace (L"Returning %d characters", result.GetLength ());
#endif
    return result.str ();
}

template    <>
template    <>
Memory::BLOB InputStream<Byte>::ReadAll (size_t upTo) const
{
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    Debug::TraceContextBumper ctx (L"InputStream<Byte>::ReadAll");
    DbgTrace (L"(upTo: %u)", upTo);
#endif
    if (IsSeekable ()) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("Seekable case");
#endif
        SeekOffsetType  size = GetOffsetToEndOfStream ();
        if (size >= numeric_limits<size_t>::max ()) {
            Execution::Throw (bad_alloc ());
        }
        size_t sb = static_cast<size_t> (size);
        sb = min (sb, upTo);
        if (sb == 0) {
            return BLOB ();
        }
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("(should be able to read)sb=%u", sb);
#endif
        // @todo this isn't crazy worse than SmallStackBuffer, because if sb is the size read and wouldn't
        // fit in a small stack buffer (stack part) - we avoid a second allocation.
        // But - on balance - thats a lot of iffs. And we probably should use SmallStackBuffer and just
        // do another alloc if needed. Maybe use an artificially large stack allocaiton here so we are likely to
        // actually use the stack, or new stl 'get_temporeary_buffer' or wahtever the new routine is for stack allocs
        //
        Byte* b = new Byte[sb];   // if this fails, we had no way to create the BLOB
        try {

            // Even though we've allocated a large enough buffer, the guarnatee of Read () is that it will return
            // > 0, or less or equal than args buf size, but only 0 means EOF, so must re-read if more out there.
#if 1
            size_t  bytesLeft =  sb;
            Byte*   pi = b;
            while (bytesLeft > 0) {
                size_t n = Read (pi, pi + bytesLeft);
                Assert (n <= bytesLeft);
                bytesLeft -= n;
                pi += n;
                if (n == 0) {
                    AssertNotReached ();        // @todo decide how to handle this - means stream changed size - doesnt work with this
                    // algorithm, but not necesarily SB disallowed.
                    // for now - hack
                    sb -= bytesLeft;
                }
            }
#else
            // WRONG
            size_t n = Read (b, b + sb);
            Assert (n <= sb);
#endif
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
            DbgTrace ("returning %u bytes", sb);
#endif
            return BLOB::Attach (b, b + sb);
        }
        catch (...) {
            delete[] (b);
            Execution::ReThrow ();
        }
    }
    else {
        // Less efficient implementation
        vector<Byte>    r;
        for (size_t nEltsLeft = upTo; nEltsLeft != 0; ) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
            DbgTrace ("Unseekable case: nEltsLeft=%u", nEltsLeft);
#endif
            Byte            buf[64 * 1024];
            Byte*           s           =   std::begin (buf);
            Byte*           e           =   std::end (buf);
            if (nEltsLeft < NEltsOf (buf)) {
                e = s + nEltsLeft;
            }
            Assert (s < e);
            size_t          n           =   Read (s, e);
            Assert (0 <= n and n <= nEltsLeft);
            Assert (0 <= n and n < NEltsOf (buf));
            if (n == 0) {
                break;
            }
            else {
                // @todo???
                //      could also maintain linked list - std::list<> - of BLOBs, and then construct BLOB from
                //      list of BLOBs - that would be quite efficeint too - maybe more
                Containers::ReserveSpeedTweekAddNCapacity (r, n, 32 * 1024); // grow exponentially, so not too many reallocs
                Assert (n <= nEltsLeft);
                nEltsLeft -= n;
                r.insert (r.end (), s, s + n);
            }
        }
        return BLOB (r);
    }
}
<|endoftext|>