<commit_before>#include "NodeTreeSerializer.h"
#include "NodeTree.h"
#include "NodeType.h"
#include "NodeSystem.h"

#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include <QDebug>

NodeTreeSerializer::NodeTreeSerializer(const std::string& rootDir)
	: _rootDirectory(rootDir)
{
}

void NodeTreeSerializer::setRootDirectory(const std::string& rootDir)
{
	_rootDirectory = rootDir;
}

QJsonObject NodeTreeSerializer::serializeJson(const std::shared_ptr<NodeTree>& nodeTree)
{
	// Iterate over all nodes and serialize it as JSON value of JSON array
	QJsonArray jsonNodes;
	auto nodeIt = nodeTree->createNodeIterator();
	NodeID nodeID;
	while(const Node* node = nodeIt->next(nodeID))
	{
		QJsonObject jsonNode;

		QString typeName = QString::fromStdString(nodeTree->nodeTypeName(nodeID));
		QString name = QString::fromStdString(node->nodeName());

		jsonNode.insert(QStringLiteral("id"), nodeID);
		jsonNode.insert(QStringLiteral("class"), typeName);
		jsonNode.insert(QStringLiteral("name"), name);

		// Save properties' values
		NodeConfig nodeConfig;
		node->configuration(nodeConfig);
		PropertyID propID = 0;
		QJsonArray jsonProperties;

		if(nodeConfig.pProperties)
		{
			while(nodeConfig.pProperties[propID].type != EPropertyType::Unknown)
			{
				NodeProperty propValue = node->property(propID);

				if(propValue.isValid())
				{
					const auto& prop = nodeConfig.pProperties[propID];
					jsonProperties.append(serializeProperty(propID, prop.name, prop.type, propValue));
				}

				++propID;
			}
		}

		if(!jsonProperties.isEmpty())
			jsonNode.insert(QStringLiteral("properties"), jsonProperties);

		jsonNodes.append(jsonNode);
	}

	// Iterate over all links and serialize it as JSON value of JSON array
	QJsonArray jsonLinks;
	auto linkIt = nodeTree->createNodeLinkIterator();
	NodeLink nodeLink;
	while(linkIt->next(nodeLink))
	{
		QJsonObject jsonLink;

		jsonLink.insert(QStringLiteral("fromNode"), nodeLink.fromNode);
		jsonLink.insert(QStringLiteral("fromSocket"), nodeLink.fromSocket);
		jsonLink.insert(QStringLiteral("toNode"), nodeLink.toNode);
		jsonLink.insert(QStringLiteral("toSocket"), nodeLink.toSocket);

		jsonLinks.append(jsonLink);
	}

	// Finally, add JSON arrays representing nodes and links
	QJsonObject jsonTree;
	jsonTree.insert(QStringLiteral("nodes"), jsonNodes);
	jsonTree.insert(QStringLiteral("links"), jsonLinks);
	return jsonTree;
}

bool NodeTreeSerializer::deserializeJson(std::shared_ptr<NodeTree>& nodeTree,
										 const QJsonObject& jsonTree,
										 std::map<NodeID, NodeID>* oldToNewNodeID)
{
	nodeTree->clear();

	QJsonArray nodes = jsonTree["nodes"].toArray();
	QJsonArray links = jsonTree["links"].toArray();

	/// TODO : check if the "nodes", "links" are indeed QVariantList?
	std::map<NodeID, NodeID> mapping;

	if(!deserializeJsonNodes(nodeTree, nodes, mapping))
	{
		qCritical("Didn't load all saved nodes, tree will be discarded");
		nodeTree->clear();
		return false;
	}
	if(!deserializeJsonLinks(nodeTree, links, mapping))
	{
		qCritical("Didn't load all saved links, tree will be discarded");
		nodeTree->clear();
		return false;
	}

	if(oldToNewNodeID != nullptr)
		*oldToNewNodeID = mapping;

	return true;
}

bool NodeTreeSerializer::deserializeJsonNodes(std::shared_ptr<NodeTree>& nodeTree,
											  const QJsonArray& jsonNodes,
											  std::map<NodeID, NodeID>& mapping)
{
	QVariantList nodes = jsonNodes.toVariantList();
	int i = 0;

	// Load nodes
	for(const auto& node : nodes)
	{
		QVariantMap mapNode = node.toMap();

		bool ok;
		NodeID nodeId = mapNode["id"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"id\" is bad";
			break;
		}

		QString nodeTypeName = mapNode["class"].toString();
		if(nodeTypeName.isEmpty())
		{
			qCritical() << QString("\"class\" is bad (id:%1)").arg(nodeId);;
			break;
		}

		QString nodeName = mapNode["name"].toString();
		if(nodeName.isEmpty())
		{
			qCritical() << QString("\"name\" is bad (id:%1)").arg(nodeId);;
			break;
		}

		// Try to create new node
		NodeTypeID nodeTypeId = nodeTree->nodeSystem()->nodeTypeID(nodeTypeName.toStdString());
		NodeID _nodeId = nodeTree->createNode(nodeTypeId, nodeName.toStdString());
		if(_nodeId == InvalidNodeID)
		{
			qCritical() << QString("Couldn't create node of id: %1 and type name: %3")
				.arg(nodeId)
				.arg(nodeTypeName);
			break;
		}
		mapping.insert(std::make_pair(nodeId, _nodeId));

		QVariant varProperties = mapNode["properties"];
		if(varProperties.isValid()
			&& varProperties.type() == QVariant::List)
		{
			QVariantList properties = varProperties.toList();

			for(const auto& prop : properties)
			{
				QVariantMap propMap = prop.toMap();

				bool ok;
				uint propId = propMap["id"].toUInt(&ok);
				if(!ok)
				{
					qWarning() << "\"id\" is bad, property will be skipped";
					continue;
				}

				QVariant qvalue = propMap["value"];
				if(!qvalue.isValid())
				{
					qWarning() << "\"value\" is bad, property of id" << propId << "will be skipped";
					continue;
				}

				QString qpropType = propMap["type"].toString();
				EPropertyType propType = deserializePropertyType(qpropType.toStdString());
				if(propType == EPropertyType::Unknown)
				{
					qWarning() << "\"type\" is bad, property of id" << propId << "will be skipped";
					continue;
				}

				NodeProperty propValue = deserializeProperty(propType, qvalue);

				try
				{
					if(!nodeTree->nodeSetProperty(_nodeId, propId, propValue))
					{
						qWarning() << "Couldn't set loaded property" << propId <<  "to" << qvalue;
					}
				}
				catch(std::exception& ex)
				{
					qWarning() << ex.what();
				}
			}
		}

		++i;
	}

	return nodes.count() == i;
}

bool NodeTreeSerializer::deserializeJsonLinks(std::shared_ptr<NodeTree>& nodeTree,
											  const QJsonArray& jsonLinks,
											  std::map<NodeID, NodeID>& mapping)
{
	int i = 0;
	QVariantList links = jsonLinks.toVariantList();

	for(const auto& link : links)
	{
		QVariantMap mapLink = link.toMap();
		bool ok;

		NodeID fromNode = mapLink["fromNode"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"fromNode\" is bad";
			break;
		}
		SocketID fromSocket = mapLink["fromSocket"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"fromSocket\" is bad";
			break;
		}
		NodeID toNode = mapLink["toNode"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"toNode\" is bad";
			break;
		}
		SocketID toSocket = mapLink["toSocket"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"toSocket\" is bad";
			break;
		}

		if(nodeTree->linkNodes(SocketAddress(mapping[fromNode], fromSocket, true),
							   SocketAddress(mapping[toNode], toSocket, false)) != ELinkNodesResult::Ok)
		{
			qCritical() << QString("Couldn't link nodes %1:%2 with %3:%4")
				.arg(fromNode)
				.arg(fromSocket)
				.arg(toNode)
				.arg(toSocket);
			break;
		}
		++i;
	}

	return links.count() == i;
}

