<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XercesElementWrapper.hpp"

#include <xercesc/dom/DOMElement.hpp>

#include <XalanDOM/XalanAttr.hpp>

#include <DOMSupport/DOMServices.hpp>

#include "XercesWrapperHelper.hpp"
#include "XercesWrapperNavigator.hpp"
#include "XercesDOMWrapperException.hpp"
#include "XercesDocumentWrapper.hpp"

XercesElementWrapper::XercesElementWrapper(
			const DOMElement*				theXercesElement,
			const XercesWrapperNavigator&	theNavigator) :
	XalanElement(),
	m_xercesNode(theXercesElement),
	m_navigator(theNavigator),
	m_children(theXercesElement->getChildNodes(),
			   theNavigator),
	m_attributes(theXercesElement->getAttributes(),
				 theNavigator)
{
	assert(theXercesElement != 0);
}

XercesElementWrapper::~XercesElementWrapper()
{
}

const XalanDOMString&
XercesElementWrapper::getNodeName() const
{
	return m_navigator.getPooledString(m_xercesNode->getNodeName());
}

const XalanDOMString&
XercesElementWrapper::getNodeValue() const
{
	return m_navigator.getPooledString(m_xercesNode->getNodeValue());
}

XercesElementWrapper::NodeType
XercesElementWrapper::getNodeType() const
{
	return ELEMENT_NODE;
}

XalanNode*
XercesElementWrapper::getParentNode() const
{
	return m_navigator.getParentNode(m_xercesNode);
}

const XalanNodeList*
XercesElementWrapper::getChildNodes() const
{
	return &m_children;
}

XalanNode*
XercesElementWrapper::getFirstChild() const
{
	return m_navigator.getFirstChild(m_xercesNode);
}

XalanNode*
XercesElementWrapper::getLastChild() const
{
	return m_navigator.getLastChild(m_xercesNode);
}

XalanNode*
XercesElementWrapper::getPreviousSibling() const
{
	return m_navigator.getPreviousSibling(m_xercesNode);
}

XalanNode*
XercesElementWrapper::getNextSibling() const
{
	return m_navigator.getNextSibling(m_xercesNode);
}

const XalanNamedNodeMap*
XercesElementWrapper::getAttributes() const
{
	return &m_attributes;
}

XalanDocument*
XercesElementWrapper::getOwnerDocument() const
{
	return m_navigator.getOwnerDocument();
}

#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
XalanNode*
#else
XercesElementWrapper*
#endif
XercesElementWrapper::cloneNode(bool	/* deep */) const
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

	return 0;
}

XalanNode*
XercesElementWrapper::insertBefore(
			XalanNode*	/* newChild */,
			XalanNode*	/* refChild */)
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::HIERARCHY_REQUEST_ERR);

	return 0;
}

XalanNode*
XercesElementWrapper::replaceChild(
			XalanNode*	/* newChild */,
			XalanNode*	/* oldChild */)
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::HIERARCHY_REQUEST_ERR);

	return 0;
}

XalanNode*
XercesElementWrapper::removeChild(XalanNode*	/* oldChild */)
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::HIERARCHY_REQUEST_ERR);

	return 0;
}

XalanNode*
XercesElementWrapper::appendChild(XalanNode*	/* newChild */)
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::HIERARCHY_REQUEST_ERR);

	return 0;
}

bool
XercesElementWrapper::hasChildNodes() const
{
	return m_xercesNode->hasChildNodes();
}

void
XercesElementWrapper::setNodeValue(const XalanDOMString&	/* nodeValue */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

void
XercesElementWrapper::normalize()
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

bool
XercesElementWrapper::isSupported(
			const XalanDOMString&	feature,
			const XalanDOMString&	version) const
{
	return XercesWrapperHelper::isSupported(m_xercesNode, feature, version);
}

const XalanDOMString&
XercesElementWrapper::getNamespaceURI() const
{
	return m_navigator.getPooledString(m_xercesNode->getNamespaceURI());
}

const XalanDOMString&
XercesElementWrapper::getPrefix() const
{
	return m_navigator.getPooledString(m_xercesNode->getPrefix());
}

const XalanDOMString&
XercesElementWrapper::getLocalName() const
{
	return m_navigator.getPooledString(m_xercesNode->getLocalName());
}

void
XercesElementWrapper::setPrefix(const XalanDOMString&	/* prefix */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

bool
XercesElementWrapper::isIndexed() const
{
	return m_navigator.getOwnerDocument()->isIndexed();
}

unsigned long
XercesElementWrapper::getIndex() const
{
	return m_navigator.getIndex();
}

const XalanDOMString&
XercesElementWrapper::getTagName() const
{
	return m_navigator.getPooledString(m_xercesNode->getTagName());
}

const XalanDOMString&
XercesElementWrapper::getAttribute(const XalanDOMString&		name) const
{
	return m_navigator.getPooledString(m_xercesNode->getAttribute(c_wstr(name)));
}

XalanAttr*
XercesElementWrapper::getAttributeNode(const XalanDOMString&		name) const
{
#if defined(XALAN_OLD_STYLE_CASTS)
	return (XalanAttr*)m_attributes.getNamedItem(name);
#else
	return static_cast<XalanAttr*>(m_attributes.getNamedItem(name));
#endif
}

XalanNodeList*
XercesElementWrapper::getElementsByTagName(const XalanDOMString&	/* name */) const
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

	return 0;
}

void
XercesElementWrapper::setAttribute(
			const XalanDOMString&	/* name */,
			const XalanDOMString&	/* value */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

XalanAttr*
XercesElementWrapper::setAttributeNode(XalanAttr*	/* newAttr */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

XalanAttr*
XercesElementWrapper::removeAttributeNode(XalanAttr*	/* oldAttr */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

void
XercesElementWrapper::removeAttribute(const XalanDOMString&		/* name */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

const XalanDOMString&
XercesElementWrapper::getAttributeNS(
			const XalanDOMString&	namespaceURI,
			const XalanDOMString&	localName) const
{
	return m_navigator.getPooledString(m_xercesNode->getAttributeNS(c_wstr(namespaceURI), c_wstr(localName)));
}

void
XercesElementWrapper::setAttributeNS(
			const XalanDOMString&	/* namespaceURI */,
			const XalanDOMString&	/* qualifiedName */,
			const XalanDOMString&	/* value */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

void
XercesElementWrapper::removeAttributeNS(
			const XalanDOMString&	/* namespaceURI */,
			const XalanDOMString&	/* localName */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

XalanAttr*
XercesElementWrapper::getAttributeNodeNS(
			const XalanDOMString&	namespaceURI,
			const XalanDOMString&	localName) const
{
	DOMAttr* const	theAttrNode =
		m_xercesNode->getAttributeNodeNS(c_wstr(namespaceURI), c_wstr(localName));

	return m_navigator.mapNode(theAttrNode);
}

XalanAttr*
XercesElementWrapper::setAttributeNodeNS(XalanAttr*		/* newAttr */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);

	return 0;
}

XalanNodeList*
XercesElementWrapper::getElementsByTagNameNS(
			const XalanDOMString&	/* namespaceURI */,
			const XalanDOMString&	/* localName */) const
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

	return 0;
}
<commit_msg>Added missing return statements.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XercesElementWrapper.hpp"

#include <xercesc/dom/DOMElement.hpp>

#include <XalanDOM/XalanAttr.hpp>

#include <DOMSupport/DOMServices.hpp>

#include "XercesWrapperHelper.hpp"
#include "XercesWrapperNavigator.hpp"
#include "XercesDOMWrapperException.hpp"
#include "XercesDocumentWrapper.hpp"

XercesElementWrapper::XercesElementWrapper(
			const DOMElement*				theXercesElement,
			const XercesWrapperNavigator&	theNavigator) :
	XalanElement(),
	m_xercesNode(theXercesElement),
	m_navigator(theNavigator),
	m_children(theXercesElement->getChildNodes(),
			   theNavigator),
	m_attributes(theXercesElement->getAttributes(),
				 theNavigator)
{
	assert(theXercesElement != 0);
}

XercesElementWrapper::~XercesElementWrapper()
{
}

const XalanDOMString&
XercesElementWrapper::getNodeName() const
{
	return m_navigator.getPooledString(m_xercesNode->getNodeName());
}

const XalanDOMString&
XercesElementWrapper::getNodeValue() const
{
	return m_navigator.getPooledString(m_xercesNode->getNodeValue());
}

XercesElementWrapper::NodeType
XercesElementWrapper::getNodeType() const
{
	return ELEMENT_NODE;
}

XalanNode*
XercesElementWrapper::getParentNode() const
{
	return m_navigator.getParentNode(m_xercesNode);
}

const XalanNodeList*
XercesElementWrapper::getChildNodes() const
{
	return &m_children;
}

XalanNode*
XercesElementWrapper::getFirstChild() const
{
	return m_navigator.getFirstChild(m_xercesNode);
}

XalanNode*
XercesElementWrapper::getLastChild() const
{
	return m_navigator.getLastChild(m_xercesNode);
}

XalanNode*
XercesElementWrapper::getPreviousSibling() const
{
	return m_navigator.getPreviousSibling(m_xercesNode);
}

XalanNode*
XercesElementWrapper::getNextSibling() const
{
	return m_navigator.getNextSibling(m_xercesNode);
}

const XalanNamedNodeMap*
XercesElementWrapper::getAttributes() const
{
	return &m_attributes;
}

XalanDocument*
XercesElementWrapper::getOwnerDocument() const
{
	return m_navigator.getOwnerDocument();
}

#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
XalanNode*
#else
XercesElementWrapper*
#endif
XercesElementWrapper::cloneNode(bool	/* deep */) const
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

	return 0;
}

XalanNode*
XercesElementWrapper::insertBefore(
			XalanNode*	/* newChild */,
			XalanNode*	/* refChild */)
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::HIERARCHY_REQUEST_ERR);

	return 0;
}

XalanNode*
XercesElementWrapper::replaceChild(
			XalanNode*	/* newChild */,
			XalanNode*	/* oldChild */)
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::HIERARCHY_REQUEST_ERR);

	return 0;
}