QJsonObject NodeTreeSerializer::serializeProperty(PropertyID propID,
												  const std::string& propName,
												  EPropertyType propType,
												  const NodeProperty& propValue)
{
	QJsonObject jsonProp;
	jsonProp.insert(QStringLiteral("id"), propID);
	jsonProp.insert(QStringLiteral("name"), QString::fromStdString(propName));

	switch(propType)
	{
	case EPropertyType::Boolean:
		jsonProp.insert(QStringLiteral("value"), propValue.toBool());
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("boolean"));
		break;
	case EPropertyType::Integer:
		jsonProp.insert(QStringLiteral("value"), propValue.toInt());
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("integer"));
		break;
	case EPropertyType::Double:
		jsonProp.insert(QStringLiteral("value"), propValue.toDouble());
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("double"));
		break;
	case EPropertyType::Enum:
		jsonProp.insert(QStringLiteral("value"), (int) propValue.toEnum().data());
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("enum"));
		break;
	case EPropertyType::Matrix:
		{
			QJsonArray jsonMatrix;
			Matrix3x3 matrix = propValue.toMatrix3x3();
			for(double v : matrix.v)
				jsonMatrix.append(v);
			jsonProp.insert(QStringLiteral("value"), jsonMatrix);
			jsonProp.insert(QStringLiteral("type"), QStringLiteral("matrix3x3"));
			break;
		}
	case EPropertyType::Filepath:
		{
			QString rootDirStr = QString::fromStdString(_rootDirectory);
			QString filePath = QString::fromStdString(propValue.toFilepath().data());
			QDir rootDir(rootDirStr);
			if(rootDir.exists())
				jsonProp.insert(QStringLiteral("value"), rootDir.relativeFilePath(filePath));
			else
				jsonProp.insert(QStringLiteral("value"), filePath);
			jsonProp.insert(QStringLiteral("type"), QStringLiteral("filepath"));
		}
		break;
	case EPropertyType::String:
		jsonProp.insert(QStringLiteral("value"), QString::fromStdString(propValue.toString()));
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("string"));
		break;
	case EPropertyType::Unknown:
		break;
	}

	return jsonProp;
}

EPropertyType NodeTreeSerializer::deserializePropertyType(const std::string& type)
{
	if(type == "boolean")
		return EPropertyType::Boolean;
	else if(type == "integer")
		return EPropertyType::Integer;
	else if(type == "double")
		return EPropertyType::Double;
	else if(type == "enum")
		return EPropertyType::Enum;
	else if(type == "matrix3x3")
		return EPropertyType::Matrix;
	else if(type == "filepath")
		return EPropertyType::Filepath;
	else if(type == "string")
		return EPropertyType::String;
	else
		return EPropertyType::Unknown;
}

NodeProperty NodeTreeSerializer::deserializeProperty(EPropertyType propType,
													 const QVariant& qvalue)
{
	switch(propType)
	{
	case EPropertyType::Boolean:
		return NodeProperty(qvalue.toBool());
	case EPropertyType::Integer:
		return NodeProperty(qvalue.toInt());
	case EPropertyType::Double:
		return NodeProperty(qvalue.toDouble());
	case EPropertyType::Enum:
		return NodeProperty(Enum(qvalue.toUInt()));
	case EPropertyType::Matrix:
		{
			QVariantList matrixList = qvalue.toList();
			Matrix3x3 matrix;
			for(int i = 0; i < matrixList.count() && i < 9; ++i)
				matrix.v[i] = matrixList[i].toDouble();
			return NodeProperty(matrix);
		}
	case EPropertyType::Filepath:
		{
			QString rootDirStr = QString::fromStdString(_rootDirectory);
			QDir rootDir(rootDirStr);
			if(rootDir.exists())
				return NodeProperty(Filepath(rootDir.absoluteFilePath(qvalue.toString()).toStdString()));
			return NodeProperty();
		}
	case EPropertyType::String:
		return NodeProperty(qvalue.toString().toStdString());
	}

	return NodeProperty();
}<commit_msg>added more information in case of an error during deserializing node properties<commit_after>#include "NodeTreeSerializer.h"
#include "NodeTree.h"
#include "NodeType.h"
#include "NodeSystem.h"

#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include <QDebug>

NodeTreeSerializer::NodeTreeSerializer(const std::string& rootDir)
	: _rootDirectory(rootDir)
{
}

void NodeTreeSerializer::setRootDirectory(const std::string& rootDir)
{
	_rootDirectory = rootDir;
}

QJsonObject NodeTreeSerializer::serializeJson(const std::shared_ptr<NodeTree>& nodeTree)
{
	// Iterate over all nodes and serialize it as JSON value of JSON array
	QJsonArray jsonNodes;
	auto nodeIt = nodeTree->createNodeIterator();
	NodeID nodeID;
	while(const Node* node = nodeIt->next(nodeID))
	{
		QJsonObject jsonNode;

		QString typeName = QString::fromStdString(nodeTree->nodeTypeName(nodeID));
		QString name = QString::fromStdString(node->nodeName());

		jsonNode.insert(QStringLiteral("id"), nodeID);
		jsonNode.insert(QStringLiteral("class"), typeName);
		jsonNode.insert(QStringLiteral("name"), name);

		// Save properties' values
		NodeConfig nodeConfig;
		node->configuration(nodeConfig);
		PropertyID propID = 0;
		QJsonArray jsonProperties;

		if(nodeConfig.pProperties)
		{
			while(nodeConfig.pProperties[propID].type != EPropertyType::Unknown)
			{
				NodeProperty propValue = node->property(propID);

				if(propValue.isValid())
				{
					const auto& prop = nodeConfig.pProperties[propID];
					jsonProperties.append(serializeProperty(propID, prop.name, prop.type, propValue));
				}

				++propID;
			}
		}

		if(!jsonProperties.isEmpty())
			jsonNode.insert(QStringLiteral("properties"), jsonProperties);

		jsonNodes.append(jsonNode);
	}

	// Iterate over all links and serialize it as JSON value of JSON array
	QJsonArray jsonLinks;
	auto linkIt = nodeTree->createNodeLinkIterator();
	NodeLink nodeLink;
	while(linkIt->next(nodeLink))
	{
		QJsonObject jsonLink;

		jsonLink.insert(QStringLiteral("fromNode"), nodeLink.fromNode);
		jsonLink.insert(QStringLiteral("fromSocket"), nodeLink.fromSocket);
		jsonLink.insert(QStringLiteral("toNode"), nodeLink.toNode);
		jsonLink.insert(QStringLiteral("toSocket"), nodeLink.toSocket);

		jsonLinks.append(jsonLink);
	}

	// Finally, add JSON arrays representing nodes and links
	QJsonObject jsonTree;
	jsonTree.insert(QStringLiteral("nodes"), jsonNodes);
	jsonTree.insert(QStringLiteral("links"), jsonLinks);
	return jsonTree;
}

bool NodeTreeSerializer::deserializeJson(std::shared_ptr<NodeTree>& nodeTree,
										 const QJsonObject& jsonTree,
										 std::map<NodeID, NodeID>* oldToNewNodeID)
{
	nodeTree->clear();

	QJsonArray nodes = jsonTree["nodes"].toArray();
	QJsonArray links = jsonTree["links"].toArray();

	/// TODO : check if the "nodes", "links" are indeed QVariantList?
	std::map<NodeID, NodeID> mapping;

	if(!deserializeJsonNodes(nodeTree, nodes, mapping))
	{
		qCritical("Didn't load all saved nodes, tree will be discarded");
		nodeTree->clear();
		return false;
	}
	if(!deserializeJsonLinks(nodeTree, links, mapping))
	{
		qCritical("Didn't load all saved links, tree will be discarded");
		nodeTree->clear();
		return false;
	}

	if(oldToNewNodeID != nullptr)
		*oldToNewNodeID = mapping;

	return true;
}

bool NodeTreeSerializer::deserializeJsonNodes(std::shared_ptr<NodeTree>& nodeTree,
											  const QJsonArray& jsonNodes,
											  std::map<NodeID, NodeID>& mapping)
{
	QVariantList nodes = jsonNodes.toVariantList();
	int i = 0;

	// Load nodes
	for(const auto& node : nodes)
	{
		QVariantMap mapNode = node.toMap();

		bool ok;
		NodeID nodeId = mapNode["id"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"id\" is bad";
			break;
		}

		QString nodeTypeName = mapNode["class"].toString();
		if(nodeTypeName.isEmpty())
		{
			qCritical() << QString("\"class\" is bad (id:%1)").arg(nodeId);;
			break;
		}

		QString nodeName = mapNode["name"].toString();
		if(nodeName.isEmpty())
		{
			qCritical() << QString("\"name\" is bad (id:%1)").arg(nodeId);;
			break;
		}

		// Try to create new node
		NodeTypeID nodeTypeId = nodeTree->nodeSystem()->nodeTypeID(nodeTypeName.toStdString());
		NodeID _nodeId = nodeTree->createNode(nodeTypeId, nodeName.toStdString());
		if(_nodeId == InvalidNodeID)
		{
			qCritical() << QString("Couldn't create node of id: %1 and type name: %3")
				.arg(nodeId)
				.arg(nodeTypeName);
			break;
		}
		mapping.insert(std::make_pair(nodeId, _nodeId));

		QVariant varProperties = mapNode["properties"];
		if(varProperties.isValid()
			&& varProperties.type() == QVariant::List)
		{
			QVariantList properties = varProperties.toList();

			for(const auto& prop : properties)
			{
				QVariantMap propMap = prop.toMap();

				bool ok;
				uint propId = propMap["id"].toUInt(&ok);
				if(!ok)
				{
					qWarning() << QString("property \"id\" is bad, property will be skipped (id:%1, name:%2)")
						.arg(nodeId)
						.arg(nodeName);
					continue;
				}

				QVariant qvalue = propMap["value"];
				if(!qvalue.isValid())
				{
					qWarning() << QString("\"value\" is bad, property of id %1 will be skipped (id:%2, name:%3)")
						.arg(propId)
						.arg(nodeId)
						.arg(nodeName);
					continue;
				}

				QString qpropType = propMap["type"].toString();
				EPropertyType propType = deserializePropertyType(qpropType.toStdString());
				if(propType == EPropertyType::Unknown)
				{
					qWarning() << QString("\"type\" is bad, property of id %1 will be skipped (id:%2, name:%3)")
						.arg(propId)
						.arg(nodeId)
						.arg(nodeName);
					continue;
				}

				NodeProperty propValue = deserializeProperty(propType, qvalue);

				try
				{
					if(!nodeTree->nodeSetProperty(_nodeId, propId, propValue))
					{
						qWarning() << "Couldn't set loaded property" << propId << "to" << qvalue;
					}
				}
				catch(std::exception& ex)
				{
					qWarning() << ex.what();
				}
			}
		}

		++i;
	}

	return nodes.count() == i;
}

bool NodeTreeSerializer::deserializeJsonLinks(std::shared_ptr<NodeTree>& nodeTree,
											  const QJsonArray& jsonLinks,
											  std::map<NodeID, NodeID>& mapping)
{
	int i = 0;
	QVariantList links = jsonLinks.toVariantList();

	for(const auto& link : links)
	{
		QVariantMap mapLink = link.toMap();
		bool ok;

		NodeID fromNode = mapLink["fromNode"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"fromNode\" is bad";
			break;
		}
		SocketID fromSocket = mapLink["fromSocket"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"fromSocket\" is bad";
			break;
		}
		NodeID toNode = mapLink["toNode"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"toNode\" is bad";
			break;
		}
		SocketID toSocket = mapLink["toSocket"].toUInt(&ok);
		if(!ok)
		{
			qCritical() << "\"toSocket\" is bad";
			break;
		}

		if(nodeTree->linkNodes(SocketAddress(mapping[fromNode], fromSocket, true),
							   SocketAddress(mapping[toNode], toSocket, false)) != ELinkNodesResult::Ok)
		{
			qCritical() << QString("Couldn't link nodes %1:%2 with %3:%4")
				.arg(fromNode)
				.arg(fromSocket)
				.arg(toNode)
				.arg(toSocket);
			break;
		}
		++i;
	}

	return links.count() == i;
}

QJsonObject NodeTreeSerializer::serializeProperty(PropertyID propID,
												  const std::string& propName,
												  EPropertyType propType,
												  const NodeProperty& propValue)
{
	QJsonObject jsonProp;
	jsonProp.insert(QStringLiteral("id"), propID);
	jsonProp.insert(QStringLiteral("name"), QString::fromStdString(propName));

	switch(propType)
	{
	case EPropertyType::Boolean:
		jsonProp.insert(QStringLiteral("value"), propValue.toBool());
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("boolean"));
		break;
	case EPropertyType::Integer:
		jsonProp.insert(QStringLiteral("value"), propValue.toInt());
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("integer"));
		break;
	case EPropertyType::Double:
		jsonProp.insert(QStringLiteral("value"), propValue.toDouble());
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("double"));
		break;
	case EPropertyType::Enum:
		jsonProp.insert(QStringLiteral("value"), (int) propValue.toEnum().data());
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("enum"));
		break;
	case EPropertyType::Matrix:
		{
			QJsonArray jsonMatrix;
			Matrix3x3 matrix = propValue.toMatrix3x3();
			for(double v : matrix.v)
				jsonMatrix.append(v);
			jsonProp.insert(QStringLiteral("value"), jsonMatrix);
			jsonProp.insert(QStringLiteral("type"), QStringLiteral("matrix3x3"));
			break;
		}
	case EPropertyType::Filepath:
		{
			QString rootDirStr = QString::fromStdString(_rootDirectory);
			QString filePath = QString::fromStdString(propValue.toFilepath().data());
			QDir rootDir(rootDirStr);
			if(rootDir.exists())
				jsonProp.insert(QStringLiteral("value"), rootDir.relativeFilePath(filePath));
			else
				jsonProp.insert(QStringLiteral("value"), filePath);
			jsonProp.insert(QStringLiteral("type"), QStringLiteral("filepath"));
		}
		break;
	case EPropertyType::String:
		jsonProp.insert(QStringLiteral("value"), QString::fromStdString(propValue.toString()));
		jsonProp.insert(QStringLiteral("type"), QStringLiteral("string"));
		break;
	case EPropertyType::Unknown:
		break;
	}

	return jsonProp;
}

EPropertyType NodeTreeSerializer::deserializePropertyType(const std::string& type)
{
	if(type == "boolean")
		return EPropertyType::Boolean;
	else if(type == "integer")
		return EPropertyType::Integer;
	else if(type == "double")
		return EPropertyType::Double;
	else if(type == "enum")
		return EPropertyType::Enum;
	else if(type == "matrix3x3")
		return EPropertyType::Matrix;
	else if(type == "filepath")
		return EPropertyType::Filepath;
	else if(type == "string")
		return EPropertyType::String;
	else
		return EPropertyType::Unknown;
}

NodeProperty NodeTreeSerializer::deserializeProperty(EPropertyType propType,
													 const QVariant& qvalue)
{
	switch(propType)
	{
	case EPropertyType::Boolean:
		return NodeProperty(qvalue.toBool());
	case EPropertyType::Integer:
		return NodeProperty(qvalue.toInt());
	case EPropertyType::Double:
		return NodeProperty(qvalue.toDouble());
	case EPropertyType::Enum:
		return NodeProperty(Enum(qvalue.toUInt()));
	case EPropertyType::Matrix:
		{
			QVariantList matrixList = qvalue.toList();
			Matrix3x3 matrix;
			for(int i = 0; i < matrixList.count() && i < 9; ++i)
				matrix.v[i] = matrixList[i].toDouble();
			return NodeProperty(matrix);
		}
	case EPropertyType::Filepath:
		{
			QString rootDirStr = QString::fromStdString(_rootDirectory);
			QDir rootDir(rootDirStr);
			if(rootDir.exists())
				return NodeProperty(Filepath(rootDir.absoluteFilePath(qvalue.toString()).toStdString()));
			return NodeProperty();
		}
	case EPropertyType::String:
		return NodeProperty(qvalue.toString().toStdString());
	}

	return NodeProperty();
}<|endoftext|>


<commit_before>/*************************************************************************
 *                                                                       *
 * Open Dynamics Engine, Copyright (C) 2001 Russell L. Smith.            *
 *                                                                       *
 * This library is free software; you can redistribute it and/or         *
 * modify it under the terms of the GNU Lesser General Public            *
 * License as published by the Free Software Foundation; either          *
 * version 2.1 of the License, or (at your option) any later version.    *
 *                                                                       *
 * 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 (see the file LICENSE.TXT); if not,   *
 * write to the Free Software Foundation, Inc., 59 Temple Place,         *
 * Suite 330, Boston, MA 02111-1307 USA.                                 *
 *                                                                       *
 *************************************************************************/

#include "ode/common.h"
#include "ode/odemath.h"

void dNormalize3 (dVector3 a)
{
  dASSERT (a);
  dReal l = dDOT(a,a);
  if (l > 0) {
    l = dRecipSqrt(l);
    a[0] *= l;
    a[1] *= l;
    a[2] *= l;
  }
  else {
    a[0] = 1;
    a[1] = 0;
    a[2] = 0;
  }
}