XalanNode*
XercesElementWrapper::removeChild(XalanNode*	/* oldChild */)
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::HIERARCHY_REQUEST_ERR);

	return 0;
}

XalanNode*
XercesElementWrapper::appendChild(XalanNode*	/* newChild */)
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::HIERARCHY_REQUEST_ERR);

	return 0;
}

bool
XercesElementWrapper::hasChildNodes() const
{
	return m_xercesNode->hasChildNodes();
}

void
XercesElementWrapper::setNodeValue(const XalanDOMString&	/* nodeValue */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

void
XercesElementWrapper::normalize()
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

bool
XercesElementWrapper::isSupported(
			const XalanDOMString&	feature,
			const XalanDOMString&	version) const
{
	return XercesWrapperHelper::isSupported(m_xercesNode, feature, version);
}

const XalanDOMString&
XercesElementWrapper::getNamespaceURI() const
{
	return m_navigator.getPooledString(m_xercesNode->getNamespaceURI());
}

const XalanDOMString&
XercesElementWrapper::getPrefix() const
{
	return m_navigator.getPooledString(m_xercesNode->getPrefix());
}

const XalanDOMString&
XercesElementWrapper::getLocalName() const
{
	return m_navigator.getPooledString(m_xercesNode->getLocalName());
}

void
XercesElementWrapper::setPrefix(const XalanDOMString&	/* prefix */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

bool
XercesElementWrapper::isIndexed() const
{
	return m_navigator.getOwnerDocument()->isIndexed();
}

unsigned long
XercesElementWrapper::getIndex() const
{
	return m_navigator.getIndex();
}

const XalanDOMString&
XercesElementWrapper::getTagName() const
{
	return m_navigator.getPooledString(m_xercesNode->getTagName());
}

const XalanDOMString&
XercesElementWrapper::getAttribute(const XalanDOMString&		name) const
{
	return m_navigator.getPooledString(m_xercesNode->getAttribute(c_wstr(name)));
}

XalanAttr*
XercesElementWrapper::getAttributeNode(const XalanDOMString&		name) const
{
#if defined(XALAN_OLD_STYLE_CASTS)
	return (XalanAttr*)m_attributes.getNamedItem(name);
#else
	return static_cast<XalanAttr*>(m_attributes.getNamedItem(name));
#endif
}

XalanNodeList*
XercesElementWrapper::getElementsByTagName(const XalanDOMString&	/* name */) const
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

	return 0;
}

void
XercesElementWrapper::setAttribute(
			const XalanDOMString&	/* name */,
			const XalanDOMString&	/* value */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

XalanAttr*
XercesElementWrapper::setAttributeNode(XalanAttr*	/* newAttr */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);

	return 0;
}

XalanAttr*
XercesElementWrapper::removeAttributeNode(XalanAttr*	/* oldAttr */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);

	return 0;
}

void
XercesElementWrapper::removeAttribute(const XalanDOMString&		/* name */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

const XalanDOMString&
XercesElementWrapper::getAttributeNS(
			const XalanDOMString&	namespaceURI,
			const XalanDOMString&	localName) const
{
	return m_navigator.getPooledString(m_xercesNode->getAttributeNS(c_wstr(namespaceURI), c_wstr(localName)));
}

void
XercesElementWrapper::setAttributeNS(
			const XalanDOMString&	/* namespaceURI */,
			const XalanDOMString&	/* qualifiedName */,
			const XalanDOMString&	/* value */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

void
XercesElementWrapper::removeAttributeNS(
			const XalanDOMString&	/* namespaceURI */,
			const XalanDOMString&	/* localName */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);
}

XalanAttr*
XercesElementWrapper::getAttributeNodeNS(
			const XalanDOMString&	namespaceURI,
			const XalanDOMString&	localName) const
{
	DOMAttr* const	theAttrNode =
		m_xercesNode->getAttributeNodeNS(c_wstr(namespaceURI), c_wstr(localName));

	return m_navigator.mapNode(theAttrNode);
}

XalanAttr*
XercesElementWrapper::setAttributeNodeNS(XalanAttr*		/* newAttr */)
{
	throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR);

	return 0;
}

XalanNodeList*
XercesElementWrapper::getElementsByTagNameNS(
			const XalanDOMString&	/* namespaceURI */,
			const XalanDOMString&	/* localName */) const
{
	throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

	return 0;
}
<|endoftext|>


<commit_before>/** Copyright (C) 2016, 2017 European Spallation Source ERIC */

#include <gdgem/srs/SRSTime.h>
#include <string>
#include <test/TestBase.h>
#include <unistd.h>

constexpr float no_offset = 0.0;
constexpr float unit_slope = 1.0;

class SRSTimeTest : public TestBase {
protected:
  SRSTime *time;
  virtual void SetUp() { time = new SRSTime(); }
  virtual void TearDown() { delete time; }
};

TEST_F(SRSTimeTest, SettersGetters) {
  time->set_bc_clock(42.0);
  time->set_tac_slope(42.0);
  time->set_trigger_resolution_ns(42.0);
  time->set_target_resolution_ns(42.0);
  time->set_acquisition_window(1234);
  ASSERT_EQ(time->bc_clock(), 42.0);
  ASSERT_EQ(time->tac_slope(), 42.0);
  ASSERT_EQ(time->trigger_resolution_ns(), 42.0);
  ASSERT_EQ(time->target_resolution_ns(), 42.0);
  ASSERT_EQ(time->acquisition_window(), 1234);
}

TEST_F(SRSTimeTest, Eval) {
  ASSERT_EQ(time->target_resolution_ns(), 0.5);

  /// \todo should return 0.0 on zero input?
  MESSAGE() << "Warning - timestamp_ns() might not be what we want!\n";
  ASSERT_EQ(time->timestamp_ns(0, 0, 0, no_offset, unit_slope), 1);

  /// \todo I think this should actually return 0.5 ?
  MESSAGE() << "Warning - timestamp() might not be correct\n";
  ASSERT_EQ(time->timestamp(0, 0, 0, no_offset, unit_slope), 0);
}