void dNormalize4 (dVector4 a)
{
  dASSERT (a);
  dReal l = dDOT(a,a)+a[3]*a[3];
  if (l > 0) {
    l = dRecipSqrt(l);
    a[0] *= l;
    a[1] *= l;
    a[2] *= l;
    a[3] *= l;
  }
  else {
    a[0] = 1;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
  }
}

void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q)
{
  if (dFabs(n[2]) > M_SQRT1_2) {
    // choose p in y-z plane
    dReal a = n[1]*n[1] + n[2]*n[2];
    dReal k = dRecipSqrt (a);
    p[0] = 0;
    p[1] = -n[2]*k;
    p[2] = n[1]*k;
    // set q = n x p
    q[0] = a*k;
    q[1] = -n[0]*p[2];
    q[2] = n[0]*p[1];
  }
  else {
    // choose p in x-y plane
    dReal a = n[0]*n[0] + n[1]*n[1];
    dReal k = dRecipSqrt (a);
    p[0] = -n[1]*k;
    p[1] = n[0]*k;
    p[2] = 0;
    // set q = n x p
    q[0] = -n[2]*p[1];
    q[1] = n[2]*p[0];
    q[2] = a*k;
  }
}
<commit_msg>new dNormalize3() with bugfix<commit_after>/*************************************************************************
 *                                                                       *
 * Open Dynamics Engine, Copyright (C) 2001 Russell L. Smith.            *
 *                                                                       *
 * This library is free software; you can redistribute it and/or         *
 * modify it under the terms of the GNU Lesser General Public            *
 * License as published by the Free Software Foundation; either          *
 * version 2.1 of the License, or (at your option) any later version.    *
 *                                                                       *
 * 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 (see the file LICENSE.TXT); if not,   *
 * write to the Free Software Foundation, Inc., 59 Temple Place,         *
 * Suite 330, Boston, MA 02111-1307 USA.                                 *
 *                                                                       *
 *************************************************************************/

#include "ode/common.h"
#include "ode/odemath.h"

// this may be called for vectors `a' with extremely small magnitude, for
// example the result of a cross product on two nearly perpendicular vectors.
// we must be robust to these small vectors. to prevent numerical error,
// first find the component a[i] with the largest magnitude and then scale
// all the components by 1/a[i]. then we can compute the length of `a' and
// scale the components by 1/l. this has been verified to work with vectors
// containing the smallest representable numbers.

void dNormalize3 (dVector3 a)
{
  dReal a0,a1,a2,aa0,aa1,aa2,l;
  a0 = a[0];
  a1 = a[1];
  a2 = a[2];
  dASSERT (a);
  aa0 = dFabs(a0);
  aa1 = dFabs(a1);
  aa2 = dFabs(a2);
  if (aa1 > aa0) {
    if (aa2 > aa1) {
      goto aa2_largest;
    }
    else {		// aa1 is largest
      a0 /= aa1;
      a2 /= aa1;
      l = dRecipSqrt (a0*a0 + a2*a2 + 1);
      a[0] = a0*l;
      a[1] = copysign(l,a1);
      a[2] = a2*l;
    }
  }
  else {
    if (aa2 > aa0) {
      aa2_largest:	// aa2 is largest
      a0 /= aa2;
      a1 /= aa2;
      l = dRecipSqrt (a0*a0 + a1*a1 + 1);
      a[0] = a0*l;
      a[1] = a1*l;
      a[2] = copysign(l,a2);
    }
    else {		// aa0 is largest
      if (aa0 <= 0) {
	a[0] = 1;	// if all a's are zero, this is where we'll end up.
	a[1] = 0;	// return a default unit length vector.
	a[2] = 0;
	return;
      }
      a1 /= aa0;
      a2 /= aa0;
      l = dRecipSqrt (a1*a1 + a2*a2 + 1);
      a[0] = copysign(l,a0);
      a[1] = a1*l;
      a[2] = a2*l;
    }
  }
}

/* OLD VERSION */
/*
void dNormalize3 (dVector3 a)
{
  dASSERT (a);
  dReal l = dDOT(a,a);
  if (l > 0) {
    l = dRecipSqrt(l);
    a[0] *= l;
    a[1] *= l;
    a[2] *= l;
  }
  else {
    a[0] = 1;
    a[1] = 0;
    a[2] = 0;
  }
}
*/

void dNormalize4 (dVector4 a)
{
  dASSERT (a);
  dReal l = dDOT(a,a)+a[3]*a[3];
  if (l > 0) {
    l = dRecipSqrt(l);
    a[0] *= l;
    a[1] *= l;
    a[2] *= l;
    a[3] *= l;
  }
  else {
    a[0] = 1;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
  }
}

void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q)
{
  if (dFabs(n[2]) > M_SQRT1_2) {
    // choose p in y-z plane
    dReal a = n[1]*n[1] + n[2]*n[2];
    dReal k = dRecipSqrt (a);
    p[0] = 0;
    p[1] = -n[2]*k;
    p[2] = n[1]*k;
    // set q = n x p
    q[0] = a*k;
    q[1] = -n[0]*p[2];
    q[2] = n[0]*p[1];
  }
  else {
    // choose p in x-y plane
    dReal a = n[0]*n[0] + n[1]*n[1];
    dReal k = dRecipSqrt (a);
    p[0] = -n[1]*k;
    p[1] = n[0]*k;
    p[2] = 0;
    // set q = n x p
    q[0] = -n[2]*p[1];
    q[1] = n[2]*p[0];
    q[2] = a*k;
  }
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id: runReconstruction.C 23207 2007-12-20 09:59:20Z ivana $ */

/// \ingroup macros
/// \file runDataReconstruction.C
/// \brief Macro for running reconstruction
///
/// Macro for running reconstruction on the cosmics run data.
///
/// \author Laurent Aphecetche, Nicole Bastid, Bogdan Vulpescu, ...

#if !defined(__CINT__) || defined(__MAKECINT__)
#include "AliMUONReconstructor.h"
#include "AliMUONRecoParam.h"
#include "AliRecoParam.h"
#include "AliCDBManager.h"
#include "AliMagFMaps.h"
#include "AliTracker.h"
#include "AliReconstruction.h"
#include <TRandom.h>
#include <TGrid.h>
//#include <TObjectTable.h>
#endif

// Data file, OCDB on Grid
#TString input="alien:///alice/data/2007/LHC07w/000014493/raw/07000014493001.10.root";
TString input="alien:///alice/data/2008/LHC08a/000021931/raw/08000021931001.50.root";
TString ocdbPath = "alien://folder=/alice/data/2008/LHC08a/OCDB";

// Data file, OCDB locally
//TString input="$ALICE_ROOT/MUON/test_out.100/raw.root";
//TString ocdbPath = "local://$ALICE_ROOT";

TString caliboption1 = "NOGAIN";
TString caliboption2 = "GAINCONSTANTCAPA";
TString recoptions = "SAVEDIGITS";
Int_t seed = 1234567;

void runDataReconstruction(Int_t calib = 1)
{
  TGrid::Connect("alien://");

  AliCDBManager* man = AliCDBManager::Instance();
  man->SetDefaultStorage(ocdbPath.Data());
  //man->SetSpecificStorage("MUON/Calib/Mapping","local://$ALICE_ROOT");
  //man->SetSpecificStorage("MUON/Calib/DDLStore","local://$ALICE_ROOT");
  man->SetSpecificStorage("MUON/Calib/Gains","local://$ALICE_ROOT");

  gRandom->SetSeed(seed);

  AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k5kG);
  AliTracker::SetFieldMap(field, kFALSE);
  AliReconstruction *MuonRec = new AliReconstruction();

  MuonRec->SetInput(input.Data());
  MuonRec->SetRunVertexFinder(kFALSE);
  MuonRec->SetRunLocalReconstruction("MUON");
  MuonRec->SetRunTracking("MUON");
  MuonRec->SetFillESD(" ");
  MuonRec->SetLoadAlignData("MUON");
  MuonRec->SetNumberOfEventsPerFile(1000);
  MuonRec->SetOption("MUON",recoptions.Data());
  //  MuonRec->SetEventRange(319,319);
  MuonRec->SetWriteAOD();
  //MuonRec.SetEventRange(0,100);
  AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLowFluxParam();
  muonRecoParam->CombineClusterTrackReco(kTRUE);
  TString caliboption = caliboption1;
  if ( calib == 2 ) caliboption = caliboption2;
  muonRecoParam->SetCalibrationMode(caliboption.Data());
  //muonRecoParam->SetClusteringMode("PEAKFIT");
  //muonRecoParam->SetClusteringMode("PEAKCOG");
  muonRecoParam->Print("FULL");
  AliRecoParam::Instance()->RegisterRecoParam(muonRecoParam);

  MuonRec->Run();

  delete MuonRec;

  //gObjectTable->Print();
}

<commit_msg>Do not set specific storage for Gains, as this is not needed anymore<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id: runReconstruction.C 23207 2007-12-20 09:59:20Z ivana $ */

/// \ingroup macros
/// \file runDataReconstruction.C
/// \brief Macro for running reconstruction
///
/// Macro for running reconstruction on the cosmics run data.
///
/// \author Laurent Aphecetche, Nicole Bastid, Bogdan Vulpescu, ...

#if !defined(__CINT__) || defined(__MAKECINT__)
#include "AliMUONReconstructor.h"
#include "AliMUONRecoParam.h"
#include "AliRecoParam.h"
#include "AliCDBManager.h"
#include "AliMagFMaps.h"
#include "AliTracker.h"
#include "AliReconstruction.h"
#include <TRandom.h>
#include <TGrid.h>
//#include <TObjectTable.h>
#endif

// Data file, OCDB on Grid
#TString input="alien:///alice/data/2007/LHC07w/000014493/raw/07000014493001.10.root";
TString input="alien:///alice/data/2008/LHC08a/000021931/raw/08000021931001.50.root";
TString ocdbPath = "alien://folder=/alice/data/2008/LHC08a/OCDB";

// Data file, OCDB locally
//TString input="$ALICE_ROOT/MUON/test_out.100/raw.root";
//TString ocdbPath = "local://$ALICE_ROOT";

TString caliboption1 = "NOGAIN";
TString caliboption2 = "GAINCONSTANTCAPA";
TString recoptions = "SAVEDIGITS";
Int_t seed = 1234567;

void runDataReconstruction(Int_t calib = 1)
{
  TGrid::Connect("alien://");

  AliCDBManager* man = AliCDBManager::Instance();
  man->SetDefaultStorage(ocdbPath.Data());
  //man->SetSpecificStorage("MUON/Calib/Mapping","local://$ALICE_ROOT");
  //man->SetSpecificStorage("MUON/Calib/DDLStore","local://$ALICE_ROOT");
  //man->SetSpecificStorage("MUON/Calib/Gains","local://$ALICE_ROOT");

  gRandom->SetSeed(seed);

  AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k5kG);
  AliTracker::SetFieldMap(field, kFALSE);
  AliReconstruction *MuonRec = new AliReconstruction();

  MuonRec->SetInput(input.Data());
  MuonRec->SetRunVertexFinder(kFALSE);
  MuonRec->SetRunLocalReconstruction("MUON");
  MuonRec->SetRunTracking("MUON");
  MuonRec->SetFillESD(" ");
  MuonRec->SetLoadAlignData("MUON");
  MuonRec->SetNumberOfEventsPerFile(1000);
  MuonRec->SetOption("MUON",recoptions.Data());
  //  MuonRec->SetEventRange(319,319);
  MuonRec->SetWriteAOD();
  //MuonRec.SetEventRange(0,100);
  AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLowFluxParam();
  muonRecoParam->CombineClusterTrackReco(kTRUE);
  TString caliboption = caliboption1;
  if ( calib == 2 ) caliboption = caliboption2;
  muonRecoParam->SetCalibrationMode(caliboption.Data());
  //muonRecoParam->SetClusteringMode("PEAKFIT");
  //muonRecoParam->SetClusteringMode("PEAKCOG");
  muonRecoParam->Print("FULL");
  AliRecoParam::Instance()->RegisterRecoParam(muonRecoParam);

  MuonRec->Run();

  delete MuonRec;

  //gObjectTable->Print();
}

<|endoftext|>


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

#ifndef DBACCESS_INDEXCOLUMN_HXX_
#define DBACCESS_INDEXCOLUMN_HXX_

#ifndef _CONNECTIVITY_ADABAS_COLUMN_HXX_
#include "adabas/BColumn.hxx"
#endif

namespace connectivity
{
    namespace adabas
    {
        class OIndexColumn : public OAdabasColumn
        {
        protected:
            sal_Bool    m_IsAscending;
        public:
            OIndexColumn();
            OIndexColumn(   sal_Bool _IsAscending,
                            const ::rtl::OUString& _Name,
                            const ::rtl::OUString& _TypeName,
                            const ::rtl::OUString& _DefaultValue,
                            sal_Int32       _IsNullable,
                            sal_Int32       _Precision,
                            sal_Int32       _Scale,
                            sal_Int32       _Type,
                            sal_Bool        _IsAutoIncrement);

            virtual void construct();
        };
    }
}
#endif // DBACCESS_INDEXCOLUMN_HXX_
<commit_msg>INTEGRATION: CWS ooo19126 (1.2.516); FILE MERGED 2005/09/05 17:31:57 rt 1.2.516.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: CIndexColumn.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 09:51:20 $
 *
 *  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
 *
 ************************************************************************/

#ifndef DBACCESS_INDEXCOLUMN_HXX_
#define DBACCESS_INDEXCOLUMN_HXX_

#ifndef _CONNECTIVITY_ADABAS_COLUMN_HXX_
#include "adabas/BColumn.hxx"
#endif

namespace connectivity
{
    namespace adabas
    {
        class OIndexColumn : public OAdabasColumn
        {
        protected:
            sal_Bool    m_IsAscending;
        public:
            OIndexColumn();
            OIndexColumn(   sal_Bool _IsAscending,
                            const ::rtl::OUString& _Name,
                            const ::rtl::OUString& _TypeName,
                            const ::rtl::OUString& _DefaultValue,
                            sal_Int32       _IsNullable,
                            sal_Int32       _Precision,
                            sal_Int32       _Scale,
                            sal_Int32       _Type,
                            sal_Bool        _IsAutoIncrement);

            virtual void construct();
        };
    }
}
#endif // DBACCESS_INDEXCOLUMN_HXX_
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TableGrantCtrl.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-06 08:25:15 $
 *
 *  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
 *
 ************************************************************************/
#ifndef DBAUI_TABLEGRANTCONTROL_HXX
#define DBAUI_TABLEGRANTCONTROL_HXX

#ifndef _SVTOOLS_EDITBROWSEBOX_HXX_
#include <svtools/editbrowsebox.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XAUTHORIZABLE_HPP_
#include <com/sun/star/sdbcx/XAuthorizable.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif

class Edit;
namespace dbaui
{

class OTableGrantControl : public ::svt::EditBrowseBox
{
    typedef struct
    {
        sal_Int32 nRights;
        sal_Int32 nWithGrant;
    } TPrivileges;

    DECLARE_STL_USTRINGACCESS_MAP(TPrivileges,TTablePrivilegeMap);

    OModuleClient        m_aModuleClient;

    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >    m_xUsers;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >    m_xTables;
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory> m_xORB;
    ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XAuthorizable>       m_xGrantUser;
    ::com::sun::star::uno::Sequence< ::rtl::OUString>                               m_aTableNames;

    mutable TTablePrivilegeMap  m_aPrivMap;
    ::rtl::OUString             m_sUserName;
    ::svt::CheckBoxControl*     m_pCheckCell;
    Edit*                       m_pEdit;
    long                        m_nDataPos;
    BOOL                        m_bEnable;
    ULONG                       m_nDeactivateEvent;

public:
    OTableGrantControl( Window* pParent,const ResId& _RsId);
    virtual ~OTableGrantControl();
    void UpdateTables();
    void setUserName(const ::rtl::OUString _sUserName);
    void setGrantUser(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XAuthorizable>& _xGrantUser);

    void setTablesSupplier(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier >& _xTablesSup);
    void setORB(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _xORB);

    virtual void Init();

    // IAccessibleTableProvider
    /** Creates the accessible object of a data table cell.
        @param nRow  The row index of the cell.
        @param nColumnId  The column ID of the cell.
        @return  The XAccessible interface of the specified cell. */
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible >
    CreateAccessibleCell( sal_Int32 nRow, sal_uInt16 nColumnId );

protected:
    virtual void Resize();

    virtual long PreNotify(NotifyEvent& rNEvt );

    virtual BOOL IsTabAllowed(BOOL bForward) const;
    virtual void InitController( ::svt::CellControllerRef& rController, long nRow, USHORT nCol );
    virtual ::svt::CellController* GetController( long nRow, USHORT nCol );
    virtual void PaintCell( OutputDevice& rDev, const Rectangle& rRect, USHORT nColId ) const;
    virtual BOOL SeekRow( long nRow );
    virtual BOOL SaveModified();
    virtual String GetCellText( long nRow, USHORT nColId ) const;