TEST_F(SRSTimeTest, DebugString) {
  MESSAGE() << "This is not a test, just calling the debug function\n";
  auto debugstr = time->debug();
  MESSAGE() << debugstr << "\n";
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>added assert for internal_clock_period_ns()<commit_after>/** Copyright (C) 2016, 2017 European Spallation Source ERIC */

#include <gdgem/srs/SRSTime.h>
#include <string>
#include <test/TestBase.h>
#include <unistd.h>

constexpr float no_offset = 0.0;
constexpr float unit_slope = 1.0;

class SRSTimeTest : public TestBase {
protected:
  SRSTime *time;
  virtual void SetUp() { time = new SRSTime(); }
  virtual void TearDown() { delete time; }
};

TEST_F(SRSTimeTest, SettersGetters) {
  time->set_bc_clock(42.0);
  time->set_tac_slope(42.0);
  time->set_trigger_resolution_ns(42.0);
  time->set_target_resolution_ns(42.0);
  time->set_acquisition_window(1234);
  ASSERT_EQ(time->bc_clock(), 42.0);
  ASSERT_EQ(time->tac_slope(), 42.0);
  ASSERT_EQ(time->trigger_resolution_ns(), 42.0);
  ASSERT_EQ(time->target_resolution_ns(), 42.0);
  ASSERT_EQ(time->acquisition_window(), 1234);
  ASSERT_EQ(time->internal_clock_period_ns(), 25);
}

TEST_F(SRSTimeTest, Eval) {
  ASSERT_EQ(time->target_resolution_ns(), 0.5);

  /// \todo should return 0.0 on zero input?
  MESSAGE() << "Warning - timestamp_ns() might not be what we want!\n";
  ASSERT_EQ(time->timestamp_ns(0, 0, 0, no_offset, unit_slope), 1);

  /// \todo I think this should actually return 0.5 ?
  MESSAGE() << "Warning - timestamp() might not be correct\n";
  ASSERT_EQ(time->timestamp(0, 0, 0, no_offset, unit_slope), 0);
}

TEST_F(SRSTimeTest, DebugString) {
  MESSAGE() << "This is not a test, just calling the debug function\n";
  auto debugstr = time->debug();
  MESSAGE() << debugstr << "\n";
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include "src/file_utils.h"
#include "src/log.h"
#include "src/errors.h"

#include <wordexp.h>
#include <fstream>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

LOG_DECLARE_NAMESPACE("file_utils");

namespace CthunAgent {
namespace FileUtils {

// HERE(ale): copied from Pegasus

std::string shellExpand(std::string txt) {
    // This will store the expansion outcome
    wordexp_t result;

    // Expand and check the success
    if (wordexp(txt.c_str(), &result, 0) != 0) {
        wordfree(&result);
        return "";
    }

    // Get the expanded text and free the memory
    std::string expanded_txt { result.we_wordv[0] };
    wordfree(&result);
    return expanded_txt;
}

bool fileExists(const std::string& file_path) {
    bool exists { false };
    if (file_path.empty()) {
        LOG_WARNING("file path is an empty string");
    } else {
        std::ifstream file_stream { file_path };
        exists = file_stream.good();
        file_stream.close();
    }
    return exists;
}

void removeFile(const std::string& file_path) {
    if (FileUtils::fileExists(file_path)) {
        if (std::remove(file_path.c_str()) != 0) {
            throw file_error { "failed to remove " + file_path };
        }
    }
}

void streamToFile(const std::string& text,
                  const std::string& file_path,
                  std::ios_base::openmode mode) {
    std::ofstream ofs;
    ofs.open(file_path, mode);
    if (!ofs.is_open()) {
        throw file_error { "failed to open " + file_path };
    }
    ofs << text;
}

void writeToFile(const std::string& text, const std::string& file_path) {
    streamToFile(text, file_path, std::ofstream::out | std::ofstream::trunc);
}

bool createDirectory(const std::string& dirname) {
    boost::filesystem::path dir(dirname);
    if (boost::filesystem::create_directory(dir)) {
        return true;
    }

    return false;
}

std::string readFileAsString(std::string path) {
    std::string content = "";

    if (!fileExists(path)) {
        return content;
    }

    std::ifstream file { path };
    std::string buffer;

    while (std::getline(file, buffer)) {
        content += buffer;
        content.push_back('\n');
    }

    return content;
}

}  // namespace FileUtils
}  // namespace CthunAgent
<commit_msg>(CTH-125) Make streamToFile atomic<commit_after>#include "src/file_utils.h"
#include "src/log.h"
#include "src/errors.h"

#include <wordexp.h>
#include <fstream>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>

LOG_DECLARE_NAMESPACE("file_utils");

namespace CthunAgent {
namespace FileUtils {

// HERE(ale): copied from Pegasus

std::string shellExpand(std::string txt) {
    // This will store the expansion outcome
    wordexp_t result;

    // Expand and check the success
    if (wordexp(txt.c_str(), &result, 0) != 0) {
        wordfree(&result);
        return "";
    }

    // Get the expanded text and free the memory
    std::string expanded_txt { result.we_wordv[0] };
    wordfree(&result);
    return expanded_txt;
}

bool fileExists(const std::string& file_path) {
    bool exists { false };
    if (file_path.empty()) {
        LOG_WARNING("file path is an empty string");
    } else {
        std::ifstream file_stream { file_path };
        exists = file_stream.good();
        file_stream.close();
    }
    return exists;
}

void removeFile(const std::string& file_path) {
    if (FileUtils::fileExists(file_path)) {
        if (std::remove(file_path.c_str()) != 0) {
            throw file_error { "failed to remove " + file_path };
        }
    }
}

void streamToFile(const std::string& text,
                  const std::string& file_path,
                  std::ios_base::openmode mode) {
    std::ofstream ofs;
    std::string tmp_name = file_path + "~";
    ofs.open(tmp_name, mode);
    if (!ofs.is_open()) {
        throw file_error { "failed to open " + file_path };
    }
    ofs << text;
    ofs.close();
    rename(tmp_name.data(), file_path.data());
}

void writeToFile(const std::string& text, const std::string& file_path) {
    streamToFile(text, file_path, std::ofstream::out | std::ofstream::trunc);
}

bool createDirectory(const std::string& dirname) {
    boost::filesystem::path dir(dirname);
    if (boost::filesystem::create_directory(dir)) {
        return true;
    }

    return false;
}

std::string readFileAsString(std::string path) {
    std::string content = "";

    if (!fileExists(path)) {
        return content;
    }

    std::ifstream file { path };
    std::string buffer;

    while (std::getline(file, buffer)) {
        content += buffer;
        content.push_back('\n');
    }

    return content;
}

}  // namespace FileUtils
}  // namespace CthunAgent
<|endoftext|>


<commit_before>
#pragma once

#include "geometry/symmetric_bilinear_form.hpp"

#include <string>

#include "geometry/grassmann.hpp"
#include "geometry/r3_element.hpp"
#include "quantities/elementary_functions.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"

namespace principia {
namespace geometry {
namespace internal_symmetric_bilinear_form {

using quantities::Angle;
using quantities::ArcCos;
using quantities::Cos;
using quantities::Sqrt;
using quantities::si::Radian;

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>& SymmetricBilinearForm<Scalar, Frame>::
operator+=(SymmetricBilinearForm const& right) {
  return *this = *this + right;
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>& SymmetricBilinearForm<Scalar, Frame>::
operator-=(SymmetricBilinearForm const& right) {
  return *this = *this - right;
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>& SymmetricBilinearForm<Scalar, Frame>::
operator*=(double const right) {
  return *this = *this * right;
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>& SymmetricBilinearForm<Scalar, Frame>::
operator/=(double const right) {
  return *this = *this / right;
}

template<typename Scalar, typename Frame>
template<typename LScalar, typename RScalar>
Product<Scalar, Product<LScalar, RScalar>>
SymmetricBilinearForm<Scalar, Frame>::operator()(
    Vector<LScalar, Frame> const& left,
    Vector<RScalar, Frame> const& right) const {
  return InnerProduct(left, *this * right);
}

template<typename Scalar, typename Frame>
template<typename Eigenframe>
typename SymmetricBilinearForm<Scalar, Frame>::Eigensystem<Eigenframe>
SymmetricBilinearForm<Scalar, Frame>::Diagonalize() const {
  R3x3Matrix<Scalar> const& A = matrix_;
  auto const I = R3x3Matrix<double>::Identity();

  // This algorithm follows
  // https://en.wikipedia.org/wiki/Eigenvalue_algorithm#3%C3%973_matrices which
  // gives closed-form formulæ for 3x3 matrices.
  Scalar const q = A.Trace() / 3;
  R3x3Matrix<Scalar> const A_minus_qI = A - q * I;
  Scalar const p = Sqrt((A_minus_qI * A_minus_qI).Trace() / 6);
  R3x3Matrix<double> const B = A_minus_qI / p;
  double const det_B = B.Determinant();
  Angle const θ = ArcCos(det_B * 0.5);
  double const β₀ = 2 * Cos(θ / 3);
  double const β₁ = 2 * Cos((θ + 2 * π * Radian) / 3);
  double const β₂ = 2 * Cos((θ + 4 * π * Radian) / 3);
  std::array<Scalar, 3> αs = {p * β₀ + q, p * β₁ + q, p * β₂ + q};
  std::sort(αs.begin(), αs.end());
  Scalar const& α₀ = αs[0];
  Scalar const& α₁ = αs[1];
  Scalar const& α₂ = αs[2];
  R3x3Matrix<Scalar> const A_minus_α₀I = A - α₀ * I;
  R3x3Matrix<Scalar> const A_minus_α₁I = A - α₁ * I;
  R3x3Matrix<Scalar> const A_minus_α₂I = A - α₂ * I;

  // The form in its diagonal basis.
  Scalar const zero;
  SymmetricBilinearForm<Scalar, Eigenframe> form(
      R3x3Matrix<Scalar>({  α₀, zero, zero},
                         {zero,   α₁, zero},
                         {zero, zero,   α₂}));

  // Use the Cayley-Hamilton theorem to efficiently find the eigenvectors.  The
  // m matrices contain, in columns, eigenvector for the corresponding α.
  // However it's possible for a column to be identically 0.  To deal with this
  // the call to PickEigenvector extracts the column with the largest norm.
  auto const m₀ = A_minus_α₁I * A_minus_α₂I;
  auto const m₁ = A_minus_α₂I * A_minus_α₀I;
  auto const m₂ = A_minus_α₀I * A_minus_α₁I;
  auto const v₀ = PickEigenvector(m₀);
  auto const v₁ = PickEigenvector(m₁);

  // The vectors (v₀, v₁, v₂) forms an orthonormal basis.  Make sure that it is
  // direct.
  auto v₂ = PickEigenvector(m₂);
  if (R3x3Matrix(v₀, v₁, v₂).Determinant() < 0) {
    v₂ = -v₂;
  }
  Rotation<Frame, Eigenframe> const rotation{
      Vector<double, Frame>(v₀),
      Vector<double, Frame>(v₁),
      Bivector<double, Frame>(v₂)};  // This bivector is a bit dodgy.
  return {form, rotation};
}

template<typename Scalar, typename Frame>
void SymmetricBilinearForm<Scalar, Frame>::WriteToMessage(
    not_null<serialization::SymmetricBilinearForm*> message) const {
  Frame::WriteToMessage(message->mutable_frame());
  matrix_.WriteToMessage(message->mutable_matrix());
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>
SymmetricBilinearForm<Scalar, Frame>::ReadFromMessage(
    serialization::SymmetricBilinearForm const& message) {
  Frame::ReadFromMessage(message.frame());
  return SymmetricBilinearForm(
      R3x3Matrix<Scalar>::ReadFromMessage(message.matrix()));
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>::SymmetricBilinearForm(
    R3x3Matrix<Scalar> const& matrix)
    : matrix_(matrix) {
  DCHECK_EQ(matrix_(0, 1), matrix_(1, 0));
  DCHECK_EQ(matrix_(0, 2), matrix_(2, 0));
  DCHECK_EQ(matrix_(1, 2), matrix_(2, 1));
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>::SymmetricBilinearForm(
    R3x3Matrix<Scalar>&& matrix)
    : matrix_(std::move(matrix)) {
  DCHECK_EQ(matrix_(0, 1), matrix_(1, 0));
  DCHECK_EQ(matrix_(0, 2), matrix_(2, 0));
  DCHECK_EQ(matrix_(1, 2), matrix_(2, 1));
}

template<typename Scalar, typename Frame>
template<typename S>
R3Element<double> SymmetricBilinearForm<Scalar, Frame>::PickEigenvector(
    R3x3Matrix<S> const& matrix) {
  static R3Element<double> const e₀{1, 0, 0};
  static R3Element<double> const e₁{0, 1, 0};
  static R3Element<double> const e₂{0, 0, 1};
  std::array<R3Element<S>, 3> vs = {matrix * e₀, matrix * e₁, matrix * e₂};
  std::sort(vs.begin(),
            vs.end(),
            [](R3Element<S> const& left, R3Element<S> const& right) {
              return left.Norm²() < right.Norm²();
            });
  return NormalizeOrZero(vs.back());
}

template<typename Frame>
SymmetricBilinearForm<double, Frame> const& InnerProductForm() {
  static auto const identity =
      SymmetricBilinearForm<double, Frame>(R3x3Matrix<double>::Identity());
  return identity;
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator+(
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator-(
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(-right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator+(
    SymmetricBilinearForm<Scalar, Frame> const& left,
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(left.matrix_ + right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator-(
    SymmetricBilinearForm<Scalar, Frame> const& left,
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(left.matrix_ - right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator*(
    double const left,
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(left * right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator*(
    SymmetricBilinearForm<Scalar, Frame> const& left,
    double const right) {
  return SymmetricBilinearForm<Scalar, Frame>(left.matrix_ * right);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator/(
    SymmetricBilinearForm<Scalar, Frame> const& left,
    double const right) {
  return SymmetricBilinearForm<Scalar, Frame>(left.matrix_ / right);
}

template<typename LScalar, typename RScalar, typename Frame>
Vector<Product<LScalar, RScalar>, Frame> operator*(
    SymmetricBilinearForm<LScalar, Frame> const& left,
    Vector<RScalar, Frame> const& right) {
  return Vector<Product<LScalar, RScalar>, Frame>(left.matrix_ *
                                                  right.coordinates());
}

template<typename LScalar, typename RScalar, typename Frame>
Vector<Product<LScalar, RScalar>, Frame> operator*(
    Vector<LScalar, Frame> const& left,
    SymmetricBilinearForm<RScalar, Frame> const& right) {
  return Vector<Product<LScalar, RScalar>, Frame>(left.coordinates() *
                                                  right.matrix_);
}

template<typename LScalar, typename RScalar, typename Frame>
SymmetricBilinearForm<Product<LScalar, RScalar>, Frame> SymmetricProduct(
    Vector<LScalar, Frame> const& left,
    Vector<RScalar, Frame> const& right) {
  return SymmetricBilinearForm<Product<LScalar, RScalar>, Frame>(
      0.5 * (KroneckerProduct(left.coordinates(), right.coordinates()) +
             KroneckerProduct(right.coordinates(), left.coordinates())));
}

template<typename LScalar, typename RScalar, typename Frame>
Bivector<Product<LScalar, RScalar>, Frame> Anticommutator(
    SymmetricBilinearForm<LScalar, Frame> const& form,
    Bivector<RScalar, Frame> const& bivector) {
  return Bivector<Product<LScalar, RScalar>, Frame>(
      form.matrix_.Trace() * bivector.coordinates() -
      form.matrix_ * bivector.coordinates());
}

template<typename Scalar, typename Frame>
bool operator==(SymmetricBilinearForm<Scalar, Frame> const& left,
                SymmetricBilinearForm<Scalar, Frame> const& right) {
  return left.matrix_ == right.matrix_;
}

template<typename Scalar, typename Frame>
bool operator!=(SymmetricBilinearForm<Scalar, Frame> const& left,
                SymmetricBilinearForm<Scalar, Frame> const& right) {
  return left.matrix_ != right.matrix_;
}

template<typename Scalar, typename Frame>
std::string DebugString(SymmetricBilinearForm<Scalar, Frame> const& form) {
  return DebugString(form.matrix_);
}

template<typename Scalar, typename Frame>
std::ostream& operator<<(std::ostream& out,
                         SymmetricBilinearForm<Scalar, Frame> const& form) {
  out << form.matrix_;
  return out;
}

}  // namespace internal_symmetric_bilinear_form
}  // namespace geometry
}  // namespace principia
<commit_msg>Typo.<commit_after>
#pragma once

#include "geometry/symmetric_bilinear_form.hpp"

#include <string>

#include "geometry/grassmann.hpp"
#include "geometry/r3_element.hpp"
#include "quantities/elementary_functions.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"

namespace principia {
namespace geometry {
namespace internal_symmetric_bilinear_form {

using quantities::Angle;
using quantities::ArcCos;
using quantities::Cos;
using quantities::Sqrt;
using quantities::si::Radian;

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>& SymmetricBilinearForm<Scalar, Frame>::
operator+=(SymmetricBilinearForm const& right) {
  return *this = *this + right;
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>& SymmetricBilinearForm<Scalar, Frame>::
operator-=(SymmetricBilinearForm const& right) {
  return *this = *this - right;
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>& SymmetricBilinearForm<Scalar, Frame>::
operator*=(double const right) {
  return *this = *this * right;
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>& SymmetricBilinearForm<Scalar, Frame>::
operator/=(double const right) {
  return *this = *this / right;
}

template<typename Scalar, typename Frame>
template<typename LScalar, typename RScalar>
Product<Scalar, Product<LScalar, RScalar>>
SymmetricBilinearForm<Scalar, Frame>::operator()(
    Vector<LScalar, Frame> const& left,
    Vector<RScalar, Frame> const& right) const {
  return InnerProduct(left, *this * right);
}

template<typename Scalar, typename Frame>
template<typename Eigenframe>
typename SymmetricBilinearForm<Scalar, Frame>::Eigensystem<Eigenframe>
SymmetricBilinearForm<Scalar, Frame>::Diagonalize() const {
  R3x3Matrix<Scalar> const& A = matrix_;
  auto const I = R3x3Matrix<double>::Identity();

  // This algorithm follows
  // https://en.wikipedia.org/wiki/Eigenvalue_algorithm#3%C3%973_matrices which
  // gives closed-form formulæ for 3x3 matrices.
  Scalar const q = A.Trace() / 3;
  R3x3Matrix<Scalar> const A_minus_qI = A - q * I;
  Scalar const p = Sqrt((A_minus_qI * A_minus_qI).Trace() / 6);
  R3x3Matrix<double> const B = A_minus_qI / p;
  double const det_B = B.Determinant();
  Angle const θ = ArcCos(det_B * 0.5);
  double const β₀ = 2 * Cos(θ / 3);
  double const β₁ = 2 * Cos((θ + 2 * π * Radian) / 3);
  double const β₂ = 2 * Cos((θ + 4 * π * Radian) / 3);
  std::array<Scalar, 3> αs = {p * β₀ + q, p * β₁ + q, p * β₂ + q};
  std::sort(αs.begin(), αs.end());
  Scalar const& α₀ = αs[0];
  Scalar const& α₁ = αs[1];
  Scalar const& α₂ = αs[2];
  R3x3Matrix<Scalar> const A_minus_α₀I = A - α₀ * I;
  R3x3Matrix<Scalar> const A_minus_α₁I = A - α₁ * I;
  R3x3Matrix<Scalar> const A_minus_α₂I = A - α₂ * I;

  // The form in its diagonal basis.
  Scalar const zero;
  SymmetricBilinearForm<Scalar, Eigenframe> form(
      R3x3Matrix<Scalar>({  α₀, zero, zero},
                         {zero,   α₁, zero},
                         {zero, zero,   α₂}));

  // Use the Cayley-Hamilton theorem to efficiently find the eigenvectors.  The
  // m matrices contain, in columns, eigenvectors for the corresponding α.
  // However it's possible for a column to be identically 0.  To deal with this
  // the call to PickEigenvector extracts the column with the largest norm.
  auto const m₀ = A_minus_α₁I * A_minus_α₂I;
  auto const m₁ = A_minus_α₂I * A_minus_α₀I;
  auto const m₂ = A_minus_α₀I * A_minus_α₁I;
  auto const v₀ = PickEigenvector(m₀);
  auto const v₁ = PickEigenvector(m₁);

  // The vectors (v₀, v₁, v₂) forms an orthonormal basis.  Make sure that it is
  // direct.
  auto v₂ = PickEigenvector(m₂);
  if (R3x3Matrix(v₀, v₁, v₂).Determinant() < 0) {
    v₂ = -v₂;
  }
  Rotation<Frame, Eigenframe> const rotation{
      Vector<double, Frame>(v₀),
      Vector<double, Frame>(v₁),
      Bivector<double, Frame>(v₂)};  // This bivector is a bit dodgy.
  return {form, rotation};
}

template<typename Scalar, typename Frame>
void SymmetricBilinearForm<Scalar, Frame>::WriteToMessage(
    not_null<serialization::SymmetricBilinearForm*> message) const {
  Frame::WriteToMessage(message->mutable_frame());
  matrix_.WriteToMessage(message->mutable_matrix());
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>
SymmetricBilinearForm<Scalar, Frame>::ReadFromMessage(
    serialization::SymmetricBilinearForm const& message) {
  Frame::ReadFromMessage(message.frame());
  return SymmetricBilinearForm(
      R3x3Matrix<Scalar>::ReadFromMessage(message.matrix()));
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>::SymmetricBilinearForm(
    R3x3Matrix<Scalar> const& matrix)
    : matrix_(matrix) {
  DCHECK_EQ(matrix_(0, 1), matrix_(1, 0));
  DCHECK_EQ(matrix_(0, 2), matrix_(2, 0));
  DCHECK_EQ(matrix_(1, 2), matrix_(2, 1));
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame>::SymmetricBilinearForm(
    R3x3Matrix<Scalar>&& matrix)
    : matrix_(std::move(matrix)) {
  DCHECK_EQ(matrix_(0, 1), matrix_(1, 0));
  DCHECK_EQ(matrix_(0, 2), matrix_(2, 0));
  DCHECK_EQ(matrix_(1, 2), matrix_(2, 1));
}

template<typename Scalar, typename Frame>
template<typename S>
R3Element<double> SymmetricBilinearForm<Scalar, Frame>::PickEigenvector(
    R3x3Matrix<S> const& matrix) {
  static R3Element<double> const e₀{1, 0, 0};
  static R3Element<double> const e₁{0, 1, 0};
  static R3Element<double> const e₂{0, 0, 1};
  std::array<R3Element<S>, 3> vs = {matrix * e₀, matrix * e₁, matrix * e₂};
  std::sort(vs.begin(),
            vs.end(),
            [](R3Element<S> const& left, R3Element<S> const& right) {
              return left.Norm²() < right.Norm²();
            });
  return NormalizeOrZero(vs.back());
}

template<typename Frame>
SymmetricBilinearForm<double, Frame> const& InnerProductForm() {
  static auto const identity =
      SymmetricBilinearForm<double, Frame>(R3x3Matrix<double>::Identity());
  return identity;
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator+(
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator-(
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(-right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator+(
    SymmetricBilinearForm<Scalar, Frame> const& left,
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(left.matrix_ + right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator-(
    SymmetricBilinearForm<Scalar, Frame> const& left,
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(left.matrix_ - right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator*(
    double const left,
    SymmetricBilinearForm<Scalar, Frame> const& right) {
  return SymmetricBilinearForm<Scalar, Frame>(left * right.matrix_);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator*(
    SymmetricBilinearForm<Scalar, Frame> const& left,
    double const right) {
  return SymmetricBilinearForm<Scalar, Frame>(left.matrix_ * right);
}

template<typename Scalar, typename Frame>
SymmetricBilinearForm<Scalar, Frame> operator/(
    SymmetricBilinearForm<Scalar, Frame> const& left,
    double const right) {
  return SymmetricBilinearForm<Scalar, Frame>(left.matrix_ / right);
}

template<typename LScalar, typename RScalar, typename Frame>
Vector<Product<LScalar, RScalar>, Frame> operator*(
    SymmetricBilinearForm<LScalar, Frame> const& left,
    Vector<RScalar, Frame> const& right) {
  return Vector<Product<LScalar, RScalar>, Frame>(left.matrix_ *
                                                  right.coordinates());
}

template<typename LScalar, typename RScalar, typename Frame>
Vector<Product<LScalar, RScalar>, Frame> operator*(
    Vector<LScalar, Frame> const& left,
    SymmetricBilinearForm<RScalar, Frame> const& right) {
  return Vector<Product<LScalar, RScalar>, Frame>(left.coordinates() *
                                                  right.matrix_);
}

template<typename LScalar, typename RScalar, typename Frame>
SymmetricBilinearForm<Product<LScalar, RScalar>, Frame> SymmetricProduct(
    Vector<LScalar, Frame> const& left,
    Vector<RScalar, Frame> const& right) {
  return SymmetricBilinearForm<Product<LScalar, RScalar>, Frame>(
      0.5 * (KroneckerProduct(left.coordinates(), right.coordinates()) +
             KroneckerProduct(right.coordinates(), left.coordinates())));
}

template<typename LScalar, typename RScalar, typename Frame>
Bivector<Product<LScalar, RScalar>, Frame> Anticommutator(
    SymmetricBilinearForm<LScalar, Frame> const& form,
    Bivector<RScalar, Frame> const& bivector) {
  return Bivector<Product<LScalar, RScalar>, Frame>(
      form.matrix_.Trace() * bivector.coordinates() -
      form.matrix_ * bivector.coordinates());
}

template<typename Scalar, typename Frame>
bool operator==(SymmetricBilinearForm<Scalar, Frame> const& left,
                SymmetricBilinearForm<Scalar, Frame> const& right) {
  return left.matrix_ == right.matrix_;
}

template<typename Scalar, typename Frame>
bool operator!=(SymmetricBilinearForm<Scalar, Frame> const& left,
                SymmetricBilinearForm<Scalar, Frame> const& right) {
  return left.matrix_ != right.matrix_;
}

template<typename Scalar, typename Frame>
std::string DebugString(SymmetricBilinearForm<Scalar, Frame> const& form) {
  return DebugString(form.matrix_);
}

template<typename Scalar, typename Frame>
std::ostream& operator<<(std::ostream& out,
                         SymmetricBilinearForm<Scalar, Frame> const& form) {
  out << form.matrix_;
  return out;
}

}  // namespace internal_symmetric_bilinear_form
}  // namespace geometry
}  // namespace principia
<|endoftext|>


<commit_before>#include "ossimCurlHttpRequest.h"

ossimRefPtr<ossimWebResponse> ossimCurlHttpRequest::getResponse()
{
   ossimRefPtr<ossimWebResponse> response;
   ossimString protocol = getUrl().getProtocol();
   if(!supportsProtocol(protocol))
   {
      return 0;
   }
   curl_easy_reset(m_curl);
   switch (m_methodType)
   {
      case ossimHttpRequest::HTTP_METHOD_GET:
      {
         ossimCurlHttpResponse* curlResponse = new ossimCurlHttpResponse();
         response = curlResponse;

         curl_easy_setopt(m_curl, CURLOPT_HEADERFUNCTION, curlWriteResponseHeader);
         curl_easy_setopt(m_curl, CURLOPT_HEADERDATA, (void*)response.get());
         curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, curlWriteResponseBody);
         curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, (void*)response.get());
         curl_easy_setopt(m_curl, CURLOPT_HEADER, 0);
         curl_easy_setopt(m_curl, CURLOPT_NOBODY, 0);
         //curl_easy_setopt(m_curl, CURLOPT_CONNECT_ONLY, 1);
        // ossimKeywordlist::KeywordMap& headerMap = m_headerOptions.getMap();
        // struct curl_slist *headers=0; /* init to NULL is important */
         ossimString range = m_headerOptions.find("Range");
         range=range.substitute("bytes=", "");
         curl_easy_setopt(m_curl, CURLOPT_RANGE, range.c_str());
         // ossimKeywordlist::KeywordMap::iterator iter = headerMap.begin();
         // while(iter != headerMap.end())
         // {
         //    std::cout << ((*iter).first + ":"+(*iter).second).c_str() << std::endl;
         //    headers = curl_slist_append(headers, ((*iter).first + ":"+(*iter).second).c_str());
         //    ++iter;
         // }
         ossimString urlString = getUrl().toString();
         curl_easy_setopt(m_curl, CURLOPT_URL, urlString.c_str());

         if(protocol == "https")
         {
            curl_easy_setopt(m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);//);
            curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, 0L);
         }

         int rc = curl_easy_perform(m_curl);

         if(rc == CURLE_SSL_CONNECT_ERROR)
         {
            // try default if an error for SSL connect ocurred
            curl_easy_setopt(m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
            rc = curl_easy_perform(m_curl);
         }
         bool result = (rc < 1);
         if(result)
         {
            curlResponse->convertHeaderStreamToKeywordlist();
         }
         else
         {
            m_lastError = curl_easy_strerror((CURLcode)rc);
            //std::cout << curl_easy_strerror((CURLcode)rc) << std::endl;
            response = 0;
         }
         break;
      }

      default:
         break;
   }

   return response;
}

bool ossimCurlHttpRequest::supportsProtocol(const ossimString& protocol)const
{
   bool result = false;
   if(protocol == "http")
   {
      result = true;
   }
   else if(protocol == "https")
   {
      curl_version_info_data * vinfo = curl_version_info( CURLVERSION_NOW );
      if( vinfo->features & CURL_VERSION_SSL )
      {
         result = true;
      }
   }
   return result;
}

int ossimCurlHttpRequest::curlWriteResponseBody(void *buffer, size_t size, size_t nmemb, void *stream)
{
   ossimHttpResponse* cStream = static_cast<ossimHttpResponse*>(stream);

   if(cStream)
   {
      cStream->bodyStream().write((char*)buffer, nmemb*size);
      return nmemb*size;
   }

   return 0;
}

int ossimCurlHttpRequest::curlWriteResponseHeader(void *buffer, size_t size, size_t nmemb, void *stream)
{
   ossimHttpResponse* cStream = static_cast<ossimHttpResponse*>(stream);
   if(cStream)
   {
      cStream->headerStream().write((char*)buffer, nmemb*size);
      return nmemb*size;
   }

   return 0;
}

ossim_int64 ossimCurlHttpRequest::getContentLength()const
{
   double contentLength=-1;
   curl_easy_reset(m_curl);

   ossimString urlString = getUrl().toString();
   ossimString protocol = getUrl().getProtocol();
   ossimRefPtr<ossimCurlHttpResponse> response = new ossimCurlHttpResponse();

   curl_easy_setopt(m_curl, CURLOPT_HEADERFUNCTION, curlWriteResponseHeader);
   curl_easy_setopt(m_curl, CURLOPT_HEADERDATA, (void*)response.get());
   curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, curlWriteResponseBody);
   curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, (void*)response.get());
   curl_easy_setopt(m_curl, CURLOPT_HEADER, 0);
   curl_easy_setopt(m_curl, CURLOPT_NOBODY, 1);
   curl_easy_setopt(m_curl, CURLOPT_RANGE, "");

   const ossimKeywordlist::KeywordMap& headerMap = m_headerOptions.getMap();
   struct curl_slist *headers=0; /* init to NULL is important */

   ossimKeywordlist::KeywordMap::const_iterator iter = headerMap.begin();
   while(iter != headerMap.end())
   {
//      std::cout << ((*iter).first + ":"+(*iter).second).c_str() << std::endl;
      headers = curl_slist_append(headers, ((*iter).first + ":"+(*iter).second).c_str());
      ++iter;
   }
   curl_easy_setopt(m_curl, CURLOPT_URL, urlString.c_str());
   if(protocol == "https")
   {
      curl_easy_setopt(m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);//);
      curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, 0L);
   }
   int rc = curl_easy_perform(m_curl);

   //rc = curl_easy_getinfo(m_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
   if(rc == CURLE_SSL_CONNECT_ERROR)
   {
      // try default if an error for SSL connect ocurred
      curl_easy_setopt(m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
      rc = curl_easy_perform(m_curl);
   }
   bool result = (rc < 1);
   if(result)
   {
      response->convertHeaderStreamToKeywordlist();
      rc = curl_easy_getinfo(m_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
   //if(rc>=1) contentLength = -1;
   // response->convertHeaderStreamToKeywordlist();
   //std::cout << response->headerKwl() << "\n";
   }
   else
   {
      m_lastError = curl_easy_strerror((CURLcode)rc);
      //std::cout << curl_easy_strerror((CURLcode)rc) << std::endl;
   }

   return static_cast<ossim_int64> (contentLength);
}

<commit_msg>Added clearLastError<commit_after>#include "ossimCurlHttpRequest.h"

ossimRefPtr<ossimWebResponse> ossimCurlHttpRequest::getResponse()
{
   ossimRefPtr<ossimWebResponse> response;
   ossimString protocol = getUrl().getProtocol();
   if(!supportsProtocol(protocol))
   {
      return 0;
   }
   curl_easy_reset(m_curl);
   clearLastError();
   switch (m_methodType)
   {
      case ossimHttpRequest::HTTP_METHOD_GET:
      {
         ossimCurlHttpResponse* curlResponse = new ossimCurlHttpResponse();
         response = curlResponse;

         curl_easy_setopt(m_curl, CURLOPT_HEADERFUNCTION, curlWriteResponseHeader);
         curl_easy_setopt(m_curl, CURLOPT_HEADERDATA, (void*)response.get());
         curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, curlWriteResponseBody);
         curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, (void*)response.get());
         curl_easy_setopt(m_curl, CURLOPT_HEADER, 0);
         curl_easy_setopt(m_curl, CURLOPT_NOBODY, 0);
         //curl_easy_setopt(m_curl, CURLOPT_CONNECT_ONLY, 1);
        // ossimKeywordlist::KeywordMap& headerMap = m_headerOptions.getMap();
        // struct curl_slist *headers=0; /* init to NULL is important */
         ossimString range = m_headerOptions.find("Range");
         range=range.substitute("bytes=", "");
         curl_easy_setopt(m_curl, CURLOPT_RANGE, range.c_str());
         // ossimKeywordlist::KeywordMap::iterator iter = headerMap.begin();
         // while(iter != headerMap.end())
         // {
         //    std::cout << ((*iter).first + ":"+(*iter).second).c_str() << std::endl;
         //    headers = curl_slist_append(headers, ((*iter).first + ":"+(*iter).second).c_str());
         //    ++iter;
         // }
         ossimString urlString = getUrl().toString();
         curl_easy_setopt(m_curl, CURLOPT_URL, urlString.c_str());

         if(protocol == "https")
         {
            curl_easy_setopt(m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);//);
            curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, 0L);
         }

         int rc = curl_easy_perform(m_curl);

         if(rc == CURLE_SSL_CONNECT_ERROR)
         {
            // try default if an error for SSL connect ocurred
            curl_easy_setopt(m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
            rc = curl_easy_perform(m_curl);
         }
         bool result = (rc < 1);
         if(result)
         {
            curlResponse->convertHeaderStreamToKeywordlist();
         }
         else
         {
            m_lastError = curl_easy_strerror((CURLcode)rc);
            //std::cout << curl_easy_strerror((CURLcode)rc) << std::endl;
            response = 0;
         }
         break;
      }

      default:
         break;
   }

   return response;
}

bool ossimCurlHttpRequest::supportsProtocol(const ossimString& protocol)const
{
   bool result = false;
   if(protocol == "http")
   {
      result = true;
   }
   else if(protocol == "https")
   {
      curl_version_info_data * vinfo = curl_version_info( CURLVERSION_NOW );
      if( vinfo->features & CURL_VERSION_SSL )
      {
         result = true;
      }
   }
   return result;
}

int ossimCurlHttpRequest::curlWriteResponseBody(void *buffer, size_t size, size_t nmemb, void *stream)
{
   ossimHttpResponse* cStream = static_cast<ossimHttpResponse*>(stream);

   if(cStream)
   {
      cStream->bodyStream().write((char*)buffer, nmemb*size);
      return nmemb*size;
   }

   return 0;
}

int ossimCurlHttpRequest::curlWriteResponseHeader(void *buffer, size_t size, size_t nmemb, void *stream)
{
   ossimHttpResponse* cStream = static_cast<ossimHttpResponse*>(stream);
   if(cStream)
   {
      cStream->headerStream().write((char*)buffer, nmemb*size);
      return nmemb*size;
   }

   return 0;
}

ossim_int64 ossimCurlHttpRequest::getContentLength()const
{
   double contentLength=-1;
   curl_easy_reset(m_curl);
   clearLastError();
   ossimString urlString = getUrl().toString();
   ossimString protocol = getUrl().getProtocol();
   ossimRefPtr<ossimCurlHttpResponse> response = new ossimCurlHttpResponse();

   curl_easy_setopt(m_curl, CURLOPT_HEADERFUNCTION, curlWriteResponseHeader);
   curl_easy_setopt(m_curl, CURLOPT_HEADERDATA, (void*)response.get());
   curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, curlWriteResponseBody);
   curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, (void*)response.get());
   curl_easy_setopt(m_curl, CURLOPT_HEADER, 0);
   curl_easy_setopt(m_curl, CURLOPT_NOBODY, 1);
   curl_easy_setopt(m_curl, CURLOPT_RANGE, "");

   const ossimKeywordlist::KeywordMap& headerMap = m_headerOptions.getMap();
   struct curl_slist *headers=0; /* init to NULL is important */

   ossimKeywordlist::KeywordMap::const_iterator iter = headerMap.begin();
   while(iter != headerMap.end())
   {
//      std::cout << ((*iter).first + ":"+(*iter).second).c_str() << std::endl;
      headers = curl_slist_append(headers, ((*iter).first + ":"+(*iter).second).c_str());
      ++iter;
   }
   curl_easy_setopt(m_curl, CURLOPT_URL, urlString.c_str());
   if(protocol == "https")
   {
      curl_easy_setopt(m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);//);
      curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, 0L);
   }
   int rc = curl_easy_perform(m_curl);

   //rc = curl_easy_getinfo(m_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
   if(rc == CURLE_SSL_CONNECT_ERROR)
   {
      // try default if an error for SSL connect ocurred
      curl_easy_setopt(m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
      rc = curl_easy_perform(m_curl);
   }
   bool result = (rc < 1);
   if(result)
   {
      response->convertHeaderStreamToKeywordlist();
      rc = curl_easy_getinfo(m_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
   //if(rc>=1) contentLength = -1;
   // response->convertHeaderStreamToKeywordlist();
   //std::cout << response->headerKwl() << "\n";
   }
   else
   {
      m_lastError = curl_easy_strerror((CURLcode)rc);
      //std::cout << curl_easy_strerror((CURLcode)rc) << std::endl;
   }

   return static_cast<ossim_int64> (contentLength);
}

<|endoftext|>


<commit_before>// bslh_siphashalgorithm.cpp                                          -*-C++-*-
#include <bslh_siphashalgorithm.h>

#include <bsls_ident.h>
BSLS_IDENT("$Id$ $CSID$")

#include <bsls_assert.h>
#include <bsls_types.h>
#include <bsls_platform.h>

#include <algorithm>
#include <stddef.h>  // for 'size_t'
#include <string.h>

///Changes
///-------
// The third party code begins with the "siphash.h" header below, and continues
// until the Bloomberg LP copyright banner below.  Changes made to the original
// code include:
//
//: 1  Adding BloombergLP and bslh namespaces
//:
//: 2  Renaming 'siphash' to 'SipHashAlgorithm'
//:
//: 3  White space to meet BDE standards.
//:
//: 4  Added initializer list to handle class member initializers removed from
//:    the header
//:
//: 5  Added 'computeHash()' to handle explicit conversion removed from header.
//:
//: 6  Changed the constructor to accept a 'const char *'
//:
//: 7  Changed endianness check to use BDE-defined check
//:
//: 8  Removed unnamed namespace in favour of 'static'
//:
//: 9  Added function contracts
//:
//: 10 Added asserts to check passed pointers
//:
//: 11 Re-wrote unaligned reads to buffer data and then perform aligned reads
//:    to prevent runtime errors in opt builds on Sun machines.
//
///Third Party Doc
///---------------
//------------------------------- siphash.h -----------------------------------
//
// This software is in the public domain.  The only restriction on its use is
// that no one can remove it from the public domain by claiming ownership of
// it, including the original authors.
//
// There is no warranty of correctness on the software contained herein.  Use
// at your own risk.
//
// Derived from:
//
// SipHash reference C implementation
//
// Written in 2012 by Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
// Daniel J. Bernstein <djb@cr.yp.to>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide.  This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software.  If not, see
// <http://creativecommons.org/publicdomain/zero/1.0/>.
//
//-----------------------------------------------------------------------------

namespace BloombergLP {

namespace bslh {

typedef bsls::Types::Uint64 u64;
typedef unsigned int        u32;
typedef unsigned char       u8;

inline
static u64 rotl(u64 x, u64 b)
    // Return the bits of the specified 'x' rotated to the left by  the
    // specified 'b' number of bits.  Bits that are rotated off the end are
    // wrapped around to the beginning.
{
    return (x << b) | (x >> (64 - b));
}

inline
static void sipround(u64& v0, u64& v1, u64& v2, u64& v3)
    // Mix the specified 'v0', 'v1', 'v2', and 'v3' in a "Sip Round" as
    // described in the SipHash algorithm
{
    v0 += v1;
    v1 = rotl(v1, 13);
    v1 ^= v0;
    v0 = rotl(v0, 32);
    v2 += v3;
    v3 = rotl(v3, 16);
    v3 ^= v2;
    v0 += v3;
    v3 = rotl(v3, 21);
    v3 ^= v0;
    v2 += v1;
    v1 = rotl(v1, 17);
    v1 ^= v2;
    v2 = rotl(v2, 32);
}

inline
static u64 u8to64_le(const u8* p)
    // Return the 64-bit integer representation of the specified 'p' taking
    // into account endianness.  Undefined unless 'p' points to at least one
    // byte of initialized memory.
{
    BSLS_ASSERT(p);

    union { char bytes[8]; u64 ret; };
#if defined(BSLS_PLATFORM_CPU_X86) || defined(BSLS_PLATFORM_CPU_X86_64)
    ret = *reinterpret_cast<const u64 *>(p);  // Ignore alignment.
#elif defined(BSLS_PLATFORM_IS_LITTLE_ENDIAN)
    memcpy(bytes, p, sizeof(bytes));
#elif defined(BSLS_PLATFORM_CMP_SUN)  // SUNPRO optimizes better this way?
    bytes[0] = p[7];
    bytes[1] = p[6];
    bytes[2] = p[5];
    bytes[3] = p[4];
    bytes[4] = p[3];
    bytes[5] = p[2];
    bytes[6] = p[1];
    bytes[7] = p[0];
#else
    ret = u64(p[7]) << 56 | u64(p[6]) << 48 |
          u64(p[5]) << 40 | u64(p[4]) << 32 |
          u64(p[3]) << 24 | u64(p[2]) << 16 |
          u64(p[1]) <<  8 | u64(p[0]);
#endif
    return ret;
}

SipHashAlgorithm::SipHashAlgorithm(const char *seed)
: d_v0(0x736f6d6570736575ULL)
, d_v1(0x646f72616e646f6dULL)
, d_v2(0x6c7967656e657261ULL)
, d_v3(0x7465646279746573ULL)
, d_bufSize(0)
, d_totalLength(0)
{
    BSLS_ASSERT(seed);

#if defined(BSLS_PLATFORM_CPU_X86) || defined(BSLS_PLATFORM_CPU_X86_64)
    const u64 *aligned = reinterpret_cast<const u64 *>(seed);
#else
    union { char bytes[16]; u64 aligned[2]; };
    memcpy(&bytes, seed, sizeof(bytes));
#endif
    d_v0 ^= aligned[0];
    d_v1 ^= aligned[1];
    d_v2 ^= aligned[0];
    d_v3 ^= aligned[1];
}

void
SipHashAlgorithm::operator()(const void *data, size_t numBytes)
{
    BSLS_ASSERT(data);

    u8 const* in = static_cast<const u8*>(data);

    d_totalLength += numBytes;
    if (d_bufSize + numBytes < 8)
    {
        std::copy(in, in + numBytes, d_buf + d_bufSize);
        d_bufSize += numBytes;
        return;                                                       // RETURN
    }
    if (d_bufSize > 0)
    {
        size_t t = 8 - d_bufSize;
        std::copy(in, in+t, d_buf + d_bufSize);
        u64 m = u8to64_le( d_buf );
        d_v3 ^= m;
        sipround(d_v0, d_v1, d_v2, d_v3);
        sipround(d_v0, d_v1, d_v2, d_v3);
        d_v0 ^= m;
        in += t;
        numBytes -= t;
    }
    d_bufSize = numBytes & 7;
    u8 const* const end = in + (numBytes - d_bufSize);
    for ( ; in != end; in += 8 )
    {
        u64 m = u8to64_le( in );
        d_v3 ^= m;
        sipround(d_v0, d_v1, d_v2, d_v3);
        sipround(d_v0, d_v1, d_v2, d_v3);
        d_v0 ^= m;
    }
    std::copy(end, end + d_bufSize, d_buf);
}

SipHashAlgorithm::result_type SipHashAlgorithm::computeHash()
{
    result_type b = static_cast<u64>(d_totalLength) << 56;
    switch(d_bufSize)
    {
    case 7:
        b |= static_cast<u64>(d_buf[6]) << 48;
    case 6:
        b |= static_cast<u64>(d_buf[5]) << 40;
    case 5:
        b |= static_cast<u64>(d_buf[4]) << 32;
    case 4:
        b |= static_cast<u64>(d_buf[3]) << 24;
    case 3:
        b |= static_cast<u64>(d_buf[2]) << 16;
    case 2:
        b |= static_cast<u64>(d_buf[1]) << 8;
    case 1:
        b |= static_cast<u64>(d_buf[0]);
    case 0:
        break;
    }
    d_v3 ^= b;
    sipround(d_v0, d_v1, d_v2, d_v3);
    sipround(d_v0, d_v1, d_v2, d_v3);
    d_v0 ^= b;
    d_v2 ^= 0xff;
    sipround(d_v0, d_v1, d_v2, d_v3);
    sipround(d_v0, d_v1, d_v2, d_v3);
    sipround(d_v0, d_v1, d_v2, d_v3);
    sipround(d_v0, d_v1, d_v2, d_v3);
    b = d_v0 ^ d_v1 ^ d_v2  ^ d_v3;
    return b;
}

}  // close package namespace

}  // close enterprise namespace

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

<commit_msg>use bsls_byteorder instead of rolling our own<commit_after>// bslh_siphashalgorithm.cpp                                          -*-C++-*-
#include <bslh_siphashalgorithm.h>

#include <bsls_ident.h>
BSLS_IDENT("$Id$ $CSID$")

#include <bsls_assert.h>
#include <bsls_types.h>
#include <bsls_platform.h>
#include <bsls_byteorder.h>

#include <algorithm>
#include <stddef.h>  // for 'size_t'
#include <string.h>

///Changes
///-------
// The third party code begins with the "siphash.h" header below, and continues
// until the Bloomberg LP copyright banner below.  Changes made to the original
// code include:
//
//: 1  Adding BloombergLP and bslh namespaces
//:
//: 2  Renaming 'siphash' to 'SipHashAlgorithm'
//:
//: 3  White space to meet BDE standards.
//:
//: 4  Added initializer list to handle class member initializers removed from
//:    the header
//:
//: 5  Added 'computeHash()' to handle explicit conversion removed from header.
//:
//: 6  Changed the constructor to accept a 'const char *'
//:
//: 7  Changed endianness check to use BDE-defined check
//:
//: 8  Removed unnamed namespace in favour of 'static'
//:
//: 9  Added function contracts
//:
//: 10 Added asserts to check passed pointers
//:
//: 11 Re-wrote unaligned reads to buffer data and then perform aligned reads
//:    to prevent runtime errors in opt builds on Sun machines.
//
///Third Party Doc
///---------------
//------------------------------- siphash.h -----------------------------------
//
// This software is in the public domain.  The only restriction on its use is
// that no one can remove it from the public domain by claiming ownership of
// it, including the original authors.
//
// There is no warranty of correctness on the software contained herein.  Use
// at your own risk.
//
// Derived from:
//
// SipHash reference C implementation
//
// Written in 2012 by Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
// Daniel J. Bernstein <djb@cr.yp.to>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide.  This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software.  If not, see
// <http://creativecommons.org/publicdomain/zero/1.0/>.
//
//-----------------------------------------------------------------------------

namespace BloombergLP {

namespace bslh {

typedef bsls::Types::Uint64 u64;
typedef unsigned int        u32;
typedef unsigned char       u8;

inline
static u64 rotl(u64 x, u64 b)
    // Return the bits of the specified 'x' rotated to the left by  the
    // specified 'b' number of bits.  Bits that are rotated off the end are
    // wrapped around to the beginning.
{
    return (x << b) | (x >> (64 - b));
}

inline
static void sipround(u64& v0, u64& v1, u64& v2, u64& v3)
    // Mix the specified 'v0', 'v1', 'v2', and 'v3' in a "Sip Round" as
    // described in the SipHash algorithm
{
    v0 += v1;
    v1 = rotl(v1, 13);
    v1 ^= v0;
    v0 = rotl(v0, 32);
    v2 += v3;
    v3 = rotl(v3, 16);
    v3 ^= v2;
    v0 += v3;
    v3 = rotl(v3, 21);
    v3 ^= v0;
    v2 += v1;
    v1 = rotl(v1, 17);
    v1 ^= v2;
    v2 = rotl(v2, 32);
}

inline
static u64 u8to64_le(const u8* p)
    // Return the 64-bit integer representation of the specified 'p' taking
    // into account endianness.  Undefined unless 'p' points to at least one
    // byte of initialized memory.
{
    BSLS_ASSERT(p);

#if defined(BSLS_PLATFORM_CPU_X86) || defined(BSLS_PLATFORM_CPU_X86_64)
    return *reinterpret_cast<const u64 *>(p);  // Ignore alignment.
#else
    u64 ret;
    memcpy(&ret, p, sizeof(ret));
    return(BSLS_BYTEORDER_LE_U64_TO_HOST(ret));
#endif
}

SipHashAlgorithm::SipHashAlgorithm(const char *seed)
: d_v0(0x736f6d6570736575ULL)
, d_v1(0x646f72616e646f6dULL)
, d_v2(0x6c7967656e657261ULL)
, d_v3(0x7465646279746573ULL)
, d_bufSize(0)
, d_totalLength(0)
{
    BSLS_ASSERT(seed);

#if defined(BSLS_PLATFORM_CPU_X86) || defined(BSLS_PLATFORM_CPU_X86_64)
    const u64 *aligned = reinterpret_cast<const u64 *>(seed);
#else
    u64 aligned[2];
    memcpy(&aligned, seed, sizeof(aligned));
#endif
    d_v0 ^= aligned[0];
    d_v1 ^= aligned[1];
    d_v2 ^= aligned[0];
    d_v3 ^= aligned[1];
}

void
SipHashAlgorithm::operator()(const void *data, size_t numBytes)
{
    BSLS_ASSERT(data);

    u8 const* in = static_cast<const u8*>(data);

    d_totalLength += numBytes;
    if (d_bufSize + numBytes < 8)
    {
        std::copy(in, in + numBytes, d_buf + d_bufSize);
        d_bufSize += numBytes;
        return;                                                       // RETURN
    }
    if (d_bufSize > 0)
    {
        size_t t = 8 - d_bufSize;
        std::copy(in, in+t, d_buf + d_bufSize);
        u64 m = u8to64_le( d_buf );
        d_v3 ^= m;
        sipround(d_v0, d_v1, d_v2, d_v3);
        sipround(d_v0, d_v1, d_v2, d_v3);
        d_v0 ^= m;
        in += t;
        numBytes -= t;
    }
    d_bufSize = numBytes & 7;
    u8 const* const end = in + (numBytes - d_bufSize);
    for ( ; in != end; in += 8 )
    {
        u64 m = u8to64_le( in );
        d_v3 ^= m;
        sipround(d_v0, d_v1, d_v2, d_v3);
        sipround(d_v0, d_v1, d_v2, d_v3);
        d_v0 ^= m;
    }
    std::copy(end, end + d_bufSize, d_buf);
}

SipHashAlgorithm::result_type SipHashAlgorithm::computeHash()
{
    result_type b = static_cast<u64>(d_totalLength) << 56;
    switch(d_bufSize)
    {
    case 7:
        b |= static_cast<u64>(d_buf[6]) << 48;
    case 6:
        b |= static_cast<u64>(d_buf[5]) << 40;
    case 5:
        b |= static_cast<u64>(d_buf[4]) << 32;
    case 4:
        b |= static_cast<u64>(d_buf[3]) << 24;
    case 3:
        b |= static_cast<u64>(d_buf[2]) << 16;
    case 2:
        b |= static_cast<u64>(d_buf[1]) << 8;
    case 1:
        b |= static_cast<u64>(d_buf[0]);
    case 0:
        break;
    }
    d_v3 ^= b;
    sipround(d_v0, d_v1, d_v2, d_v3);
    sipround(d_v0, d_v1, d_v2, d_v3);
    d_v0 ^= b;
    d_v2 ^= 0xff;
    sipround(d_v0, d_v1, d_v2, d_v3);
    sipround(d_v0, d_v1, d_v2, d_v3);
    sipround(d_v0, d_v1, d_v2, d_v3);
    sipround(d_v0, d_v1, d_v2, d_v3);
    b = d_v0 ^ d_v1 ^ d_v2  ^ d_v3;
    return b;
}

}  // close package namespace

}  // close enterprise namespace

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

<|endoftext|>