    virtual void CellModified();

private:
    DECL_LINK( AsynchActivate, void* );
    DECL_LINK( AsynchDeactivate, void* );

    sal_Bool    isAllowed(USHORT _nColumnId,sal_Int32 _nPrivilege) const;
    void        fillPrivilege(sal_Int32 _nRow) const;
    TTablePrivilegeMap::const_iterator findPrivilege(sal_Int32 _nRow) const;
};

}

#endif // DBAUI_TABLEGRANTCONTROL_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.10.162); FILE MERGED 2008/03/31 13:27:44 rt 1.10.162.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: TableGrantCtrl.hxx,v $
 * $Revision: 1.11 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef DBAUI_TABLEGRANTCONTROL_HXX
#define DBAUI_TABLEGRANTCONTROL_HXX

#ifndef _SVTOOLS_EDITBROWSEBOX_HXX_
#include <svtools/editbrowsebox.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XAUTHORIZABLE_HPP_
#include <com/sun/star/sdbcx/XAuthorizable.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif

class Edit;
namespace dbaui
{

class OTableGrantControl : public ::svt::EditBrowseBox
{
    typedef struct
    {
        sal_Int32 nRights;
        sal_Int32 nWithGrant;
    } TPrivileges;

    DECLARE_STL_USTRINGACCESS_MAP(TPrivileges,TTablePrivilegeMap);

    OModuleClient        m_aModuleClient;

    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >    m_xUsers;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >    m_xTables;
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory> m_xORB;
    ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XAuthorizable>       m_xGrantUser;
    ::com::sun::star::uno::Sequence< ::rtl::OUString>                               m_aTableNames;

    mutable TTablePrivilegeMap  m_aPrivMap;
    ::rtl::OUString             m_sUserName;
    ::svt::CheckBoxControl*     m_pCheckCell;
    Edit*                       m_pEdit;
    long                        m_nDataPos;
    BOOL                        m_bEnable;
    ULONG                       m_nDeactivateEvent;

public:
    OTableGrantControl( Window* pParent,const ResId& _RsId);
    virtual ~OTableGrantControl();
    void UpdateTables();
    void setUserName(const ::rtl::OUString _sUserName);
    void setGrantUser(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XAuthorizable>& _xGrantUser);

    void setTablesSupplier(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier >& _xTablesSup);
    void setORB(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _xORB);

    virtual void Init();

    // IAccessibleTableProvider
    /** Creates the accessible object of a data table cell.
        @param nRow  The row index of the cell.
        @param nColumnId  The column ID of the cell.
        @return  The XAccessible interface of the specified cell. */
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible >
    CreateAccessibleCell( sal_Int32 nRow, sal_uInt16 nColumnId );

protected:
    virtual void Resize();

    virtual long PreNotify(NotifyEvent& rNEvt );

    virtual BOOL IsTabAllowed(BOOL bForward) const;
    virtual void InitController( ::svt::CellControllerRef& rController, long nRow, USHORT nCol );
    virtual ::svt::CellController* GetController( long nRow, USHORT nCol );
    virtual void PaintCell( OutputDevice& rDev, const Rectangle& rRect, USHORT nColId ) const;
    virtual BOOL SeekRow( long nRow );
    virtual BOOL SaveModified();
    virtual String GetCellText( long nRow, USHORT nColId ) const;

    virtual void CellModified();

private:
    DECL_LINK( AsynchActivate, void* );
    DECL_LINK( AsynchDeactivate, void* );

    sal_Bool    isAllowed(USHORT _nColumnId,sal_Int32 _nPrivilege) const;
    void        fillPrivilege(sal_Int32 _nRow) const;
    TTablePrivilegeMap::const_iterator findPrivilege(sal_Int32 _nRow) const;
};

}

#endif // DBAUI_TABLEGRANTCONTROL_HXX
<|endoftext|>


<commit_before>#include <iostream>

#include "basemachine.h"

//init static variables
int Base_Machine::m_num_instructions = 1;
int Base_Machine::m_program_counter = 0;
bool Base_Machine::m_pipe_scoreboard = false;
int Base_Machine::m_num_cycles = 1;
int Base_Machine::m_nop_counter = 0;

void Base_Machine::begin() {
	m_program_counter = MIN_SEGMENT_INSTRUCTION;
	m_num_instructions = 1;
	m_num_cycles = 1;
	m_nop_counter = 0;

	while (m_program_counter < Memory::m_instruction_counter) {
		if (m_program_counter == 10) {
			int i = 0;
		}
 		getNextInstruction();
		processInstruction();
		m_num_cycles++;
	}
	processRemainingInstructions();

	std::cout << "Number of Instructions: " << m_num_instructions << std::endl;
	std::cout << "Number of Cycles: " << m_num_cycles << std::endl;
	std::cout << "Number of nop's in code: " << m_nop_counter << std::endl;
}

void Base_Machine::getNextInstruction() {
	m_current_instruction = Memory::loadInstruction(m_program_counter);
}<commit_msg>Update basemachine.cpp<commit_after>#include <iostream>

#include "basemachine.h"

//init static variables
int Base_Machine::m_num_instructions = 1;
int Base_Machine::m_program_counter = 0;
bool Base_Machine::m_pipe_scoreboard = false;
int Base_Machine::m_num_cycles = 1;
int Base_Machine::m_nop_counter = 0;

void Base_Machine::begin() {
	m_program_counter = MIN_SEGMENT_INSTRUCTION;
	m_num_instructions = 1;
	m_num_cycles = 1;
	m_nop_counter = 0;

	while (m_program_counter < Memory::m_instruction_counter) {
 		getNextInstruction();
		processInstruction();
		m_num_cycles++;
	}
	processRemainingInstructions();

	std::cout << "Number of Instructions: " << m_num_instructions << std::endl;
	std::cout << "Number of Cycles: " << m_num_cycles << std::endl;
	std::cout << "Number of nop's in code: " << m_nop_counter << std::endl;
}

void Base_Machine::getNextInstruction() {
	m_current_instruction = Memory::loadInstruction(m_program_counter);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/range/irange.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/test/unit_test.hpp>
#include <stdint.h>

#include "tests/test-utils.hh"
#include "tests/cql_test_env.hh"
#include "tests/cql_assertions.hh"
#include "tests/test_services.hh"

#include "db/size_estimates_virtual_reader.hh"
#include "core/future-util.hh"
#include "cql3/query_processor.hh"
#include "transport/messages/result_message.hh"

#include "disk-error-handler.hh"

thread_local disk_error_signal_type commit_error;
thread_local disk_error_signal_type general_disk_error;

SEASTAR_TEST_CASE(test_query_virtual_table) {
    return do_with_cql_env([] (auto& e) {
        storage_service_for_tests ss_for_tests;
        auto ranges = db::size_estimates::size_estimates_mutation_reader::get_local_ranges().get0();
        auto start_token1 = utf8_type->to_string(ranges[3].start);
        auto start_token2 = utf8_type->to_string(ranges[5].start);
        auto end_token1 = utf8_type->to_string(ranges[3].end);
        auto end_token2 = utf8_type->to_string(ranges[55].end);
        auto &qp = e.local_qp();
        return e.execute_cql("create table cf1(pk text PRIMARY KEY, v int);").discard_result().then([&e] {
            return e.execute_cql("create table cf2(pk text PRIMARY KEY, v int);").discard_result();
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' limit 100;").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 100);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name = 'cf1';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 256);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name > 'cf1';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 256);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name >= 'cf1';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name < 'cf2';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 256);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name <= 'cf2';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name in ('cf1', 'cf2');").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name >= 'cf1' and table_name <= 'cf1';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 256);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name >= 'cf1' and table_name <= 'cf2';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name > 'cf1' and table_name < 'cf2';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 0);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start >= '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 253);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start > '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 252);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start <= '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 4);
            });
         }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start < '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 3);
            });
          }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start >= '%s' and range_start <= '%s';", start_token1, start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start >= '%s' and range_start <= '%s';", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 3);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start > '%s' and range_start < '%s';", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start in ('%s', '%s');", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 2);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start > '%s' and range_start <= '%s';", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 2);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start >= '%s' and range_start < '%s';", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 2);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end = '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end >= '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end > '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 0);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end <= '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end < '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 0);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end >= '%s' and range_end <= '%s';", start_token1, end_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end > '%s' and range_end < '%s';", start_token1, end_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 0);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and (table_name, range_start, range_end) = ('cf1', '%s', '%s');", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and (table_name, range_start, range_end) >= ('cf1', '%s', '%s') and (table_name) <= ('cf2');", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 509);
            });
        }).then([&qp, start_token1, start_token2, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and (table_name, range_start, range_end) >= ('cf1', '%s', '%s') "
                                              "and (table_name, range_start) <= ('cf2', '%s');", start_token1, end_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 259);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and (table_name, range_start) < ('cf2', '%s');", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 259);
            });
        }).discard_result();
    });
}
<commit_msg>tests: Fix failure virtual_reader_test<commit_after>/*
 * Copyright (C) 2016 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/range/irange.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/test/unit_test.hpp>
#include <stdint.h>

#include "tests/test-utils.hh"
#include "tests/cql_test_env.hh"
#include "tests/cql_assertions.hh"
#include "tests/test_services.hh"

#include "db/size_estimates_virtual_reader.hh"
#include "core/future-util.hh"
#include "cql3/query_processor.hh"
#include "transport/messages/result_message.hh"

#include "disk-error-handler.hh"

thread_local disk_error_signal_type commit_error;
thread_local disk_error_signal_type general_disk_error;

SEASTAR_TEST_CASE(test_query_virtual_table) {
    return do_with_cql_env([] (auto& e) {
        auto ranges = db::size_estimates::size_estimates_mutation_reader::get_local_ranges().get0();
        auto start_token1 = utf8_type->to_string(ranges[3].start);
        auto start_token2 = utf8_type->to_string(ranges[5].start);
        auto end_token1 = utf8_type->to_string(ranges[3].end);
        auto end_token2 = utf8_type->to_string(ranges[55].end);
        auto &qp = e.local_qp();
        return e.execute_cql("create table cf1(pk text PRIMARY KEY, v int);").discard_result().then([&e] {
            return e.execute_cql("create table cf2(pk text PRIMARY KEY, v int);").discard_result();
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' limit 100;").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 100);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name = 'cf1';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 256);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name > 'cf1';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 256);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name >= 'cf1';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name < 'cf2';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 256);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name <= 'cf2';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name in ('cf1', 'cf2');").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name >= 'cf1' and table_name <= 'cf1';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 256);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name >= 'cf1' and table_name <= 'cf2';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 512);
            });
        }).then([&qp] {
            return qp.execute_internal("select * from system.size_estimates where keyspace_name = 'ks' "
                                       "and table_name > 'cf1' and table_name < 'cf2';").then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 0);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start >= '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 253);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start > '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 252);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start <= '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 4);
            });
         }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start < '%s';", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 3);
            });
          }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start >= '%s' and range_start <= '%s';", start_token1, start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start >= '%s' and range_start <= '%s';", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 3);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start > '%s' and range_start < '%s';", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start in ('%s', '%s');", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 2);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start > '%s' and range_start <= '%s';", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 2);
            });
        }).then([&qp, start_token1, start_token2] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start >= '%s' and range_start < '%s';", start_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 2);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end = '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end >= '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end > '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 0);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end <= '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end < '%s';", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 0);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end >= '%s' and range_end <= '%s';", start_token1, end_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and table_name = 'cf1' and range_start = '%s' and range_end > '%s' and range_end < '%s';", start_token1, end_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 0);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and (table_name, range_start, range_end) = ('cf1', '%s', '%s');", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 1);
            });
        }).then([&qp, start_token1, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and (table_name, range_start, range_end) >= ('cf1', '%s', '%s') and (table_name) <= ('cf2');", start_token1, end_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 509);
            });
        }).then([&qp, start_token1, start_token2, end_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and (table_name, range_start, range_end) >= ('cf1', '%s', '%s') "
                                              "and (table_name, range_start) <= ('cf2', '%s');", start_token1, end_token1, start_token2)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 259);
            });
        }).then([&qp, start_token1] {
            return qp.execute_internal(sprint("select * from system.size_estimates where keyspace_name = 'ks' "
                                              "and (table_name, range_start) < ('cf2', '%s');", start_token1)).then([](auto rs) {
                BOOST_REQUIRE_EQUAL(rs->size(), 259);
            });
        }).discard_result();
    });
}
<|endoftext|>


<commit_before>/** Copyright (C) 2018 European Spallation Source ERIC */

#include <arpa/inet.h>
#include <cinttypes>
#include <common/Trace.h>
#include <cstdio>
#include <gdgem/vmm3/ParserVMM3.h>
#include <string.h>

//#undef TRC_LEVEL
//#define TRC_LEVEL TRC_L_DEB

int VMM3SRSData::parse(uint32_t data1, uint16_t data2, struct VMM3Data *vmd) {

	XTRACE(PROCESS, DEB, "data1: 0x%08x, data2: 0x%04x", data1, data2);
	int dataflag = (data2 >> 15) & 0x1;

	if (dataflag) {
		/// Data
		XTRACE(PROCESS, DEB, "SRS Data");

		vmd->overThreshold = (data2 >> 14) & 0x01;
		vmd->chno = (data2 >> 8) & 0x3f;
		vmd->tdc = data2 & 0xff;

		vmd->vmmid = (data1 >> 22) & 0x1F;
		vmd->triggerOffset = (data1 >> 27) & 0x1F;
		vmd->adc = (data1 >> 12) & 0x3FF;
		vmd->bcid = BitMath::gray2bin32(data1 & 0xFFF);

		vmd->fecTimeStamp = markers[(parserData.fecId-1)*maximumNumberVMM+vmd->vmmid].fecTimeStamp;
		if (markers[(parserData.fecId-1)*maximumNumberVMM+vmd->vmmid].fecTimeStamp > 0) {
			vmd->hasDataMarker = true;
		}
		return 1;
	} else {
		/// Marker
		uint8_t vmmid = (data2 >> 10) & 0x1F;
		uint32_t timestamp_lower_10bit = data2 & 0x03FF;
		uint32_t timestamp_upper_32bit = data1;

		uint64_t timestamp_42bit = (timestamp_upper_32bit << 10)
				+ timestamp_lower_10bit;
		XTRACE(PROCESS, DEB, "SRS Marker vmmid %d: timestamp lower 10bit %u, timestamp upper 32 bit %u, 42 bit timestamp %"
		       PRIu64 "",  vmmid, timestamp_lower_10bit, timestamp_upper_32bit,timestamp_42bit);
		markers[(parserData.fecId-1)*maximumNumberVMM+vmmid].fecTimeStamp = timestamp_42bit;

		//XTRACE(PROCESS, DEB, "vmmid: %d", vmmid);
		return 0;
	}
}

int VMM3SRSData::receive(const char *buffer, int size) {
	memset(&stats, 0, sizeof(stats));

	if (size < 4) {
		XTRACE(PROCESS, DEB, "Undersize data");
		stats.errors += size;
		return 0;
	}

	struct SRSHdr *srsHeaderPtr = (struct SRSHdr *) buffer;
	srsHeader.frameCounter = ntohl(srsHeaderPtr->frameCounter);
	if (srsHeader.frameCounter == 0xfafafafa) {
		//XTRACE(PROCESS, INF, "End of Frame");
		stats.badFrames++;
		//printf("bad frames I: %d\n", stats.bad_frames);
		stats.errors += size;
		return -1;
	}

	if (parserData.fcIsInitialized == true) {
		///
		int64_t fcDiff = srsHeader.frameCounter
				- parserData.nextFrameCounter;
		if (fcDiff < 0) {
			fcDiff += 0xffffffff;
		}
		if (fcDiff) {
			//printf("FC: curr: %d, expect: %d, diff: %" PRId64 "\n", srsHeader.frameCounter,
			//		parserData.nextFrameCounter, fcDiff);
			stats.lostFrames += fcDiff; /// \todo test
			parserData.nextFrameCounter = srsHeader.frameCounter + 1;
		} else {
			parserData.nextFrameCounter++;
		}
	} else {
		parserData.nextFrameCounter = srsHeader.frameCounter + 1;
		parserData.fcIsInitialized = true;
	}

	if (size < SRSHeaderSize + HitAndMarkerSize) {
		XTRACE(PROCESS, WAR, "Undersize data");
		stats.badFrames++;
		stats.errors += size;
		return 0;
	}

	srsHeader.dataId = ntohl(srsHeaderPtr->dataId);
	/// maybe add a protocol error counter here
	if ((srsHeader.dataId & 0xffffff00) != 0x564d3300) {
		XTRACE(PROCESS, WAR, "Unknown data");
		stats.badFrames++;
		stats.errors += size;
		return 0;
	}

	parserData.fecId = (srsHeader.dataId >> 4) & 0x0f;
	if(parserData.fecId < 1 || parserData.fecId > 15)
	{
		XTRACE(PROCESS, WAR, "Invalid fecId: %u", parserData.fecId);
		stats.badFrames++;
		stats.errors += size;
		return 0;
	}
	srsHeader.udpTimeStamp = ntohl(srsHeaderPtr->udpTimeStamp);
	srsHeader.offsetOverflow = ntohl(srsHeaderPtr->offsetOverflow);

	auto datalen = size - SRSHeaderSize;
	if ((datalen % 6) != 0) {
		XTRACE(PROCESS, WAR, "Invalid data length: %d", datalen);
		stats.badFrames++;
		stats.errors += size;
		return 0;
	}

	// XTRACE(PROCESS, DEB, "VMM3a Data, VMM Id %d", vmmid);

	int dataIndex = 0;
	int readoutIndex = 0;
	while (datalen >= HitAndMarkerSize) {
		//XTRACE(PROCESS, DEB, "readoutIndex: %d, datalen %d, elems: %u",
		//		readoutIndex, datalen, stats.hits);
		auto Data1Offset = SRSHeaderSize + HitAndMarkerSize * readoutIndex;
		auto Data2Offset = Data1Offset + Data1Size;
		uint32_t data1 = htonl(*(uint32_t *) &buffer[Data1Offset]);
		uint16_t data2 = htons(*(uint16_t *) &buffer[Data2Offset]);

		int res = parse(data1, data2, &data[dataIndex]);
		if (res == 1) { // This was data
			stats.hits++;
			dataIndex++;
		} else {
			stats.markers++;
		}
		readoutIndex++;

		datalen -= 6;
		if (stats.hits == maxHits && datalen > 0) {
			XTRACE(PROCESS, INF, "Data overflow, skipping %d bytes", datalen);
			stats.errors += datalen;
			break;
		}
	}
	stats.goodFrames++;

	return stats.hits;
}
<commit_msg>Fixed timestamp error<commit_after>/** Copyright (C) 2018 European Spallation Source ERIC */

#include <arpa/inet.h>
#include <cinttypes>
#include <common/Trace.h>
#include <cstdio>
#include <gdgem/vmm3/ParserVMM3.h>
#include <string.h>

//#undef TRC_LEVEL
//#define TRC_LEVEL TRC_L_DEB

int VMM3SRSData::parse(uint32_t data1, uint16_t data2, struct VMM3Data *vmd) {

	XTRACE(PROCESS, DEB, "data1: 0x%08x, data2: 0x%04x", data1, data2);
	int dataflag = (data2 >> 15) & 0x1;

	if (dataflag) {
		/// Data
		XTRACE(PROCESS, DEB, "SRS Data");

		vmd->overThreshold = (data2 >> 14) & 0x01;
		vmd->chno = (data2 >> 8) & 0x3f;
		vmd->tdc = data2 & 0xff;

		vmd->vmmid = (data1 >> 22) & 0x1F;
		vmd->triggerOffset = (data1 >> 27) & 0x1F;
		vmd->adc = (data1 >> 12) & 0x3FF;
		vmd->bcid = BitMath::gray2bin32(data1 & 0xFFF);

		vmd->fecTimeStamp = markers[(parserData.fecId-1)*maximumNumberVMM+vmd->vmmid].fecTimeStamp;
		if (markers[(parserData.fecId-1)*maximumNumberVMM+vmd->vmmid].fecTimeStamp > 0) {
			vmd->hasDataMarker = true;
		}
		return 1;
	} else {
		/// Marker
		uint8_t vmmid = (data2 >> 10) & 0x1F;
		uint64_t timestamp_lower_10bit = data2 & 0x03FF;
		uint64_t timestamp_upper_32bit = data1;

		uint64_t timestamp_42bit = (timestamp_upper_32bit << 10)
				+ timestamp_lower_10bit;
		XTRACE(PROCESS, DEB, "SRS Marker vmmid %d: timestamp lower 10bit %u, timestamp upper 32 bit %u, 42 bit timestamp %"
		       PRIu64 "",  vmmid, timestamp_lower_10bit, timestamp_upper_32bit,timestamp_42bit);
		markers[(parserData.fecId-1)*maximumNumberVMM+vmmid].fecTimeStamp = timestamp_42bit;

		//XTRACE(PROCESS, DEB, "vmmid: %d", vmmid);
		return 0;
	}
}

int VMM3SRSData::receive(const char *buffer, int size) {
	memset(&stats, 0, sizeof(stats));

	if (size < 4) {
		XTRACE(PROCESS, DEB, "Undersize data");
		stats.errors += size;
		return 0;
	}

	struct SRSHdr *srsHeaderPtr = (struct SRSHdr *) buffer;
	srsHeader.frameCounter = ntohl(srsHeaderPtr->frameCounter);
	if (srsHeader.frameCounter == 0xfafafafa) {
		//XTRACE(PROCESS, INF, "End of Frame");
		stats.badFrames++;
		//printf("bad frames I: %d\n", stats.bad_frames);
		stats.errors += size;
		return -1;
	}

	if (parserData.fcIsInitialized == true) {
		///
		int64_t fcDiff = srsHeader.frameCounter
				- parserData.nextFrameCounter;
		if (fcDiff < 0) {
			fcDiff += 0xffffffff;
		}
		if (fcDiff) {
			//printf("FC: curr: %d, expect: %d, diff: %" PRId64 "\n", srsHeader.frameCounter,
			//		parserData.nextFrameCounter, fcDiff);
			stats.lostFrames += fcDiff; /// \todo test
			parserData.nextFrameCounter = srsHeader.frameCounter + 1;
		} else {
			parserData.nextFrameCounter++;
		}
	} else {
		parserData.nextFrameCounter = srsHeader.frameCounter + 1;
		parserData.fcIsInitialized = true;
	}

	if (size < SRSHeaderSize + HitAndMarkerSize) {
		XTRACE(PROCESS, WAR, "Undersize data");
		stats.badFrames++;
		stats.errors += size;
		return 0;
	}

	srsHeader.dataId = ntohl(srsHeaderPtr->dataId);
	/// maybe add a protocol error counter here
	if ((srsHeader.dataId & 0xffffff00) != 0x564d3300) {
		XTRACE(PROCESS, WAR, "Unknown data");
		stats.badFrames++;
		stats.errors += size;
		return 0;
	}

	parserData.fecId = (srsHeader.dataId >> 4) & 0x0f;
	if(parserData.fecId < 1 || parserData.fecId > 15)
	{
		XTRACE(PROCESS, WAR, "Invalid fecId: %u", parserData.fecId);
		stats.badFrames++;
		stats.errors += size;
		return 0;
	}
	srsHeader.udpTimeStamp = ntohl(srsHeaderPtr->udpTimeStamp);
	srsHeader.offsetOverflow = ntohl(srsHeaderPtr->offsetOverflow);

	auto datalen = size - SRSHeaderSize;
	if ((datalen % 6) != 0) {
		XTRACE(PROCESS, WAR, "Invalid data length: %d", datalen);
		stats.badFrames++;
		stats.errors += size;
		return 0;
	}

	// XTRACE(PROCESS, DEB, "VMM3a Data, VMM Id %d", vmmid);

	int dataIndex = 0;
	int readoutIndex = 0;
	while (datalen >= HitAndMarkerSize) {
		//XTRACE(PROCESS, DEB, "readoutIndex: %d, datalen %d, elems: %u",
		//		readoutIndex, datalen, stats.hits);
		auto Data1Offset = SRSHeaderSize + HitAndMarkerSize * readoutIndex;
		auto Data2Offset = Data1Offset + Data1Size;
		uint32_t data1 = htonl(*(uint32_t *) &buffer[Data1Offset]);
		uint16_t data2 = htons(*(uint16_t *) &buffer[Data2Offset]);

		int res = parse(data1, data2, &data[dataIndex]);
		if (res == 1) { // This was data
			stats.hits++;
			dataIndex++;
		} else {
			stats.markers++;
		}
		readoutIndex++;

		datalen -= 6;
		if (stats.hits == maxHits && datalen > 0) {
			XTRACE(PROCESS, INF, "Data overflow, skipping %d bytes", datalen);
			stats.errors += datalen;
			break;
		}
	}
	stats.goodFrames++;

	return stats.hits;
}
<|endoftext|>